feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
module ;
# include <signal.h>
# include <stdio.h>
module Crafter . Review : Run_impl ;
import : Run ;
import : Json ;
import : Text ;
import : Core ;
import : Platform ;
import : Process ;
import : Http ;
import : Schema ;
import : Plan ;
import : Artifact ;
import : Inventory ;
import : Dispositions ;
import : State ;
import : Normalize ;
import : Stream ;
import : Prompt ;
import : Config ;
import : Memory ;
import : PgWire ;
import : Freeze ;
import : Seats ;
import : SeatPool ;
import : OpenCode ;
import : Pool ;
import std ;
namespace fs = std : : filesystem ;
namespace Crafter : : Review : : Run {
namespace {
[[noreturn]] void Die ( const std : : string & message ) {
throw Preflight ( message ) ;
}
void WriteText ( const fs : : path & path , std : : string_view text ) {
std : : ofstream file ( path , std : : ios : : binary | std : : ios : : trunc ) ;
file < < text ;
}
// A temp file renamed into place: what a reader opens is whole.
void WriteReplace ( const fs : : path & path , std : : string_view text ) {
const fs : : path temp = std : : format ( " {}.tmp " , path . string ( ) ) ;
WriteText ( temp , text ) ;
fs : : rename ( temp , path ) ;
}
std : : string Basename ( const fs : : path & path ) {
return Dyn : : BaseName ( path . string ( ) ) ;
}
double Number ( const Json & value ) {
if ( value . is_number ( ) ) return value . get < double > ( ) ;
if ( value . is_boolean ( ) ) return value . get < bool > ( ) ? 1.0 : 0.0 ;
return 0.0 ;
}
// A number or a numeric string, as an integer.
std : : int64_t Int ( const Json & value ) {
if ( value . is_number_integer ( ) ) return value . get < std : : int64_t > ( ) ;
if ( value . is_number ( ) ) return static_cast < std : : int64_t > ( value . get < double > ( ) ) ;
if ( value . is_boolean ( ) ) return value . get < bool > ( ) ? 1 : 0 ;
if ( value . is_string ( ) ) {
if ( const std : : optional < std : : int64_t > parsed = Dyn : : ParseInt ( value . get_ref < const std : : string & > ( ) ) ) return * parsed ;
throw Dyn : : Error ( " ValueError " , Dyn : : IntError ( value . get_ref < const std : : string & > ( ) ) ) ;
}
throw Dyn : : Error ( " TypeError " , std : : format ( " int() argument must be a string, a bytes-like object or a real number, not '{}' " , Dyn : : TypeName ( value ) ) ) ;
}
// Floor division of floats through fmod, exact where a plain quotient
// would round, and with the sign of zero kept.
double FloorDiv ( double vx , double wx ) {
double mod = std : : fmod ( vx , wx ) ;
double div = ( vx - mod ) / wx ;
if ( mod ! = 0 & & ( ( wx < 0 ) ! = ( mod < 0 ) ) ) {
mod + = wx ;
div - = 1.0 ;
}
if ( div ! = 0 ) {
double floordiv = std : : floor ( div ) ;
if ( div - floordiv > 0.5 ) floordiv + = 1.0 ;
return floordiv ;
}
return std : : copysign ( 0.0 , vx / wx ) ;
}
std : : vector < std : : string > Strings ( const Json & array ) {
std : : vector < std : : string > out ;
for ( const Json & item : Dyn : : Or ( array , Dyn : : EmptyList ( ) ) ) out . push_back ( Dyn : : Str ( item ) ) ;
return out ;
}
Json Array ( std : : span < const std : : string > values ) {
Json out = Json : : array ( ) ;
for ( const std : : string & v : values ) out . push_back ( v ) ;
return out ;
}
// The text a JSON object key is written as.
std : : string KeyText ( const Json & key ) {
return key . is_string ( ) ? key . get < std : : string > ( ) : DumpCompact ( key ) ;
}
// [x.strip() for x in text.split(',') if x.strip()]
std : : vector < std : : string > CommaList ( std : : string_view text ) {
std : : vector < std : : string > out ;
for ( const std : : string & part : Dyn : : Split ( text , " , " ) ) {
std : : string item = Dyn : : Strip ( part ) ;
if ( ! item . empty ( ) ) out . push_back ( std : : move ( item ) ) ;
}
return out ;
}
// label.replace('/', '_').replace(' ', '_')
std : : string FileLabel ( const Json & job ) {
return Dyn : : Replace ( Dyn : : Replace ( Dyn : : Str ( Dyn : : At ( job , " label " ) ) , " / " , " _ " ) , " " , " _ " ) ;
}
// The run a signal or `crafter-review stop` reaches.
std : : atomic < Run * > Current = nullptr ;
// The default: the process ends; what it started goes with it.
[[noreturn]] void EndNow ( std : : int32_t signal ) {
Process : : KillDescendants ( ) ;
std : : _Exit ( 128 + signal ) ;
}
void Trigger ( const std : : string & why , std : : int32_t signal ) {
Run * run = Current . load ( ) ;
if ( ! run | | ! run - > Ready ( ) | | signal = = SIGHUP ) EndNow ( signal ? signal : SIGTERM ) ;
run - > Stop ( why , signal ) ;
}
std : : string ScratchRoot ( const std : : optional < std : : string > & given ) {
if ( given & & ! given - > empty ( ) ) return * given ;
if ( const std : : optional < std : : string > configured = Platform : : GetEnv ( " REVIEW_GATES_SCRATCH " ) ; configured & & ! configured - > empty ( ) ) return * configured ;
return ( fs : : path ( Platform : : Home ( ) ) / " .cache " / " review-gates " ) . string ( ) ;
}
std : : map < std : : string , std : : int64_t > DefaultCosts ( ) {
std : : map < std : : string , std : : int64_t > out ;
for ( const Plan : : Environment & e : Plan : : Environments ) out [ std : : string ( e . name ) ] = e . memMb ;
return out ;
}
std : : vector < std : : string > ModelIds ( ) {
std : : vector < std : : string > out ;
for ( const Plan : : ModelTier & m : Plan : : Models ( ) ) {
if ( ! std : : ranges : : contains ( out , m . id ) ) out . push_back ( m . id ) ;
}
return out ;
}
}
void OnSignal ( std : : int32_t signal ) {
Trigger ( std : : format ( " signal {} " , signal ) , signal ) ;
}
Json ArgsJson ( const Arguments & a ) {
auto opt = [ ] ( const std : : optional < std : : string > & v ) { return v ? Json ( * v ) : Json ( ) ; } ;
Json units ;
if ( a . units ) {
units = Json : : array ( ) ;
for ( const std : : string & u : * a . units ) units . push_back ( u ) ;
}
return {
{ " config " , opt ( a . config ) } ,
{ " mode " , a . mode } ,
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
{ " subsystem " , opt ( a . subsystem ) } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " artifact " , a . artifact } ,
{ " hash " , opt ( a . hash ) } ,
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
{ " reviewers " , a . reviewers } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " dispositions " , opt ( a . dispositions ) } ,
{ " base " , a . base } ,
{ " date " , a . date } ,
{ " trees " , opt ( a . trees ) } ,
{ " context_paths " , a . contextPaths } ,
{ " only " , opt ( a . only ) } ,
{ " without " , opt ( a . without ) } ,
{ " units " , units } ,
{ " warm " , a . warm } ,
2026-10-31 17:33:11 +01:00
{ " concurrency " , a . concurrency ? Json ( * a . concurrency ) : Json ( ) } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " effort " , a . effort } ,
{ " reads " , a . reads } ,
{ " no_reuse " , a . noReuse } ,
{ " no_salvage " , a . noSalvage } ,
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
{ " persona_blocks " , a . personaBlocks } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " dry_run " , a . dryRun } ,
{ " claude_bin " , opt ( a . claudeBin ) } ,
{ " models " , a . models } ,
{ " scratch " , opt ( a . scratch ) } ,
{ " seats " , opt ( a . seats ) } ,
{ " env_file " , opt ( a . envFile ) } ,
{ " no_probe " , a . noProbe } ,
{ " api_budget " , a . apiBudget ? Json ( * a . apiBudget ) : Json ( ) } ,
{ " harness " , a . harness } ,
{ " variant " , opt ( a . variant ) } ,
{ " opencode_bin " , opt ( a . opencodeBin ) } ,
} ;
}
std : : pair < bool , std : : string > AppReady ( std : : string_view url , std : : string_view path , double timeout ) {
const std : : string full = std : : format ( " {}/{} " , Dyn : : RStrip ( url , " / " ) , Dyn : : LStrip ( path . empty ( ) ? std : : string_view ( " / " ) : path , " / " ) ) ;
try {
const Http : : Response r = Http : : UrlOpen ( full , { { " User-Agent " , " review-gates " } } , timeout ) ;
return { r . status < 500 , std : : format ( " HTTP {} from {} " , r . status , full ) } ;
} catch ( const Http : : HttpError & e ) {
return { e . Code ( ) < 500 , std : : format ( " HTTP {} from {} " , e . Code ( ) , full ) } ;
} catch ( const std : : exception & e ) {
return { false , std : : format ( " {}: {} " , full , e . what ( ) ) } ;
}
}
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
std : : pair < std : : int64_t , std : : vector < std : : string > > SlotsPlan ( const Json & cfg , const fs : : path & repo , const std : : optional < fs : : path > & artifact , const std : : optional < fs : : path > & scratchRoot , const Log & given ,
const Machine & machine ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const Log log = given ? given : Log ( [ ] ( const std : : string & line ) { std : : println ( " {} " , line ) ; } ) ;
const Json & sl = cfg . at ( " slots " ) ;
if ( ! Dyn : : Truthy ( Dyn : : Get ( sl , " dir " ) ) ) {
log ( " slots: the config names no slots.dir - the one stack of functional.* and supabase.*, one browser pass at a time on it " ) ;
return { 1 , { } } ;
}
const Config : : Slots slotted = Config : : SlotStacks ( cfg , repo ) ;
const Json & up = slotted . stacks ;
for ( const std : : string & x : slotted . problems ) log ( std : : format ( " slots: {} " , x ) ) ;
const std : : vector < std : : string > off = Config : : LensesOff ( cfg ) ;
const Json envs = Config : : Environments ( cfg ) ;
std : : set < std : : string > appEnvs ;
for ( auto it = envs . begin ( ) ; it ! = envs . end ( ) ; + + it ) {
const Plan : : Environment * e = Plan : : FindEnvironment ( Dyn : : Str ( it . value ( ) ) ) ;
if ( ! std : : ranges : : contains ( off , it . key ( ) ) & & e & & e - > app ) appEnvs . insert ( Dyn : : Str ( it . value ( ) ) ) ;
}
if ( appEnvs . empty ( ) ) {
log ( " slots: no lens that runs drives the application - no slot needed " ) ;
return { 0 , { } } ;
}
const fs : : path root = scratchRoot & & ! scratchRoot - > empty ( ) ? * scratchRoot : fs : : path ( ScratchRoot ( std : : nullopt ) ) ;
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
const Memory : : Calibration calib ( root / " memory.json " , artifact ? Freeze : : ReviewedBy ( * artifact , repo ) . repo : repo , DefaultCosts ( ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : optional < Memory : : Calibration : : Cost > best ;
for ( const std : : string & e : appEnvs ) {
Memory : : Calibration : : Cost cost = calib . CostOf ( e ) ;
if ( ! best | | Number ( cost . megabytes ) > Number ( best - > megabytes ) ) best = std : : move ( cost ) ;
}
const double passMb = Number ( best - > megabytes ) ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const std : : optional < std : : int64_t > avail = machine . available ? machine . available ( ) : Memory : : Available ( ) ;
const std : : int64_t reserve = machine . reserve ? machine . reserve ( ) : Memory : : Reserve ( ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const auto upCount = static_cast < std : : int64_t > ( up . size ( ) ) ;
if ( ! avail ) {
log ( " slots: no /proc/meminfo - cannot size the slots by memory " ) ;
return { std : : max < std : : int64_t > ( 1 , upCount ) , { } } ;
}
const double room = static_cast < double > ( * avail - reserve ) - static_cast < double > ( upCount ) * passMb ;
const std : : int64_t more = std : : max < std : : int64_t > ( 0 , static_cast < std : : int64_t > ( FloorDiv ( room , Number ( sl . at ( " memMb " ) ) + passMb ) ) ) ;
std : : int64_t want = upCount + more ;
std : : optional < std : : int64_t > planned ;
if ( artifact ) {
const Inventory : : Built built = Inventory : : Build ( " commits " , artifact - > string ( ) ) ;
const std : : vector < std : : string > exclude = Strings ( cfg . at ( " functional " ) . at ( " exclude " ) ) ;
std : : int64_t most = 0 ;
for ( auto it = envs . begin ( ) ; it ! = envs . end ( ) ; + + it ) {
const Plan : : Environment * e = Plan : : FindEnvironment ( Dyn : : Str ( it . value ( ) ) ) ;
if ( std : : ranges : : contains ( off , it . key ( ) ) | | ! e | | ! e - > app ) continue ;
const Plan : : LensPlan plan = Plan : : PlanLens ( it . key ( ) , built . out . at ( " units " ) , built . lines , { } , exclude ) ;
most = std : : max < std : : int64_t > ( most , std : : ranges : : count_if ( plan . blocks , [ ] ( const Json & b ) { return b . at ( " kind " ) = = " block " ; } ) ) ;
}
planned = most ;
want = std : : min ( want , std : : max < std : : int64_t > ( 1 , * planned ) ) ;
}
log ( std : : format ( " memory: {} MB free, reserve {} MB; a slot {} MB (slots.memMb), a pass with the browser ~{:.0f} MB ({}) " , * avail , reserve , Dyn : : Str ( sl . at ( " memMb " ) ) , passMb , best - > source ) ) ;
std : : vector < std : : string > ids ;
for ( const Json & s : up ) ids . push_back ( Dyn : : Str ( s . at ( " id " ) ) ) ;
log ( std : : format ( " slots up: {}{}; room for {} more by memory{} " , upCount , ids . empty ( ) ? std : : string ( ) : std : : format ( " ({}) " , Dyn : : Join ( ids , " , " ) ) , more ,
planned ? std : : format ( " ; the range has {} browser block pass(es) to run at once at most " , * planned ) : std : : string ( ) ) ) ;
std : : set < std : : int64_t > have ;
for ( const std : : string & id : ids ) {
const std : : vector < std : : string > words = Dyn : : Split ( id ) ;
if ( words . empty ( ) ) continue ;
if ( const std : : optional < std : : int64_t > n = Dyn : : ParseInt ( words . back ( ) ) ; n & & std : : ranges : : all_of ( Dyn : : Decode ( words . back ( ) ) , Dyn : : IsDecimal ) ) have . insert ( * n ) ;
}
std : : vector < std : : int64_t > fresh ;
for ( std : : int64_t n = 1 ; static_cast < std : : int64_t > ( have . size ( ) + fresh . size ( ) ) < want ; + + n ) {
if ( ! have . contains ( n ) ) fresh . push_back ( n ) ;
}
const std : : vector < std : : string > cmds = Config : : SlotCommands ( cfg , " start " , fresh ) ;
if ( ! fresh . empty ( ) & & cmds . empty ( ) ) {
std : : vector < std : : string > numbers ;
for ( const std : : int64_t n : fresh ) numbers . push_back ( std : : to_string ( n ) ) ;
log ( std : : format ( " slots: the config names no slots.start - bring up slots {} by hand " , Dyn : : Join ( numbers , " , " ) ) ) ;
}
const Json & startMb = Dyn : : Get ( sl , " startMb " ) ;
std : : int64_t batch = 1 ;
if ( Dyn : : Truthy ( startMb ) ) {
const double free = std : : max ( 0.0 , static_cast < double > ( * avail - reserve ) - static_cast < double > ( upCount ) * passMb ) ;
batch = std : : max < std : : int64_t > ( 1 , std : : min < std : : int64_t > ( fresh . empty ( ) ? 1 : static_cast < std : : int64_t > ( fresh . size ( ) ) , static_cast < std : : int64_t > ( FloorDiv ( free , Number ( startMb ) ) ) ) ) ;
}
if ( ! fresh . empty ( ) ) {
log ( std : : format ( " slots: bring up {} more -> {}, at most {} at once ({} " , fresh . size ( ) , want , batch ,
Dyn : : Truthy ( startMb ) ? std : : format ( " slots.startMb {} MB each while it comes up) " , Dyn : : Str ( startMb ) ) : std : : string ( " no slots.startMb: one at a time) " ) ) ) ;
} else {
log ( std : : format ( " slots: {} up, nothing more to bring up " , upCount ) ) ;
}
for ( const std : : string & c : cmds ) log ( std : : format ( " {} " , c ) ) ;
return { want , cmds } ;
}
// ---- the Run ---------------------------------------------------------------------------
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
Run : : Run ( ) : repo ( fs : : current_path ( ) ) , reviewed ( repo ) , t0 ( Platform : : Now ( ) ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
log = [ this ] ( const std : : string & message ) { Message ( message ) ; } ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
appReady = [ ] ( std : : string_view url , std : : string_view path ) { return AppReady ( url , path ) ; } ;
probe = [ ] ( std : : string_view url ) { return PgWire : : Probe ( url ) ; } ;
query = [ ] ( std : : string_view url , std : : string_view sql ) { return PgWire : : Query ( url , sql ) ; } ;
bypassesRls = [ ] ( std : : string_view url ) { return PgWire : : BypassesRls ( url ) ; } ;
migrationsAtHead = [ this ] { return MigrationsAtHead ( ) ; } ;
migrationsDrift = [ this ] ( const std : : string & url ) { return MigrationsDrift ( url ) ; } ;
treeDrift = [ this ] { return TreeDrift ( ) ; } ;
promptFor = [ this ] ( const Json & job ) { return PromptFor ( job ) ; } ;
runPass = [ this ] ( const Json & job , const std : : string & prompt , const fs : : path & systemPath , std : : string_view schema , std : : int64_t maxTurns , std : : int64_t timeoutMin , bool persist ) {
return runner - > Run ( job , prompt , systemPath , schema , trees , maxTurns , timeoutMin , persist ) ;
} ;
resumable = [ this ] ( const std : : string & name , const std : : string & lensFile , std : : string_view title ) { return Resumable ( name , lensFile , title ) ; } ;
instrumentPreflight = [ this ] ( std : : span < const std : : string > lensFiles ) { InstrumentPreflight ( lensFiles ) ; } ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
Run : : Run ( Arguments given , Json config ) : Run ( ) {
a = std : : move ( given ) ;
cfg = std : : move ( config ) ;
// The lens files the config turns off, and the environment of each.
off = Config : : LensesOff ( cfg ) ;
environments = Config : : Environments ( cfg ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
bool Run : : Kernel ( ) const {
return Plan : : IsKernelMode ( a . mode ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Run : : ~ Run ( ) {
// atexit's board.leave: everything of this driver off the board.
if ( board ) board - > Leave ( ) ;
if ( broker ) broker - > Close ( ) ;
}
void Run : : Message ( const std : : string & message ) {
const std : : string line = std : : format ( " {} {} " , Platform : : LocalTime ( " %H:%M:%S " ) , message ) ;
const std : : lock_guard guard ( logLock ) ;
logs . push_back ( line ) ;
std : : println ( " {} " , line ) ;
std : : fflush ( stdout ) ;
if ( logFile ) {
std : : ofstream file ( * logFile , std : : ios : : binary | std : : ios : : app ) ;
file < < line < < ' \n ' ;
}
}
bool Run : : Ready ( ) const {
return ready . load ( ) ;
}
std : : optional < fs : : path > Run : : StopFile ( ) const {
const std : : lock_guard guard ( shared ) ;
return stopFile ;
}
void Run : : Stop ( const std : : string & why , std : : int32_t signal ) {
const std : : int32_t n = runner ? runner - > KillChildren ( ) : 0 ;
const std : : string reason = signal ? std : : format ( " stopped by signal {} ({} running processes killed) " , signal , n ) : std : : format ( " stopped by {} ({} running processes killed) " , why , n ) ;
{
const std : : lock_guard guard ( shared ) ;
stopped = reason ;
if ( sched ) sched - > Abort ( reason ) ;
}
log ( signal ? std : : format ( " signal {}: {} running processes killed - aborting " , signal , n ) : std : : format ( " {}: {} running processes killed - aborting " , why , n ) ) ;
}
// ---- Gate 0 -------------------------------------------------------------------------
void Run : : Gate0 ( ) {
if ( ! fs : : exists ( a . artifact ) ) Die ( std : : format ( " artifact {} does not exist " , a . artifact ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
hash = Artifact : : ArtifactHash ( a . mode , a . artifact ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( a . hash & & ! a . hash - > empty ( ) & & * a . hash ! = hash ) Die ( std : : format ( " --hash {} does not match the artifact ({}) " , Dyn : : Slice ( * a . hash , 0 , 12 ) , hash . substr ( 0 , 12 ) ) ) ;
h8 = hash . substr ( 0 , 8 ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( a . mode = = " commits " ) {
// The lenses read the live checkout named first in --trees: it
// must be the range HEAD the artifact was cut from, and clean -
// anything else is evidence the review never saw (re-checked
// before every launch).
const std : : optional < std : : string > patchHead = Artifact : : PatchHead ( a . artifact ) ;
if ( ! patchHead | | patchHead - > empty ( ) ) Die ( " the last patch has no `From <sha>` line - not a git format-patch export (use `freeze`) " ) ;
head = * patchHead ;
for ( const std : : string & t : trees ) {
if ( ! Artifact : : IsToplevel ( t ) ) Die ( std : : format ( " --trees: {} is not the toplevel of a git checkout " , t ) ) ;
}
if ( const std : : optional < std : : string > drift = treeDrift ( ) ) Die ( std : : format ( " {} - re-freeze, or check out the frozen worktree (freeze --worktree) " , * drift ) ) ;
}
// A reply's gate-state sits beside the draft; a directory artifact's
// inside it.
gateDir = Dyn : : JoinPath ( a . mode = = " reply " ? Dyn : : DirName ( a . artifact ) : a . artifact , " gate-state " ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
fs : : create_directories ( gateDir ) ;
Inventory : : Built built ;
try {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
built = Inventory : : Build ( a . mode , a . artifact ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
} catch ( const Inventory : : InvariantError & e ) {
Die ( e . what ( ) ) ;
2026-10-31 16:45:53 +01:00
} catch ( const Dyn : : Error & e ) {
// A patch that is not UTF-8 is no artifact to review: a preflight
// failure.
if ( e . Kind ( ) ! = " UnicodeDecodeError " ) throw ;
Die ( std : : format ( " the artifact's patches are not UTF-8 ({}) - re-freeze " , e . what ( ) ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
units = built . out . at ( " units " ) ;
lines = built . lines ;
const fs : : path invPath = gateDir / std : : format ( " inventory-{}.json " , h8 ) ;
if ( fs : : exists ( invPath ) ) {
const Json prev = Dyn : : LoadJsonFile ( invPath ) ;
auto shape = [ ] ( const Json & list ) {
Json out = Json : : array ( ) ;
for ( const Json & u : list ) out . push_back ( Json : : array ( { u . at ( " id " ) , u . at ( " lines " ) } ) ) ;
return out ;
} ;
if ( ! Dyn : : Equal ( shape ( prev . at ( " units " ) ) , shape ( units ) ) ) Die ( std : : format ( " stored inventory {} differs from the partition of this artifact " , invPath . string ( ) ) ) ;
} else {
WriteText ( invPath , DumpFile ( built . out ) ) ;
}
testMode = ( a . only & & ! a . only - > empty ( ) ) | | ( a . units & & ! a . units - > empty ( ) ) ;
// One full run per hash (2026-10-18): a second would number itself the
// same, clobber the resume file and buy every pass twice. The lock is
// the kernel's: a killed driver releases it, no lens child inherits it.
// A test or dry run takes none but numbers itself past a live holder.
Json holder ;
if ( ! a . dryRun & & ! testMode ) {
try {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
runLock = std : : make_unique < State : : RunLock > ( gateDir , a . mode , h8 ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
} catch ( const State : : RunLocked & e ) {
const std : : string how = Platform : : InSandbox ( ) ? std : : format ( " wait for it or stop it (`{} stop <its scratch dir>`) " , Invocation ( ) ) : std : : string ( " wait for it or kill it " ) ;
Die ( std : : format ( " a full run on this hash is already live in {}: {} - {}; a dead holder releases the lock " , Dyn : : RelPath ( gateDir . string ( ) , repo . string ( ) ) , e . what ( ) , how ) ) ;
}
} else {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : optional < Json > found = State : : LockHolder ( gateDir , a . mode , h8 ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( found ) holder = * found ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : int64_t runN = State : : NextRunNumber ( gateDir , a . mode , h8 ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( Dyn : : Truthy ( holder ) & & Dyn : : Truthy ( Dyn : : Get ( holder , " run_n " ) ) ) runN = std : : max ( runN , Int ( holder . at ( " run_n " ) ) + 1 ) ;
const fs : : path scratchRoot = ScratchRoot ( a . scratch ) ;
// A run killed before its first checkpoint left no dump but did leave
// outputs: never reuse its scratch dir (salvage reads it); and never
// share one with a live driver (the .driver marker).
auto hasOutputs = [ ] ( const fs : : path & dir ) {
std : : error_code error ;
for ( fs : : directory_iterator it ( dir / " out " , error ) , end ; ! error & & it ! = end ; it . increment ( error ) ) {
const std : : string name = it - > path ( ) . filename ( ) . string ( ) ;
if ( ! name . starts_with ( ' . ' ) & & name . ends_with ( " .jsonl " ) ) return true ;
}
return false ;
} ;
2026-10-31 09:59:12 +01:00
// Nor the number of a dump on record: past a killed run's gap, a later
// run that bought nothing (no outputs in its dir) would otherwise have
// its number taken again and its dump written over.
auto dumped = [ & ] ( std : : int64_t n ) {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
return fs : : exists ( gateDir / std : : format ( " {}-{}-run-{}.json " , a . mode , h8 , n ) ) | | fs : : exists ( gateDir / std : : format ( " {}-{}-run-{}-test.json " , a . mode , h8 , n ) ) ;
2026-10-31 09:59:12 +01:00
} ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
while ( ! a . dryRun ) {
const fs : : path candidate = scratchRoot / std : : format ( " {}-run-{} " , h8 , runN ) ;
2026-10-31 09:59:12 +01:00
if ( ! dumped ( runN ) & & ! hasOutputs ( candidate ) & & SeatPool : : ClaimScratch ( candidate ) ) break ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
+ + runN ;
}
scratch = scratchRoot / std : : format ( " {}-run-{}{} " , h8 , runN , a . dryRun ? " -dry " : " " ) ;
fs : : create_directories ( scratch ) ;
2026-10-31 16:45:53 +01:00
if ( a . dryRun ) {
// Every dry run on a hash shares this dir: the report counts
// this run's prompts, not the last one's too.
std : : error_code error ;
fs : : remove_all ( scratch / " prompts " , error ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( ! a . dryRun ) {
// A stop meant for a run this dir held before is not this run's.
std : : error_code error ;
fs : : remove ( scratch / " stop " , error ) ;
// The marker a later run reads before salvaging this dir's outputs.
Json marker = Json : : object ( ) ;
for ( auto it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it ) marker [ Plan : : LensName ( it . key ( ) ) ] = it . value ( ) ;
WriteText ( scratch / " environments " , DumpSpaced ( marker ) ) ;
}
{
const std : : lock_guard guard ( shared ) ;
stopFile = scratch / " stop " ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
dumpPath = a . dryRun ? scratch / " dry-run.json " : gateDir / std : : format ( " {}-{}-run-{}{}.json " , a . mode , h8 , runN , testMode ? " -test " : " " ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( runLock ) {
runLock - > WriteInfo ( { { " pid " , Platform : : PublishedPid ( ) } ,
{ " since " , Platform : : LocalTime ( " %Y-%m-%dT%H:%M:%S " ) } ,
{ " artifact " , Dyn : : RelPath ( a . artifact , repo . string ( ) ) } ,
{ " scratch " , scratch . string ( ) } ,
{ " run_n " , runN } } ) ;
}
logFile = scratch / " log.txt " ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
log ( std : : format ( " crafter-review {} prompt v{}: {} {} @ {} " , Version ( ) , PromptVersion , a . mode , Dyn : : RelPath ( a . artifact , repo . string ( ) ) , hash ) ) ;
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
std : : error_code canonical ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( a . mode = = " commits " & & fs : : weakly_canonical ( reviewed , canonical ) ! = fs : : weakly_canonical ( repo , canonical ) ) log ( std : : format ( " repository under review: {} (read at {}) " , reviewed . string ( ) , trees . front ( ) ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
log ( std : : format ( " config: {} " , Dyn : : Truthy ( Dyn : : Get ( cfg , " _path " ) ) ? Dyn : : Str ( cfg . at ( " _path " ) ) : std : : string ( " defaults (no .review-gates/config.json) " ) ) ) ;
for ( const Json & w : Dyn : : Or ( Dyn : : Get ( cfg , " _warnings " ) , Dyn : : EmptyList ( ) ) ) log ( std : : format ( " config: warning: {} " , Dyn : : Str ( w ) ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
// The mode's lenses: the others are another mode's and say nothing
// about this run.
const std : : vector < std : : string > modeLenses = Plan : : ModeLenses ( a . mode ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > lensParts ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const std : : string & lf : modeLenses ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const std : : string name = Plan : : LensName ( lf ) ;
lensParts . push_back ( std : : ranges : : contains ( off , lf ) ? std : : format ( " {} OFF (lenses.{}.run = false) " , name , name ) : std : : format ( " {} ({}) " , name , Dyn : : Str ( Dyn : : At ( environments , lf ) ) ) ) ;
}
log ( std : : format ( " lenses: {} " , Dyn : : Join ( lensParts , " , " ) ) ) ;
std : : vector < std : : string > running ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const std : : string & lf : modeLenses ) {
if ( ! std : : ranges : : contains ( off , lf ) ) running . push_back ( lf ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
const std : : vector < std : : string > exclude = Strings ( cfg . at ( " functional " ) . at ( " exclude " ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Kernel ( ) ) {
// The kernel modes excuse nothing: a unit no lens owns is a hole.
notReviewed . clear ( ) ;
log ( std : : format ( " inventory: {} units ({}) " , units . size ( ) , Dyn : : RelPath ( invPath . string ( ) , repo . string ( ) ) ) ) ;
} else {
notReviewed = Plan : : NotReviewed ( units , lines , running , exclude ) ;
log ( std : : format ( " inventory: {} units ({}); {} units no lens that runs reads " , units . size ( ) , Dyn : : RelPath ( invPath . string ( ) , repo . string ( ) ) , notReviewed . size ( ) ) ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( a . units ) {
std : : set < std : : string > known ;
for ( const Json & u : units ) known . insert ( Dyn : : Str ( u . at ( " id " ) ) ) ;
std : : vector < std : : string > unknown ;
for ( const std : : string & u : * a . units ) {
if ( ! known . contains ( u ) ) unknown . push_back ( u ) ;
}
if ( ! unknown . empty ( ) ) Die ( std : : format ( " --units names ids not in the inventory: {} " , Dyn : : Join ( unknown , " , " ) ) ) ;
}
dispEntries = Dispositions : : Load ( a . dispositions . value_or ( " " ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
dispRows = Dispositions : : Classify ( dispEntries , hash , a . artifact , a . mode ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
inForce = Dispositions : : InForce ( dispEntries , dispRows ) ;
std : : vector < std : : string > rowParts ;
for ( const Json & r : dispRows ) rowParts . push_back ( std : : format ( " {}:{} " , Dyn : : Str ( r . at ( " id " ) ) , Dyn : : Str ( r . at ( " status " ) ) ) ) ;
log ( std : : format ( " dispositions: {} in force of {} ({}) " , inForce . size ( ) , dispEntries . size ( ) , rowParts . empty ( ) ? std : : string ( " none " ) : Dyn : : Join ( rowParts , " , " ) ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Kernel ( ) ) {
// The references the artifact cites, prefetched into the
// gate-state (a dry run reads an existing index and fetches
// nothing), and each reviewer's calibration map.
const std : : string text = a . mode = = " reply " ? Dyn : : ReadText ( fs : : path ( a . artifact ) ) : Dyn : : Join ( lines , " \n " ) ;
refUrls = Refs : : ParseRefs ( text ) ;
const fs : : path refsDir = gateDir / " refs " ;
const fs : : path indexPath = gateDir / std : : format ( " refs-{}.json " , h8 ) ;
if ( a . dryRun & & fs : : exists ( indexPath ) ) {
refIndex = Dyn : : LoadJsonFile ( indexPath ) ;
log ( std : : format ( " refs: {} entries loaded from the existing index (dry run, no fetch) " , refIndex . size ( ) ) ) ;
} else {
refIndex = Refs : : Prefetch ( repo , refUrls , refsDir , indexPath , log ) ;
}
refDigest = Dyn : : Truthy ( refIndex ) ? Refs : : Digest ( refIndex ) : std : : string ( " REFERENCES prefetched: (none - the artifact cites no lore URLs) " ) ;
const std : : string since = Refs : : SinceOf ( a . date ) ;
corpora . clear ( ) ;
for ( const std : : string & name : reviewers ) {
auto [ path , corpus ] = Refs : : PersonaCorpus ( repo , name , refsDir , since , log ) ;
if ( corpus . empty ( ) ) {
// A private contributor (no lore record): their mail is
// indexed in the ledger's live-threads table.
const std : : string s = a . subsystem . value_or ( " " ) ;
corpus = std : : format ( " lore.py search for mail from {} since {}: NO RESULTS - this person has no mail on lore in the last year. "
" Their mail is PRIVATE: the Live threads table in journal/{}/ledger.md indexes every message with its capture path "
" under journal/{}/captures/, and their submissions are frozen under journal/{}/patch/. Calibrate on those, verbatim. " ,
name , since , s , s , s ) ;
}
corpora [ name ] = corpus ;
}
anchorText . clear ( ) ;
for ( const Json & u : units ) {
if ( u . at ( " id " ) = = " anchor " ) {
anchorText = Plan : : UnitText ( lines , u ) ;
break ;
}
}
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
statePath = gateDir / " unit-state.json " ;
state = a . noReuse ? State : : EmptyState ( ) : State : : LoadState ( statePath ) ;
salvageDirs . clear ( ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( state , " entries " ) ) ) log ( std : : format ( " unit-state: {} stored unit results available for reuse " , state . at ( " entries " ) . size ( ) ) ) ;
resumePath = gateDir / std : : format ( " resume-{}.json " , h8 ) ;
resume = nullptr ;
if ( ! testMode & & ! a . dryRun & & ! a . noReuse & & fs : : exists ( resumePath ) ) {
try {
const Json r = Dyn : : LoadJsonFile ( resumePath ) ;
if ( Dyn : : Get ( r , " hash " ) = = hash & & Dyn : : Get ( r , " results " ) . is_array ( ) & & Dyn : : Truthy ( r . at ( " results " ) ) ) {
resume = r ;
std : : vector < std : : string > names ;
for ( const Json & x : r . at ( " results " ) ) names . push_back ( Dyn : : Str ( Dyn : : At ( x , " lens " ) ) ) ;
log ( std : : format ( " resume: {} lens result(s) from {} on this hash ({}) - fully returned lenses are re-normalised, not re-run " , r . at ( " results " ) . size ( ) , Dyn : : Str ( Dyn : : Get ( r , " run " ) ) ,
Dyn : : Join ( names , " , " ) ) ) ;
}
} catch ( const std : : exception & e ) {
log ( std : : format ( " resume: {} unreadable ({}) - ignored " , resumePath . string ( ) , e . what ( ) ) ) ;
}
}
x = a . reads ;
if ( x > 1 ) {
Json prev ;
try {
if ( fs : : exists ( resumePath ) ) prev = Dyn : : LoadJsonFile ( resumePath ) ;
} catch ( const std : : exception & ) {
prev = nullptr ;
}
const bool sameHash = Dyn : : Truthy ( prev ) & & Dyn : : Get ( prev , " hash " ) = = hash ;
if ( sameHash ) {
newRound = Dyn : : Truthy ( Dyn : : Get ( prev , " complete " ) ) ;
const Json & r = Dyn : : Get ( prev , " round " ) ;
round = ( Dyn : : Truthy ( r ) ? Int ( r ) : 1 ) + ( newRound ? 1 : 0 ) ;
}
if ( ! a . dryRun ) WriteText ( scratch / " round " , std : : to_string ( round ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
log ( std : : format ( " reads: every code unit of the {}code lenses needs {} clean reads, one per round; this is round {} on this hash{} " , Kernel ( ) ? " " : " static " , x , round ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
newRound | | ! sameHash ? std : : string ( ) : std : : string ( " (continuing an unfinished run) " ) ) ) ;
}
feat(config): lens sections - a repository's own text appended to a shipped charter
A lens has one charter, the one this pipeline ships; what a repository
knows that is not general to the lens - its platform and layers, the
record it keeps its decisions in, what its users already have, the
calibration entries that are its own - goes in a file the config names
for the lens (lenses.<name>.section), and Charter appends it after one
blank line. The charter sha in every reuse key covers the combined text.
The config refuses a path outside the repository - absolute, or
climbing out with `..` - by the check slots.dir had, now one both
settings share; a file missing or one the run could not use (a dangling
link, unreadable, not UTF-8) is a problem too, checked through the
reader Charter uses (Prompt::ReadSection), so a section is never
dropped in silence, and a name that is no lens is the unknown key it
always was. Nothing lists a directory, so what lies beside the files is
no concern of the config's: a directory listed would have to tolerate or
refuse every foreign entry. The run logs which charters got one.
The better-solution charter gains a consumer's general entry
(2026-10-31: a mechanism reworked a second time in one submission is the
signal to derive the fix at every layer the data crosses). The procedure
names the section wherever it names the charter: among the config's keys,
in the lens inputs, in the reuse rule (an edit to either re-runs the lens)
and in the feedback loop, which routes a repository's own lesson to its
section and a general one to the shipped charter.
2026-11-01 01:30:22 +01:00
// The repository's own lens sections (lenses.<name>.section): each
// file is appended to its lens's shipped charter (Prompt::Charter), so
// the charter sha in every reuse key covers it. The config refused a
// path outside the repository and a file the run could not read.
const std : : map < std : : string , fs : : path > sections = Config : : LensSectionsOf ( cfg , repo ) ;
Prompt : : SetLensSections ( sections ) ;
if ( ! sections . empty ( ) ) {
std : : vector < std : : string > own ;
for ( const std : : string & lf : modeLenses ) {
if ( sections . contains ( lf ) ) own . push_back ( Plan : : LensName ( lf ) ) ;
}
log ( std : : format ( " lenses: the repository's sections appended to {} " , own . empty ( ) ? std : : string ( " no charter of this mode " ) : Dyn : : Join ( own , " , " ) ) ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
for ( const Plan : : Lens & lens : Plan : : Lenses ) {
const std : : string lf ( lens . file ) ;
charters [ lf ] = Prompt : : Charter ( lf ) ;
charterSha [ lf ] = Plan : : Sha ( charters [ lf ] ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
systemText = Prompt : : SystemText ( a . mode ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
systemPaths . clear ( ) ;
systemByLens . clear ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
runLayer = Kernel ( ) ? Prompt : : RunLayerKernel ( a . mode , Dyn : : RelPath ( a . artifact , repo . string ( ) ) , a . subsystem . value_or ( " " ) , a . base , reviewers , a . date , trees , hash , lines , units , refDigest , contextPaths )
: Prompt : : RunLayer ( Dyn : : RelPath ( a . artifact , repo . string ( ) ) , a . base , a . date , trees , hash , lines , units , contextPaths , Basename ( reviewed ) , a . subsystem . value_or ( " " ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// The application under test: the login fixture, the TOTP helper.
const Json & fcfg = cfg . at ( " functional " ) ;
loginFixture = Config : : LoginFixture ( cfg , repo ) ;
stacks = LoadStacks ( ) ;
const Json first = * stacks - > First ( ) ;
appBlock = Prompt : : AppBlock ( fcfg , loginFixture , Pool : : TotpCommand ( loginFixture ) , slotMode ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
schemas = { { " block " , Schema : : SchemaJson ( " block " , a . mode ) } , { " whole " , Schema : : SchemaJson ( " whole " , a . mode ) } } ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// Memory: every pass's tree measured, its peak recorded per repository
// and environment; the budget per gate.
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
calibration = std : : make_unique < Memory : : Calibration > ( scratchRoot / " memory.json " , reviewed , DefaultCosts ( ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( ! a . dryRun ) {
// A pass runs under the supervisor: its tree is claude's, the
// supervisor itself left out, so a peak measures claude's tree
// alone.
sampler = std : : make_unique < Memory : : Sampler > ( 3.0 , [ ] ( std : : int64_t pid , const std : : map < std : : int64_t , std : : vector < std : : int64_t > > & kids ) {
std : : vector < std : : int64_t > tree = Platform : : Tree ( pid , kids ) ;
std : : erase ( tree , pid ) ;
return Platform : : PssMb ( tree ) ;
} ) ;
}
// The database URLs stay here: a db pass gets the broker's address and
// its stack's token.
bool anyDb = false ;
for ( auto it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it ) {
const Plan : : Environment * e = Plan : : FindEnvironment ( Dyn : : Str ( it . value ( ) ) ) ;
anyDb = anyDb | | ( e & & e - > db & & ! std : : ranges : : contains ( off , it . key ( ) ) ) ;
}
if ( ! a . dryRun & & anyDb ) {
broker = std : : make_unique < PgWire : : Broker > ( ) ;
broker - > Start ( ) ;
}
std : : map < std : : string , std : : string > environmentMap ;
for ( auto it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it ) environmentMap [ it . key ( ) ] = Dyn : : Str ( it . value ( ) ) ;
const Json & firstLogin = Dyn : : Get ( first , " login " ) ;
const Json & firstDb = Dyn : : Get ( first , " dbUrl " ) ;
runner = std : : make_unique < Pool : : Runner > ( Pool : : RunnerOptions {
. repo = repo ,
. scratch = scratch ,
. bin = a . claudeBin . value_or ( " " ) ,
. effort = a . effort ,
. log = log ,
. dryRun = a . dryRun ,
. harness = a . harness ,
. variant = a . variant ,
. opencodeBin = a . opencodeBin . value_or ( " " ) ,
. functional = fcfg ,
. loginFixture = firstLogin . is_null ( ) ? std : : nullopt : std : : optional < std : : string > ( Dyn : : Str ( firstLogin ) ) ,
. environments = environmentMap ,
. dbUrl = Dyn : : Truthy ( firstDb ) ? std : : optional < std : : string > ( Dyn : : Str ( firstDb ) ) : std : : nullopt ,
. sampler = sampler . get ( ) ,
. broker = broker . get ( ) ,
} ) ;
const std : : map < std : : string , std : : string > processEnv = Platform : : Environment ( ) ;
apiCfg = SeatPool : : ApiConfig ( processEnv ) ;
if ( a . apiBudget ) apiCfg [ " budgetUsd " ] = * a . apiBudget ;
ledger = std : : make_unique < SeatPool : : Ledger > ( SeatPool : : Ledger : : Load ( SeatPool : : LedgerPath ( scratchRoot ) , apiCfg ) ) ;
std : : optional < std : : string > envFile = a . envFile ;
if ( ! envFile ) {
if ( const std : : optional < std : : string > configured = Platform : : GetEnv ( " SEATS_ENV_FILE " ) ; configured & & ! configured - > empty ( ) ) {
envFile = configured ;
} else if ( fs : : exists ( repo / " .env " ) ) {
envFile = ( repo / " .env " ) . string ( ) ;
}
}
try {
seats = SeatPool : : LoadSeats ( processEnv , envFile & & ! envFile - > empty ( ) ? std : : optional < fs : : path > ( * envFile ) : std : : nullopt , a . seats . value_or ( " " ) , ledger . get ( ) , apiCfg ) ;
} catch ( const std : : invalid_argument & e ) {
Die ( e . what ( ) ) ;
} catch ( const Dyn : : Error & e ) {
2026-10-31 16:35:26 +01:00
// The errors that mean the file could not be read: the OS errors, a
// file that is not UTF-8 (UnicodeDecodeError), and ValueError.
constexpr std : : array < std : : string_view , 6 > Caught = { " FileNotFoundError " , " PermissionError " , " IsADirectoryError " , " OSError " , " UnicodeDecodeError " , " ValueError " } ;
if ( ! std : : ranges : : contains ( Caught , e . Kind ( ) ) ) throw ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Die ( e . what ( ) ) ;
}
// The board (2026-10-31): the other drivers on this machine, what they
// hold on these seats, the memory and the stacks their passes hold -
// the pool places against all of it; a dry run launches nothing and
// stays off it.
if ( ! a . dryRun ) {
const std : : optional < Platform : : Identity > self = Platform : : Self ( ) ;
if ( ! self ) Die ( " no identity another driver could check (no bwrapinfo.json in this sandbox, as under `flatpak build`): a full run needs one - run it with `flatpak run` " ) ;
try {
lifetime = std : : make_unique < Platform : : LifetimeLock > ( SeatPool : : BoardPath ( ) . parent_path ( ) / " drivers " , * self ) ;
} catch ( const std : : runtime_error & e ) {
Die ( e . what ( ) ) ;
}
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
const Json pc = SeatPool : : PoolConfig ( processEnv , a . effort ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
board = std : : make_unique < SeatPool : : Board > ( SeatPool : : BoardPath ( ) , std : : string ( ) , std : : nullopt , log ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : string > runParts = { a . mode } ;
if ( a . subsystem & & ! a . subsystem - > empty ( ) ) runParts . push_back ( * a . subsystem ) ;
runParts . push_back ( Basename ( Dyn : : RStrip ( a . artifact , " / " ) ) ) ;
runParts . emplace_back ( " @ " ) ;
runParts . push_back ( h8 ) ;
board - > Join ( { { " run " , Dyn : : Join ( runParts , " " ) } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " dump " , Basename ( dumpPath ) } ,
{ " scratch " , scratch . string ( ) } ,
{ " effort " , a . effort } ,
2026-10-31 17:33:11 +01:00
{ " settings " , { { " maxUtil " , pc . at ( " maxUtil " ) } , { " apiConcurrency " , apiCfg . at ( " concurrency " ) } , { " lensCostPct " , pc . at ( " lensCostPct " ) } ,
// Shown as the driver's width by every driver's `seats`.
{ " concurrency " , a . concurrency ? Json ( * a . concurrency ) : Json ( std : : format ( " {} per account " , Dyn : : Str ( pc . at ( " oauthConcurrency " ) ) ) ) } } } } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Platform : : Now ( ) ) ;
}
const bool openrouter = std : : ranges : : any_of ( seats , [ ] ( const Json & s ) { return s . at ( " kind " ) = = " openrouter " ; } ) ;
if ( a . harness = = " opencode " & & ! openrouter ) Die ( " --harness opencode runs on OpenRouter seats only: add --seats openrouter (OPENROUTER_KEY in the env file) " ) ;
const std : : vector < std : : string > modelIds = ModelIds ( ) ;
if ( openrouter & & ! std : : ranges : : all_of ( Plan : : Models ( ) , [ ] ( const Plan : : ModelTier & m ) { return m . id . contains ( ' / ' ) ; } ) ) {
std : : vector < std : : string > sorted = modelIds ;
std : : ranges : : sort ( sorted ) ;
Die ( std : : format ( " OpenRouter seats need OpenRouter model ids (vendor/model): --models opus=...,fable=... (now {}) " , Dyn : : Join ( sorted , " , " ) ) ) ;
}
if ( ! a . dryRun & & ! a . noProbe ) SeatPool : : Probe ( seats , runner - > Bin ( ) , 30 , modelIds , log ) ;
if ( board ) {
// Our readings onto the board (a probed-ok seat clears a verdict
// another driver left), theirs into our seats.
const double now = Platform : : Now ( ) ;
board - > Publish ( seats , now , ! a . noProbe ) ;
board - > Fold ( seats , now ) ;
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
for ( const std : : string & line : board - > OthersLines ( seats , now , SeatPool : : PoolConfig ( processEnv , a . effort ) , apiCfg , a . concurrency ) ) log ( line ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
if ( a . harness = = " opencode " ) {
runner - > opencodeHome = OpenCode : : PrepareHome ( scratch , repo , modelIds ) ;
log ( std : : format ( " harness: opencode ({}), variant {}, routing {}; home {} (view dir = the project: no CLAUDE.md reaches the model) " , a . opencodeBin . value_or ( OpenCode : : DefaultBin ( ) ) ,
a . variant . value_or ( " None " ) , DumpSpaced ( OpenCode : : Routing ( ) ) , Dyn : : RelPath ( runner - > opencodeHome . string ( ) , repo . string ( ) ) ) ) ;
if ( ! a . dryRun ) {
const Json & keySeat = * std : : ranges : : find_if ( seats , [ ] ( const Json & s ) { return s . at ( " kind " ) = = " openrouter " ; } ) ;
const auto [ ok , detail ] = OpenCode : : Warm ( a . opencodeBin . value_or ( OpenCode : : DefaultBin ( ) ) , runner - > opencodeHome , OpenCode : : BaseEnv ( runner - > opencodeHome , Dyn : : Str ( keySeat . at ( " secret " ) ) , runner - > Env ( ) ) ,
modelIds . front ( ) , log ) ;
if ( ! ok ) Die ( std : : format ( " opencode warm-up failed: {} " , Dyn : : Slice ( detail , - 400 ) ) ) ;
}
} else if ( openrouter ) {
log ( " harness: claude on OpenRouter's Anthropic-format endpoint - provider routing (zero data retention) cannot be set per request there; the account's privacy setting decides " ) ;
}
std : : vector < std : : string > names ;
for ( const Json & s : seats ) names . push_back ( std : : format ( " {} ({}) " , Dyn : : Str ( s . at ( " id " ) ) , Dyn : : Str ( s . at ( " kind " ) ) ) ) ;
std : : string line = std : : format ( " seats: {} from {} " , Dyn : : Join ( names , " , " ) , envFile & & ! envFile - > empty ( ) ? * envFile : std : : string ( " this machine " ) ) ;
if ( std : : ranges : : any_of ( seats , [ ] ( const Json & s ) { return s . at ( " kind " ) = = " api " ; } ) ) {
line + = std : : format ( " ; {}, budget ${:g} per api seat per cycle (ledger {}) " , Dyn : : Str ( apiCfg . at ( " order " ) ) , Number ( apiCfg . at ( " budgetUsd " ) ) , ledger - > Path ( ) . string ( ) ) ;
}
if ( openrouter ) {
line + = std : : format ( " ; budget ${:g} per OpenRouter seat per cycle, {} concurrent (ledger {}) " , Number ( apiCfg . at ( " orBudgetUsd " ) ) , Dyn : : Str ( apiCfg . at ( " orConcurrency " ) ) , ledger - > Path ( ) . string ( ) ) ;
}
log ( line ) ;
for ( const std : : string & row : Dyn : : Split ( SeatPool : : Table ( seats ) , " \n " ) ) log ( std : : format ( " {} " , row ) ) ;
// From here a signal or `crafter-review stop` stops the run: every
// running process killed, the pool aborted.
ready = true ;
std : : vector < fs : : path > dirs ;
std : : error_code error ;
for ( fs : : directory_iterator it ( scratchRoot , error ) , end ; ! error & & it ! = end ; it . increment ( error ) ) {
const std : : string name = it - > path ( ) . filename ( ) . string ( ) ;
if ( name . starts_with ( std : : format ( " {}-run- " , h8 ) ) & & it - > path ( ) ! = scratch & & ! name . ends_with ( " -dry " ) ) dirs . push_back ( scratchRoot / name ) ;
}
// Newest first, in run order: run-10 before run-9.
std : : ranges : : sort ( dirs , [ & ] ( const fs : : path & l , const fs : : path & r ) {
auto n = [ & ] ( const fs : : path & p ) { return Dyn : : ParseInt ( Dyn : : Slice ( p . filename ( ) . string ( ) , static_cast < std : : int64_t > ( h8 . size ( ) + 5 ) ) ) . value_or ( 0 ) ; } ;
return std : : pair ( n ( l ) , l . string ( ) ) > std : : pair ( n ( r ) , r . string ( ) ) ;
} ) ;
salvageDirs = dirs ;
if ( ! salvageDirs . empty ( ) & & ! a . noSalvage & & ! testMode & & ! a . dryRun ) {
std : : int64_t outputs = 0 ;
for ( const fs : : path & d : salvageDirs ) {
for ( fs : : directory_iterator it ( d / " out " , error ) , end ; ! error & & it ! = end ; it . increment ( error ) ) {
const std : : string name = it - > path ( ) . filename ( ) . string ( ) ;
if ( ! name . starts_with ( ' . ' ) & & name . ends_with ( " .jsonl " ) ) + + outputs ;
}
error . clear ( ) ;
}
log ( std : : format ( " salvage: {} earlier scratch dir(s) on this hash with {} process outputs - finished ok outputs are reused, not re-bought " , salvageDirs . size ( ) , outputs ) ) ;
}
log ( std : : format ( " run layer: {} bytes (~{} tokens); scratch {} " , Dyn : : Length ( runLayer ) , static_cast < std : : int64_t > ( static_cast < double > ( Dyn : : Length ( runLayer ) ) / 3.7 ) , scratch . string ( ) ) ) ;
}
std : : map < std : : string , std : : string > Run : : AppLenses ( std : : span < const std : : string > lensFiles ) const {
std : : map < std : : string , std : : string > out ;
for ( const std : : string & lf : lensFiles ) {
const std : : string e = Dyn : : Str ( Dyn : : At ( environments , lf ) ) ;
if ( Plan : : FindEnvironment ( e ) - > app ) out [ lf ] = e ;
}
return out ;
}
std : : map < std : : string , std : : string > Run : : DbLenses ( std : : span < const std : : string > lensFiles ) const {
std : : map < std : : string , std : : string > out ;
for ( const std : : string & lf : lensFiles ) {
const std : : string e = Dyn : : Str ( Dyn : : At ( environments , lf ) ) ;
if ( Plan : : FindEnvironment ( e ) - > db ) out [ lf ] = e ;
}
return out ;
}
void Run : : InstrumentPreflight ( std : : span < const std : : string > lensFiles ) {
// The harness can give the instrument (the opencode harness runs no
// MCP server, and the database check reads the claude stream), the
// application answers, the database answers.
if ( a . harness = = " opencode " ) {
std : : vector < std : : string > need ;
for ( const std : : string & lf : lensFiles ) {
const Plan : : Environment * e = Plan : : FindEnvironment ( Dyn : : Str ( Dyn : : At ( environments , lf ) ) ) ;
if ( ! e - > mcp . empty ( ) | | e - > db ) need . push_back ( lf ) ;
}
if ( ! need . empty ( ) ) {
Die ( std : : format ( " the {} environment of {} needs the claude harness (an MCP server, or the database check that reads the claude stream), which the opencode harness is not: run with --without {} on that harness " ,
Dyn : : Str ( environments . at ( need . front ( ) ) ) , Plan : : LensName ( need . front ( ) ) , Dyn : : Join ( need , " , " ) ) ) ;
}
}
if ( ! AppLenses ( lensFiles ) . empty ( ) | | ! DbLenses ( lensFiles ) . empty ( ) ) StackPreflight ( lensFiles ) ;
}
std : : optional < std : : string > Run : : MigrationVersion ( std : : string_view file ) {
// re.match(r'^\d+_.*\.sql$', basename)
const std : : string base = Dyn : : BaseName ( file ) ;
const std : : size_t digits = Dyn : : DecimalRun ( base , 0 ) ;
if ( digits = = 0 | | digits > = base . size ( ) | | base [ digits ] ! = ' _ ' | | ! base . ends_with ( " .sql " ) | | base . size ( ) < digits + 5 | | base . contains ( ' \n ' ) ) return std : : nullopt ;
return Dyn : : Split ( base , " _ " , 1 ) . front ( ) ;
}
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
MigrationsHead Run : : MigrationsAtHead ( ) {
constexpr std : : string_view M = " supabase/migrations/ " ;
auto git = [ & ] ( std : : vector < std : : string > args ) {
std : : vector < std : : string > argv = { " git " , " -C " , trees . front ( ) } ;
std : : ranges : : move ( args , std : : back_inserter ( argv ) ) ;
return Process : : Run ( argv ) . out ;
} ;
std : : map < std : : string , std : : string > atHead ;
for ( const std : : string & f : Dyn : : Split ( git ( { " ls-tree " , " --name-only " , " HEAD " , std : : string ( M ) } ) ) ) {
if ( const std : : optional < std : : string > v = MigrationVersion ( f ) ) atHead [ * v ] = f ;
}
std : : vector < std : : string > inRange ;
if ( ! a . base . empty ( ) & & ! atHead . empty ( ) ) {
for ( const std : : string & f : Dyn : : Split ( git ( { " diff " , " --name-only " , " --diff-filter=AM " , std : : format ( " {}..HEAD " , a . base ) , " -- " , std : : string ( M ) } ) ) ) {
if ( MigrationVersion ( f ) ) inRange . push_back ( f ) ;
}
}
std : : map < std : : string , std : : string > headFp ;
for ( const std : : string & f : inRange ) headFp [ f ] = PgWire : : Fingerprint ( git ( { " show " , std : : format ( " HEAD:{} " , f ) } ) ) ;
return { atHead , inRange , headFp } ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : pair < std : : optional < std : : string > , std : : optional < std : : string > > Run : : MigrationsDrift ( const std : : string & url ) {
// The HEAD side is the same for every stack: worked out once per tree
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
// and base (a tree's HEAD does not move during a run - TreeDrift
// aborts it first).
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
constexpr std : : string_view M = " supabase/migrations/ " ;
const std : : pair < std : : string , std : : string > key = { trees . front ( ) , a . base } ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
if ( ! migCache . contains ( key ) ) migCache [ key ] = migrationsAtHead ( ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const auto & [ atHead , inRange , headFp ] = migCache . at ( key ) ;
if ( atHead . empty ( ) ) return { std : : nullopt , std : : format ( " no {} at the range HEAD - applied migrations not compared " , M ) } ;
std : : vector < std : : vector < std : : optional < std : : string > > > rows ;
try {
try {
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
rows = query ( url , " select version, array_to_string(statements, ' ') from supabase_migrations.schema_migrations " ) . second ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
} catch ( const PgWire : : SqlError & e ) {
// No statements column (an old CLI): versions alone.
if ( ! e . fields . contains ( ' C ' ) | | e . fields . at ( ' C ' ) ! = " 42703 " ) throw ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
rows = query ( url , " select version, null from supabase_migrations.schema_migrations " ) . second ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
} catch ( const PgWire : : SqlError & e ) {
const std : : string code = e . fields . contains ( ' C ' ) ? e . fields . at ( ' C ' ) : std : : string ( ) ;
if ( code = = " 42P01 " | | code = = " 3F000 " ) return { std : : nullopt , std : : string ( " no supabase_migrations.schema_migrations in the database - applied migrations not compared " ) } ;
return { std : : format ( " its applied migrations could not be read ({}) " , e . what ( ) ) , std : : nullopt } ;
} catch ( const PgWire : : DbError & e ) {
return { std : : format ( " its applied migrations could not be read ({}) " , e . what ( ) ) , std : : nullopt } ;
}
std : : map < std : : string , std : : optional < std : : string > > applied ;
for ( const auto & row : rows ) applied [ row . at ( 0 ) . value_or ( " None " ) ] = row . size ( ) > 1 ? row . at ( 1 ) : std : : nullopt ;
std : : vector < std : : string > missing ;
std : : vector < std : : string > extra ;
for ( const auto & [ v , f ] : atHead ) {
if ( ! applied . contains ( v ) ) missing . push_back ( v ) ;
}
for ( const auto & [ v , statements ] : applied ) {
if ( ! atHead . contains ( v ) ) extra . push_back ( v ) ;
}
std : : vector < std : : string > changed ;
std : : int64_t compared = 0 ;
for ( const std : : string & f : inRange ) {
const std : : string v = * MigrationVersion ( f ) ;
const auto found = applied . find ( v ) ;
if ( found = = applied . end ( ) | | ! found - > second ) continue ;
+ + compared ;
if ( PgWire : : Fingerprint ( * found - > second ) ! = headFp . at ( f ) ) changed . push_back ( v ) ;
}
std : : ranges : : sort ( changed ) ;
if ( ! missing . empty ( ) | | ! extra . empty ( ) | | ! changed . empty ( ) ) {
auto cut = [ ] ( const std : : vector < std : : string > & xs ) {
const std : : vector < std : : string > head ( xs . begin ( ) , xs . begin ( ) + static_cast < std : : ptrdiff_t > ( std : : min < std : : size_t > ( 8 , xs . size ( ) ) ) ) ;
return Dyn : : Join ( head , " , " ) + ( xs . size ( ) > 8 ? std : : format ( " and {} more " , xs . size ( ) - 8 ) : std : : string ( ) ) ;
} ;
std : : string problem = " its migrations are not the range HEAD's " ;
if ( ! missing . empty ( ) ) problem + = std : : format ( " - at HEAD, not applied: {} " , cut ( missing ) ) ;
if ( ! extra . empty ( ) ) problem + = std : : format ( " - applied, not at HEAD: {} " , cut ( extra ) ) ;
if ( ! changed . empty ( ) ) problem + = std : : format ( " - applied with other content than HEAD has: {} " , cut ( changed ) ) ;
problem + = " - reset the stack from the frozen tree (supabase.start / functional.start) " ;
return { problem , std : : nullopt } ;
}
return { std : : nullopt , std : : format ( " its {} applied migrations are the range HEAD's{} " , atHead . size ( ) , inRange . empty ( ) ? std : : string ( ) : std : : format ( " ({} of the range compared by content) " , compared ) ) } ;
}
std : : unique_ptr < Pool : : Stacks > Run : : LoadStacks ( ) {
// The slots that are up when the config names slots.dir, else the one
// stack of functional.* and supabase.dbUrl. A dry run with slots
// configured and none up plans on the one stack.
const Json & f = cfg . at ( " functional " ) ;
Json apiUrls = Json : : array ( ) ;
for ( const Json & u : Dyn : : Or ( Dyn : : Get ( f , " apiUrls " ) , Dyn : : EmptyList ( ) ) ) apiUrls . push_back ( u ) ;
const Json one = { { " id " , " the stack " } , { " appUrl " , f . at ( " appUrl " ) } , { " apiUrls " , apiUrls } , { " dbUrl " , cfg . at ( " supabase " ) . at ( " dbUrl " ) } ,
{ " login " , loginFixture ? Json ( * loginFixture ) : Json ( ) } , { " slot " , false } } ;
if ( ! Dyn : : Truthy ( Dyn : : Get ( cfg . at ( " slots " ) , " dir " ) ) ) return std : : make_unique < Pool : : Stacks > ( std : : vector < Json > { one } ) ;
slotMode = true ;
const Config : : Slots found = Config : : SlotStacks ( cfg , repo ) ;
slotProblems = found . problems ;
std : : vector < Json > list ;
for ( const Json & s : found . stacks ) list . push_back ( s ) ;
if ( list . empty ( ) ) {
Json dry = one ;
dry [ " id " ] = " slot 1 (dry run: none is up) " ;
dry [ " slot " ] = true ;
list . push_back ( dry ) ;
}
return std : : make_unique < Pool : : Stacks > ( list ) ;
}
std : : string Run : : StacksLine ( ) const {
if ( ! slotMode ) {
return std : : format ( " one stack ({}), one pass at a time on it; login fixture {} " , Dyn : : Str ( stacks - > First ( ) - > at ( " appUrl " ) ) ,
loginFixture ? * loginFixture : std : : string ( " NONE found - behaviours behind a login will come back unverified " ) ) ;
}
std : : vector < std : : string > ids ;
for ( const Json & s : stacks - > All ( ) ) ids . push_back ( Dyn : : Str ( s . at ( " id " ) ) ) ;
return std : : format ( " {} slot(s) under {} ({}), one pass at a time on each " , stacks - > Size ( ) , Dyn : : Str ( cfg . at ( " slots " ) . at ( " dir " ) ) , Dyn : : Join ( ids , " , " ) ) ;
}
std : : vector < Json > Run : : DbStacks ( std : : span < const std : : string > lensFiles ) const {
// Every stack for a lens that drives the application and has the
// database (its pass may hold any of them), the first for a lens with
// the database alone.
std : : vector < Json > out ;
for ( const auto & [ lf , e ] : DbLenses ( lensFiles ) ) {
const std : : vector < Json > & all = stacks - > All ( ) ;
const std : : size_t count = Plan : : FindEnvironment ( e ) - > app ? all . size ( ) : std : : min < std : : size_t > ( 1 , all . size ( ) ) ;
for ( std : : size_t i = 0 ; i < count ; + + i ) {
if ( std : : ranges : : none_of ( out , [ & ] ( const Json & o ) { return Dyn : : Equal ( o , all [ i ] ) ; } ) ) out . push_back ( all [ i ] ) ;
}
}
return out ;
}
void Run : : StackPreflight ( std : : span < const std : : string > lensFiles ) {
// Before a gate whose lenses use a stack: the slots are up (slot
// mode), and every stack the gate's passes use answers - its
// application, its database with the range HEAD's migrations, its
// login in its own database's auth.users.
const std : : map < std : : string , std : : string > app = AppLenses ( lensFiles ) ;
const std : : map < std : : string , std : : string > db = DbLenses ( lensFiles ) ;
std : : vector < std : : string > whoParts ;
std : : vector < std : : string > seen ;
for ( const std : : string & lf : lensFiles ) {
const auto inApp = app . find ( lf ) ;
const auto inDb = db . find ( lf ) ;
if ( inApp = = app . end ( ) & & inDb = = db . end ( ) ) continue ;
whoParts . push_back ( std : : format ( " {} ({}) " , Plan : : LensName ( lf ) , inApp ! = app . end ( ) ? inApp - > second : inDb - > second ) ) ;
}
const std : : string who = Dyn : : Join ( whoParts , " , " ) ;
const Json & sl = cfg . at ( " slots " ) ;
if ( ! slotProblems . empty ( ) ) Die ( std : : format ( " slots: {} " , Dyn : : Join ( slotProblems , " ; " ) ) ) ;
if ( slotMode & & ! a . dryRun & & std : : ranges : : none_of ( stacks - > All ( ) , [ ] ( const Json & s ) { return Dyn : : Truthy ( Dyn : : Get ( s , " slot " ) ) & & ! Dyn : : Str ( s . at ( " id " ) ) . ends_with ( " none is up) " ) ; } ) ) {
Die ( std : : format ( " stacks ({}): no slot is up under {} (no <n>/{}) - bring them up from the frozen tree first: `{} slots` says how many fit and prints the commands " , who , Dyn : : Str ( sl . at ( " dir " ) ) ,
Config : : SlotFile , Invocation ( ) ) ) ;
}
const std : : vector < Json > dbs = DbStacks ( lensFiles ) ;
std : : vector < std : : string > nodb ;
for ( const Json & s : dbs ) {
if ( ! Dyn : : Truthy ( Dyn : : Get ( s , " dbUrl " ) ) ) nodb . push_back ( Dyn : : Str ( s . at ( " id " ) ) ) ;
}
if ( ! nodb . empty ( ) ) {
Die ( std : : format ( " stacks ({}): no database for {} (no dbUrl in {}) - a lens with the database runs its SQL on its own stack's, never on another's: bring the slot up again, or give the lens an environment without the database " ,
who , Dyn : : Join ( nodb , " , " ) , Config : : SlotFile ) ) ;
}
std : : set < std : : string > roles ;
for ( const Json & s : dbs ) roles . insert ( PgWire : : ParseUrl ( Dyn : : Str ( s . at ( " dbUrl " ) ) ) . user ) ;
dbRole = roles . size ( ) = = 1 ? std : : optional < std : : string > ( * roles . begin ( ) ) : std : : nullopt ;
if ( a . dryRun ) {
dbChecked = std : : nullopt ;
dbBypass = std : : nullopt ;
std : : vector < std : : string > redacted ;
for ( const Json & s : dbs ) redacted . push_back ( PgWire : : Redact ( Dyn : : Str ( s . at ( " dbUrl " ) ) ) ) ;
log ( std : : format ( " stacks ({}): dry run - not probed; {}{} " , who , StacksLine ( ) , dbs . empty ( ) ? std : : string ( ) : std : : format ( " ; database {} " , Dyn : : Join ( redacted , " , " ) ) ) ) ;
return ;
}
const Json & fcfg = cfg . at ( " functional " ) ;
std : : vector < Json > apps ;
if ( ! app . empty ( ) ) apps = stacks - > All ( ) ;
for ( const Json & s : apps ) {
const Json & readyPath = Dyn : : Get ( fcfg , " readyPath " ) ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const auto [ ok , detail ] = appReady ( Dyn : : Str ( s . at ( " appUrl " ) ) , Dyn : : Truthy ( readyPath ) ? Dyn : : Str ( readyPath ) : std : : string ( " / " ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( ! ok ) {
const Json & how = Dyn : : Truthy ( Dyn : : Get ( s , " slot " ) ) ? Dyn : : Get ( sl , " start " ) : Dyn : : Get ( fcfg , " start " ) ;
Die ( std : : format ( " stacks ({}): {}: the application does not answer ({}) - start it from the frozen tree first{} " , who , Dyn : : Str ( s . at ( " id " ) ) , detail ,
Dyn : : Truthy ( how ) ? std : : format ( " ({}) " , Dyn : : Str ( how ) ) : std : : string ( ) ) ) ;
}
}
std : : set < std : : optional < bool > > bypass ;
std : : optional < std : : string > firstDetail ;
std : : optional < std : : string > note ;
for ( const Json & s : dbs ) {
const std : : string url = Dyn : : Str ( s . at ( " dbUrl " ) ) ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const auto [ ok , detail ] = probe ( url ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( ! ok ) {
const Json & supabaseStart = Dyn : : Get ( cfg . at ( " supabase " ) , " start " ) ;
const Json & how = Dyn : : Truthy ( Dyn : : Get ( s , " slot " ) ) ? Dyn : : Get ( sl , " start " ) : ( Dyn : : Truthy ( supabaseStart ) ? supabaseStart : Dyn : : Get ( fcfg , " start " ) ) ;
Die ( std : : format ( " stacks ({}): {}: the database does not answer ({}) - start the stack from the frozen tree first{} " , who , Dyn : : Str ( s . at ( " id " ) ) , detail ,
Dyn : : Truthy ( how ) ? std : : format ( " ({}) " , Dyn : : Str ( how ) ) : std : : string ( ) ) ) ;
}
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const auto [ drift , n ] = migrationsDrift ( url ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( drift ) Die ( std : : format ( " stacks ({}): {}: the database: {} " , who , Dyn : : Str ( s . at ( " id " ) ) , * drift ) ) ;
if ( ! firstDetail | | firstDetail - > empty ( ) ) firstDetail = detail ;
if ( ! note | | note - > empty ( ) ) note = n ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
bypass . insert ( bypassesRls ( url ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
if ( ! dbs . empty ( ) ) {
dbChecked = dbs . size ( ) = = 1 ? std : : format ( " it answers ({}); {} " , firstDetail . value_or ( " None " ) , note . value_or ( " None " ) )
: std : : format ( " the database of each of the {} stacks answers ({} for {}); {} " , dbs . size ( ) , firstDetail . value_or ( " None " ) , Dyn : : Str ( dbs . front ( ) . at ( " id " ) ) , note . value_or ( " None " ) ) ;
dbBypass = bypass . size ( ) = = 1 ? * bypass . begin ( ) : std : : nullopt ;
}
std : : vector < std : : string > notes ;
for ( const Json & s : apps ) {
if ( ! Dyn : : Truthy ( Dyn : : Get ( s , " login " ) ) ) {
notes . push_back ( std : : format ( " {} has no login fixture - behaviours behind a login will come back unverified " , Dyn : : Str ( s . at ( " id " ) ) ) ) ;
} else if ( Dyn : : Truthy ( Dyn : : Get ( s , " dbUrl " ) ) & & ( Dyn : : Truthy ( Dyn : : Get ( s , " slot " ) ) | | std : : ranges : : any_of ( dbs , [ & ] ( const Json & d ) { return Dyn : : Equal ( d , s ) ; } ) ) ) {
if ( const std : : optional < std : : string > gone = LoginMissing ( s ) ) {
Die ( std : : format ( " stacks ({}): {}: its login {} ({}) is not in that stack's auth.users - the fixture is left from another bring-up: bring the stack up again " , who , Dyn : : Str ( s . at ( " id " ) ) ,
Dyn : : Str ( s . at ( " login " ) ) , * gone ) ) ;
}
}
}
// What was checked, no more.
const std : : string dbline = dbs . empty ( ) ? std : : string ( )
: std : : format ( " ; {} answer{} ({}); {} " , dbs . size ( ) = = 1 ? std : : string ( " its database " ) : std : : format ( " the databases of {} stacks " , dbs . size ( ) ) , dbs . size ( ) = = 1 ? " s " : " " ,
firstDetail . value_or ( " None " ) , note . value_or ( " None " ) ) ;
if ( ! app . empty ( ) ) {
const Json & exclude = fcfg . at ( " exclude " ) ;
log ( std : : format ( " stacks ({}): {}; every application answers{}{}; exclude {} " , who , StacksLine ( ) , dbline , notes . empty ( ) ? std : : string ( ) : std : : format ( " ; {} " , Dyn : : Join ( notes , " ; " ) ) ,
Dyn : : Truthy ( exclude ) ? Dyn : : ReprValue ( exclude ) : std : : string ( " [] " ) ) ) ;
} else {
log ( std : : format ( " stacks ({}): a pass with the database alone uses {}'s, every call rolled back{} " , who , Dyn : : Str ( dbs . front ( ) . at ( " id " ) ) , dbline ) ) ;
}
}
std : : optional < std : : string > Run : : LoginMissing ( const Json & stack ) const {
// The login's email when the stack's database answers and has no such
// user, else nullopt (not checked).
std : : string email ;
try {
const Json fixture = Dyn : : LoadJsonFile ( repo / Dyn : : Str ( stack . at ( " login " ) ) ) ;
email = Dyn : : Lower ( Dyn : : Strip ( Dyn : : StrOr ( Dyn : : Get ( fixture , " email " ) , " " ) ) ) ;
} catch ( const std : : exception & ) {
return std : : nullopt ;
}
if ( email . empty ( ) | | PgWire : : CheckUrl ( Dyn : : Get ( stack , " dbUrl " ) ) ) return std : : nullopt ;
try {
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const auto [ columns , rows ] = query ( Dyn : : Str ( stack . at ( " dbUrl " ) ) , std : : format ( " select 1 from auth.users where lower(email) = '{}' " , Dyn : : Replace ( email , " ' " , " '' " ) ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
return rows . empty ( ) ? std : : optional < std : : string > ( email ) : std : : nullopt ;
} catch ( const PgWire : : SqlError & ) {
return std : : nullopt ;
} catch ( const PgWire : : DbError & ) {
return std : : nullopt ;
}
}
std : : optional < std : : string > Run : : TreeDrift ( ) {
// A moved HEAD or a dirty tree under the lenses is evidence drift,
// like an artifact re-hash mismatch; the paths the config allows are
// not drift.
try {
const std : : string th = Artifact : : TreeHead ( trees . front ( ) ) ;
if ( th ! = head ) return std : : format ( " tree {} is at {}, the artifact was cut from {} " , trees . front ( ) , Dyn : : Slice ( th , 0 , 12 ) , Dyn : : Slice ( head , 0 , 12 ) ) ;
const auto [ counted , ignored ] = Freeze : : DirtyPaths ( trees . front ( ) , Strings ( cfg . at ( " allowDirty " ) ) ) ;
if ( ! counted . empty ( ) ) {
std : : vector < std : : string > shown ;
for ( std : : size_t i = 0 ; i < std : : min < std : : size_t > ( 3 , counted . size ( ) ) ; + + i ) shown . push_back ( Dyn : : Slice ( counted [ i ] , 3 ) ) ;
return std : : format ( " tree {} has uncommitted tracked changes ({}) " , trees . front ( ) , Dyn : : Join ( shown , " , " ) ) ;
}
} catch ( const std : : exception & e ) {
return std : : format ( " tree check failed: {} " , e . what ( ) ) ;
}
return std : : nullopt ;
}
// ---- prompts ------------------------------------------------------------------------
std : : pair < fs : : path , std : : string > Run : : PromptFor ( const Json & job ) {
// The system file holds the common text, the run layer and the lens
// layer - identical for every pass of the lens, written once, served
// from the prompt cache; the user message is the scope of this pass.
const std : : lock_guard guard ( shared ) ;
const std : : string lens = Dyn : : Str ( Dyn : : At ( job , " lens " ) ) ;
const std : : string lensFile = Dyn : : Str ( Dyn : : At ( job , " lensFile " ) ) ;
std : : string summary ;
if ( job . at ( " kind " ) ! = " whole " ) {
if ( const auto found = summaries . find ( lens ) ; found ! = summaries . end ( ) ) summary = found - > second ;
}
const Plan : : Environment & env = * Plan : : FindEnvironment ( Dyn : : Str ( Dyn : : At ( environments , lensFile ) ) ) ;
const std : : string db = env . db ? Prompt : : DbBlock ( cfg . at ( " supabase " ) , Pool : : SqlCommand ( ) , dbRole , env . app , dbChecked , dbBypass ) : std : : string ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : string persona = Dyn : : StrOr ( Dyn : : Get ( job , " persona " ) , " " ) ;
const auto corpus = corpora . find ( persona ) ;
const std : : string ll = Prompt : : LensLayer ( lensFile , charters . at ( lensFile ) , Dispositions : : Block ( inForce , dispRows , lensFile , hash , a . subsystem . value_or ( " " ) ) , env . app ? appBlock : std : : string ( ) , summary , db ,
persona , corpus = = corpora . end ( ) ? std : : string ( ) : corpus - > second ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
lensLayersBytes [ lens ] = static_cast < std : : int64_t > ( Dyn : : Length ( ll ) ) ;
const std : : string sysText = Prompt : : SystemPrompt ( systemText , runLayer , ll ) ;
const std : : string sha = Plan : : Sha ( sysText ) ;
auto found = std : : ranges : : find_if ( systemPaths , [ & ] ( const auto & entry ) { return entry . first = = sha ; } ) ;
if ( found = = systemPaths . end ( ) ) {
const fs : : path path = scratch / std : : format ( " system-{}.md " , sha . substr ( 0 , 8 ) ) ;
WriteText ( path , sysText ) ;
systemPaths . emplace_back ( sha , path ) ;
found = systemPaths . end ( ) - 1 ;
}
auto byLens = std : : ranges : : find_if ( systemByLens , [ & ] ( const auto & entry ) { return entry . first = = lens ; } ) ;
if ( byLens = = systemByLens . end ( ) ) {
systemByLens . emplace_back ( lens , std : : set < std : : string > { } ) ;
byLens = systemByLens . end ( ) - 1 ;
}
byLens - > second . insert ( sha ) ;
std : : string stackText ;
const Json & stack = Dyn : : Get ( job , " stack " ) ;
if ( slotMode & & Dyn : : Truthy ( stack ) ) {
const Json & login = Dyn : : Get ( stack , " login " ) ;
stackText = Prompt : : StackText ( stack , Pool : : TotpCommand ( login . is_null ( ) ? std : : nullopt : std : : optional < std : : string > ( Dyn : : Str ( login ) ) ) ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
return { found - > second , Prompt : : UserPrompt ( Prompt : : Tail ( job , units , lines , summary ) , job , stackText , Kernel ( ) ) } ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
std : : optional < std : : string > Run : : CacheKey ( Json & job ) {
if ( Dyn : : Get ( job , " cacheKey " ) . is_null ( ) ) job [ " cacheKey " ] = Basename ( PromptFor ( job ) . first ) ;
return Dyn : : Str ( job . at ( " cacheKey " ) ) ;
}
bool Run : : WarmProbe ( const Json & job ) const {
const std : : optional < std : : string > text = Platform : : ReadFile ( scratch / " out " / std : : format ( " {}.jsonl " , FileLabel ( job ) ) ) ;
return text & & ( text - > contains ( " \" type \" : \" assistant \" " ) | | text - > contains ( " \" type \" : \" step_start \" " ) ) ;
}
// ---- reuse --------------------------------------------------------------------------
const Plan : : CommitCode & Run : : RangeCode ( ) {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( ! commitCode ) {
commitCode = Plan : : CommitCodeOf ( Artifact : : PatchTexts ( a . artifact ) , a . mode = = " series " ) ;
if ( a . mode = = " series " & & ! a . base . empty ( ) ) {
// A kernel export carries a base-commit line only when it was
// cut with --base, and then in the cover letter: the
// submission base the run was given is part of every code
// key as well.
commitCode - > base = commitCode - > base . empty ( ) ? a . base : std : : format ( " {},{} " , commitCode - > base , a . base ) ;
}
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
return * commitCode ;
}
std : : optional < Json > Run : : ReuseWhole ( const std : : string & name , Json & job ) {
// A lens with wholeReuse: the stored clean whole pass for this code as
// a part, re-normalised against today's dispositions, with its summary
// for the block passes. nullopt: the whole pass runs.
const std : : string lensFile = Dyn : : Str ( job . at ( " lensFile " ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( a . mode ! = " commits " ) {
// Only the push gates reuse a whole pass; a kernel whole pass
// runs on every hash.
job [ " reuseKey " ] = nullptr ;
job [ " otherKeys " ] = Json : : array ( ) ;
return std : : nullopt ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > ids ;
for ( const Json & d : inForce ) ids . push_back ( Dyn : : Str ( d . at ( " id " ) ) ) ;
std : : map < std : : string , std : : optional < std : : string > > keys ;
for ( const Plan : : Environment & e : Plan : : Environments ) keys [ std : : string ( e . name ) ] = Plan : : WholeCodeKey ( job , lensFile , RangeCode ( ) , ids , charterSha . at ( lensFile ) , PromptVersion , e . name ) ;
const Json & configured = Dyn : : Get ( environments , lensFile ) ;
const std : : optional < std : : string > key = keys . at ( configured . is_null ( ) ? std : : string ( Plan : : LensOf ( lensFile ) . env ) : Dyn : : Str ( configured ) ) ;
job [ " reuseKey " ] = key ? Json ( * key ) : Json ( ) ;
std : : set < std : : string > others ;
for ( const auto & [ e , k ] : keys ) {
if ( k & & ! k - > empty ( ) & & k ! = key ) others . insert ( * k ) ;
}
job [ " otherKeys " ] = Array ( std : : vector < std : : string > ( others . begin ( ) , others . end ( ) ) ) ;
const Json & hit = key ? Dyn : : Get ( state . at ( " entries " ) , * key ) : Dyn : : EmptyDict ( ) ;
if ( ! Dyn : : Truthy ( hit ) | | a . dryRun ) return std : : nullopt ;
Json v = { { " verdict " , " SEND-READY " } , { " findings " , Dyn : : At ( hit , " findings " ) } , { " notes " , Dyn : : At ( hit , " notes " ) } , { " coverage " , Dyn : : At ( hit , " coverage " ) } , { " summary " , Dyn : : Get ( hit , " summary " ) } } ;
Json expected = Json : : array ( ) ;
std : : vector < std : : string > allIds ;
const std : : vector < std : : string > wanted = Strings ( job . at ( " expectedIds " ) ) ;
for ( const Json & u : units ) {
allIds . push_back ( Dyn : : Str ( u . at ( " id " ) ) ) ;
if ( std : : ranges : : contains ( wanted , allIds . back ( ) ) ) expected . push_back ( u ) ;
}
Json n = Normalize : : NormalizeOutput ( v , inForce , lensFile , hash , expected , allIds ) ;
if ( n . at ( " verdict " ) ! = " SEND-READY " | | Dyn : : Truthy ( n . at ( " coverageMissing " ) ) ) {
log ( std : : format ( " {}: stored result re-blocked against today's dispositions or slots - re-running " , Dyn : : Str ( job . at ( " label " ) ) ) ) ;
return std : : nullopt ;
}
const std : : string judgedAt = Dyn : : Slice ( Dyn : : StrOr ( Dyn : : Has ( hit , " hash " ) ? hit . at ( " hash " ) : Json ( " " ) , " " ) , 0 , 8 ) ;
n [ " partLabel " ] = job . at ( " label " ) ;
n [ " partKind " ] = " whole " ;
n [ " partUnit " ] = nullptr ;
n [ " status " ] = " reused " ;
n [ " reused " ] = std : : format ( " unit-state {} (run {} at {}) " , * key , Dyn : : Str ( Dyn : : Get ( hit , " run " ) ) , judgedAt ) ;
n [ " usage " ] = nullptr ;
n [ " turns " ] = 0 ;
{
const std : : lock_guard guard ( shared ) ;
summaries [ name ] = Dyn : : Slice ( Dyn : : StrOr ( Dyn : : Get ( n , " summary " ) , " " ) , 0 , 2500 ) ;
}
records . push_back ( { { " label " , job . at ( " label " ) } , { " lens " , name } , { " lensFile " , lensFile } , { " unit " , nullptr } , { " kind " , " whole " } , { " status " , " reused " } , { " reuseKey " , * key } , { " gate " , Dyn : : Get ( job , " gate " ) } } ) ;
log ( std : : format ( " {}: whole pass REUSED - the code of the range is the code {} judged at {} " , name , Dyn : : Str ( Dyn : : Get ( hit , " run " ) ) , judgedAt ) ) ;
return n ;
}
std : : optional < std : : string > Run : : ReuseKey ( const Json & job , const std : : optional < std : : string > & environment ) {
// The block's reuse key in this run's environment for its lens (or in
// the one named).
const std : : string lensFile = Dyn : : Str ( job . at ( " lensFile " ) ) ;
if ( job . at ( " kind " ) ! = " block " | | ! Plan : : LensOf ( lensFile ) . reuse ) return std : : nullopt ;
const auto u = std : : ranges : : find_if ( units , [ & ] ( const Json & x ) { return x . at ( " id " ) = = job . at ( " unit " ) ; } ) ;
if ( u = = units . end ( ) ) throw Dyn : : Error ( " StopIteration " , " " ) ;
const std : : string text = Plan : : UnitText ( lines , * u ) ;
std : : vector < std : : string > ids ;
for ( const Json & d : inForce ) ids . push_back ( Dyn : : Str ( d . at ( " id " ) ) ) ;
const Json & configured = Dyn : : Get ( environments , lensFile ) ;
const std : : string env = environment & & ! environment - > empty ( ) ? * environment : ( configured . is_null ( ) ? std : : string ( ) : Dyn : : Str ( configured ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Kernel ( ) ) {
// A series' code unit is keyed on the code (the push gates'
// rule, 2026-10-06.6); every text unit on its text and what it
// cites: the [n] URLs, the anchor when it is dated, the R-units
// it names.
if ( a . mode = = " series " & & Dyn : : Get ( job , " unitKind " ) = = " code " ) return Plan : : CodeReuseKey ( job , lensFile , text , RangeCode ( ) , ids , charterSha . at ( lensFile ) , PromptVersion , env ) ;
return Plan : : ReuseKey ( job , lensFile , text , Plan : : TextDeps ( text , units , lines , refUrls , anchorText ) , ids , charterSha . at ( lensFile ) , PromptVersion ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
return Plan : : BlockReuseKey ( job , lensFile , text , RangeCode ( ) , ids , charterSha . at ( lensFile ) , PromptVersion , env ) ;
}
std : : vector < std : : string > Run : : OtherKeys ( const Json & job , const std : : optional < std : : string > & key ) {
// The block's keys in every other environment: a defect its pass
// returns here drops the clean verdicts those hold for the same code -
// a finding is not undone by switching the lens's environment.
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Kernel ( ) ) return { } ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : set < std : : string > out ;
for ( const Plan : : Environment & e : Plan : : Environments ) {
const std : : optional < std : : string > k = ReuseKey ( job , std : : string ( e . name ) ) ;
if ( k & & ! k - > empty ( ) & & k ! = key ) out . insert ( * k ) ;
}
return { out . begin ( ) , out . end ( ) } ;
}
Json Run : : DirEnvironments ( const fs : : path & dir ) {
// {lens name: environment} a scratch dir's passes ran with; a dir
// without the marker ran every lens in its default environment.
const std : : lock_guard guard ( shared ) ;
if ( ! envMarkers . contains ( dir ) ) {
try {
const Json m = Dyn : : LoadJsonFile ( dir / " environments " ) ;
envMarkers [ dir ] = m . is_object ( ) ? m : Json : : object ( ) ;
} catch ( const std : : exception & ) {
envMarkers [ dir ] = Json : : object ( ) ;
}
}
return envMarkers . at ( dir ) ;
}
std : : int64_t Run : : DirRound ( const fs : : path & dir ) {
const std : : optional < std : : string > text = Platform : : ReadFile ( dir / " round " ) ;
if ( ! text ) return 1 ;
return Dyn : : ParseInt ( Dyn : : Strip ( * text ) ) . value_or ( 1 ) ;
}
std : : int64_t Run : : ReadsNeeded ( const Json & job ) const {
// Clean reads this pass's unit needs before its verdict is reused: x
// for a code unit of a lens marked `reads`.
return x > 1 & & job . at ( " kind " ) = = " block " & & Dyn : : Get ( job , " unitKind " ) = = " code " & & Plan : : LensOf ( Dyn : : Str ( job . at ( " lensFile " ) ) ) . reads ? x : 1 ;
}
std : : optional < std : : pair < Json , Json > > Run : : Salvage ( const Json & job ) {
// A finished, ok output for this label from an earlier scratch dir on
// the same hash: reused instead of launched.
if ( testMode | | a . dryRun | | a . noSalvage ) return std : : nullopt ;
const std : : string lensFile = Dyn : : Str ( job . at ( " lensFile " ) ) ;
const Json & configured = Dyn : : Get ( environments , lensFile ) ;
const std : : string env = configured . is_null ( ) ? std : : string ( " none " ) : Dyn : : Str ( configured ) ;
const Plan : : Lens & lens = Plan : : LensOf ( lensFile ) ;
for ( const fs : : path & d : salvageDirs ) {
if ( x > 1 & & DirRound ( d ) ! = round & & ReadsNeeded ( job ) > 1 ) continue ;
const std : : string name = Plan : : LensName ( lensFile ) ;
const Json markers = DirEnvironments ( d ) ;
const std : : string was = Dyn : : Has ( markers , name ) ? Dyn : : Str ( markers . at ( name ) ) : std : : string ( lens . env ) ;
if ( was ! = env ) {
// Evidence bought in one environment is never reused in another.
bool first = false ;
{
const std : : lock_guard guard ( shared ) ;
first = envSkips . insert ( { d . string ( ) , name } ) . second ;
}
if ( first ) log ( std : : format ( " {}: nothing salvaged from {} - its passes ran in the {} environment, this run gives the lens {} " , name , Basename ( d ) , was , env ) ) ;
continue ;
}
const fs : : path f = d / " out " / std : : format ( " {}.jsonl " , FileLabel ( job ) ) ;
if ( ! fs : : exists ( f ) ) continue ;
Json ps ;
Json raw ;
try {
const std : : string text = Dyn : : UniversalNewlines ( Dyn : : DecodeReplace ( Platform : : ReadFile ( f ) . value_or ( " " ) ) ) ;
if ( text . starts_with ( " { \" type \" : \" review_gates_meta \" " ) ) {
const Json meta = Json : : parse ( text . substr ( 0 , text . find ( ' \n ' ) ) ) ;
const std : : string fs = f . string ( ) ;
ps = OpenCode : : ParseEvents ( text , std : : format ( " {}.so.json " , fs . substr ( 0 , fs . size ( ) - std : : string_view ( " .jsonl " ) . size ( ) ) ) ) ;
ps [ " init " ] = { { " model " , Dyn : : Get ( meta , " model " ) } } ;
ps [ " denials " ] = Json : : array ( ) ;
ps [ " result " ] = nullptr ;
const auto [ st , reason ] = OpenCode : : Classify ( ps , 0 , " " ) ;
if ( st = = " ok " ) raw = ps . at ( " structured " ) ;
} else {
ps = Stream : : ParseStream ( text ) ;
const auto [ st , reason ] = Stream : : Classify ( ps , 0 , " " ) ;
if ( st = = " ok " ) {
const std : : optional < Json > structured = Stream : : StructuredOutput ( ps . at ( " result " ) ) ;
if ( structured ) raw = * structured ;
}
}
} catch ( const std : : exception & ) {
continue ;
}
if ( raw . is_null ( ) ) continue ;
const std : : string got = Dyn : : StrOr ( Dyn : : Get ( Dyn : : Or ( Dyn : : Get ( ps , " init " ) , Dyn : : EmptyDict ( ) ) , " model " ) , " " ) ;
if ( got ! = Dyn : : Str ( job . at ( " model " ) ) ) {
log ( std : : format ( " {}: not salvaged from {} - model {} != {} " , Dyn : : Str ( job . at ( " label " ) ) , Dyn : : RelPath ( f . string ( ) , repo . string ( ) ) , got . empty ( ) ? std : : string ( " ? " ) : got , Dyn : : Str ( job . at ( " model " ) ) ) ) ;
continue ;
}
const auto [ st , reason ] = Pool : : Exercised ( ps , env , Dyn : : Str ( job . at ( " kind " ) ) , lens . empirical ) ;
if ( st ! = " ok " ) {
// An output whose instrument was missing is no evidence,
// salvaged or not.
log ( std : : format ( " {}: not salvaged from {} - {} " , Dyn : : Str ( job . at ( " label " ) ) , Dyn : : RelPath ( f . string ( ) , repo . string ( ) ) , Dyn : : Slice ( reason , 0 , 120 ) ) ) ;
continue ;
}
Json rec = { { " label " , job . at ( " label " ) } ,
{ " sessionId " , ps . at ( " sessionId " ) } ,
{ " status " , " ok " } ,
{ " reason " , " " } ,
{ " salvaged " , Dyn : : RelPath ( f . string ( ) , repo . string ( ) ) } ,
{ " maxTurns " , Dyn : : Get ( job , " maxTurns " ) } ,
{ " environment " , env } ,
{ " usage " , ps . at ( " usage " ) } ,
{ " firstTurn " , ps . at ( " firstTurn " ) } ,
{ " turns " , ps . at ( " turns " ) } ,
{ " toolCalls " , ps . at ( " toolCalls " ) } ,
{ " toolErrors " , ps . at ( " toolErrors " ) } ,
{ " costUsd " , 0.0 } ,
{ " costUsdOriginal " , ps . at ( " costUsd " ) } ,
{ " denials " , ps . at ( " denials " ) } ,
{ " rateLimit " , Json : : object ( ) } ,
{ " promptBytes " , nullptr } } ;
return std : : pair ( rec , raw ) ;
}
return std : : nullopt ;
}
// ---- one process ----------------------------------------------------------------------
std : : pair < Json , Json > Run : : ExecJob ( const Json & job , std : : int64_t ) {
auto stamp = [ & ] ( Json & rec ) {
rec [ " lens " ] = job . at ( " lens " ) ;
rec [ " lensFile " ] = job . at ( " lensFile " ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
rec [ " persona " ] = Dyn : : Get ( job , " persona " ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
rec [ " kind " ] = job . at ( " kind " ) ;
rec [ " unit " ] = Dyn : : Get ( job , " unit " ) ;
rec [ " unitSha " ] = Dyn : : Get ( job , " unitSha " ) ;
rec [ " model " ] = job . at ( " model " ) ;
rec [ " effort " ] = a . effort ;
rec [ " gate " ] = Dyn : : Get ( job , " gate " ) ;
rec [ " reuseKey " ] = Dyn : : Get ( job , " reuseKey " ) ;
rec [ " otherKeys " ] = Dyn : : Get ( job , " otherKeys " ) ;
rec [ " readNo " ] = Dyn : : Get ( job , " readNo " ) ;
} ;
if ( std : : optional < std : : pair < Json , Json > > s = Salvage ( job ) ) {
auto [ rec , raw ] = std : : move ( * s ) ;
stamp ( rec ) ;
{
const std : : lock_guard guard ( shared ) ;
jobsRun . push_back ( job ) ;
}
log ( std : : format ( " {}: salvaged from {} " , Dyn : : Str ( job . at ( " label " ) ) , Dyn : : Str ( rec . at ( " salvaged " ) ) ) ) ;
return { rec , raw } ;
}
auto abortPool = [ & ] ( const std : : string & reason ) {
const std : : lock_guard guard ( shared ) ;
if ( sched ) sched - > Abort ( reason ) ;
} ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : string now = Artifact : : ArtifactHash ( a . mode , a . artifact ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( now ! = hash ) {
abortPool ( std : : format ( " artifact changed during the run ({} != {}) " , now . substr ( 0 , 8 ) , h8 ) ) ;
return { { { " label " , job . at ( " label " ) } , { " status " , " error " } , { " reason " , " artifact changed during the run - aborted " } } , nullptr } ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( const std : : optional < std : : string > drift = a . mode = = " commits " ? treeDrift ( ) : std : : nullopt ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
abortPool ( std : : format ( " evidence drift during the run ({}) " , * drift ) ) ;
return { { { " label " , job . at ( " label " ) } , { " status " , " error " } , { " reason " , std : : format ( " {} - aborted " , * drift ) } } , nullptr } ;
}
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
const auto [ systemPath , prompt ] = promptFor ( job ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const bool whole = job . at ( " kind " ) = = " whole " ;
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
auto [ rec , raw ] = runPass ( job , prompt , systemPath , schemas . at ( whole ? " whole " : " block " ) , Dyn : : Has ( job , " maxTurns " ) ? Int ( job . at ( " maxTurns " ) ) : 20 ,
Dyn : : Has ( job , " timeoutMin " ) ? Int ( job . at ( " timeoutMin " ) ) : 20 , whole ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( Dyn : : Truthy ( Dyn : : Get ( job , " stack " ) ) ) rec [ " stack " ] = job . at ( " stack " ) . at ( " id " ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( rec , " memPeakMb " ) ) ) {
const Json & configured = Dyn : : Get ( environments , Dyn : : Str ( job . at ( " lensFile " ) ) ) ;
calibration - > Record ( configured . is_null ( ) ? std : : string ( " none " ) : Dyn : : Str ( configured ) , Number ( rec . at ( " memPeakMb " ) ) ) ;
}
stamp ( rec ) ;
{
const std : : lock_guard guard ( shared ) ;
const auto found = lensLayersBytes . find ( Dyn : : Str ( job . at ( " lens " ) ) ) ;
rec [ " lensLayerBytes " ] = found = = lensLayersBytes . end ( ) ? Json ( ) : Json ( found - > second ) ;
jobsRun . push_back ( job ) ;
}
rec [ " systemFile " ] = Dyn : : RelPath ( systemPath . string ( ) , repo . string ( ) ) ;
return { rec , raw } ;
}
Json Run : : PartFrom ( const Json & job , const Json & rec , Json raw ) {
Json expected = Json : : array ( ) ;
std : : vector < std : : string > allIds ;
const std : : vector < std : : string > wanted = Strings ( job . at ( " expectedIds " ) ) ;
for ( const Json & u : units ) {
allIds . push_back ( Dyn : : Str ( u . at ( " id " ) ) ) ;
if ( std : : ranges : : contains ( wanted , allIds . back ( ) ) ) expected . push_back ( u ) ;
}
Json n = Normalize : : NormalizeOutput ( raw , inForce , Dyn : : Str ( job . at ( " lensFile " ) ) , hash , expected , allIds ) ;
for ( const Json & l : n . at ( " normalizeLogs " ) ) log ( Dyn : : Str ( l ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( job , " readNo " ) ) ) {
for ( Json & f : n [ " findings " ] ) f [ " read " ] = job . at ( " readNo " ) ;
}
n [ " partLabel " ] = job . at ( " label " ) ;
n [ " partKind " ] = job . at ( " kind " ) ;
n [ " partUnit " ] = Dyn : : Get ( job , " unit " ) ;
n [ " status " ] = Dyn : : Has ( rec , " status " ) ? rec . at ( " status " ) : Json ( " ok " ) ;
n [ " usage " ] = Dyn : : Get ( rec , " usage " ) ;
n [ " turns " ] = Dyn : : Get ( rec , " turns " ) ;
n [ " reused " ] = nullptr ;
return n ;
}
Json Run : : DryPart ( const Json & job ) {
Json coverage = Json : : array ( ) ;
for ( const Json & i : job . at ( " expectedIds " ) ) coverage . push_back ( { { " item " , i } , { " verdict " , " clear " } , { " basis " , " dry run " } } ) ;
return { { " partLabel " , job . at ( " label " ) } , { " partKind " , job . at ( " kind " ) } , { " partUnit " , Dyn : : Get ( job , " unit " ) } , { " verdict " , " SEND-READY " } , { " findings " , Json : : array ( ) } , { " notes " , Json : : array ( ) } ,
{ " coverage " , coverage } , { " coverageMissing " , Json : : array ( ) } , { " status " , " dry-run " } , { " summary " , " dry run " } , { " reused " , nullptr } } ;
}
// ---- a gate -----------------------------------------------------------------------------
std : : vector < Json > Run : : RunGate ( std : : string_view title , std : : vector < std : : string > lensFiles ) {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : pair < std : : string , std : : string > > specs ;
for ( const std : : string & lf : lensFiles ) specs . emplace_back ( lf , std : : string ( ) ) ;
return RunGate ( title , std : : move ( specs ) ) ;
}
std : : vector < Json > Run : : RunGate ( std : : string_view title , std : : vector < std : : pair < std : : string , std : : string > > specs ) {
// specs -> the merged lens results, one per lens instance.
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > names ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const auto & [ lf , persona ] : specs ) names . push_back ( Plan : : LensName ( lf , persona ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
log ( std : : format ( " {}: {} " , title , Dyn : : Join ( names , " , " ) ) ) ;
std : : vector < Json > resumed ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : pair < std : : string , std : : string > > live ;
for ( const auto & [ lf , persona ] : specs ) {
if ( std : : optional < Json > r = resumable ( Plan : : LensName ( lf , persona ) , lf , title ) ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
resumed . push_back ( std : : move ( * r ) ) ;
} else {
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
live . emplace_back ( lf , persona ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
specs = live ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// Nothing runs: no stack, database or application is needed for a
// result already bought.
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( specs . empty ( ) ) return resumed ;
std : : vector < std : : string > lensFiles ;
for ( const auto & [ lf , persona ] : specs ) {
if ( ! std : : ranges : : contains ( lensFiles , lf ) ) lensFiles . push_back ( lf ) ;
}
test(run): the store rules, stacks and memory, and the review fixes, check by check
StoreRules (23 checks), StacksMemory (24) and ReviewFixes (19), each a
test of its own.
Run and SlotsPlan now have seams that start as the real ones: appReady,
probe, query, bypassesRls, migrationsAtHead, migrationsDrift, treeDrift,
promptFor, runPass, resumable, instrumentPreflight, and a Machine for
SlotsPlan. MigrationsAtHead is split out of MigrationsDrift for it; the
HEAD side is still worked out once per tree and base.
The Postgres stand-in and the raw broker call move to tests/Common, shared
by PgWire and ReviewFixes. ReviewFixes runs this binary as `sql`, and a
real server that resets every connection makes the startup message either
fail to go out or never get its answer - a DbError either way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:39:53 +01:00
instrumentPreflight ( lensFiles ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : map < std : : string , std : : vector < Json > > parts ;
std : : map < std : : string , std : : set < std : : string > > missing ;
std : : map < std : : string , std : : set < std : : string > > planned ;
std : : map < std : : string , std : : vector < Json > > pendingBlocks ;
std : : vector < Json > initial ;
const std : : vector < std : : string > exclude = Strings ( cfg . at ( " functional " ) . at ( " exclude " ) ) ;
std : : vector < std : : string > unitFilter ;
if ( a . units ) unitFilter . assign ( a . units - > begin ( ) , a . units - > end ( ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const auto & [ lf , persona ] : specs ) {
const std : : string name = Plan : : LensName ( lf , persona ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
parts [ name ] ;
missing [ name ] ;
planned [ name ] ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
Plan : : LensPlan plan = Plan : : PlanLens ( lf , units , lines , unitFilter , exclude , persona ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( ! plan . whole . is_null ( ) ) {
plan . whole [ " gate " ] = title ;
for ( const Json & id : plan . whole . at ( " expectedIds " ) ) planned [ name ] . insert ( Dyn : : Str ( id ) ) ;
}
for ( Json & j : plan . blocks ) {
j [ " gate " ] = title ;
for ( const Json & id : j . at ( " expectedIds " ) ) planned [ name ] . insert ( Dyn : : Str ( id ) ) ;
}
if ( ! plan . whole . is_null ( ) ) {
pendingBlocks [ name ] = plan . blocks ;
if ( std : : optional < Json > part = ReuseWhole ( name , plan . whole ) ) {
parts [ name ] . push_back ( std : : move ( * part ) ) ;
std : : ranges : : move ( PrepareBlocks ( name , plan . blocks , parts ) , std : : back_inserter ( initial ) ) ;
} else {
initial . push_back ( plan . whole ) ;
}
} else {
std : : ranges : : move ( PrepareBlocks ( name , plan . blocks , parts ) , std : : back_inserter ( initial ) ) ;
}
}
auto onDone = [ & ] ( const Json & job , const Json & rec , const Json & raw ) - > std : : vector < Json > {
const std : : string name = Dyn : : Str ( job . at ( " lens " ) ) ;
records . push_back ( rec ) ;
const std : : string status = Dyn : : StrOr ( Dyn : : Get ( rec , " status " ) , " " ) ;
if ( status ! = " ok " & & status ! = " dry-run " ) {
for ( const Json & id : job . at ( " expectedIds " ) ) missing [ name ] . insert ( Dyn : : Str ( id ) ) ;
if ( job . at ( " kind " ) = = " whole " ) {
for ( const Json & b : pendingBlocks [ name ] ) missing [ name ] . insert ( Dyn : : Str ( b . at ( " unit " ) ) ) ;
}
log ( std : : format ( " {}: {} - {} " , Dyn : : Str ( job . at ( " label " ) ) , Dyn : : Str ( Dyn : : Get ( rec , " status " ) ) , Dyn : : Slice ( Dyn : : Has ( rec , " reason " ) ? Dyn : : Str ( rec . at ( " reason " ) ) : std : : string ( ) , 0 , 120 ) ) ) ;
return { } ;
}
Json part = raw . is_null ( ) ? DryPart ( job ) : PartFrom ( job , rec , raw ) ;
for ( const Json & id : Dyn : : Or ( Dyn : : Get ( part , " coverageMissing " ) , Dyn : : EmptyList ( ) ) ) missing [ name ] . insert ( Dyn : : Str ( id ) ) ;
parts [ name ] . push_back ( part ) ;
if ( job . at ( " kind " ) ! = " whole " ) return { } ;
wholeParts [ name ] = part ;
if ( part . at ( " verdict " ) ! = " SEND-READY " ) {
log ( std : : format ( " {}: whole pass FIX FIRST ({} undischarged) - block passes skipped until the whole pass is accepted " , name , Dyn : : Str ( Dyn : : Get ( part , " undischarged " ) ) ) ) ;
parts [ name ] . push_back ( { { " partLabel " , std : : format ( " {}:blocks " , name ) } , { " partKind " , " skipped " } , { " verdict " , nullptr } , { " findings " , Json : : array ( ) } , { " notes " , Json : : array ( ) } ,
{ " coverage " , Json : : array ( ) } , { " coverageMissing " , Json : : array ( ) } } ) ;
return { } ;
}
{
const std : : lock_guard guard ( shared ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
// A persona's digest is its summary, else the review it
// would send.
std : : string digest = Dyn : : StrOr ( Dyn : : Get ( part , " summary " ) , " " ) ;
if ( digest . empty ( ) ) digest = Dyn : : StrOr ( Dyn : : Get ( part , " predictedReview " ) , " " ) ;
summaries [ name ] = Dyn : : Slice ( digest , 0 , 2500 ) ;
}
std : : vector < Json > blocks = pendingBlocks [ name ] ;
if ( Dyn : : Truthy ( Dyn : : Get ( job , " persona " ) ) & & a . personaBlocks ! = " all " ) {
// The units the persona's whole pass marked not-mine get no
// block pass from it: each becomes a pruned part with that
// verdict.
std : : vector < std : : string > notMine ;
for ( const Json & id : Dyn : : Or ( Dyn : : Get ( part , " notMine " ) , Dyn : : EmptyList ( ) ) ) notMine . push_back ( Dyn : : Str ( id ) ) ;
std : : ranges : : sort ( notMine ) ;
notMine . erase ( std : : ranges : : unique ( notMine ) . begin ( ) , notMine . end ( ) ) ;
if ( ! notMine . empty ( ) ) {
const double ratio = static_cast < double > ( notMine . size ( ) ) / static_cast < double > ( std : : max < std : : size_t > ( 1 , blocks . size ( ) ) ) ;
log ( std : : format ( " {}: {} units marked not-mine by the whole pass ({:.0f}%){}; those block passes are pruned " , name , notMine . size ( ) , ratio * 100 ,
ratio > 0.5 ? " - WARNING above 50% " : " " ) ) ;
for ( const std : : string & uid : notMine ) {
parts [ name ] . push_back ( { { " partLabel " , std : : format ( " {}:not-mine:{} " , name , uid ) } , { " partKind " , " pruned " } , { " partUnit " , uid } , { " verdict " , " SEND-READY " } , { " findings " , Json : : array ( ) } ,
{ " notes " , Json : : array ( ) } , { " coverage " , Json : : array ( { { { " item " , uid } , { " verdict " , " not-mine " } , { " basis " , " whole pass: not this reviewer's tree, file or decision " } } } ) } ,
{ " coverageMissing " , Json : : array ( ) } , { " reused " , nullptr } } ) ;
}
std : : vector < Json > kept ;
for ( const Json & b : blocks ) {
if ( ! std : : ranges : : contains ( notMine , Dyn : : Str ( b . at ( " unit " ) ) ) ) kept . push_back ( b ) ;
}
blocks = kept ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
return PrepareBlocks ( name , blocks , parts ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
} ;
const bool warm = ! a . dryRun & & ( ! testMode | | a . warm ) ;
std : : unique_ptr < Pool : : Admission > admission = Admission ( lensFiles ) ;
Pool : : Scheduler scheduler ( { . runner = runner . get ( ) ,
. concurrency = a . concurrency ,
. log = log ,
. progressPath = scratch / " progress.json " ,
. cacheKey = warm ? std : : function < std : : optional < std : : string > ( Json & ) > ( [ this ] ( Json & job ) { return CacheKey ( job ) ; } ) : nullptr ,
. warmProbe = warm ? std : : function < bool ( const Json & ) > ( [ this ] ( const Json & job ) { return WarmProbe ( job ) ; } ) : nullptr ,
. seats = & seats ,
feat(seats): accounts without a 5-hour limit
Anthropic is removing the 5-hour limit in stages (from 2026-10-31), and
an account without it reports the weekly window alone. Until now the pool
took such an account for an unprobed seat: always eligible, ranked after
every other, never held to the weekly cutoff, with no cap on its passes.
- The burst window is the 5-hour one, else the weekly one
(Seats::BurstWindow). An account whose burst window is the weekly one is
ranked by it and admitted under the 95 % cutoff with the passes in
flight projected on it, at the measured share per pass (0.04 at xhigh,
0.125 otherwise; REVIEW_GATES_LENS_COST_7D_PCT), and waits for the weekly
reset when over it.
- Every OAuth account and the local login takes at most 128 passes at once,
every driver's counted (REVIEW_GATES_OAUTH_CONCURRENCY): every run
measured with 149 or more in flight on one account drew usage-limit
rejections, none of the 119 with 139 or fewer.
- A 'concurrents' rejection pauses the seat for 20 s or its retry-after,
not until a window's reset (a seat sat two hours at 10 % on one).
- Board entries, the folded foreign record and the board's view carry
cost7d, so the drivers see each other's weekly load.
- `seats` and the log table say `no limit` in such an account's 5-hour
column; the board's others-line names its weekly projection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:07:17 +01:00
. seatConfig = SeatPool : : PoolConfig ( Platform : : Environment ( ) , a . effort ) ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
. apiConfig = apiCfg ,
. ledger = ledger . get ( ) ,
. admission = admission . get ( ) ,
2026-10-31 09:59:12 +01:00
. board = board . get ( ) } ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{
2026-10-31 09:59:12 +01:00
// A stop before this gate, or while its pool was set up, stays in
// force: the pool starts aborted, so the next gate never runs.
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const std : : lock_guard guard ( shared ) ;
2026-10-31 09:59:12 +01:00
if ( stopped ) scheduler . Abort ( * stopped ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
sched = & scheduler ;
}
scheduler . Run ( initial , [ this ] ( const Json & job , std : : int64_t attempt ) { return ExecJob ( job , attempt ) ; } , onDone ) ;
{
const std : : lock_guard guard ( shared ) ;
sched = nullptr ;
}
if ( const std : : optional < std : : string > aborted = scheduler . Aborted ( ) ) abort = aborted ;
std : : vector < Json > out ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const auto & [ lf , persona ] : specs ) {
const std : : string name = Plan : : LensName ( lf , persona ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const bool stoppedEarly = std : : ranges : : any_of ( parts [ name ] , [ ] ( const Json & p ) { return Dyn : : Get ( p , " partKind " ) = = " skipped " ; } ) ;
std : : vector < Json > real ;
for ( const Json & p : parts [ name ] ) {
if ( Dyn : : Get ( p , " partKind " ) ! = " skipped " ) real . push_back ( p ) ;
}
std : : set < std : : string > covered ;
for ( const Json & p : real ) {
for ( const Json & c : Dyn : : Or ( Dyn : : Get ( p , " coverage " ) , Dyn : : EmptyList ( ) ) ) covered . insert ( Dyn : : Str ( c . at ( " item " ) ) ) ;
}
if ( ! stoppedEarly ) {
for ( const std : : string & id : planned [ name ] ) {
if ( ! covered . contains ( id ) ) missing [ name ] . insert ( id ) ;
}
}
const std : : vector < std : : string > missingList ( missing [ name ] . begin ( ) , missing [ name ] . end ( ) ) ;
Json m = Normalize : : MergeParts ( name , lf , real , missingList , stoppedEarly ? Json ( " whole pass FIX FIRST - block passes skipped " ) : Json ( ) ) ;
if ( ! Plan : : LensOf ( lf ) . whole . empty ( ) & & std : : ranges : : none_of ( real , [ ] ( const Json & p ) { return Dyn : : Get ( p , " partKind " ) = = " whole " ; } ) ) {
Json coverageMissing = Json : : array ( ) ;
for ( const Json & id : m . at ( " coverageMissing " ) ) {
if ( std : : ranges : : none_of ( coverageMissing , [ & ] ( const Json & c ) { return c = = id ; } ) ) coverageMissing . push_back ( id ) ;
}
if ( std : : ranges : : none_of ( coverageMissing , [ ] ( const Json & c ) { return c = = " (whole pass) " ; } ) ) coverageMissing . push_back ( " (whole pass) " ) ;
m [ " coverageMissing " ] = coverageMissing ;
m [ " contractViolations " ] . push_back ( { { " lens " , lf } , { " kind " , " whole pass did not return - lens NOT RETURNED " } } ) ;
}
std : : size_t logged = 0 ;
for ( const Json & p : real ) logged + = Dyn : : Or ( Dyn : : Get ( p , " normalizeLogs " ) , Dyn : : EmptyList ( ) ) . size ( ) ;
const Json & merged = m . at ( " normalizeLogs " ) ;
for ( std : : size_t i = logged ; i < merged . size ( ) ; + + i ) log ( Dyn : : Str ( merged . at ( i ) ) ) ;
log ( std : : format ( " {}: {} - findings {} (undischarged {}), passes {}, missing {} " , name , Dyn : : Str ( m . at ( " verdict " ) ) , m . at ( " findings " ) . size ( ) , Dyn : : Str ( m . at ( " undischarged " ) ) , real . size ( ) , m . at ( " coverageMissing " ) . size ( ) ) ) ;
out . push_back ( std : : move ( m ) ) ;
}
std : : ranges : : move ( out , std : : back_inserter ( resumed ) ) ;
return resumed ;
}
std : : unique_ptr < Pool : : Admission > Run : : Admission ( std : : span < const std : : string > lensFiles ) {
// Free memory less the reserve is the budget, each pass held at its
// environment's measured cost; a pass that drives an application
// holds a stack of its own. Free memory is the reading of now - or,
// while other drivers' passes are in flight, the board's reading from
// before they were.
std : : set < std : : string > envs ;
for ( const std : : string & lf : lensFiles ) envs . insert ( Dyn : : Str ( Dyn : : At ( environments , lf ) ) ) ;
const std : : optional < std : : int64_t > free = Memory : : Available ( ) ;
const std : : int64_t reserve = Memory : : Reserve ( ) ;
std : : optional < double > avail = free ? std : : optional < double > ( static_cast < double > ( * free ) ) : std : : nullopt ;
std : : optional < std : : string > how ;
bool recorded = false ;
if ( free & & board ) {
const auto [ base , why ] = board - > MemoryBase ( * free , Platform : : Now ( ) ) ;
avail = base ;
how = why ;
recorded = base ! = static_cast < double > ( * free ) ;
}
const std : : optional < double > budget = avail ? std : : optional < double > ( std : : max ( 0.0 , * avail - static_cast < double > ( reserve ) ) ) : std : : nullopt ;
std : : map < std : : string , Memory : : Calibration : : Cost > cost ;
for ( const std : : string & e : envs ) cost . emplace ( e , calibration - > CostOf ( e ) ) ;
std : : vector < std : : string > partsText ;
for ( const std : : string & e : envs ) {
const double mb = Number ( cost . at ( e ) . megabytes ) ;
std : : string line = std : : format ( " {} ~{:.0f} MB a pass - {} " , e , mb , cost . at ( e ) . source ) ;
if ( budget ) line + = std : : format ( " -> {} at once by memory " , static_cast < std : : int64_t > ( FloorDiv ( * budget , mb ) ) ) ;
if ( Plan : : FindEnvironment ( e ) - > app ) {
const auto size = static_cast < std : : int64_t > ( stacks - > Size ( ) ) ;
line + = std : : format ( " , {} stack(s) -> {} at once " , size , budget ? std : : min < std : : int64_t > ( size , std : : max < std : : int64_t > ( 1 , static_cast < std : : int64_t > ( FloorDiv ( * budget , mb ) ) ) ) : size ) ;
}
partsText . push_back ( line ) ;
}
( void ) recorded ;
log ( std : : format ( " memory: {}{} " , avail ? std : : format ( " {:.0f} MB free{}, reserve {} MB -> budget {:.0f} MB; " , * avail , how ? std : : format ( " ({}) " , * how ) : std : : string ( ) , reserve , * budget )
: std : : string ( " no /proc/meminfo - memory not limited; " ) ,
Dyn : : Join ( partsText , " ; " ) ) ) ;
std : : map < std : : string , double > costOf ;
for ( const auto & [ e , c ] : cost ) costOf [ e ] = Number ( c . megabytes ) ;
const Json envCopy = environments ;
return std : : make_unique < Pool : : Admission > ( [ costOf , envCopy ] ( const Json & j ) { return costOf . at ( Dyn : : Str ( Dyn : : At ( envCopy , Dyn : : Str ( j . at ( " lensFile " ) ) ) ) ) ; } ,
[ envCopy ] ( const Json & j ) { return Plan : : FindEnvironment ( Dyn : : Str ( Dyn : : At ( envCopy , Dyn : : Str ( j . at ( " lensFile " ) ) ) ) ) - > app ; } , stacks . get ( ) , budget ,
static_cast < double > ( reserve ) , Pool : : Admission : : Available ( ) , log ) ;
}
std : : optional < Json > Run : : Resumable ( const std : : string & name , const std : : string & lensFile , std : : string_view title ) {
// A lens result from the resume file (same hash) that returned fully:
// discharge re-derived against the dispositions in force NOW, reused.
if ( ! Dyn : : Truthy ( resume ) ) return std : : nullopt ;
if ( x > 1 & & newRound & & Plan : : LensOf ( lensFile ) . reads ) return std : : nullopt ;
const Json * src = nullptr ;
for ( const Json & r : resume . at ( " results " ) ) {
if ( Dyn : : Get ( r , " lens " ) = = name ) {
src = & r ;
break ;
}
}
if ( ! src | | Dyn : : Truthy ( Dyn : : Get ( * src , " coverageMissing " ) ) | | ! ( Dyn : : Get ( * src , " verdict " ) = = " SEND-READY " | | Dyn : : Get ( * src , " verdict " ) = = " FIX FIRST " ) ) return std : : nullopt ;
// A checkpoint written before 2026-10-16.1 carries no environments:
// its lenses ran in their defaults.
const Json & markers = Dyn : : Or ( Dyn : : Get ( resume , " environments " ) , Dyn : : EmptyDict ( ) ) ;
const std : : string fallback ( Plan : : LensOf ( lensFile ) . env ) ;
const std : : string was = Dyn : : Has ( markers , name ) ? Dyn : : Str ( markers . at ( name ) ) : fallback ;
const Json & configured = Dyn : : Get ( environments , lensFile ) ;
const std : : string now = configured . is_null ( ) ? fallback : Dyn : : Str ( configured ) ;
if ( was ! = now ) {
log ( std : : format ( " {}: not resumed - its result on this hash was bought in the {} environment, this run gives the lens {} " , name , was , now ) ) ;
return std : : nullopt ;
}
Json r = * src ;
std : : set < std : : string > ids ;
for ( const Json & d : inForce ) ids . insert ( Dyn : : Str ( d . at ( " id " ) ) ) ;
std : : int64_t undischarged = 0 ;
for ( Json & f : r [ " findings " ] ) {
const Json & by = Dyn : : Get ( f , " dischargedBy " ) ;
f [ " discharged " ] = Dyn : : Truthy ( by ) & & ids . contains ( Dyn : : Str ( by ) ) ;
if ( ! f . at ( " discharged " ) . get < bool > ( ) ) + + undischarged ;
}
r [ " undischarged " ] = undischarged ;
r [ " verdict " ] = undischarged ? " FIX FIRST " : " SEND-READY " ;
r [ " resumed " ] = Dyn : : Str ( Dyn : : Get ( resume , " run " ) ) ;
records . push_back ( { { " label " , std : : format ( " {}:resumed " , name ) } , { " lens " , name } , { " lensFile " , lensFile } , { " kind " , " resumed " } , { " status " , " resumed " } , { " gate " , title } , { " from " , Dyn : : Get ( resume , " run " ) } } ) ;
log ( std : : format ( " {}: RESUMED from {} - {} (findings {}, undischarged {}, re-normalised against {} disposition(s) in force) " , name , Dyn : : Str ( Dyn : : Get ( resume , " run " ) ) , Dyn : : Str ( r . at ( " verdict " ) ) ,
r . at ( " findings " ) . size ( ) , undischarged , ids . size ( ) ) ) ;
return r ;
}
void Run : : Checkpoint ( std : : string_view title ) {
if ( testMode | | a . dryRun ) return ;
Json markers = Json : : object ( ) ;
for ( auto it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it ) markers [ Plan : : LensName ( it . key ( ) ) ] = it . value ( ) ;
Json checkpoint = { { " hash " , hash } , { " date " , a . date } , { " run " , Basename ( dumpPath ) } , { " after " , title } , { " results " , results } , { " environments " , markers } } ;
if ( x > 1 ) {
checkpoint [ " round " ] = round ;
checkpoint [ " complete " ] = false ;
}
WriteReplace ( resumePath , DumpFile ( checkpoint ) ) ;
StoreState ( ) ;
WriteText ( dumpPath , DumpFile ( BuildDump ( std : : format ( " IN PROGRESS - after {} (partial dump, the run continues) " , title ) , nullptr , Json : : array ( ) ) ) ) ;
log ( std : : format ( " checkpoint after {}: {} + partial dump written " , title , Dyn : : RelPath ( resumePath . string ( ) , repo . string ( ) ) ) ) ;
}
std : : vector < Json > Run : : PrepareBlocks ( const std : : string & name , std : : vector < Json > blocks , std : : map < std : : string , std : : vector < Json > > & parts ) {
// Auto-n/a and reuse hits become parts at once; the rest are jobs for
// the pool.
std : : vector < Json > jobs ;
std : : vector < std : : string > allIds ;
for ( const Json & u : units ) allIds . push_back ( Dyn : : Str ( u . at ( " id " ) ) ) ;
for ( Json & j : blocks ) {
if ( j . at ( " kind " ) = = " auto-na " ) {
parts [ name ] . push_back ( { { " partLabel " , j . at ( " label " ) } , { " partKind " , " auto-na " } , { " partUnit " , j . at ( " unit " ) } , { " verdict " , " SEND-READY " } , { " findings " , Json : : array ( ) } , { " notes " , Json : : array ( ) } ,
{ " coverage " , Json : : array ( { { { " item " , j . at ( " unit " ) } , { " verdict " , " n/a " } , { " basis " , Dyn : : Has ( j , " basis " ) ? j . at ( " basis " ) : Json ( " mechanical " ) } } } ) } ,
{ " coverageMissing " , Json : : array ( ) } , { " reused " , nullptr } } ) ;
continue ;
}
const std : : optional < std : : string > key = ReuseKey ( j ) ;
Json hit = key ? Dyn : : Get ( state . at ( " entries " ) , * key ) : Json ( ) ;
const Json was = Dyn : : Truthy ( hit ) ? Dyn : : Get ( hit , " unit " ) : Json ( ) ;
if ( Dyn : : Truthy ( hit ) & & ! Dyn : : Equal ( was , j . at ( " unit " ) ) ) hit = Plan : : Rebind ( hit , Dyn : : Str ( j . at ( " unit " ) ) ) ;
const std : : int64_t need = ReadsNeeded ( j ) ;
const std : : int64_t have = Plan : : ReadsOf ( hit ) ;
if ( need > 1 & & ( ! Dyn : : Truthy ( hit ) | | ( have < need & & ! Plan : : ReadIn ( hit , h8 , round ) ) ) ) {
j [ " readNo " ] = have + 1 ;
hit = nullptr ;
}
if ( Dyn : : Truthy ( hit ) & & ! a . dryRun ) {
Json v = { { " verdict " , " SEND-READY " } , { " findings " , Dyn : : At ( hit , " findings " ) } , { " notes " , Dyn : : At ( hit , " notes " ) } , { " coverage " , Json : : array ( { Dyn : : At ( hit , " coverage " ) } ) } } ;
Json expected = Json : : array ( ) ;
for ( const Json & u : units ) {
if ( u . at ( " id " ) = = j . at ( " unit " ) ) expected . push_back ( u ) ;
}
Json n = Normalize : : NormalizeOutput ( v , inForce , Dyn : : Str ( j . at ( " lensFile " ) ) , hash , expected , allIds ) ;
if ( n . at ( " verdict " ) = = " SEND-READY " & & ! Dyn : : Truthy ( n . at ( " coverageMissing " ) ) ) {
std : : string reused = std : : format ( " unit-state {} (run {} at {} " , * key , Dyn : : Str ( Dyn : : Get ( hit , " run " ) ) , Dyn : : Slice ( Dyn : : StrOr ( Dyn : : Has ( hit , " hash " ) ? hit . at ( " hash " ) : Json ( " " ) , " " ) , 0 , 8 ) ) ;
if ( ! Dyn : : Equal ( was , j . at ( " unit " ) ) ) reused + = std : : format ( " , stored as {} " , Dyn : : Str ( was ) ) ;
if ( need > 1 ) reused + = std : : format ( " , {} of {} clean reads " , have , need ) ;
reused + = " ) " ;
n [ " partLabel " ] = j . at ( " label " ) ;
n [ " partKind " ] = " block " ;
n [ " partUnit " ] = j . at ( " unit " ) ;
n [ " status " ] = " reused " ;
n [ " reused " ] = reused ;
n [ " usage " ] = nullptr ;
n [ " turns " ] = 0 ;
parts [ name ] . push_back ( n ) ;
records . push_back ( { { " label " , j . at ( " label " ) } , { " lens " , name } , { " lensFile " , j . at ( " lensFile " ) } , { " unit " , j . at ( " unit " ) } , { " kind " , " block " } , { " status " , " reused " } , { " reuseKey " , * key } ,
{ " gate " , Dyn : : Get ( j , " gate " ) } } ) ;
continue ;
}
log ( std : : format ( " {}: stored result re-blocked against today's dispositions - re-running " , Dyn : : Str ( j . at ( " label " ) ) ) ) ;
}
j [ " reuseKey " ] = key ? Json ( * key ) : Json ( ) ;
j [ " otherKeys " ] = key ? Array ( OtherKeys ( j , key ) ) : Json : : array ( ) ;
jobs . push_back ( j ) ;
}
return jobs ;
}
// ---- the run ------------------------------------------------------------------------------
std : : int32_t Run : : Execute ( ) {
feat(run): the repository under review is the freeze record's, not the working directory's
A directory can review repositories other than itself: a workbench whose
config, env file and records serve several, freezing each with --repo and
--out. The run took the working directory for the repository under review:
the prompt named it, the calibration was kept under it, and --trees fell
back to it. The run now reads the repository from the artifact's
freeze.json - the prompt names it and the calibration is kept under it -
and --trees defaults to what the record says: the worktree, else the
repository when it is not the working directory, else `.`, the same rule
that builds the printed run line. The working directory keeps its roles:
the config, the env file, the slots, the lens processes' cwd and every
logged path. A damaged record stops the run at preflight.
2026-10-31 21:31:48 +01:00
Freeze : : Reviewed frozen ;
try {
frozen = Freeze : : ReviewedBy ( a . artifact , repo ) ;
} catch ( const std : : runtime_error & e ) {
Die ( e . what ( ) ) ;
}
reviewed = frozen . repo ;
trees = CommaList ( a . trees . value_or ( frozen . tree ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
contextPaths = CommaList ( a . contextPaths ) ;
for ( const std : : string & c : contextPaths ) {
if ( ! fs : : exists ( c ) ) Die ( std : : format ( " --context-paths: {} does not exist " , c ) ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
reviewers = CommaList ( a . reviewers ) ;
if ( ! reviewers . empty ( ) & & std : : ranges : : contains ( off , std : : string ( Plan : : PersonaLens ) ) ) {
Die ( std : : format ( " --reviewers names {} but the config turns off the persona lens (lenses.{}.run = false): turn it on, or drop --reviewers " , Dyn : : Join ( reviewers , " , " ) ,
Plan : : LensName ( Plan : : PersonaLens ) ) ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Gate0 ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : vector < std : : string > modeLenses = Plan : : ModeLenses ( a . mode ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > only ;
if ( a . only & & ! a . only - > empty ( ) ) {
only = CommaList ( * a . only ) ;
std : : vector < std : : string > bad ;
for ( const std : : string & lf : only ) {
if ( ! Plan : : IsLens ( lf ) ) bad . push_back ( lf ) ;
}
if ( ! bad . empty ( ) ) Die ( std : : format ( " --only names unknown lens file(s): {} " , Dyn : : Join ( bad , " , " ) ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : string > foreign ;
for ( const std : : string & lf : only ) {
if ( ! std : : ranges : : contains ( modeLenses , lf ) ) foreign . push_back ( lf ) ;
}
if ( ! foreign . empty ( ) ) Die ( std : : format ( " --only names lens file(s) the {} mode never runs (nothing would run): {} " , a . mode , Dyn : : Join ( foreign , " , " ) ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > isOff ;
for ( const std : : string & lf : only ) {
if ( std : : ranges : : contains ( off , lf ) ) isOff . push_back ( lf ) ;
}
if ( ! isOff . empty ( ) ) {
Die ( std : : format ( " --only names {}, which the config turns off (lenses.{}.run = false): the config is the record - edit it for a test run " , Dyn : : Join ( isOff , " , " ) , Plan : : LensName ( isOff . front ( ) ) ) ) ;
}
}
std : : vector < std : : string > without ;
if ( a . without & & ! a . without - > empty ( ) ) {
for ( const std : : string & part : Dyn : : Split ( * a . without , " , " ) ) without . push_back ( Dyn : : Strip ( part ) ) ;
std : : vector < std : : string > bad ;
for ( const std : : string & lf : without ) {
if ( ! Plan : : IsLens ( lf ) ) bad . push_back ( lf ) ;
}
if ( ! bad . empty ( ) ) Die ( std : : format ( " --without names unknown lens file(s): {} " , Dyn : : Join ( bad , " , " ) ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : string > foreign ;
for ( const std : : string & lf : without ) {
if ( ! std : : ranges : : contains ( modeLenses , lf ) ) foreign . push_back ( lf ) ;
}
if ( ! foreign . empty ( ) ) Die ( std : : format ( " --without names lens file(s) the {} mode never runs: {} " , a . mode , Dyn : : Join ( foreign , " , " ) ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
log ( std : : format ( " without: {} - left out of this run by owner ruling (recorded in the dump's args); the run stays a full run " , Dyn : : Join ( without , " , " ) ) ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : vector < Plan : : Gate > gates = Plan : : GatesFor ( a . mode , only , without , off ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
if ( gates . empty ( ) ) {
std : : vector < std : : string > why ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
std : : vector < std : : string > offHere ;
for ( const std : : string & lf : off ) {
if ( std : : ranges : : contains ( modeLenses , lf ) ) offHere . push_back ( lf ) ;
}
if ( offHere . size ( ) = = modeLenses . size ( ) ) {
2026-10-31 20:09:07 +01:00
why . emplace_back ( " the config turns on no lens (every lens is off until lenses.<name>.run = true turns it on) " ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
} else if ( ! offHere . empty ( ) ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
std : : vector < std : : string > names ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const std : : string & lf : offHere ) names . push_back ( Plan : : LensName ( lf ) ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
why . push_back ( std : : format ( " the config turns off {} " , Dyn : : Join ( names , " , " ) ) ) ;
}
if ( ! without . empty ( ) ) why . push_back ( std : : format ( " --without drops {} " , Dyn : : Join ( without , " , " ) ) ) ;
if ( ! only . empty ( ) ) why . push_back ( std : : format ( " --only keeps {} " , Dyn : : Join ( only , " , " ) ) ) ;
Die ( std : : format ( " no lens runs: {} " , Dyn : : Join ( why , " ; " ) ) ) ;
}
Json stoppedAt ;
Json incomplete = Json : : array ( ) ;
for ( const Plan : : Gate & gate : gates ) {
const std : : vector < std : : string > lensFiles ( gate . lenses . begin ( ) , gate . lenses . end ( ) ) ;
const std : : vector < Json > res = RunGate ( gate . title , lensFiles ) ;
std : : ranges : : copy ( res , std : : back_inserter ( results ) ) ;
Checkpoint ( gate . title ) ;
if ( abort ) {
stoppedAt = std : : format ( " {} - ABORTED ({}) " , gate . title , * abort ) ;
incomplete . push_back ( { { " gate " , gate . title } , { " reason " , * abort } } ) ;
break ;
}
std : : vector < std : : string > notReturned ;
Json missingByLens = Json : : object ( ) ;
for ( const Json & r : res ) {
if ( Dyn : : Truthy ( r . at ( " coverageMissing " ) ) ) {
notReturned . push_back ( Dyn : : Str ( r . at ( " lens " ) ) ) ;
missingByLens [ Dyn : : Str ( r . at ( " lens " ) ) ] = r . at ( " coverageMissing " ) ;
}
}
if ( ! notReturned . empty ( ) ) {
stoppedAt = std : : format ( " {} - INCOMPLETE ({} not returned) " , gate . title , Dyn : : Join ( notReturned , " , " ) ) ;
incomplete . push_back ( { { " gate " , gate . title } , { " notReturned " , Array ( notReturned ) } , { " missing " , missingByLens } } ) ;
log ( std : : format ( " {}: a gate that cannot fire is indistinguishable from a gate that passed - NOT a pass " , Dyn : : Str ( stoppedAt ) ) ) ;
break ;
}
if ( std : : ranges : : any_of ( res , [ ] ( const Json & r ) { return r . at ( " verdict " ) = = " FIX FIRST " ; } ) ) {
stoppedAt = gate . title ;
break ;
}
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
personaRan = false ;
const std : : string personaFile ( Plan : : PersonaLens ) ;
if ( ! Dyn : : Truthy ( stoppedAt ) & & ! reviewers . empty ( ) & & ( only . empty ( ) | | std : : ranges : : contains ( only , personaFile ) ) & & ! std : : ranges : : contains ( without , personaFile ) ) {
// The persona gate: one instance of the persona lens per
// reviewer, after every other gate passed.
std : : vector < std : : pair < std : : string , std : : string > > specs ;
for ( const std : : string & r : reviewers ) specs . emplace_back ( personaFile , r ) ;
const std : : vector < Json > res = RunGate ( Plan : : PersonaGate , specs ) ;
std : : ranges : : copy ( res , std : : back_inserter ( results ) ) ;
Checkpoint ( Plan : : PersonaGate ) ;
std : : vector < std : : string > notReturned ;
for ( const Json & r : res ) {
if ( Dyn : : Truthy ( r . at ( " coverageMissing " ) ) ) notReturned . push_back ( Dyn : : Str ( r . at ( " lens " ) ) ) ;
}
if ( abort ) {
stoppedAt = std : : format ( " {} - ABORTED ({}) " , Plan : : PersonaGate , * abort ) ;
incomplete . push_back ( { { " gate " , Plan : : PersonaGate } , { " reason " , * abort } } ) ;
} else if ( ! notReturned . empty ( ) ) {
stoppedAt = std : : format ( " {} - INCOMPLETE ({} not returned) " , Plan : : PersonaGate , Dyn : : Join ( notReturned , " , " ) ) ;
incomplete . push_back ( { { " gate " , Plan : : PersonaGate } , { " notReturned " , Array ( notReturned ) } } ) ;
} else if ( std : : ranges : : any_of ( res , [ ] ( const Json & r ) { return r . at ( " verdict " ) = = " FIX FIRST " ; } ) ) {
stoppedAt = Plan : : PersonaGate ;
} else {
personaRan = true ;
}
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const bool anyFailed = std : : ranges : : any_of ( results , [ ] ( const Json & r ) { return r . at ( " verdict " ) = = " FIX FIRST " ; } ) ;
if ( x > 1 & & ! a . dryRun & & ! testMode ) {
// The file after this run's store: a --no-reuse run counts its own
// reads there too.
const Json merged = StoreState ( ) ;
const std : : vector < std : : string > exclude = Strings ( cfg . at ( " functional " ) . at ( " exclude " ) ) ;
for ( const Json & r : results ) {
const std : : string lf = Dyn : : StrOr ( Dyn : : Get ( r , " lensFile " ) , " " ) ;
if ( ! Plan : : IsLens ( lf ) | | ! Plan : : LensOf ( lf ) . reads ) continue ;
for ( const Json & j : Plan : : PlanLens ( lf , units , lines , { } , exclude ) . blocks ) {
std : : int64_t n = x ;
if ( ReadsNeeded ( j ) > 1 ) {
const std : : optional < std : : string > k = ReuseKey ( j ) ;
n = Plan : : ReadsOf ( k ? Dyn : : Get ( merged . at ( " entries " ) , * k ) : Json ( ) ) ;
}
if ( n < x ) {
const std : : string lens = Dyn : : Str ( r . at ( " lens " ) ) ;
if ( ! owed . contains ( lens ) ) owed [ lens ] = { { " units " , 0 } , { " reads " , 0 } , { " pending " , Json : : array ( ) } } ;
Json & o = owed [ lens ] ;
o [ " units " ] = o . at ( " units " ) . get < std : : int64_t > ( ) + 1 ;
o [ " reads " ] = o . at ( " reads " ) . get < std : : int64_t > ( ) + ( x - n ) ;
o [ " pending " ] . push_back ( j . at ( " unit " ) ) ;
}
}
}
}
std : : string overall ;
if ( a . dryRun ) {
overall = " DRY RUN - NOT SEND-READY (no process launched) " ;
} else if ( testMode ) {
overall = " PARTIAL - NOT SEND-READY (test run with --only/--units) " ;
} else if ( ! incomplete . empty ( ) ) {
overall = anyFailed ? " FIX FIRST " : " INCOMPLETE - NOT SEND-READY (a gate did not fully run) " ;
} else if ( anyFailed | | Dyn : : Truthy ( stoppedAt ) ) {
overall = " FIX FIRST " ;
} else if ( ! owed . empty ( ) ) {
std : : int64_t owedUnits = 0 ;
std : : int64_t owedReads = 0 ;
for ( const Json & o : owed ) {
owedUnits + = o . at ( " units " ) . get < std : : int64_t > ( ) ;
owedReads + = o . at ( " reads " ) . get < std : : int64_t > ( ) ;
}
overall = std : : format ( " CONFIRMING - NOT SEND-READY (gates clean; {} code unit(s) owe {} clean read(s) to reach {}: run the same line again) " , owedUnits , owedReads , x ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
} else if ( personaRan | | a . mode = = " commits " ) {
// commits: no persona gate - the gates clean = push-ready (the
// owner is the last gate).
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
overall = " SEND-READY " ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
} else {
overall = " GATES CLEAN - NOT SEND-READY (no reviewers passed, Gate 4 did not run) " ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
}
return Finish ( overall , stoppedAt , incomplete ) ;
}
std : : int32_t Run : : Finish ( std : : string overall , const Json & stoppedAt , Json incomplete ) {
if ( broker ) broker - > Close ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Artifact : : ArtifactHash ( a . mode , a . artifact ) ! = hash ) {
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
overall = " INCOMPLETE - NOT SEND-READY (artifact changed during the run) " ;
incomplete . push_back ( { { " gate " , " end " } , { " reason " , " artifact hash changed during the run " } } ) ;
}
Json dump = BuildDump ( overall , stoppedAt , incomplete ) ;
if ( a . dryRun ) dump [ " dryRun " ] = DryReport ( ) ;
WriteText ( dumpPath , DumpFile ( dump ) ) ;
if ( ! testMode & & ! a . dryRun ) {
StoreState ( ) ;
if ( x > 1 & & incomplete . empty ( ) & & ! abort ) {
Json r ;
try {
r = Dyn : : LoadJsonFile ( resumePath ) ;
} catch ( const std : : exception & ) {
r = { { " hash " , hash } , { " date " , a . date } , { " run " , Basename ( dumpPath ) } , { " after " , nullptr } , { " results " , results } } ;
}
if ( Dyn : : Get ( r , " hash " ) = = hash ) {
r [ " round " ] = round ;
r [ " complete " ] = true ;
WriteReplace ( resumePath , DumpFile ( r ) ) ;
}
}
}
std : : println ( " {} " , State : : Summary ( dump ) ) ;
if ( a . dryRun ) std : : println ( " {} " , DumpFile ( dump . at ( " dryRun " ) ) ) ;
std : : fflush ( stdout ) ;
if ( overall = = " SEND-READY " ) return 0 ;
return overall = = " FIX FIRST " ? 1 : 2 ;
}
Json Run : : BuildDump ( std : : string_view overall , const Json & stoppedAt , const Json & incomplete ) {
const Json cov = Normalize : : Matrix ( units , results , notReviewed ) ;
std : : vector < Json > recs ;
std : : vector < Json > runJobs ;
{
const std : : lock_guard guard ( shared ) ;
recs = records ;
runJobs = jobsRun ;
}
// {lens: records}, in the order first met.
std : : vector < std : : pair < std : : string , std : : vector < Json > > > perLens ;
for ( const Json & r : recs ) {
const std : : string key = KeyText ( Dyn : : Get ( r , " lens " ) ) ;
auto found = std : : ranges : : find_if ( perLens , [ & ] ( const auto & entry ) { return entry . first = = key ; } ) ;
if ( found = = perLens . end ( ) ) {
perLens . emplace_back ( key , std : : vector < Json > { } ) ;
found = perLens . end ( ) - 1 ;
}
found - > second . push_back ( r ) ;
}
std : : int64_t firsts = 0 ;
std : : int64_t hits = 0 ;
const double prefix = 0.8 * ( static_cast < double > ( Dyn : : Length ( runLayer ) ) / 3.7 ) ;
for ( const Json & r : recs ) {
const Json & first = Dyn : : Get ( r , " firstTurn " ) ;
if ( ! Dyn : : Truthy ( first ) ) continue ;
+ + firsts ;
const Json & read = Dyn : : Get ( first , " cache_read_input_tokens " ) ;
if ( ( read . is_null ( ) ? 0.0 : Number ( read ) ) > = prefix ) + + hits ;
}
Json reusedUnits = Json : : object ( ) ;
for ( const Json & r : results ) {
Json reused = Json : : array ( ) ;
for ( const Json & p : r . at ( " parts " ) ) {
if ( Dyn : : Truthy ( Dyn : : Get ( p , " reused " ) ) ) reused . push_back ( Dyn : : Truthy ( Dyn : : Get ( p , " unit " ) ) ? p . at ( " unit " ) : Json ( " (whole pass) " ) ) ;
}
if ( ! reused . empty ( ) ) reusedUnits [ Dyn : : Str ( r . at ( " lens " ) ) ] = reused ;
}
Json dispositionsInForce = Json : : array ( ) ;
for ( const Json & d : inForce ) {
const auto row = std : : ranges : : find_if ( dispRows , [ & ] ( const Json & x ) { return x . at ( " id " ) = = d . at ( " id " ) ; } ) ;
if ( row = = dispRows . end ( ) ) throw Dyn : : Error ( " StopIteration " , " " ) ;
dispositionsInForce . push_back ( { { " id " , d . at ( " id " ) } , { " kind " , Dyn : : Get ( d , " kind " ) } , { " status " , row - > at ( " status " ) } } ) ;
}
Json lapsed = Json : : array ( ) ;
for ( const Json & r : dispRows ) {
if ( r . at ( " status " ) = = " lapsed " ) lapsed . push_back ( r ) ;
}
Json contests = Json : : array ( ) ;
Json violations = Json : : array ( ) ;
Json crossLens = Json : : array ( ) ;
for ( const Json & r : results ) {
for ( const Json & c : r . at ( " contests " ) ) {
Json entry = c ;
entry [ " lens " ] = r . at ( " lens " ) ;
contests . push_back ( entry ) ;
}
for ( const Json & v : r . at ( " contractViolations " ) ) violations . push_back ( v ) ;
for ( const Json & c : r . at ( " crossLensDischarges " ) ) crossLens . push_back ( c ) ;
}
Json perLensUsage = Json : : object ( ) ;
for ( const auto & [ lens , list ] : perLens ) perLensUsage [ lens ] = State : : UsageTotals ( list ) ;
Json resumedLenses = Json : : array ( ) ;
for ( const Json & r : results ) {
if ( Dyn : : Truthy ( Dyn : : Get ( r , " resumed " ) ) ) resumedLenses . push_back ( r . at ( " lens " ) ) ;
}
Json stackList = Json : : array ( ) ;
for ( const Json & s : stacks - > All ( ) ) {
const Json & db = Dyn : : Get ( s , " dbUrl " ) ;
stackList . push_back ( { { " id " , s . at ( " id " ) } , { " appUrl " , s . at ( " appUrl " ) } , { " dbUrl " , Dyn : : Truthy ( db ) ? Json ( PgWire : : Redact ( Dyn : : Str ( db ) ) ) : Json ( ) } , { " login " , Dyn : : Get ( s , " login " ) } } ) ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
const std : : vector < std : : string > modeLenses = Plan : : ModeLenses ( a . mode ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Json lensesOff = Json : : array ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( const std : : string & lf : off ) {
if ( std : : ranges : : contains ( modeLenses , lf ) ) lensesOff . push_back ( Plan : : LensName ( lf ) ) ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Json environmentNames = Json : : object ( ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
for ( auto it = environments . begin ( ) ; it ! = environments . end ( ) ; + + it ) {
if ( std : : ranges : : contains ( modeLenses , it . key ( ) ) ) environmentNames [ Plan : : LensName ( it . key ( ) ) ] = it . value ( ) ;
}
Json refs ;
if ( Kernel ( ) ) {
std : : int64_t fetched = 0 ;
Json failed = Json : : array ( ) ;
for ( auto it = refIndex . begin ( ) ; it ! = refIndex . end ( ) ; + + it ) {
const Json & status = Dyn : : Get ( it . value ( ) , " status " ) ;
if ( status = = " cached " | | status = = " fetched " ) + + fetched ;
if ( status = = " failed " ) failed . push_back ( it . key ( ) ) ;
}
refs = { { " index " , std : : format ( " gate-state/refs-{}.json " , h8 ) } , { " fetched " , fetched } , { " failed " , failed } } ;
}
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
Json dump = {
{ " driver " , DriverLine ( ) } ,
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
{ " mode " , a . mode } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " artifact " , Dyn : : RelPath ( a . artifact , repo . string ( ) ) } ,
{ " hash " , hash } ,
{ " date " , a . date } ,
{ " args " , ArgsJson ( a ) } ,
{ " config " , Config : : Redacted ( cfg ) } ,
{ " configPath " , Dyn : : Get ( cfg , " _path " ) } ,
{ " overall " , overall } ,
{ " stoppedAt " , stoppedAt } ,
{ " incomplete " , incomplete } ,
{ " reusedUnits " , reusedUnits } ,
{ " dispositionsInForce " , dispositionsInForce } ,
{ " lapsed " , lapsed } ,
{ " contests " , contests } ,
{ " contractViolations " , violations } ,
{ " crossLensDischarges " , crossLens } ,
{ " coverage " , cov } ,
{ " results " , results } ,
{ " processes " , recs } ,
{ " usage " , { { " run " , State : : UsageTotals ( recs ) } , { " perLens " , perLensUsage } , { " prefixHitRate " , firsts ? Json ( Dyn : : Round ( static_cast < double > ( hits ) / static_cast < double > ( firsts ) , 2 ) ) : Json ( ) } } } ,
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
{ " refs " , refs } ,
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
{ " estimate " , runJobs . empty ( ) ? Json ( ) : Plan : : Estimate ( runJobs , static_cast < std : : int64_t > ( Dyn : : Length ( runLayer ) ) , lensLayersBytes ) } ,
{ " wallMin " , ( Platform : : Now ( ) - t0 ) / 60 } ,
{ " scratch " , scratch . string ( ) } ,
{ " logs " , Array ( logs ) } ,
{ " dumpPath " , Dyn : : RelPath ( dumpPath . string ( ) , repo . string ( ) ) } ,
{ " resumedLenses " , resumedLenses } ,
{ " seats " , SeatPool : : Summary ( seats ) } ,
{ " apiBudget " , apiCfg } ,
{ " harness " , a . harness } ,
{ " variant " , a . variant ? Json ( * a . variant ) : Json ( ) } ,
{ " functional " , { { " appUrl " , cfg . at ( " functional " ) . at ( " appUrl " ) } , { " loginFixture " , loginFixture ? Json ( * loginFixture ) : Json ( ) } } } ,
{ " stacks " , stackList } ,
{ " supabase " , { { " dbUrl " , PgWire : : Redact ( Dyn : : Str ( cfg . at ( " supabase " ) . at ( " dbUrl " ) ) ) } } } ,
{ " lensesOff " , lensesOff } ,
{ " environments " , environmentNames } ,
} ;
if ( x > 1 ) {
Json readThisRun = Json : : object ( ) ;
for ( const Json & r : recs ) {
if ( ! Dyn : : Truthy ( Dyn : : Get ( r , " readNo " ) ) ) continue ;
const std : : string lens = KeyText ( Dyn : : Get ( r , " lens " ) ) ;
if ( readThisRun . contains ( lens ) ) continue ;
std : : int64_t n = 0 ;
for ( const Json & q : recs ) {
if ( Dyn : : Equal ( Dyn : : Get ( q , " lens " ) , Dyn : : Get ( r , " lens " ) ) & & Dyn : : Truthy ( Dyn : : Get ( q , " readNo " ) ) & & Dyn : : Get ( q , " status " ) = = " ok " ) + + n ;
}
readThisRun [ lens ] = n ;
}
dump [ " reads " ] = { { " x " , x } , { " round " , round } , { " continued " , Dyn : : Truthy ( resume ) & & ! newRound } , { " owed " , owed } , { " readThisRun " , readThisRun } } ;
}
return dump ;
}
Json Run : : DryReport ( ) {
// Every appended system prompt starts with the common text + the one
// run layer, one system prompt per lens (two for a gated lens: whole,
// and blocks with the summary), no user message carries the run layer,
// the inlined artifact re-slices to the file.
const fs : : path pdir = scratch / " prompts " ;
std : : vector < fs : : path > files ;
std : : error_code error ;
for ( fs : : directory_iterator it ( pdir , error ) , end ; ! error & & it ! = end ; it . increment ( error ) ) {
const std : : string name = it - > path ( ) . filename ( ) . string ( ) ;
if ( ! name . starts_with ( ' . ' ) & & name . ends_with ( " .txt " ) ) files . push_back ( it - > path ( ) ) ;
}
std : : ranges : : sort ( files ) ;
const std : : string runPrefix = std : : format ( " {}{}{}{} " , systemText , Prompt : : SepRun , runLayer , Prompt : : SepLens ) ;
Json badPrefix = Json : : array ( ) ;
for ( const auto & [ sha , path ] : systemPaths ) {
if ( ! Platform : : ReadFile ( path ) . value_or ( " " ) . starts_with ( runPrefix ) ) badPrefix . push_back ( Basename ( path ) ) ;
}
const std : : string runHead = Dyn : : Slice ( runLayer , 0 , 2000 ) ;
for ( const fs : : path & f : files ) {
if ( Platform : : ReadFile ( f ) . value_or ( " " ) . contains ( runHead ) ) badPrefix . push_back ( Basename ( f ) ) ;
}
std : : set < std : : tuple < std : : string , std : : string , std : : string > > tuples ;
std : : set < std : : string > models ;
for ( const Json & j : jobsRun ) {
models . insert ( Dyn : : Str ( j . at ( " model " ) ) ) ;
const auto found = std : : ranges : : find_if ( systemByLens , [ & ] ( const auto & entry ) { return entry . first = = Dyn : : Str ( j . at ( " lens " ) ) ; } ) ;
if ( found = = systemByLens . end ( ) ) continue ;
for ( const std : : string & sha : found - > second ) tuples . insert ( { Dyn : : Str ( j . at ( " model " ) ) , sha , j . at ( " kind " ) = = " whole " ? " whole " : " block " } ) ;
}
const std : : string marker = " \n ARTIFACT (frozen, hash " ;
const std : : size_t at = runLayer . find ( marker ) ;
std : : vector < std : : string > art ;
if ( at ! = std : : string : : npos ) {
const std : : string after = runLayer . substr ( at + marker . size ( ) ) ;
const std : : string body = after . substr ( 0 , after . find ( " \n \n INVENTORY - " ) ) ;
const std : : vector < std : : string > artLines = Dyn : : Split ( body , " \n " ) ;
for ( std : : size_t i = 1 ; i < artLines . size ( ) ; + + i ) art . push_back ( Dyn : : Slice ( artLines [ i ] , 6 ) ) ;
}
for ( const Json & u : units ) {
const Json & range = u . at ( " lines " ) ;
if ( ! Dyn : : Truthy ( range . at ( 0 ) ) ) continue ;
const auto [ begin , end ] = Dyn : : SliceBounds ( art . size ( ) , Int ( range . at ( 0 ) ) - 1 , Int ( range . at ( 1 ) ) ) ;
const std : : vector < std : : string > slice ( art . begin ( ) + static_cast < std : : ptrdiff_t > ( begin ) , art . begin ( ) + static_cast < std : : ptrdiff_t > ( end ) ) ;
if ( Dyn : : Join ( slice , " \n " ) ! = Plan : : UnitText ( lines , u ) ) Die ( std : : format ( " re-slice mismatch on {} " , Dyn : : Str ( u . at ( " id " ) ) ) ) ;
}
Json perLens = Json : : object ( ) ;
for ( const auto & [ lens , shas ] : systemByLens ) perLens [ lens ] = shas . size ( ) ;
Json byKind = Json : : object ( ) ;
for ( const std : : string_view kind : { " whole " , " block " , " slot " } ) byKind [ std : : string ( kind ) ] = std : : ranges : : count_if ( jobsRun , [ & ] ( const Json & j ) { return j . at ( " kind " ) = = kind ; } ) ;
Json byLens = Json : : object ( ) ;
for ( const Json & j : jobsRun ) {
const std : : string lens = Dyn : : Str ( j . at ( " lens " ) ) ;
byLens [ lens ] = ( byLens . contains ( lens ) ? byLens . at ( lens ) . get < std : : int64_t > ( ) : 0 ) + 1 ;
}
auto passes = [ & ] ( auto pred ) {
return std : : ranges : : count_if ( jobsRun , [ & ] ( const Json & j ) { return pred ( * Plan : : FindEnvironment ( Dyn : : Str ( Dyn : : At ( environments , Dyn : : Str ( j . at ( " lensFile " ) ) ) ) ) ) ; } ) ;
} ;
Json rep = {
{ " prompts " , files . size ( ) } ,
{ " systemPrompts " , systemPaths . size ( ) } ,
{ " runLayerPrefixViolations " , badPrefix } ,
{ " lensLayersPerLens " , perLens } ,
{ " modelSystemSchemaTuples " , tuples . size ( ) } ,
{ " models " , models . size ( ) } ,
{ " resliceOk " , true } ,
{ " jobsByKind " , byKind } ,
{ " jobsByLens " , byLens } ,
{ " mcpPasses " , passes ( [ ] ( const Plan : : Environment & e ) { return ! e . mcp . empty ( ) ; } ) } ,
{ " dbPasses " , passes ( [ ] ( const Plan : : Environment & e ) { return e . db ; } ) } ,
} ;
bool multi = false ;
bool atMostTwo = true ;
for ( const Json & v : perLens ) {
if ( v . get < std : : int64_t > ( ) > 1 ) {
multi = true ;
atMostTwo = atMostTwo & & v . get < std : : int64_t > ( ) < = 2 ;
}
}
rep [ " lensLayerNote " ] = multi ? " gated lenses show 2 (whole layer + block layer with the summary) " : " one lens layer per lens " ;
rep [ " ok " ] = badPrefix . empty ( ) & & atMostTwo & & tuples . size ( ) < = 2 * systemPaths . size ( ) ;
return rep ;
}
bool Run : : Storable ( const Json & rec ) const {
// A block record whose result may be reused: its own pass came back
// without an undischarged finding, and its unit is clean in the merged
// result.
const auto r = std : : ranges : : find_if ( results , [ & ] ( const Json & x ) { return x . at ( " lens " ) = = rec . at ( " lens " ) ; } ) ;
if ( r = = results . end ( ) ) return true ;
const Json * own = nullptr ;
for ( const Json & p : r - > at ( " parts " ) ) {
if ( Dyn : : Get ( p , " label " ) = = rec . at ( " label " ) ) {
own = & p ;
break ;
}
}
const Json * cov = nullptr ;
for ( const Json & c : r - > at ( " coverage " ) ) {
if ( c . at ( " item " ) = = rec . at ( " unit " ) ) {
cov = & c ;
break ;
}
}
std : : vector < const Json * > citing ;
for ( const Json & f : r - > at ( " findings " ) ) {
const Json & items = Dyn : : Or ( Dyn : : Get ( f , " items " ) , Dyn : : EmptyList ( ) ) ;
if ( std : : ranges : : any_of ( items , [ & ] ( const Json & i ) { return i = = rec . at ( " unit " ) ; } ) ) citing . push_back ( & f ) ;
}
if ( ! own | | Dyn : : Get ( * own , " verdict " ) ! = " SEND-READY " | | ! cov | | cov - > at ( " verdict " ) = = " MISSING " | | std : : ranges : : any_of ( citing , [ ] ( const Json * f ) { return ! Dyn : : Truthy ( Dyn : : Get ( * f , " discharged " ) ) ; } ) ) return false ;
if ( std : : ranges : : contains ( Schema : : CoverageBlocking , Dyn : : Str ( cov - > at ( " verdict " ) ) ) ) {
return cov - > at ( " verdict " ) = = " defect " & & ! citing . empty ( ) & & std : : ranges : : all_of ( citing , [ ] ( const Json * f ) { return Dyn : : Truthy ( Dyn : : Get ( * f , " dischargedBy " ) ) ; } ) ;
}
return true ;
}
Json Run : : StoreState ( ) {
// Reusable clean block results -> unit-state.json (full runs only). A
// pass is stored only when the pass ITSELF returned no undischarged
// finding, and a key only when EVERY pass under it in this run is
// storable. The file is merged, not overwritten (2026-10-31).
std : : int64_t n = 0 ;
std : : set < std : : string > dirty ;
for ( const Json & rec : records ) {
if ( Dyn : : Truthy ( Dyn : : Get ( rec , " reuseKey " ) ) & & Dyn : : Get ( rec , " status " ) = = " ok " & & Dyn : : Get ( rec , " kind " ) ! = " whole " & & ! Storable ( rec ) ) dirty . insert ( Dyn : : Str ( rec . at ( " reuseKey " ) ) ) ;
}
// A defect on a unit's code stands whatever environment found it: the
// clean verdicts the lens holds for the same code in its other
// environments go too, and so do a lens's other whole verdicts when
// its whole pass ran and was not clean.
for ( const Json & rec : records ) {
if ( Dyn : : Get ( rec , " status " ) ! = " ok " | | ! Dyn : : Truthy ( Dyn : : Get ( rec , " otherKeys " ) ) ) continue ;
const Json * part = nullptr ;
if ( Dyn : : Get ( rec , " kind " ) = = " whole " ) {
const auto found = wholeParts . find ( Dyn : : Str ( rec . at ( " lens " ) ) ) ;
if ( found ! = wholeParts . end ( ) ) part = & found - > second ;
}
const Json & key = Dyn : : Get ( rec , " reuseKey " ) ;
if ( ( key . is_string ( ) & & dirty . contains ( key . get < std : : string > ( ) ) ) | | ( part & & ( part - > at ( " verdict " ) ! = " SEND-READY " | | Dyn : : Truthy ( part - > at ( " coverageMissing " ) ) ) ) ) {
for ( const Json & k : rec . at ( " otherKeys " ) ) dirty . insert ( Dyn : : Str ( k ) ) ;
}
}
Json sets = Json : : object ( ) ;
for ( const Json & rec : records ) {
const Json & keyValue = Dyn : : Get ( rec , " reuseKey " ) ;
if ( ! Dyn : : Truthy ( keyValue ) | | Dyn : : Get ( rec , " status " ) ! = " ok " ) continue ;
const std : : string key = Dyn : : Str ( keyValue ) ;
if ( dirty . contains ( key ) ) continue ;
const auto r = std : : ranges : : find_if ( results , [ & ] ( const Json & x ) { return x . at ( " lens " ) = = rec . at ( " lens " ) ; } ) ;
if ( r = = results . end ( ) ) continue ;
if ( Dyn : : Get ( rec , " kind " ) = = " whole " ) {
const auto found = wholeParts . find ( Dyn : : Str ( rec . at ( " lens " ) ) ) ;
if ( found ! = wholeParts . end ( ) ) {
const Json & part = found - > second ;
if ( Dyn : : Get ( part , " status " ) = = " ok " & & part . at ( " verdict " ) = = " SEND-READY " & & ! Dyn : : Truthy ( part . at ( " coverageMissing " ) ) ) {
sets [ key ] = { { " lens " , rec . at ( " lensFile " ) } , { " unit " , nullptr } , { " kind " , " whole " } , { " hash " , hash } , { " run " , Basename ( dumpPath ) } , { " date " , a . date } , { " coverage " , part . at ( " coverage " ) } ,
{ " findings " , Normalize : : Dedupe ( part . at ( " findings " ) . get < std : : vector < Json > > ( ) ) } , { " notes " , Normalize : : Dedupe ( part . at ( " notes " ) . get < std : : vector < Json > > ( ) ) } ,
{ " summary " , Dyn : : Get ( part , " summary " ) } } ;
+ + n ;
}
}
continue ;
}
const Json * cov = nullptr ;
for ( const Json & c : r - > at ( " coverage " ) ) {
if ( c . at ( " item " ) = = rec . at ( " unit " ) ) {
cov = & c ;
break ;
}
}
Json citing = Json : : array ( ) ;
for ( const Json & f : r - > at ( " findings " ) ) {
const Json & items = Dyn : : Or ( Dyn : : Get ( f , " items " ) , Dyn : : EmptyList ( ) ) ;
if ( std : : ranges : : any_of ( items , [ & ] ( const Json & i ) { return i = = rec . at ( " unit " ) ; } ) ) citing . push_back ( f ) ;
}
if ( ! Storable ( rec ) ) continue ;
std : : vector < Json > notes ;
for ( const Json & note : r - > at ( " notes " ) ) {
const Json & items = Dyn : : Or ( Dyn : : Get ( note , " items " ) , Dyn : : EmptyList ( ) ) ;
if ( std : : ranges : : any_of ( items , [ & ] ( const Json & i ) { return i = = rec . at ( " unit " ) ; } ) ) notes . push_back ( note ) ;
}
sets [ key ] = { { " lens " , rec . at ( " lensFile " ) } , { " unit " , rec . at ( " unit " ) } , { " unitSha " , Dyn : : Get ( rec , " unitSha " ) } , { " hash " , hash } , { " run " , Basename ( dumpPath ) } , { " date " , a . date } ,
{ " coverage " , cov ? * cov : Json ( ) } , { " findings " , citing } , { " notes " , Normalize : : Dedupe ( notes ) } } ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
if ( Dyn : : Truthy ( Dyn : : Get ( rec , " persona " ) ) ) sets [ key ] [ " persona " ] = rec . at ( " persona " ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
+ + n ;
}
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
// One clean read per round, not for a reply: the count comes from the
// FILE at write time, so a read another driver stored is kept; a
// second store of the same run, or the relaunch of an unfinished run,
// adds nothing. The persona pass is recorded once the persona gate
// passed.
const Json read = a . mode = = " reply " ? Json ( ) : Json ( { { " hash " , h8 } , { " round " , round } , { " run " , Basename ( dumpPath ) } } ) ;
const Json persona = personaRan ? Json ( { { " hash " , hash } , { " reviewers " , Array ( reviewers ) } , { " date " , a . date } } ) : Json ( ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
const std : : vector < std : : string > drops ( dirty . begin ( ) , dirty . end ( ) ) ;
feat(modes): the kernel modes - a patch series and a mailing-list reply
Beside the push gates, crafter-review runs the pre-send review of a kernel
contributor's workbench: --mode series over a format-patch export with its
cover letter, --mode reply over a mail draft. The inventory partitions a
cover letter, a plain mail and the camera review's shape; ten kernel lenses
join the table with their gates (structure, code, artifact truth) and the
persona gate - one maintainer-persona instance per --reviewers entry, its
whole pass gating its blocks and pruning the units that are not theirs. A
series' code units are keyed on the code like the push gates'; every text
unit on its text, the references it cites and the anchor when it is dated.
The references an artifact cites are prefetched through utilities/lore.py
into the gate-state, with a digest in the run layer, and a persona's
calibration map is its lore listing. The kernel schema carries the persona
vocabulary, the kernel note kinds, the predicted review and the not-mine
list; the matrix the persona holes, the thin and the modelled units; gates
clean without a persona pass is GATES CLEAN. A reply's gate-state sits
beside the draft and is read once; a kernel mode needs --subsystem,
defaults the effort to max and the trees to work/linux,work/milos-linux,
and excuses no unit from the holes.
The kernel lenses and the common text ship verbatim; the table lists them
after the push gates' lenses and the config template holds them off, so a
repository that never turns them on changes nothing. Prompts, keys and plans
were checked byte for byte against the pipeline these modes replace, on its
own artifacts: two replies and a series, every system prompt, user prompt,
job and reuse key identical.
2026-10-31 22:56:12 +01:00
Json merged = State : : SaveState ( statePath , sets , drops , read , persona ) ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// A --no-reuse run keeps its empty view for the reuse decisions; its
// reads are counted from the file.
if ( ! a . noReuse ) state = merged ;
log ( std : : format ( " unit-state: {} reusable unit results stored ({}) " , n , Dyn : : RelPath ( statePath . string ( ) , repo . string ( ) ) ) ) ;
return merged ;
}
std : : int32_t Main ( Arguments a , const Json & cfg ) {
Process : : BecomeSubreaper ( ) ;
Run run ( std : : move ( a ) , cfg ) ;
Current = & run ;
2026-10-31 16:45:53 +01:00
// However this ends - a return, or an exception on its way to Main's
// handler - the signal handler loses its run, and whatever is left
// below this subreaper (a daemon a git call started) goes with it;
// never a process it did not start.
struct Cleanup {
~ Cleanup ( ) {
Current = nullptr ;
Process : : KillDescendants ( ) ;
}
} const cleanup ;
feat(run): `crafter-review run` and `slots`, the driver of the gates
Run: gate 0 (the artifact, the trees, the inventory, the run lock, the
scratch dir, dispositions, reuse state, resume, reads per round, seats,
the board), the stack and migration preflights, the prompts, reuse of
whole and block verdicts, salvage, a gate on the pool, checkpoints, the
dump, the dry-run report and the unit-state store; slots_plan and
app_ready beside it. The CLI parses run's 28 options, types and choices
included.
A full run takes its lifetime lock beside the board before it joins it.
A signal - or the stop file `crafter-review stop` writes, looked at
every 2 s - stops the run once gate 0 is through, and the stop stays in
force for the gates after; before that it ends the process with its
descendants.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 09:16:41 +01:00
// `crafter-review stop`: the file is looked at every 2 s, and a stop
// is handled exactly like SIGTERM.
std : : jthread watcher ( [ & run ] ( const std : : stop_token & token ) {
std : : mutex sleep ;
std : : condition_variable_any wake ;
while ( ! token . stop_requested ( ) ) {
{
std : : unique_lock guard ( sleep ) ;
wake . wait_for ( guard , token , std : : chrono : : seconds ( 2 ) , [ ] { return false ; } ) ;
}
if ( token . stop_requested ( ) ) return ;
const std : : optional < fs : : path > file = run . StopFile ( ) ;
std : : error_code error ;
if ( file & & fs : : exists ( * file , error ) ) {
Trigger ( std : : string ( " crafter-review stop " ) , 0 ) ;
return ;
}
}
} ) ;
std : : int32_t code = 0 ;
try {
code = run . Execute ( ) ;
} catch ( const Preflight & e ) {
std : : println ( std : : cerr , " preflight: {} " , e . what ( ) ) ;
code = 3 ;
}
watcher . request_stop ( ) ;
watcher . join ( ) ;
return code ;
}
}