feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
module ;
# include <cerrno>
# include <fcntl.h>
# include <sys/file.h>
# include <unistd.h>
module Crafter . Review : State_impl ;
import : State ;
import : Json ;
import : Text ;
import : Platform ;
import std ;
namespace fs = std : : filesystem ;
namespace Crafter : : Review : : State {
namespace {
std : : string Formatted ( double value , std : : int32_t precision ) {
return std : : format ( " {:.{}f} " , value , precision ) ;
}
double AsDouble ( const Json & value ) {
if ( value . is_number_float ( ) ) return value . get < double > ( ) ;
if ( value . is_boolean ( ) ) return value . get < bool > ( ) ? 1.0 : 0.0 ;
if ( value . is_number_unsigned ( ) ) return static_cast < double > ( value . get < std : : uint64_t > ( ) ) ;
if ( value . is_number_integer ( ) ) return static_cast < double > ( value . get < std : : int64_t > ( ) ) ;
throw Dyn : : Error ( " TypeError " , std : : format ( " unsupported operand type(s) for /: '{}' and 'float' " , Dyn : : TypeName ( value ) ) ) ;
}
// `value or 0` for a number that is summed.
Json OrZero ( const Json & value ) {
return Dyn : : Truthy ( value ) ? value : Json ( 0 ) ;
}
// The key's value, or the fallback only when the key is absent.
const Json & GetOr ( const Json & dict , std : : string_view key , const Json & fallback ) {
return Dyn : : Has ( dict , key ) ? Dyn : : At ( dict , key ) : fallback ;
}
std : : size_t Len ( const Json & value ) {
return value . is_string ( ) ? Dyn : : Length ( value . get_ref < const std : : string & > ( ) ) : value . size ( ) ;
}
// A string, or Error (TypeError): only a string is concatenated.
const std : : string & Text ( const Json & value ) {
if ( ! value . is_string ( ) ) throw Dyn : : Error ( " TypeError " , std : : format ( " can only concatenate str (not \" {} \" ) to str " , Dyn : : TypeName ( value ) ) ) ;
return value . get_ref < const std : : string & > ( ) ;
}
// f'{value:<width}' of a str.
std : : string Padded ( const Json & value , std : : size_t width ) {
if ( ! value . is_string ( ) ) throw Dyn : : Error ( " TypeError " , std : : format ( " unsupported format string passed to {}.__format__ " , Dyn : : TypeName ( value ) ) ) ;
return Dyn : : LJust ( value . get_ref < const std : : string & > ( ) , width ) ;
}
}
Json EmptyState ( ) {
return { { " version " , 1 } , { " entries " , Json : : object ( ) } , { " personaPass " , nullptr } } ;
}
Json LoadState ( const fs : : path & path ) {
if ( ! path . empty ( ) & & fs : : exists ( path ) ) {
try {
return Json : : parse ( Dyn : : ReadText ( path ) ) ;
} catch ( const std : : exception & ) {
// A damaged file is the empty state.
}
}
return EmptyState ( ) ;
}
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 MergeState ( const Json & disk , const Json & sets , std : : span < const std : : string > drops , const Json & read , const Json & persona ) {
feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
const bool ok = disk . is_object ( ) & & Dyn : : Get ( disk , " entries " ) . is_object ( ) ;
Json state = {
{ " version " , 1 } ,
{ " entries " , ok ? Dyn : : At ( disk , " entries " ) : Json : : object ( ) } ,
{ " personaPass " , ok ? Dyn : : Get ( disk , " personaPass " ) : Json ( ) } ,
} ;
Json & entries = state [ " entries " ] ;
for ( const std : : string & key : drops ) entries . erase ( key ) ;
for ( auto it = sets . begin ( ) ; it ! = sets . end ( ) ; + + it ) {
if ( std : : ranges : : contains ( drops , it . key ( ) ) ) continue ;
Json entry = it . value ( ) ;
if ( ! entry . is_object ( ) ) throw Dyn : : Error ( " TypeError " , std : : format ( " '{}' object is not iterable " , Dyn : : TypeName ( entry ) ) ) ;
if ( ! read . is_null ( ) & & ! Dyn : : Equal ( Dyn : : Get ( entry , " kind " ) , Json ( " whole " ) ) ) {
// One clean read per round: a second store of the same run, or
// the relaunch of an unfinished run, adds nothing.
const Json & previous = Dyn : : Get ( entries , it . key ( ) ) ;
Json reads = Json : : array ( ) ;
if ( Dyn : : Truthy ( previous ) ) {
const Json & stored = Dyn : : Get ( previous , " reads " ) ;
if ( Dyn : : Truthy ( stored ) ) {
reads = stored ;
} else {
const Json & hash = Dyn : : Get ( previous , " hash " ) ;
const std : : string head = Dyn : : Truthy ( hash ) ? Dyn : : Slice ( Text ( hash ) , 0 , 8 ) : std : : string ( ) ;
reads . push_back ( { { " hash " , head } , { " round " , 0 } , { " run " , Dyn : : Get ( previous , " run " ) } } ) ;
}
}
const bool counted = std : : ranges : : any_of ( reads , [ & ] ( const Json & x ) {
return Dyn : : Equal ( Dyn : : Get ( x , " hash " ) , Dyn : : At ( read , " hash " ) ) & & Dyn : : Equal ( Dyn : : Get ( x , " round " ) , Dyn : : At ( read , " round " ) ) ;
} ) ;
if ( ! counted ) reads . push_back ( read ) ;
entry [ " reads " ] = std : : move ( reads ) ;
}
entries [ it . key ( ) ] = std : : move ( entry ) ;
}
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 ( ! persona . is_null ( ) ) state [ " personaPass " ] = persona ;
feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
return state ;
}
void SaveWhole ( const fs : : path & path , const Json & state ) {
const fs : : path temp = std : : format ( " {}.tmp " , path . string ( ) ) ;
{
std : : ofstream out ( temp , std : : ios : : binary | std : : ios : : trunc ) ;
if ( ! out ) throw std : : runtime_error ( std : : format ( " {}: cannot write " , temp . string ( ) ) ) ;
out < < DumpFile ( state ) ;
}
fs : : rename ( temp , path ) ;
}
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 SaveState ( const fs : : path & path , const Json & sets , std : : span < const std : : string > drops , const Json & read , const Json & persona ) {
feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
// Without the lock the write is still made; a failed write throws.
const Platform : : FileLock lock ( std : : format ( " {}.lock " , path . 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
Json merged = MergeState ( LoadState ( path ) , sets , drops , read , persona ) ;
feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
Platform : : WriteAtomic ( path , DumpFile ( merged ) , 0666 ) ;
return merged ;
}
fs : : path LockPath ( const fs : : path & gateDir , std : : string_view mode , std : : string_view hash8 ) {
return gateDir / std : : format ( " .run-{}-{}.lock " , mode , hash8 ) ;
}
Json ReadLockInfo ( const fs : : path & path ) {
try {
const std : : string text = Dyn : : ReadText ( path ) ;
const Json info = Dyn : : Strip ( text ) . empty ( ) ? Json : : object ( ) : Json : : parse ( text ) ;
return info . is_object ( ) ? info : Json : : object ( ) ;
} catch ( const std : : exception & ) {
return Json : : object ( ) ;
}
}
std : : string Describe ( const Json & info ) {
if ( ! Dyn : : Truthy ( Dyn : : Get ( info , " pid " ) ) ) return " holder not identified yet (it has just started) " ;
const Json unknown = " ? " ;
return std : : format ( " pid {} since {}, run {}, scratch {} " , Dyn : : Str ( Dyn : : At ( info , " pid " ) ) , Dyn : : Str ( GetOr ( info , " since " , unknown ) ) ,
Dyn : : Str ( GetOr ( info , " run_n " , unknown ) ) , Dyn : : Str ( GetOr ( info , " scratch " , unknown ) ) ) ;
}
RunLock : : RunLock ( const fs : : path & gateDir , std : : string_view mode , std : : string_view hash8 ) {
const fs : : path path = LockPath ( gateDir , mode , hash8 ) ;
fd = open ( path . c_str ( ) , O_RDWR | O_CREAT | O_CLOEXEC , 0644 ) ;
if ( fd < 0 ) throw std : : runtime_error ( std : : format ( " {}: {} " , Dyn : : ErrnoText ( errno ) , Dyn : : Repr ( std : : string_view ( path . string ( ) ) ) ) ) ;
if ( flock ( fd , LOCK_EX | LOCK_NB ) ! = 0 ) {
const Json info = ReadLockInfo ( path ) ;
close ( fd ) ;
fd = - 1 ;
throw RunLocked ( Describe ( info ) ) ;
}
}
RunLock : : ~ RunLock ( ) {
if ( fd > = 0 ) close ( fd ) ;
}
void RunLock : : WriteInfo ( const Json & info ) {
const std : : string text = DumpSpaced ( info ) ;
if ( lseek ( fd , 0 , SEEK_SET ) < 0 | | ftruncate ( fd , 0 ) ! = 0 ) return ;
std : : size_t written = 0 ;
while ( written < text . size ( ) ) {
const ssize_t step = write ( fd , text . data ( ) + written , text . size ( ) - written ) ;
if ( step < 0 ) {
if ( errno = = EINTR ) continue ;
return ;
}
written + = static_cast < std : : size_t > ( step ) ;
}
}
std : : optional < Json > LockHolder ( const fs : : path & gateDir , std : : string_view mode , std : : string_view hash8 ) {
const fs : : path path = LockPath ( gateDir , mode , hash8 ) ;
const std : : int32_t handle = open ( path . c_str ( ) , O_RDONLY | O_CLOEXEC ) ;
if ( handle < 0 ) return std : : nullopt ;
std : : optional < Json > holder ;
if ( flock ( handle , LOCK_EX | LOCK_NB ) = = 0 ) {
flock ( handle , LOCK_UN ) ;
} else {
holder = ReadLockInfo ( path ) ;
}
close ( handle ) ;
return holder ;
}
std : : int64_t NextRunNumber ( const fs : : path & gateDir , std : : string_view mode , std : : string_view hash8 ) {
std : : int64_t n = 1 ;
while ( fs : : exists ( gateDir / std : : format ( " {}-{}-run-{}.json " , mode , hash8 , n ) ) | | fs : : exists ( gateDir / std : : format ( " {}-{}-run-{}-test.json " , mode , hash8 , n ) ) ) + + n ;
return n ;
}
Json UsageTotals ( std : : span < const Json > records ) {
Json totals = {
{ " input " , 0 } , { " cacheCreation " , 0 } , { " cacheRead " , 0 } , { " output " , 0 } , { " thinking " , 0 } ,
{ " turns " , 0 } , { " processes " , 0 } , { " costUsd " , 0.0 } , { " denials " , 0 } ,
} ;
const Json zero = 0 ;
for ( const Json & record : records ) {
const Json & usage = Dyn : : Or ( Dyn : : Get ( record , " usage " ) , Dyn : : EmptyDict ( ) ) ;
for ( const std : : string_view key : { " input " , " cacheCreation " , " cacheRead " , " output " , " thinking " } ) {
totals [ std : : string ( key ) ] = Dyn : : Add ( totals [ std : : string ( key ) ] , OrZero ( GetOr ( usage , key , zero ) ) ) ;
}
totals [ " costUsd " ] = Dyn : : Add ( totals [ " costUsd " ] , OrZero ( Dyn : : Get ( record , " costUsd " ) ) ) ;
totals [ " denials " ] = Dyn : : Add ( totals [ " denials " ] , Json ( Len ( Dyn : : Or ( Dyn : : Get ( record , " denials " ) , Dyn : : EmptyList ( ) ) ) ) ) ;
totals [ " turns " ] = Dyn : : Add ( totals [ " turns " ] , OrZero ( GetOr ( record , " turns " , zero ) ) ) ;
const Json & status = Dyn : : Get ( record , " status " ) ;
const bool counted = ! status . is_null ( ) & & status ! = " dry-run " & & status ! = " reused " ;
totals [ " processes " ] = Dyn : : Add ( totals [ " processes " ] , Json ( counted ? 1 : 0 ) ) ;
}
// input + 1.25 * cacheCreation + 0.1 * cacheRead + 5 * output: 5 * an
// integer stays an integer until it meets the float, so the dump
// prints it the same.
const Json & output = totals [ " output " ] ;
const double five = output . is_number_integer ( ) ? static_cast < double > ( 5 * output . get < std : : int64_t > ( ) ) : 5.0 * AsDouble ( output ) ;
double costUnits = AsDouble ( totals [ " input " ] ) + 1.25 * AsDouble ( totals [ " cacheCreation " ] ) ;
costUnits = costUnits + 0.1 * AsDouble ( totals [ " cacheRead " ] ) ;
costUnits = costUnits + five ;
totals [ " costUnits " ] = costUnits ;
return totals ;
}
std : : string Summary ( const Json & dump ) {
std : : vector < std : : string > lines ;
std : : string overall = std : : format ( " overall: {} " , Dyn : : Str ( Dyn : : At ( dump , " overall " ) ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( dump , " stoppedAt " ) ) ) overall + = std : : format ( " (stopped at {}) " , Dyn : : Str ( Dyn : : At ( dump , " stoppedAt " ) ) ) ;
lines . push_back ( std : : move ( overall ) ) ;
for ( const Json & result : Dyn : : At ( dump , " results " ) ) {
const Json & parts = Dyn : : Or ( Dyn : : Get ( result , " parts " ) , Dyn : : EmptyList ( ) ) ;
const auto reused = std : : ranges : : count_if ( parts , [ ] ( const Json & part ) { return Dyn : : Truthy ( Dyn : : Get ( part , " reused " ) ) ; } ) ;
std : : string line = std : : format ( " {} {} " , Padded ( Dyn : : At ( result , " lens " ) , 28 ) , Padded ( Dyn : : At ( result , " verdict " ) , 12 ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( result , " resumed " ) ) ) line + = std : : format ( " [resumed {}] " , Text ( Dyn : : At ( result , " resumed " ) ) ) ;
line + = std : : format ( " findings {} (undischarged {}), notes {}, passes {} " , Len ( Dyn : : At ( result , " findings " ) ) , Dyn : : Str ( Dyn : : At ( result , " undischarged " ) ) ,
Len ( Dyn : : At ( result , " notes " ) ) , Len ( parts ) ) ;
if ( reused ) line + = std : : format ( " ({} reused) " , reused ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( result , " coverageMissing " ) ) ) line + = std : : format ( " , missing {} " , Len ( Dyn : : At ( result , " coverageMissing " ) ) ) ;
if ( Dyn : : Truthy ( Dyn : : Get ( result , " stoppedEarly " ) ) ) line + = std : : format ( " <- {} " , Text ( Dyn : : At ( result , " stoppedEarly " ) ) ) ;
lines . push_back ( std : : move ( line ) ) ;
}
const Json & coverage = Dyn : : Or ( Dyn : : Get ( dump , " coverage " ) , Dyn : : EmptyDict ( ) ) ;
if ( Dyn : : Truthy ( coverage ) ) {
feat(config): modes - a mode is an artifact kind, the lenses it runs and its effort
The config defines the modes (modes.<name>): the kind of artifact the mode
reviews - reply, series or commits, the three shipped partitions; a kind
is a mode of its own name - the lenses it runs, in its kind's gate order,
and the effort it runs at, else the kind's default (max for a reply or a
series, xhigh for a commit range). `run --mode` names any of them, the
dump records mode and kind, and everything that decided by the mode's
name - the partition and hash, the prompts, the schemas, the disposition
and reuse-key rules, what the CLI requires - decides by the kind.
Every lens stays off until a mode lists it; lenses.<name>.run is retired
with a warning that says so, and a lens of another kind, a name that is
no lens, a lens listed twice and an unknown effort are config problems.
The defaults run no lens; the template ships the three kinds as modes
with every lens of their kind at the kind's effort, to trim (the owner's
ruling of 2026-11-01), and init says so as it writes it - a kept config
is the repository's own, and only one that lists no lens gets a step.
The readers of the retired key follow: the CI smoke config, the shipped
skill, the procedure (its description of the config as well as its
mechanics), the manifest template, the run's messages and the comments
that named the three modes. The run lock, the run numbers and the dump
names are the kind's, so one full run per hash holds across the modes
of a kind and their rounds count on together; the dump says which mode
ran. The database broker starts for a lens the mode runs, as every other
reader of the lenses off reads them. A named mode runs through the CLI
in the kernel-modes test.
2026-11-01 01:31:40 +01:00
const Json kind = Dyn : : Or ( Dyn : : Get ( dump , " kind " ) , Dyn : : Get ( dump , " mode " ) ) ;
if ( kind = = " reply " | | kind = = " series " ) {
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
lines . push_back ( std : : format ( " matrix: {} units x {} lenses; holes {}, persona holes {}, thin {}, modelled {}, units with a defect verdict {} " , Dyn : : Str ( Dyn : : At ( coverage , " units " ) ) ,
Len ( Dyn : : At ( coverage , " lenses " ) ) , Len ( Dyn : : At ( coverage , " holes " ) ) , Len ( Dyn : : Or ( Dyn : : Get ( coverage , " personaHoles " ) , Dyn : : EmptyList ( ) ) ) ,
Len ( Dyn : : Or ( Dyn : : Get ( coverage , " thin " ) , Dyn : : EmptyList ( ) ) ) , Len ( Dyn : : Or ( Dyn : : Get ( coverage , " modelled " ) , Dyn : : EmptyList ( ) ) ) , Len ( Dyn : : At ( coverage , " defects " ) ) ) ) ;
} else {
lines . push_back ( std : : format ( " matrix: {} units x {} lenses; holes {}, not reviewed by any lens that runs (messages, diffstats, documentation, the units of a lens the config turns off) {}, units with a defect verdict {} " ,
Dyn : : Str ( Dyn : : At ( coverage , " units " ) ) , Len ( Dyn : : At ( coverage , " lenses " ) ) , Len ( Dyn : : At ( coverage , " holes " ) ) ,
Len ( Dyn : : Or ( Dyn : : Get ( coverage , " notReviewed " ) , Dyn : : EmptyList ( ) ) ) , Len ( Dyn : : At ( coverage , " defects " ) ) ) ) ;
}
feat(pipeline): the pure pipeline, checked against its goldens
The modules that turn a frozen range into passes and passes into a
verdict: :Schema, :Tools (the DENY, git and base lists, a leaf, so the
config and the pool both read them), :Plan, :Artifact, :Inventory,
:Dispositions, :State, :Normalize, :Stream, :Prompt, :Config, and the URL
half of :PgWire. Units, jobs, results, the config and the claude stream
stay JSON from end to end, so every key keeps its place; :Text gives JSON
values truthiness, get, ==, membership and Str(), and throws Dyn::Error
under a name for each kind of unexpected data.
Exactness where the bytes are seen:
- the stream classifiers are hand-written scanners with case-insensitive
folds (the Kelvin sign is a k), Unicode \b and \s, and `.` stopping at
\n; the SQL call detection takes `<exe> sql` with any path before it;
- config problems carry the JSON scanner's and the UTF-8 decoder's own
texts, positions included;
- a float total is Neumaier's compensated sum, and the build passes
-ffp-contract=off: -march=native would fuse a*b+c;
- `crafter-review inventory` and `config` print what the goldens record,
byte for byte (the fixture and 14 configs, broken ones included); a
message names this binary as the command to run.
tests/Goldens: the recorded answers over the fixtures next to them (the
commits fixture, a rich versioned series with CRLF, a folded subject,
Markdown headings in and out of fences, the code-key rewrites); the suite
compares 2304 results as DumpFile writes them, so a key out of order fails
too. All agree.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:48:55 +01:00
}
const Json & usageAll = Dyn : : Has ( dump , " usage " ) ? Dyn : : At ( dump , " usage " ) : Dyn : : EmptyDict ( ) ;
const Json & usage = Dyn : : Or ( Dyn : : Get ( usageAll , " run " ) , Dyn : : EmptyDict ( ) ) ;
if ( Dyn : : Truthy ( usage ) ) {
const Json zero = 0 ;
lines . push_back ( std : : format ( " usage: {} processes, {} turns, cache write {}M, cache read {}M, output {}K, cost-units {}M, list cost ${}, denied calls {}, wall {} min, prefix hit rate {} " ,
Dyn : : Str ( Dyn : : At ( usage , " processes " ) ) , Dyn : : Str ( Dyn : : At ( usage , " turns " ) ) ,
Formatted ( AsDouble ( Dyn : : At ( usage , " cacheCreation " ) ) / 1e6 , 2 ) , Formatted ( AsDouble ( Dyn : : At ( usage , " cacheRead " ) ) / 1e6 , 2 ) ,
Formatted ( AsDouble ( Dyn : : At ( usage , " output " ) ) / 1e3 , 0 ) , Formatted ( AsDouble ( Dyn : : At ( usage , " costUnits " ) ) / 1e6 , 2 ) ,
Formatted ( AsDouble ( Dyn : : At ( usage , " costUsd " ) ) , 2 ) , Dyn : : Str ( Dyn : : At ( usage , " denials " ) ) ,
Formatted ( AsDouble ( GetOr ( dump , " wallMin " , zero ) ) , 0 ) , Dyn : : Str ( Dyn : : Get ( usageAll , " prefixHitRate " ) ) ) ) ;
}
const Json & reads = Dyn : : Get ( dump , " reads " ) ;
if ( Dyn : : Truthy ( reads ) ) {
std : : vector < std : : string > owed ;
const Json & owedBy = Dyn : : At ( reads , " owed " ) ;
for ( auto it = owedBy . begin ( ) ; it ! = owedBy . end ( ) ; + + it ) {
owed . push_back ( std : : format ( " {} {} unit(s) / {} read(s) " , it . key ( ) , Dyn : : Str ( Dyn : : At ( it . value ( ) , " units " ) ) , Dyn : : Str ( Dyn : : At ( it . value ( ) , " reads " ) ) ) ) ;
}
std : : string owedText = Dyn : : Join ( owed , " ; " ) ;
if ( owedText . empty ( ) ) owedText = " none " ;
lines . push_back ( std : : format ( " reads: x = {}, round {} on this hash{}; read this run: {}; owed: {} " , Dyn : : Str ( Dyn : : At ( reads , " x " ) ) , Dyn : : Str ( Dyn : : At ( reads , " round " ) ) ,
Dyn : : Truthy ( Dyn : : Get ( reads , " continued " ) ) ? " (continued) " : " " , Dyn : : Str ( Dyn : : Or ( Dyn : : Get ( reads , " readThisRun " ) , Dyn : : EmptyDict ( ) ) ) , owedText ) ) ;
}
lines . push_back ( std : : format ( " dump: {} " , Dyn : : Str ( Dyn : : At ( dump , " dumpPath " ) ) ) ) ;
return Dyn : : Join ( lines , " \n " ) ;
}
}