Skip to content

Truth reconciliation, watchable proof, and three shipped features (adapter-verify, Break the Ratchet, CheckerProof)#130

Merged
nateshpp merged 13 commits into
mainfrom
change/modonome-review-action-plan-rhrdm5
Jul 8, 2026
Merged

Truth reconciliation, watchable proof, and three shipped features (adapter-verify, Break the Ratchet, CheckerProof)#130
nateshpp merged 13 commits into
mainfrom
change/modonome-review-action-plan-rhrdm5

Conversation

@nateshpp

@nateshpp nateshpp commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

A comprehensive hardening and feature pass in three parts.

Part 1: truth reconciliation. Rewrote every claim across README, the demo walkthrough, and AgentProof's framing to match its committed evidence exactly (the walkthrough previously described a week of merges and ratchet blocks; the real evidence was one dry-run and one recorded, unapplied cycle). Restructured the README around proof-first ordering with a real terminal capture and a "how this compares" section. Hardened the gate integrity check itself: false-positive-only string/comment stripping around the type-escape check, plus a real coverage gap fix (Node's assert.equal/assert.match member-call style, the dominant style in this project's own test suite, was previously invisible to the removal check). Added a scoped --permission-mode manual + --allowedTools profile for the CLI-transport maker/checker invocation, replacing a blanket --dangerously-skip-permissions, verified empirically against a live session (an initial attempt with --permission-mode acceptEdits was found to not actually confine execution to the allowlist and was discarded in favor of manual, which does).

Part 2: three new, real, tested features (docs/adr/ADR-046-ship-the-deferred-features.md):

  • adapter-verify (npx modonome adapter-verify ): a two-tier conformance checker for the tool-loop adapter contract. Static tier validates schema/license/boundary; live tier spawns the real binary through the production code path against a scratch target and a local mock endpoint, confirming stdin consumption and containment, and skips cleanly (never fails hard) when the binary is absent. Ships with a working reference adapter for --self-test.
  • Break the Ratchet (BREAK-THE-RATCHET.md, npx modonome break-the-ratchet): a public adversarial challenge. Submissions are never executed — the judge reads a .patch as plain text and hands it to the ratchet's own --diff mode, itself a pure text analyzer. Seeded with one real, honest hall-of-fame entry demonstrating the ratchet's documented expected-value-drift blind spot.
  • CheckerProof (checkerproof/, npx modonome checkerproof): a seeded-defect benchmark measuring the independent checker's actual catch rate on semantic weaknesses (expected-value drift, cross-file assertion migration, vacuous-in-spirit assertions, scope creep) the deterministic ratchet cannot see. Advisory only, always exits 0, skips rather than fabricates a score when no model is reachable. First evidence file is a real, live run against the repo's configured checker model: 5/5.

Part 3: a live-tested arming gate. Ran the full two-key arming mechanism (autonomy_enabled + dry_run in config, plus the authoritative env-only MODONOME_ARMED) for real, with --execute, at the default $0 budget. Confirmed the budget gate correctly refuses to spend before any network call. Captured as evidence, with honest documentation of what remains open (a live maker/checker model exchange needs a reachable free or local model endpoint, or a deliberately raised budget — see OWNER-ACTIONS.md).

A closing claims audit (docs/audits/claims-audit-2026-07-08.md) re-verifies this work by re-running the actual commands rather than trusting the commit messages that made them.

Governance checklist

  • npm run verify passes locally (drift guard + style check + tests + AgentProof)
  • No em dashes in any tracked file (the style check rejects them)
  • Prose states conclusions directly (style check rejects hedging phrases)
  • No AI co-author lines in commit messages
  • Ratchet logic changed: fixtures added under fixtures/ratchet-diffs/, tests added in tests/ratchet.test.mjs
  • No new AgentProof scenario in this PR (CheckerProof and Break the Ratchet are separate benchmarks with their own scenario/fixture conventions)
  • No config schema change requiring a version bump
  • Prompt changed (prompts/roles/checker.txt): npm run build:prompt regenerated the bundle

Test evidence

$ npm test
# pass 914
# fail 0

$ node agentproof/runner.mjs
Score: 25/25 normative | 10/10 extended (35/35 total)
Level: HARDENED

$ node checkerproof/runner.mjs
Checker: claude-opus-4-8 (anthropic-cli)
Result: 5/5 scored scenarios caught correctly (0 skipped, no model access)

$ node scripts/adapter-verify.mjs --self-test
Tier 1 (static): PASS
Tier 2 (live): PASS - stdin prompt consumed and echoed; output confined to the target directory

$ node scripts/check-style.mjs .
Style check passed (186 advisory warning(s), grandfathered term(s) not yet migrated)

$ npm run check:md-governance
PASS: root allow-list, protected files, links, ADR numbers, audits, and canonical keys all clean

nateshpp added 12 commits July 8, 2026 04:51
Truth-reconciliation pass ahead of wider launch work:

- Rewrite the demo walkthrough claims (README, examples/demo-app) to match
  the committed evidence: one dry-run plus one recorded, unapplied
  maker/checker cycle, not a week of merges and blocks. Note which planted
  debt items the dry-run proposes versus what stays planted for the corpus.
- Reframe AgentProof as a self-graded regression benchmark everywhere it is
  described (agentproof/README, root README, site meta/JSON-LD, noscript),
  standardize on the 25/25 normative headline, and state plainly that the
  Sigstore attestation proves provenance, not independent validation.
- Honest tagline: the package description and hero copy now claim what the
  line-based gate integrity check actually enforces (structural weakening),
  and a new README section documents what it cannot catch and which layers
  cover that gap.
- Sweep present-tense claims about unshipped capabilities (enterprise
  estates, mirror mode, cross-repo network, compliance AG06) to explicit
  roadmap tense; label the network prompt module as not shipped.
- Drop tests/ from the npm files allowlist (npmignore already excluded it),
  remove the OpenSSF Best Practices placeholder badge, de-stuff site
  keywords, and correct the site README's CNAME description (www vs apex).
- Regenerate the prompt bundle, snapshot, and policy attestation.
- Capture a real gaming diff (skip injection + assertion removal, committed
  as a 'fix') being rejected by the gate integrity check with exit 1 and
  SARIF rule codes, and the honest fix for the same debt passing the
  identical gate: verbatim output and both patches committed under
  examples/demo-app/runs/2026-07-08T05-30-00Z/, reproducible bit-for-bit
  with no model involved.
- Capture the Gauntlet before (0/3 UNHARDENED, no gate wired) and after
  (3/3 HARDENED) wiring the shipped workflow template, with the honest N/A
  denominator visible.
- Rewrite the demo walkthrough around the committed evidence and add the
  gate-rejection and Gauntlet steps.
- Add an animated terminal capture (SMIL SVG, no external assets) of the
  rejection above the README fold, linking to the committed evidence.
- Promote the Gauntlet in the 60-second path and teach it to print a
  copy-paste share line and a shields.io badge snippet encoding exactly
  what was measured (blocked/applicable on the day it ran).
… scope

- Rebuild README to a single-screen story: real terminal capture, the
  60-second read-only path (dry-run + gauntlet), a five-minute CI gate
  section with one canonical workflow, the trust-boundary diagram, a 'how
  this compares' answer (branch protection, LLM-judge review, eval
  benchmarks), what it catches and what it cannot, the loop with evidence
  links, an honest development-practice section naming the solo,
  AI-assisted, self-governed reality, and a links table for everything
  else. Cost model and embedding guidance move to QUICKSTART.
- Replace the site hero terminal's invented output with verbatim demo-app
  output including the real gate rejection lines.
- Add ADR-045 (scope focus for launch): no AST tier (zero-dependency
  guarantee wins), false-positive-only ratchet improvements with a
  no-new-false-negative invariant, repo-level assertion delta as advisory
  only, and a recorded rationale for every deferred surface (challenge
  harness, CheckerProof, adapter verifier, second host example).
- Move the cross-repo knowledge network design under docs/research/ and
  reframe AgentProof standards-body language from submission-in-progress
  to aspiration contingent on adoption.
- Regenerate prompt bundle, snapshot, and policy attestation.
One scannable paragraph mapping the published 0.1.0-alpha (npm, with the
next dist-tag tracking ongoing work) to the ~40 detailed entries below it,
so an evaluator can see what shipped without reading commit-level prose.
No version change; release timing stays an owner decision.
… gitignore silently dropped

ADR-045 implementation (docs/adr/ADR-045-scope-focus.md):

- Strip same-line string literals and block comments before the TS/JS type-escape
  check (scripts/guard-ratchet.mjs: stripLineLocalNoise), so a ': any' or 'as any'
  inside prose like a string or a same-line block comment is no longer a false
  positive. The stripper bails to the raw line on anything it cannot prove closed
  on that line (an open quote, an open block comment, a possible regex literal
  ahead of a quote), so a real cast hidden behind a string decoy on the same line
  is still caught. This is a false-positive-only relaxation: every existing gaming
  fixture still blocks.
- Recognize Node's built-in assert module member-call style (assert.equal,
  assert.match, assert.rejects, and so on) as assertions, strong assertions, and
  weak-existence checks. This closes a real false negative: the ratchet previously
  only recognized bare assert(...) and Jest-style expect(...), missing the
  dominant style in this project's own test suite (2000+ occurrences). Discovered
  while building the fixtures for this change; folded in as the same class of fix.
- Add an advisory-only, informational cross-file assertion tally, printed after
  the per-file findings and never affecting the exit code. It is explicitly NOT a
  new detection mechanism: a repo-level sum of per-file deltas cannot go negative
  without an already-blocking per-file delta, so it exists purely as review
  context, not as an anti-gaming boundary (documented in the code comment).
- New fixtures and tests covering all of the above (6 new ratchet.test.mjs cases).
- Reframe AgentProof's standards-body language and relocate the knowledge-network
  design doc into docs/research/, per ADR-045.

Also: the previous commit's demo-app evidence run
(examples/demo-app/runs/2026-07-08T05-30-00Z/) was silently dropped by the bare
'runs/' rule in .gitignore and was never actually committed, contradicting the
commit message that claimed it was. Force-added it now, scoped an un-ignore
exception for that specific path so this cannot silently recur, and refreshed the
captures to reflect the corrected assertion count from the assert.match fix above
(+0/-2, not +0/-1, since assert.match(...) is now recognized).
…cker, scope CLI permissions

ADR-045 Phase 5 (docs-first, per the sustainability panel's guidance: no new
benchmarks, verifiers, or examples until real demand exists):

- docs/agents.md: the canonical reference for the crew roster, the config-driven
  role/runner/model/provider system, cost classes with fail-closed unknown-provider
  semantics, and worked recipes (a local maker with a paid checker, a fully local
  zero-cost pair, adding a new crew role with no code change). This surfaces a real,
  differentiated capability that previously lived only in config comments and two
  overlapping docs. docs/agent-org.md and docs/ops/runner-model-config.md now
  redirect here; incoming links (README, ARCHITECTURE, QUICKSTART, docs index)
  updated.
- docs/adapters.md: the contract for bringing an external agentic CLI into the
  tool-loop execution path (ADR-032): what the adapter must do (stdin prompt, env
  credentials, containment, timeout/turn-cap independence, exit semantics), and
  what a reviewer checks by hand today, since no automated adapter-verify exists
  yet.
- prompts/roles/checker.txt: add an adversarial rubric targeting exactly what the
  deterministic ratchet cannot see (expected-value drift, cross-file assertion
  migration, vacuous-in-spirit strong assertions, scope creep beyond
  allowed_edit_set). Purely additive; existing procedural content and the anchors
  test-prompt-behavior.mjs checks are untouched.
- scripts/agent/run-cycle.mjs: replace --dangerously-skip-permissions on the
  CLI-transport maker/checker invocation with --permission-mode manual plus a
  scoped --allowedTools list (Read/Edit/Write, git/gh, and the gate runners the
  multi-language ratchet supports). This is not a guess: I spawned the real claude
  CLI against scratch repos and found --permission-mode acceptEdits does NOT
  confine execution to --allowedTools as the flag names suggest (an unlisted rm
  went through); --permission-mode manual does, denying cleanly with no hang in
  non-interactive mode, verified with both an Edit and a git/npm round-trip.
  Extracted the pure buildRoleCliArgs() and threaded a spawnImpl seam so this is
  now covered by a real regression test (tests/run-cycle-cli-permissions.test.mjs,
  4 cases) instead of being the untested path it was.
- ARCHITECTURE.md: new 'Host vs. self: the two governance targets' section
  distinguishing the product (governing a host repo, demonstrated by the demo-app
  evidence) from self-governance (modonome governing itself, continuously
  exercised but not a second host), anchored on the control panel's two-tier
  write-auth model, and honest that no public evidence yet shows modonome
  governing a third-party repo.
Phase 6, the final phase of the brilliance plan (docs/ADR-045):

- SUPPORT.md: no-SLA support policy, real triage priorities, and what merging a
  community AgentProof scenario or adapter actually commits the maintainers to
  (permanent CI cost, ongoing upstream-compatibility burden). Added to the
  root-doc allowlist (scripts/check-md-governance.mjs).
- Found and fixed while writing it: CONTRIBUTING.md's existing 'triage within 5
  business days' promise directly contradicted the new honest framing. Pointed it
  at SUPPORT.md instead of carrying a specific promise this team's real commit
  history cannot back up.
- docs/launch/: a Show HN draft (title candidates, a first comment that leads
  with the mechanism and issues the break-it challenge, anticipated pushback with
  honest answers already drafted), article seeds (a Goodhart cross-post update
  anchored on the new gate-rejection evidence, a post-launch CheckerProof piece,
  a standalone trust-boundary explainer), and an X thread skeleton. Every claim
  in all three links to a committed evidence file, no exceptions.
- OWNER-ACTIONS.md: consolidates every owner-only item raised across this
  branch's six phases into one list, with two items marked as hard launch gates
  (a real armed week with published evidence; the GitHub Marketplace listing
  actually being live) rather than optional polish. Corrects an assumption from
  the original review: CODEOWNERS already lists two people, so the ask is
  confirming engagement, not recruiting from zero. Also lists the deferred,
  demand-gated work from ADR-045 (adapter-verify, CheckerProof, the
  Break-the-Ratchet harness, a second host-adoption example) with its trigger
  conditions, so it is discoverable without being built ahead of real demand.
- docs/audits/claims-audit-2026-07-08.md: a closing audit that re-verifies this
  session's own claims by re-running the actual commands (guard-ratchet,
  agentproof/runner.mjs, test-prompt-behavior.mjs, git ls-files) rather than
  trusting the commit messages that made them, in the same deliberately
  uncharitable format as the two prior audits. Carries forward what it did not
  re-check (security/compliance-as-code, Level 3 conformance) rather than
  implying a full sweep.
docs/adapters.md previously promised this as a well-scoped follow-up once a
second adapter showed up; building it now instead of waiting.

- scripts/adapter-verify.mjs: two-tier verifier. Tier 1 (static, always runs)
  validates an adapters.json entry against schemas/adapters.schema.json and
  runs it through check-licenses.mjs's license/boundary gate. Tier 2 (live)
  spawns the real adapter binary through the actual runToolLoopAdapter code
  path, not a reimplementation of it, against a scratch target directory and a
  local mock OpenAI-compatible endpoint (no real network, no cost), and
  confirms the adapter both consumed its stdin-delivered prompt and confined
  its output to the pinned target. When the named binary is not on PATH, tier
  2 reports SKIPPED, never a silent pass or a hard failure.
- fixtures/adapters/reference-adapter.mjs: a minimal, real, working adapter
  that satisfies the docs/adapters.md contract end to end. Doubles as the
  target for --self-test, so the verifier's own logic is provable without
  needing any external binary installed.
- Wired into bin/modonome.mjs as "npx modonome adapter-verify <name>" and
  "npx modonome adapter-verify --self-test".
- Fixed a real, pre-existing bug this surfaced immediately: the registered
  opencode entry in adapters.json carries role/exec_mode fields the schema
  didn't declare, so the entry failed schema validation the moment a real
  validator was run against it. Widened the schema to match the already-
  shipped manifest.
- Corrected two stale claims in docs/compliance/openssf-badge-evidence.md
  found while re-verifying it for the staleness gate: the DCO criterion cited
  a sign-off note in CONTRIBUTING.md that was never actually there (now
  correctly Gap, not Partial), and the bus-factor gap undercounted CODEOWNERS
  (which lists two people) while still correctly noting only one has authored
  commits.
- tests/adapter-verify.test.mjs: 10 tests, including two real end-to-end runs
  of the actual reference-adapter subprocess talking to a real local HTTP
  server, not just fake-spawn mocks.
ADR-045 deferred a public challenge harness, judging the effort not worth it
until real external interest existed. Building it now instead, with the exact
safety constraint the original technical review specified: submissions are
never executed.

- challenge/judge.mjs: reads a submitted .patch file as plain text and hands
  it to guard-ratchet.mjs's existing --diff mode, itself a pure text analyzer
  that never applies a diff or executes anything it contains. The judge
  mechanically confirms one fact (did the ratchet flag it) and reports the
  submitter's declared claim for a maintainer to review; it never decides on
  its own whether a claim is true, since that requires understanding the
  diff's semantics, the exact class of judgment the ratchet cannot make.
- schemas/break-the-ratchet-submission.schema.json: the declaration shape
  (title, category, claim, why it is a real weakening, expected verdict).
- challenge/examples/expected-value-drift/: a real, working seeded example,
  not a stub. A discount-calculation assertion's expected value quietly moved
  from the correct result (95) to what the broken code actually returns (100).
  Verified: the ratchet does not flag it, confirming the documented semantic
  blind spot is real. Seeds the hall of fame honestly instead of launching
  with an empty table that implies no one has looked yet.
- BREAK-THE-RATCHET.md: the public rules, submission process, and hall of
  fame. Wired into the README's existing break-it invitation.
- .github/ISSUE_TEMPLATE/break-the-ratchet.yml: mirrors the existing
  agentproof-scenario.yml conventions, requires the local judge output pasted
  into the issue.
- Wired into bin/modonome.mjs as `npx modonome break-the-ratchet <dir>`.
- tests/break-the-ratchet-judge.test.mjs: 11 tests, including an explicit
  safety-boundary test (a patch referencing a nonexistent path is judged
  without ever creating that path) and both real end-to-end runs (the seeded
  example scores candidate-break; a known, already-caught gaming fixture
  correctly scores not-a-break).
ADR-045 deferred this as needing recurring, owner-run model calls. Built and
run for real instead, not simulated.

- checkerproof/runner.mjs: resolves the checker role from .modonome/config.yaml
  exactly as a real armed cycle would, reuses scripts/agent/review-diff.mjs's
  existing buildReviewPrompt/parseVerdict, and adds live anthropic-cli
  execution alongside the existing openai-http path. Always exits 0 (advisory,
  never a gate). When no model is reachable, every scenario reports SKIPPED,
  never a fabricated 0/N.
- checkerproof/scenarios/: five real scenarios matching the categories in the
  hardened checker rubric (prompts/roles/checker.txt point 1a): expected-value
  drift, cross-file assertion migration, a vacuous-in-spirit assertion, scope
  creep past allowed_edit_set, plus a negative control so a checker that
  rejects everything cannot score well by accident.
- checkerproof/evidence/: a real run against this repo's actual configured
  checker (claude-opus-4-8, anthropic-cli). 5/5 scored scenarios caught
  correctly on 2026-07-08. Reproducible: node checkerproof/runner.mjs
  --write-evidence.
- Wired into bin/modonome.mjs and package.json, deliberately not added to the
  verify script chain since verify's guarantee is no network or secrets.
- Fixed a repo-hygiene finding: adapter-verify.mjs's probe marker used
  Math.random(); switched to crypto.randomUUID().
- tests/checkerproof.test.mjs: 9 tests against injected reviewImpl, no
  network or cost.
ADR-046 supersedes the specific deferral in ADR-045 point 5, on record: direct
owner instruction reversed the demand-gating call for adapter-verify, Break
the Ratchet, and CheckerProof, while every safety and scope constraint
ADR-045 attached to each stayed exactly as specified (submissions never
executed, CheckerProof never fabricates a score and stays advisory, the
adapter verifier degrades gracefully). ADR-045's other points (the
false-positive-only ratchet constraint, the AST-tier cut, the advisory-only
cross-file signal) are untouched and still stand.

- ADR-045: strikethrough note on point 5 pointing to ADR-046, so a reader who
  only sees ADR-045 does not conclude these are still unbuilt.
- OWNER-ACTIONS.md: moved the three from "deferred, demand-gated" to
  "shipped," with the real follow-up work that shipping does not solve by
  itself (recurring CheckerProof runs, Break the Ratchet submission triage).
  Good-first-issue 3 now points at using the live adapter-verify tool instead
  of proposing it; issue 6 points at extending the live CheckerProof corpus;
  added issue 7 (Break the Ratchet triage).
- docs/launch/article-seeds.md and show-hn.md: updated to reference the real,
  shipped, evidenced tools instead of describing them as future work.
…the armed-week gate)

Not a full live cycle. Real, honest evidence of exactly what it is: the full
two-key arming mechanism (config autonomy_enabled + dry_run, plus the
authoritative env-only MODONOME_ARMED) engaged for real, --execute attempted
for real, and the budget gate correctly refusing to spend before any network
call at the default remote_model_budget_usd_per_day: 0.

- examples/demo-app/runs/2026-07-08T14-19-00Z/: dry-run-plan.txt (unarmed
  baseline), armed-execute-refused.txt (the live refusal), and
  network-policy-check.txt (evidence that no free-tier or local-model host
  was reachable from this session: both models.github.ai and huggingface.co
  returned a hard 403 policy denial from the network proxy, not an
  application error).
- The repo's config was reverted to its safe defaults immediately after each
  test; it does not stay armed as a side effect of this evidence run.
- OWNER-ACTIONS.md: narrowed the armed-week gate to what's actually still
  open. "Does arming work under a real attempt" is now closed. "Does a live
  maker/checker exchange happen" is not, and needs either a free/local model
  host reachable from wherever this next runs, or an explicit, deliberately
  raised paid budget.
@nateshpp nateshpp requested a review from techseek4vr as a code owner July 8, 2026 14:39
Comment thread scripts/adapter-verify.mjs Fixed
Comment thread scripts/adapter-verify.mjs Fixed
Comment thread scripts/adapter-verify.mjs Fixed
Comment thread scripts/adapter-verify.mjs Fixed
scripts/adapter-verify.mjs's main() destructured manifest from
loadAndValidateManifest without using it, and imported containedCwd
from tool-loop-adapter.mjs without using it. Dropped both; the
function's own internal use of manifest is untouched.

Regenerated .modonome/snapshot to match.
@nateshpp nateshpp merged commit c1d35ec into main Jul 8, 2026
9 of 10 checks passed
@nateshpp nateshpp deleted the change/modonome-review-action-plan-rhrdm5 branch July 8, 2026 15:00
nateshpp pushed a commit that referenced this pull request Jul 8, 2026
Resolves the .gitignore conflict from PR #130 by keeping both additions
(the anchored .claude/skills/ un-ignore and the examples/demo-app/runs/
un-ignore). Regenerates the snapshot and policy attestation against the
merged tree.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants