Crafter.Network master now carries, in their final shape, the pieces the
HTTP layer and the SQL broker were written against on a side branch:
ClientHTTP1::Fetch follows redirects by RFC 9110 §15.4 on a URL type of
its own, and SocketErrorException is a std::system_error with the phase
that failed. The broker and the HTTP layer read the errno or the resolver
code from code() and the phase from the field, instead of matching
message prefixes, and the pin moves to that commit, so the build no
longer needs --local against a checkout of the side branch.
The messages the run log, the preflight detail and the SQL helper show
are unchanged, but for the wording of a refused URL.
Found compiling the environment-variable table for AGENTS.md:
- A REVIEW_GATES_MEM_RESERVE_MB that is no number threw
std::invalid_argument, which nothing caught: the process aborted where
it should end with a ValueError, exit 1. nan and inf were an unchecked
cast. They raise ValueError / OverflowError now; a value past int64
saturates.
- An env file that is not UTF-8: `run` ended with exit 1 where its
preflight should stop it (exit 3), and `seats` parsed the raw bytes. Both
read it as strict UTF-8 text now.
- A broker address with a port past 65535 was cut to 16 bits; it is an
OverflowError now, uncaught (exit 1).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`crafter-review sql` hands the SQL to the driver's broker named in
REVIEW_GATES_DB; the broker runs it as one transaction, rolled back, and
streams the lines back with the exit code last. The client speaks protocol
3.0 over Crafter.Network's TCP client: cleartext, MD5 and SCRAM-SHA-256,
one Parse per statement, the transaction status as the backstop. The
splitter, the refusals, the table layout and every message work on code
points; connect and socket errors read "[Errno 111] Connection refused"
or "timed out". `crafter-review totp` prints "123456 (valid 17s)".
No sleep after the last connect attempt; TOTP reads the clock once; a
broker token that is no string gets the NO DATABASE answer and the exit
mark.
The goldens add the splitter, the comment stripping, the fingerprint, the
refusals, the first words, the headline, the cell, table, error and notice
layouts, the run's refusals and limits and 40 TOTP codes (2774 checks
now). tests/PgWire runs the helper over a Postgres stand-in and compares
its output with the goldens, line for line, plus the broker's protocol.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>