Commit graph Crafter.Review/tests
Author SHA1 Message Date
8ffbd6cf5d
feat(seats): memory, the Playwright MCP config, and the seats library
:Memory: MemAvailable and the reserve policy, the sampler of a pass's peak
tree PSS (one sweep, a pause of three sweeps at least, stopped with the
driver), and the calibration file every driver on the machine shares,
re-read and written under its lock.

:Mcp: the pinned @playwright/mcp 0.0.83 arguments and the --mcp-config of
one pass, compact and in a fixed key order.

:Seats: the dotenv loader (token lines only, TOKEN7 inert), the one-word
probe (run under the supervisor, a missing binary reported with its errno
text), the window maths, the ranking, the Fable merge, the editor-bundle
lookup of the claude binary, the redaction of anything token-shaped, and
the report. This libc++ has no tzdb, so a zone by name converts through
the C library with TZ set, reading the system's zoneinfo.

tests/Seats: 92 checks against reference vectors, numbered in order, all
green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:32:14 +01:00
e8a58f893f
feat(sql): the database helper and the TOTP helper, as subcommands
`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>
2026-10-31 07:20:00 +01:00
61acd6a72e
feat(freeze): crafter-review freeze, and --verify that names a git upgrade
Freeze: identity, AI trailers by the consumer's rule (the pattern with
case-insensitive folds and its \s* that crosses lines), a clean tree, no
merges, a fast-forward, then format-patch, the hash, the dispositions
register and the optional detached worktree; --verify at push time. The
command line takes --opt=value, unique prefixes and the last of a repeat,
with a usage error at exit 3 like every command that cannot start; the
config is loaded and its warnings and problems reported first. The run
line it prints names this binary.

freeze.json records gitVersion. format-patch ends every patch with the
git version, so a fresh export under another git hashes differently;
--verify's MISMATCH says which git exported the artifact and which the
fresh copy, reading the patches' own signature when freeze.json does not
record it. freeze becomes a subreaper and takes down whatever gpg left
running for %G?.

tests/Freeze: 18 checks, plus the gitVersion record and both MISMATCH
messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:03:48 +01:00
71dba5690f
test(pipeline): the checks of the pure pipeline
Stream, Normalize, Merge, Dispositions, Config, CodeKeys and the pure half
of CommitsMode, each a test of its own (131 checks). The fixture rewrites
are checked in (code-keys/<name>/, commits3/), so the suite reads fixtures
and edits nothing. The allowlist, command-line and MCP checks of
CommitsMode come with the pool they test.

Among them: this binary's `<exe> sql` spelling counts as a SQL call, and a
result line with a raw U+2028 in a JSON string is still the result line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 06:56:09 +01:00
741e3a656d
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
f94d895701
feat(platform): processes that never outlive their pass, shared files, the board identity
:Process makes sure no child outlives what it was started for. SIGKILL to
the direct child alone would leave the Playwright server and Chromium
running after a timeout, and every pass running after a SIGKILLed driver:

- every child is forked by one long-lived spawner thread, the reaper's
  registry locked across fork, so PR_SET_PDEATHSIG holds and a fast exit
  is never reaped unregistered; one reaper thread owns waitpid(-1);
- the child gets an empty signal mask, SIGPIPE and SIGXFSZ at their
  defaults, and nothing but its three streams (close_range); the driver
  ignores SIGPIPE and takes SIGINT/SIGTERM/SIGHUP on a thread of its own;
- `crafter-review __supervise <argv>` is a pass's subreaper. It kills the
  pass's whole tree, Chromium's detached process group included, when the
  target exits, on SIGTERM, and when the driver dies, by its death signal.
- Run() captures both outputs without the deadlock.

The shared state the detached threads wait on is never destroyed: a
condition variable destroyed under a waiter makes glibc's
pthread_cond_destroy, and with it exit(), wait forever.

:Platform: the Flatpak sandbox decided once, the host's XDG directories
restored there; WriteAtomic and LockedUpdate, the read-modify-write of
the board, ledger, memory.json and unit-state.json every driver on the
machine shares, under flock(2) on the same side files; /proc readers; and
the identity other drivers can check: natively pid and start time, in the
sandbox the instance's host pid from bwrapinfo.json with /proc/1's start
time. The lifetime lock is created under a temporary name and renamed into
place, so no prober ever finds it unlocked while its driver lives.

Tests: Process (the three ways a pass's tree must die, return codes, a
missing program, capture, timeouts, fds, the child's signal state),
Platform (atomic writes, LockedUpdate against a damaged file, two writers,
and another process holding flock on the side file; /proc on a fake
tree; both identities; the lifetime lock; the XDG restore).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:49:46 +01:00
36852edf63
feat: the crafter-review skeleton, and its semantics for text, JSON and crypto
What the rest of crafter-review stands on.

- project.cpp: a static crafter.review-lib and the crafter-review
  executable; Crafter.Network without QUIC, pinned, or with --local from
  the checkout next to this one; Crafter.LintRules' lite rules, pinned;
  the version from CRAFTER_REVIEW_VERSION, git describe or 0.0.0-dev.
- :Core and :Driver: the version, PromptVersion 1, --version.
- :Json: nlohmann's ordered_json, which keeps key order and unknown keys,
  so the files every driver on a machine shares survive a rewrite; dumps
  in the indented file layout, the spaced one-line form and the compact
  sorted form the structured-output schema needs byte for byte.
- :Crypto: SHA-256/SHA-1/MD5, HMAC, PBKDF2 through libcrypto; base64 and
  base32 written out, because what they refuse, and with which message,
  is pinned.
- :Unicode, Unicode 16.0.0's tables: whitespace, line breaks, decimal
  digits, printable characters, case mappings and case-insensitive folds.
- :Text: string functions on code points, number parsing, the shortest
  float form and half-even rounding, printed values, shell patterns, URL
  splitting and unquoting, POSIX paths, universal newlines and the
  replacing UTF-8 decoder.

Tests: Crypto (published vectors), Text (293 reference vectors).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 05:29:18 +01:00