Skip to content

Add statement-review commands - #284

Draft
Deicyde wants to merge 1 commit into
feat/readback-cardsfrom
feat/review-commands
Draft

Deicyde wants to merge 1 commit into
feat/readback-cardsfrom
feat/review-commands

Conversation

@Deicyde

@Deicyde Deicyde commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Part 6 of 8 in the split of #75. Draft; it merges after #216 (based on feat/readback-cards).

This PR replaces #75 as the stack's review-commands layer. #75 was split into eight stacked drafts and then simplified; its thread stays as the record of the earlier design and review, and the review of 765f2cb stays on #40. This layer lets a project check that a formalized statement says what its source says: review prepare writes blind Lean packets for an independent model, review record files the model's read-back of one packet as a card without running Lean, and review check, the one judge, fails until every Lean-mapped article has current cards and a review_approved equal to its review hash.

What it adds

  • review prepare blueprint --lean-root . --packets DIR [--timeout] (_review_prepare): one full extraction, build_review_bundle's refusals, then write_review_packets: one packet per declaration under blind/, named by the SHA-256 of its bytes, plus an autoform-review-packets/v1 manifest for the coordinator.
  • review record blueprint --packets DIR --article-id --declaration --testimony --model [--expected-card-hash] (_review_record): no Lean. read_review_packet takes the single manifest entry for the article and declaration and reads the packet its hash names, not the manifest's path; manifest, packet and testimony go through read_regular_file (non-blocking open, so a FIFO is refused unread); a gone article_id is refused (review-article-missing); Add read-back cards and the testimony validator #216's prepare_readback checks packet bytes and testimony, and publish_readback files the card under its lock and compare-and-swap.
  • review check blueprint --lean-root . [--json] [--timeout] (_review_check, _current_review): reads graph and cards, extracts once, and refuses with review-snapshot-changed if the cards changed, the extraction's blueprint hash does not name the graph, or a Lean-mapped article, read again for its statement, no longer hashes as the graph recorded. It prints each article's hash to approve and labels each current approval.
  • autoform_cli/review.py: build_review_bundle (in-memory evidence: title, statement, cited passage, packets), ReviewState/review_states (incomplete, unverifiable, unapproved, drift, approved; the one place approval is judged), review_findings (adds orphaned cards and approvals), canonical_statement. Lean-mapped articles need an article_id and must be declaration-sized leaves; a cited article needs an exact #L<start>-L<end> passage of an in-vault non-Markdown source; no article may cite blank lines.
  • review_approved: sha256:<64 hex> frontmatter (graph.py). approvals.py: approval_statuses(states) labels every current approval self-approved, no network; JSON {label, node_id, review_hash}. Its docstring, the README and both CODEOWNERS examples (# /blueprint/ @OWNER) say authorization is repository policy (code-owner review of blueprint/, stale approvals dismissed, approval of the latest push).
  • skeleton.py: the blueprint hash covers each article's cited passage (_source_passages, _blueprint_hash(graph, passages), public blueprint_hash(graph)), so review evidence binds the passage a reviewer reads; source_passage(files=) reads each cited file once, after main's link checks pass, and reports a failed read as that article's problem. OutputTransaction and _stage_output(stages=) own the review packet stages, and lean._OUTPUT_STAGE keeps a stage a killed writer left from being indexed as project source.
  • Opt-in marker blueprint/.autoform-review (autoform-review-policy/v1), committed by new scaffolds. Both autoform-verify.yml copies check its hash, fail if cards or approvals exist without it, and with it run review check --lean-root . once. Review packet trees are managed output (lean.py; public skeleton.validate_managed_output with an exact schema=, refusing a symlinked manifest). Human Review gains the statement-review steps, Formalize runs review check after integration, the read-back guide gains "Return only testimony". Plain audit and doctor leave review_approved to review check.

What changed in this revision

Size: +2,683/-77 in 24 files before, +2,665/-70 in 23 files now.

What changed since #75

  • Size: +3,997/-44 in 28 files at a74dba2, Add verified statement-review bundles #75's head when it was split, now +2,665/-70 in 23 (code 1,553 to 1,059 lines, tests 2,161 to 1,362, docs and workflows 283 to 244).
  • Every command derives its evidence: no bundle file, no review prepare -o, no review check --bundle, no audit --review or --review-bundle. The bundle schema, loader, writer and validators are gone; ReviewBundle is in-memory only, and audit.py, doctor.py and readback.py are untouched.
  • review record runs no Lean and re-reads no article: the scoped extraction, the post-Lean reload and the pre-write article re-read are gone. A card filed from stale packets is filed and reported readback-invalid by the next review check; a stale record that names --expected-card-hash can replace a current card with an invalid one (Git restores it).
  • canonical_statement is now the site's statement box reading (article_parts(published_page(...))): the old stripper dropped comments in indented code, which Treat every published page as untrusted #215's site shows, so the approval did not bind text the box showed.
  • Approval state lives in review_states; current_approvals and the per-approval attestation fields are gone. Review refusals from prepare and check name the article and code. Rebased on main 8638db9: textual merges with main's elaboration-limit sentence in the README, its module-import-impact imports in __main__.py and its "renew the complete claim set" step in Formalize. The README's list of what Lean indexing skips now names review packet folders, and Formalize hands every article whose read-backs or approval the result made stale, import-edit repairs included, to Human Review. From ae2db51: one import conflict in __main__.py (Publish blueprint sites transactionally #165), and the statement-box test now builds files with Publish blueprint sites transactionally #165's capture. Main's audit step in the verify workflows (Run the CI audit probe without any project code #190) is kept.

Review findings it answers

  • Add verified statement-review bundles #40 blocker 1, check half: review check judges one snapshot of graph and cards (dd33f01). The record half (d6d8d16, by ArmelRandy) and the audit half are dropped: the record compares nothing with Lean, and audit has no review path.
  • Add verified statement-review bundles #40 blocker 2, policy half: the drift-checksum and repository-policy text, written for this split; a pasted hash prints self-approved.
  • Add verified statement-review bundles #40 blocker 6: verify extracts once (91c9287, by ArmelRandy); the record half, moved out earlier as batch filing, is closed here: a record costs no extraction.
  • Item 2: a blank cited passage is refused by prepare and check alike (c4effb3, b78d71e), now for every origin. Item 3's bundle half is moot (no bundle file); the manifest reader refuses nested and long-number JSON as unreadable.
  • Item 4, verify half: removing the AUTOFORM_REVIEW_ENABLED gate fails a test (17ad389). d04b976 (card filed while Lean runs) is dropped: there is no Lean window. Item 6: a gone article_id is refused, without advice (the advice was old Harden card publication and review record #218's, dropped).
  • Item 8, part: packet, testimony and now manifest refused unread when not regular files (5be882a). The record's article re-read (ca63de9 and five follow-ups) is dropped; an edit during a record is caught by the next check.
  • Deferred finding b747ef3: article shape is checked without a children scan, with its scale test. 412a479 and 21b71ca went with audit --review.

Until the next layers land

Validation

Run 39103606387 on 1648bdf5 passed every job: Windows inspection, subprocess, and publication hardening, real Lean (fixture toolchain), real Lean skeleton suite (fixture toolchain), real REPL (fixture toolchain), test (3.10), test (3.13).

New: tests/test_review_cli.py (14 tests, 23 cases; 31 tests at a74dba2) and tests/test_review_bundle.py (24 tests, 47 cases; 29 there). Added: 2 tests in tests/test_scaffold.py, 1 each in tests/test_doctor.py, tests/test_graph_scale.py and tests/test_skill_examples.py, 1 test and a packets row in tests/test_lean_sources.py. tests/test_readback.py, which a74dba2 changed, is untouched.

Where #40's review went

Blockers are #40's review of 765f2cb; items are the open-items comment and its follow-up.

Finding Carried by
Blocker 1: split snapshot in check and record this PR (check, the blueprint hash over cited passages), #217 (render); record half dropped (record runs no Lean)
Blocker 2: a pasted hash passes as approval this PR (policy text, self-approved), #217 (label on the site), #219 (policy-enforced label from one repository-policy check); per-approval attribution dropped
Blocker 3: card writes under concurrent edits #216 (flock plus compare-and-swap); post-lock re-walk dropped
Blocker 4: testimony that hides text #216 (plain text, flat TeX allowlist)
Blocker 5: unbounded Markdown parsing #216 (no parser; linear scans within 32 KiB and 500 lines)
Blocker 6: repeated Lean work #214 (parallel probes), this PR (verify extracts once, record runs no Lean), #217 (render extracts once), #219 (Pages passes its own report)
Item 1: Pages mkdocs-material pin #212
Item 2: blank passage in derived evidence this PR, #217
Item 3: input nested too deep to decode #212, #215, #216, this PR; bundle parts dropped (no bundle)
Item 4: mutant-killing tests this PR, #219 (gate test over both workflows); testimony half moot (no Markdown), batch parts moved out
Item 5: text between paired dollar signs #216
Item 6: a record whose article_id is gone this PR (refusal); advice dropped with old #218
Item 7: records-manifest recipe moved out (batch filing)
Item 8: record and audit hardening #216 (cards), this PR (regular-file reads); the record's article re-read dropped, 9bd0052 moved out
Item 9: history the split: #216, this PR, #217 and #219 are one commit each; #215 adds its rebuild on main, a merge and a review commit to its layer commit
Item 10: probe per module and its cost #213 (design), #214 (parallel probes)

Stack

# PR Layer
1 #212 Fix roadmap loading, Lean index edge cases and undecodable JSON (merged)
2 #213 Extract Lean skeletons one probe per root module (merged)
3 #214 Run skeleton probes in parallel and isolate probe failures (merged)
4 #215 Treat every published page as untrusted
5 #216 Add read-back cards and the testimony validator
6 #284 Add statement-review commands
7 #217 Show statement review on the site
8 #219 Label statement approvals by the repository's code-owner review policy

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 13, 2026
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 511757b to d9df55b Compare October 14, 2026 02:05
@Deicyde
Deicyde force-pushed the feat/review-commands branch from 7156b17 to c897e96 Compare October 14, 2026 02:05
@Deicyde
Deicyde force-pushed the feat/review-commands branch from c897e96 to 2e9de8c Compare October 14, 2026 02:34
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from d9df55b to 0fed56a Compare October 14, 2026 02:34
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 0fed56a to 87f9b7c Compare October 14, 2026 02:57
@Deicyde
Deicyde force-pushed the feat/review-commands branch from 2e9de8c to 459ec0e Compare October 14, 2026 02:57
@Deicyde
Deicyde force-pushed the feat/review-commands branch from 459ec0e to f3a300b Compare October 14, 2026 06:43
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 87f9b7c to 0108ce4 Compare October 14, 2026 06:43
@Deicyde
Deicyde force-pushed the feat/review-commands branch from f3a300b to c8ca48f Compare October 14, 2026 17:14
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 0108ce4 to 78bc493 Compare October 14, 2026 17:14
@Deicyde
Deicyde force-pushed the feat/review-commands branch from c8ca48f to e3808e3 Compare October 14, 2026 19:35
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 78bc493 to 5a80f03 Compare October 14, 2026 19:35
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 5a80f03 to f6767bb Compare October 14, 2026 22:47
@Deicyde
Deicyde force-pushed the feat/review-commands branch from e3808e3 to de70b73 Compare October 14, 2026 22:47
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from f6767bb to 5a980e0 Compare October 17, 2026 23:23
@Deicyde
Deicyde force-pushed the feat/review-commands branch from de70b73 to 1be463d Compare October 17, 2026 23:23
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 5a980e0 to 26832e6 Compare October 17, 2026 23:55
@Deicyde
Deicyde force-pushed the feat/review-commands branch 2 times, most recently from 8a47c28 to c83c5d5 Compare October 18, 2026 00:23
@Deicyde
Deicyde force-pushed the feat/readback-cards branch from 26832e6 to f8148cb Compare October 18, 2026 01:46
@Deicyde
Deicyde force-pushed the feat/review-commands branch from c83c5d5 to 6d551a9 Compare October 18, 2026 01:46
review prepare, record and check, and the CI review check. Evidence is
derived every time from a fresh full extraction: prepare writes blind packets
named by the hash of their bytes, record files a card for one of them without
running Lean, and check, the one judge, refuses stale cards and fails until
each Lean-mapped article's review_approved matches its review hash. The
approval state is computed in one place, and every current approval reads
self-approved; who may write review_approved is repository policy.

Part 6 of the split of #75.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant