# CoreGuard STATUS — One Source of Truth

**Authoritative status file.** All repo docs (`README`, `docs/FUNDING.md`) point
here instead of duplicating numbers. Facts only — every metric below is
machine-measured, not estimated. Last verified: **2026-09-26**.

## Repo truth (measured this day)

| Item | Value | How verified |
|---|---|---|
| Test suite | **1320 / 1320 pass** (+4 main-badge-sync audit: `test/ci/main-badge-sync.test.js` audits badge↔ledger sync at the tip main actually SERVES — ledger, module badge table and every `docs/badges/*.svg` read from the GIT COMMIT TREE via `git cat-file -p <ref>:path` / `git ls-tree` (HEAD on main checkouts, else `refs/remotes/origin/main`, failing named when neither is reachable), a staged newer ledger point bites STALE by name proving the audit reads committed bytes, and the audit core moved to `test/ci/badge-audit.mjs` so working-tree and commit-tree surfaces consume ONE derivation; earlier: +4 badge-freshness audit: `test/ci/badge-freshness.test.js` re-derives badge freshness at COMMIT granularity — for every BADGE_SERIES row (parsed from the module, budgets never retyped) the committed `docs/badges/*.svg` must show the ledger's LATEST recorded point and the ladder verdict color, `perf-all` must be the worst case of exactly the rendered set (nightly absence honored: no badge before its first point), any committed `perf-*` file the module does not declare is a criminal artifact (the CG-BDG/1 `specimen-*` family is explicitly out of scope), and 3 mutation controls each apply AND bite by name (stale value / lying color / phantom badge — a green badge the ladder calls yellow fails loudly); then: +3 aggregate perf badge: a fourth rendered badge `perf-all.svg` / README row `DDE perf · all` sums the always-on set's badges by worst case — all inside budget → green `all within budget`, any series past its budget but inside the 2x bar → yellow `N above budget`, beyond the bar → red `regression detected` — computed ONLY from badges the run rendered (the nightly load tail joins when it records) with the same fail-closed atomicity, contract-tested in `perf-badges.test.js` (+3); then: +5 first-drift trend alert: `test/ci/perf-drift-alert.test.js` — the trend gate's first breach names series, metric, current, baseline and ratio three ways (structured `alert` in the --json status, stderr block, and a breach row appended to the GitHub run summary when GITHUB_STEP_SUMMARY is set — the failing run's Summary page shows the offender beside the red gate, append-only and best-effort), a FAIL-gate report is a recording error and never dresses up as a regression, a green run emits no alert and touches no summary, and a breached run still records NOTHING; then: +8 live trend page:  `docs/DDE-TREND.html` — the engine/wire/SDK median curves redrawn from the committed `benchmarks/perf-history.jsonl` on every load and re-polled every 60s so each tracker-bot point appends itself to the page without a redeploy, budgets derived live from `scripts/benchmark-trend.mjs` (a module budget bump moves the page in the same push), red named shim strips naming the exact URL whose ledger source is dark, AR/EN throughout; the contract executes the page's JS in a VM against the real bytes, drives the 60s poll and the refetch channel through the tokenizer too, and 6 page-mutation negative controls each apply AND bite; then: +4 depth-pair surfacing: the live perf page now shows the sequential median → p95-under-concurrency pair derived from the trend module, the respondent row carries `metric: "p95"` end to end, and the page queueing honesty framing + the unrecorded-point absence note are both contract-tested; then: +5 light load runner: a 50-way `POST /verify` burst whose gate requires the requested peak in flight AND an overlap factor (Σ latency / wall time) ≥ 2, refuses `--concurrency 1` as sequential by name, and fails on a p95 budget it cannot meet; +16 live-playground page contract: the page's engine copies are executed against the real packages through the full ACCEPTED/REJECTED/UNKNOWN job run and must agree state-by-state, the x402 gate must refuse before a signature on the browser crypto-shim, the shim must pass the FIPS vectors, and four page mutations plus one engine byte must each apply AND bite; +1 index card; earlier: +19 job-economy flow battery: CG-BUD/1 sibling-scope race + settlement/metered one-ceiling + hold/disposition matrix in `test/integrations/budget-acceptance-flow.test.mjs`, +1 claims-audit committed-bind negative control) | `npm test` — the pass total is machine-pinned: `scripts/run-tests.mjs` enforces it against `docs/state-snapshot.json` after every green run (drift = red), and `test/ci/current-state.test.js` re-measures the fast fields (Boundary audit | **PASS** (893 files scanned, 0 violations)
| Foundry contracts | **34 / 34 pass** | `forge test --match-path "test/contract/*"` (V2: 14 + EvidenceRegistryV3: 20) |
| Adversarial corpus | **73 / 73 pass** | `npm run corpus && npm run benchmark` |
| Execution Integrity Benchmark | **10,000 runs · False Accept 0 · False Reject 0** | `npm run benchmark:10k` |
| Mutation Laboratory | **1,000/1,000 mutants refused · 0 escaped** | `npm run mutation` |
| AgentProof `verify-provenance` surface | **exit-code discipline 0/1/2/3/4** · badge honesty tests | `test/provenance/cli-verify-provenance.test.js` (part of the suite) |
| Actor Classification Card | **12/12 tests** — HUMAN/AGENT/BOT/ROBOT/COMPANY buckets + maker/model/version | `test/provenance/actor-card.test.js` |
| Recovery engine (F-4 root fix) | **10/10 failure-injection scenarios** — no manual reconstruction, no ambiguous success | `test/recovery/recovery.test.js` |
| Secrets audit (full git history) | **PASS — 942 blobs, 0 embedded secrets** | `scripts/audit-secrets.mjs` |
| `git diff --check` | clean | gate check |
| Rust/WASM/independent parity | PASS | `test/independent-verifier/` |
| C verifier | PASS | `test/verifier-c/` (frozen reference, untouched) |
| Frozen evidence/canonical hashes | UNCHANGED | conformance suite `test/conformance/` |
| Boundary audit (committed tree) | **893 files · 0 violations · (+test/ci/badge-audit.mjs, +test/ci/main-badge-sync.test.js) PASS** | `npm run boundary:audit` — counted from `git ls-files` (the count a clean clone reproduces, not this dev disk), machine-pinned as `docs/state-snapshot.json#boundaryAudit` and re-measured by `test/ci/current-state.test.js` |
| Docs-node contract | **95 executed · 56 skip-listed · 20 docs covered** (+ `docs/PRODUCTS.md` skip-listed as text catalog) | `test/ci/docs-node-contract.test.js` — every documented `node`/`npm` command is EXECUTED or skip-listed with a named reason; pinned as `docs/state-snapshot.json#docsNode` |
| Claim registry CG-CL/1 | **28 claims · 16 VERIFIED · 12 not · 0 violations** | `npm run claims:audit` — `docs/claims-registry.json`; 11 of 28 depend on an external outcome and sit at GATED/UNKNOWN/NOT_PERFORMED. `VERIFIED` is unreachable without evidence, and the audit verdict travels INSIDE the artifact |
| Badge system CG-BDG/1 | **2 specimens · issuerCount 0 · NOT ISSUED** | `npm run badge:verify` — `verifyBadge()` re-derives every digest from its record byte for byte, so a hand-edited SVG fails; `brand` is non-enumerable so a specimen cannot be laundered into an issued badge |
| Partner journey CG-PJ/1 | **10 legs · verdict MATCH** | `npm run partner:journey` — the verdict is the WEAKEST leg, never the best one, and a clean run is `MATCH` rather than `VERIFIED` because L2 is the weakest link. DRY_RUN: no live chain, webhook, payment, or badge |
| Replay lab CG-IR/1 | **self-check PASS — a partial bundle is UNKNOWN, never a pass** | `npm run integration:replay` — replays one bundle through L0·L3 with no partial credit; the journey hash is a pure function of the bundle's link statuses |
| Risk findings CG-RF/1 | **8 findings · 4 OPEN · 4 OK** | `npm run ladder:findings:write` — `docs/risk-findings.json`, derived only from committed surfaces and proven equal to a deterministic rebuild by `test/integrations/ladder-v03.test.mjs`. Open findings are reported, never cleared |
| Reputation CG-RP/1 | **grade UNPROVEN · score 0** | `npm run ladder:reputation:write` — one point per recorded milestone, never the amount; every external counter stays 0 until a real milestone is appended to `docs/adoption-milestones.json` |
| Release gate CG-RG/1 | **18/18 legs · GATE_PASS · independence PASS (18/18 legs self-audited)** | `npm run release:gate` — `docs/release-gate.json` (timestamp- and `ms`-free, so a re-run produces no diff); audits its own source for network, credential, and external-outcome dependencies on every invocation, and that self-audit is also a CI step (`npm run release:gate:independence`) |
| Conformance CG-CR/1 | **badgeIssuerCount 0 · revenue $0** | `npm run conformance:report` — `docs/conformance-report.json`; the report carries no timestamp, and the price stays LOCKED at 0 until an owner decision names an amount |

## On-chain truth (Core Mainnet, chainId 1116)

| Item | Value |
|---|---|
| Anchor contract (V1, immutable) | `0x037dF08F2d43c5D03759279Fe35664f6AFf9EA6E` |
| Mainnet proof tx | `0xe67c61fda81200bf026faee31c23a7b7e7f56ed24f06ffe24f071fa06891a9b8` · block `38712625` |
| Proof verdict | **L1 VERIFIED (RECEIPT_INTEGRITY)** · receiptId `0x4f9d8586…` (frozen record: `scripts/verify-live.json`) |
| Cross-RPC verification | rpc.coredao.org + rpc.ankr.com — A+B+C VERIFIED ANCHOR INTEGRITY |
| **EvidenceRegistryV2 (Phase 3)** | `0x66268a47e81b8f657798d7b5bbedc956df7b13fd` (Mainnet, immutable) |
| V2 deploy tx | `0x75aabacc94abc10a04c553c04788d797315fee2c2debb35db3d6d9f37f597793` · block `38764383` |
| V2 commitIntent tx | `0x0cd2a8c0de1b030552da16052650ae3c1d74821c2dfa3a4b40afa18d7367715c` · block `38764405` |
| V2 anchorProof tx | `0x5b9e7d6806200d1f3603ebd0f759d224e3096951dfb6ecbf3539b8b6d3e478d2` · block `38764446` |
| V2 verdict | **VERIFIED ANCHOR INTEGRITY (READBACK + INDEPENDENT RECOMPUTE)** |
| **Gate 4.1 identity anchor (commitIntent)** | `0x68d9fbf1b384fe416d2222347d15e492e78d7b14f05cae0c9edbd57ce373c567` · block `38827925` · `0x1` · intentId `0xc4799b1d…60000d` · **COMMITTED** — **ON-CHAIN SUCCESS, GOVERNANCE PENDING** (P7 §5/§6 human signature required; not closed). Independent round: `scripts/verify-gate-4.1-onchain.mjs` **66/66 PASS** from raw dumps `evidence/raw/` (coredao + ankr) → `evidence/gate-4.1-independent-verify.json`. `evidence/gate-4.1-broadcast.json` is **reconstructed** (gate crashed post-send; tagged + superseded); discovery-finding F-4 filed |

## Code truth

| Item | Value |
|---|---|
| Releases (local, per-workstream) | `v0.1.0` · `v0.1.1` · `v0.2.0` · `v0.2.1` · `v0.3.0` · `v0.4.0` · `v0.5.0` · `v0.5.1` · `attack-lab-v1.0.0-closed` · `rc-2026-09-19-a` |
| v0.5.0 | **EvidenceRegistryV2 live on Core Mainnet (Phase 3)** — deploy + commitIntent + anchorProof + readback + independent verify, frozen in `evidence/` |
| v0.5.1 | **Repository encoding hygiene** — prior-art mojibake recovered, stray BOMs removed, permanent guard added; `npm test` **654/654**; frozen `scripts/verify-live.json` untouched |
| v0.5.2 | **AgentProof CLI surface (CGEP/1:VERIFY-PROVENANCE §10)** — `verify-provenance` subcommand + honest badge rendering + deterministic fixtures (`examples/provenance/`); `npm test` **721/721** (was 713 at `d7ca118`, +8 from `cli-verify-provenance.test.js`); freeze 46/46 still anchored |
| v0.5.3 | **Gate 4.1 identity anchor live on Core Mainnet** — `intentId 0xc4799b1d…60000d` committed in `commitIntent` (block `38827925`, status `0x1`); **ON-CHAIN SUCCESS verified 66/66** from raw dumps (`evidence/raw/` + `scripts/verify-gate-4.1-onchain.mjs`); **GOVERNANCE PENDING** (P7 §5/§6 human signature required — project NOT closed); `evidence/gate-4.1-broadcast.json` explicitly tagged **reconstructed** (gate crashed post-send; never re-sent); finding F-4 filed |
| **v0.5.4 (2026-09-19, this session)** | **Gate 3+4+5 + actor classification + Gate 7 RC manifest** — `@coreguard/recovery` (crash-safe broadcast pipeline, F-4 root fix; write-ahead journal, no ambiguous success) with **10/10** failure-injection tests; `scripts/audit-secrets.mjs` full-history secrets audit (**942 blobs, 0 embedded secrets**); `packages/provenance/actor-card.js` declared-level actor card (HUMAN/AGENT/BOT/ROBOT/COMPANY + maker/model/version, bilingual AR/EN, honest "declared, never detected") with **12/12** tests; `scripts/build-rc-manifest.mjs` + `docs/rc-manifest-2026-09-19.json` (**RC candidate `rc-2026-09-19-a`**, 581 files SHA-256, tag created); `npm test` **749/749**; freeze 47/47 still anchored (no pinned file touched); CI green ×3 |
| **RC 2026-09-19-a RELEASE** | **GitHub Release created** (`rc-2026-09-19-a`, prerelease, release URL on `EslaM-X/coreguard`) — RC candidate tagged + releases + notes; **NOT Production-ready claim**; Gate 6 external review NOT PERFORMED; legal NOT PERFORMED; pricing LOCKED. Gate 4.1 commitIntent **LIVE re-confirmed at release time** (`tx 0x68d9fb…` status `0x1`) via 2 independent RPC providers (coredao + ankr) + `scripts/verify-gate-4.1-onchain.mjs` **66/66** → `evidence/gate-4.1-live-reconfirmation-2026-09-19.json`; no duplicate broadcast issued |
| **PRODUCTION 2026-09-19 (owner-declared)** | **Owner decisions recorded** (`docs/OWNER-DECISIONS-2026-09-19.md`): (1) **Gate 6 CLOSED by owner decision** via strongest machine-provable independence — 3 independent re-derivations (B Rust/WASM **64/64** · C **66/66** · on-chain live **66/66**) + **clean-clone determinism 749/749 ×2**; external human review NOT performed NOR claimed. (2) **Production READY — OWNER-DECLARED** (non-prerelease GitHub release) with honest boundaries: no legal/external claims, no pricing published. (3) **Two evidence-stability fixes + proofs**: `.gitattributes -text` for frozen dashboard (CRLF drift on fresh Windows clones — was 71841 vs pinned 70787; now LF), **manifest rebuilt from pristine `core.autocrlf=false` clone → 582/582 == git blobs** at `f31eaae` (commits `a151a59`, `0788cfb`); final HEAD `0788cfb`; `npm test` **749/749** re-proven on fresh clone; CI green; 0/0 sync |
| Verifier version in receipts | `0.1.0` (release boundary locked) |
| Verification levels | L0 · L1 · L2 claimable; L3/L4 exist but **not claimable** (INCONCLUSIVE, `REQUIRED_BY_LEVEL`). Platform-side protocol ladder (independent of receipt verdicts) ships L0 commitment + L1 chain-confirmed receipt + L2 deterministic replay + L3 merkle proof primitives as AVAILABLE, and L4 frozen as **RESEARCH** — see `docs/verification-and-integration-platform-2026-09-26.md` §1 |
| EvidenceRegistryV2 | implemented; `forge build` clean (solc 0.8.24) + `forge test` 14/14 (local pass); mirror suite 12/12 |
| EvidenceRegistryV3 | implemented (`contracts/EvidenceRegistryV3.sol`) — flat `feeWei` commission + treasury; `forge test` 20/20 (part of 34/34); **not deployed** (owner-only decision) |
| Verification-level truth + Trace Availability | implemented (`levelTruth`, `TRACE_AVAILABILITY`, additive receipt fields); suite 9/9 |
| Canonicalization hardening | `securityUint` — no security-critical integer as JS `Number`; hex-spelling preserved |
| Execution Integrity Benchmark | 10,000 generated executions, deterministic (`scripts/benchmark-10k.mjs`) |
| Mutation Laboratory | 1,000 deterministic mutants of one verified execution (`scripts/mutation-lab.mjs`) |
| Phase 1 · `@coreguard/sdk` guard.* surface | `guard.test.js` 14/14 — authorize ALLOW/DENY (six attacks BLOCKED) · verify VERIFIED/INVALID · anchor = `compute-commitment.mjs` parity |
| Phase 1 · Reference Vault ladder | `npm run demo:vault` ALLOW → VERIFIED → anchor PLAN; `npm run demo:attack` **7/7 blocked** (6 PRE + 1 POST) |
| Phase 1 · consumer integration | `create-coreguard-integration` template smoke 3/3 (`test/p1/create-integration.test.js`) |
| Phase 1 · CI exposure | `.github/actions/coreguard-verify` composite action → receipt VERIFIED → `CoreGuard Verification: PASS` (engine job) |
| **v0.5.5 (2026-09-20, this session)** | **Product-expansion pack** — (1) **Actor Identity Card** in `packages/provenance/actor-identity-card.js` (HUMAN/AGENT/BOT/ROBOT/COMPANY + maker/model/version + trust DECLARED→ATTESTED→VERIFIED; human never VERIFIED) wired into `verify-provenance` CLI + `12/12` tests; (2) **`EvidenceRegistryV3.sol`** — flat explicit `feeWei` commission paid atomically with `anchorProof`, `CommissionMismatch` on any mismatch, operator-only `withdrawTreasury`, `feeWei=0` = pure V2 path, domain-separated — `forge test` **34/34** (V2 14 + V3 20); (3) **hypothesis pricing** `packages/pricing/pricing.js` + `docs/pricing.md` (gate-locked, `gated:true`, never bills) with `9/9` tests; (4) **DApp surface** `docs/coreguard-dapp-core.html` (Core gold + CoreGuard green identity); (5) `submission/14-pitch-deck.md` + `submission/15-egypt-patent-file.md`; `npm test` **852/852** (incl. 11 CI-guard tests); pricing stays LOCKED — no committed pricing |
| **v0.5.6 + (2026-09-20, this session)** | **2026 competitive-intelligence wave (all dated/sourced, G-1 addendum)** — `docs/competitive-intelligence-overtake-2026-09-20.md` (matrix + overtake roadmap); prior-art gate updated with the post-2026-09-13 wave: **x401** (Proof, 2026-06-25, authorization-at-request — closest conceptual neighbor; mandatory in any filing), **World ID + AgentKit** (2026-03), **Self Protocol** (2026-04, zk human↔agent on ERC-8004), **Arkose** (behavioral — CoreGuard's opposite philosophy), **IETF web-bot-auth**; `submission/15` disclosure list extended; `submission/14` gains a dated "Market moment" section; new honest CORE-value map `docs/adoption/coreguard-core-value.md` (usage/scarcity/partnerships vs Core's 2026 buyback+agents direction). No novelty claim added — G-1 boundary update only |
| **v0.5.7 (2026-09-20, this session)** | **Full CI red-run closure** — every red run root-caused from logs into 14 classes / 24 runs (`docs/ci-postmortem-2026-09-20.md`): bootstrap-era (no-lockfile at `41ed0b4` = setup-node opaque failure; node18 `--test` glob; WebCrypto absent), zero-jobs YAML trap (6×: 09-11 batch + `6c4ca1d`), lockfile drift (A: 3×), stack-too-deep, mojibake (5×), python-pin Dec-C-9, EIP-1271 verdict, anchored-record + re-pin honesty. **Permanent new guard (closes class H):** lock-sync guard now runs BEFORE `actions/setup-node` in Engine/Demos/DDE, and `check-lock-sync.mjs` names a missing lockfile (`no package-lock.json in repo root`) instead of raw ENOENT + regression test → `npm test` **852/852**; CI+DDE+Pages green at `649114e` |
| **v0.5.8 (2026-09-23, this session)** | **Pages-build race closed + Windows-native delivery tests + facts record** — Pages race root-caused to an EXTERNAL median pusher (`coreguard-trend-bot`, commits land 15–21 s after each content push, proven from committer-date interleaving; identity configured in no local checkout) and closed with 3 layers: `scripts/pages-settle.mjs` settle guard (exit 0/1/2) wired into DDE's trend step (`GH_TOKEN`, defer instead of race) + committed `.githooks/pre-push` (install `git config core.hooksPath .githooks`; gates every `main` push; `PAGES_SETTLE_SKIP=1` emergency bypass; **5/5** contract tests incl. abort-while-building); `test/delivery/convert-zip.test.js` rewritten pure-JS (no system `unzip` — the 2 Windows failures are gone; CI parity) with in-process ZIP verification (EOCD + CD count + local-header walk + CRC-32 recheck); Pages root 404 fixed via `docs/index.html` (Arabic-first, EN mirrored); public-thread replies recorded `docs/elizaos-thread-replies-record-2026-09-23.md` (facts-only; frozen `docs/counterparty-*` untouched); `npm test` **919/919**; forge **34/34**; corpus+benchmark **73/73**; mutation **1000/1000 refused, 0 escaped**; 10k **FA 0 · FR 0**; pricing remains LOCKED |
| **v0.5.10 (2026-09-23, this session)** | **Mapping result received (comment `#18568567`); fixture corrected** — People's Court / Epistemic Labs replied: the read-only pass **supports the narrow mapping** (agreement/criteria versioned; authorization and execution separate; delivery, rejection and both positions without an engine verdict), with one clarification: the REAL anchored transfer (0.001 CORE coupon) must not be readable as settlement of the modeled compensation (0.25 CORE). Correction shipped: `execution-attestation.json` now records `executionCoupon` (REAL settled transfer) + `compensationSettlement.status = NOT_SETTLED` (`settledByExecutionCoupon: false`); the old top-level `paymentSettled: true` is removed (honesty contract in `test/delivery/fixture.test.js` updated); provenance + fixture README aligned; `hashes.json` regenerated. Repro unchanged: hashes 10/10 byte-exact · `EXECUTION_EVIDENCE_ADMISSIBLE — CONFORMITY_UNDECIDED_BY_ENGINE` · adversarial 13/13 · compound 5/5 · fuzz 50 seed 424242 → 0 · B1 PAYMENT_INFERENCE_FORBIDDEN PASS. Not a real bilateral case nor a People's Court endorsement (their words). Owner reply with the new stable anchor + thread record updated. **2026-09-23 16:09:40Z:** counterparty confirms the evidence-labeling issue is resolved (`#18569442`); no endorsement, no chain verification, no verifier run on their side; mapping branch closed by record. **16:35:17Z (owner-directed):** narrow research-invitation follow-up posted (`DC_kwDOMT5cIs4BG1ow`) offering optional technical tracks and inviting the counterparty to choose the next boundary/use case/failure mode — no endorsement assumed, no asks sent |
| **v0.5.11 (2026-09-23, this session)** | **A/B assent paired fixture published (counterparty next-test)** — their new offer recorded (`#18569800`, 16:37:19Z: identical execution+delivery, differing modeled consent, pinned version+hashes, per-field attested permissions, preserve unknowns, bounded read-only critique offered, no commitment); acceptance posted 16:47:03Z (`DC_kwDOMT5cIs4BG1qn`). Pair shipped `assent-pair-v1.0.0` at `1c7223f` (`examples/delivery-fixture/pairs/assent-pair/`): A=ASSENT_PRESENT / B=ASSENT_MISSING with byte-identical execution+delivery, `expected-field-map.json` (permitted attester per field), SHA-256 pins (`pair-hashes.json`, self-excluded), fail-closed verifier 10/10 → `ASSENT_PAIR OK`, `.gitattributes` pins the tree `-text`. Posted to the thread 17:14:04Z (`DC_kwDOMT5cIs4BG1vQ`, dbId 18570192); CI green; `npm test` 927/927. **Awaiting their bounded read-only critique of the evidence labels** — no asks made |
| **v0.5.12 (2026-09-23, this session)** | **Pair critique received (#18570343) + evidence-labeling correction shipped + reply posted** — People's Court / Epistemic Labs read-only review 17:23:37Z: execution+delivery structurally identical across A/B, consent differs as intended, 3 SHA-256 pins match `pair-hashes.json`; did NOT run the verifier, did NOT independently check the chain receipt. Two label ambiguities fixed at `1e75fba` (CI green): **(1)** `consent.modeledAssent` is no longer a boolean — derived tri-state string (A=`FULL`, B=`PARTIAL`), state space + `modeledAssentDerivedFrom` declared, party-level fields authoritative, B's `principalB.assent` stays UNKNOWN; **(2)** `compensationSettlement.status = NOT_SETTLED` removed — replaced by `evidenceStatus = NOT_EVIDENCED_AS_SETTLED` + `actualStatus = UNKNOWN` (absence supports "not evidenced as settled", never verified nonpayment), applied to the canonical fixture + re-pinned `hashes.json` + DDE pages too. Verifier now V10+V11 → **11/11 → `ASSENT_PAIR OK`**; 2 regression tests added; fixture honesty contract + pair README aligned. Reply posted 18:15:37Z (`DC_kwDOMT5cIs4BG164`, dbId 18570936): commit + exact change set only, boundaries unchanged. `npm test` 929 total — 927 pass locally, the two known load-sensitive perf assertions green isolated + CI-authoritative. **No asks made; no new boundaries entered** |
| **v0.5.13 (2026-09-23/24, this session)** | **Round captured as repo assets (no thread posts)** — the critique→correction result became: **EVP/1 standard** (`docs/evidence-package-standard.md` — per-party consent with derived tri-state aggregate, evidence-status/actual-status split, unknowns preserved, pins, determinism); **one-command CLI** `npm run evidence-package -- --out <dir>` (`scripts/make-evidence-package.mjs`: stage→generate→verify 11/11 fail-closed→deliver→re-verify; exit 0 `EVP_OK`/1/2) + contract tests 6/6 incl. byte-parity vs the committed pair and the previously-missing pin-tamper fail-closed test; **case study + X/LinkedIn publish drafts** (`docs/case-study-agent-evidence-labels-2026-09-23.md`, honesty-claused, not published); **pitch deck** updated with the read-only-review evidence row + honesty-box line (no endorsement claim) + suite 929; **outreach draft** Variants A/B (`docs/outreach-draft-people-court-attestation-layer.md`) written but **NOT posted — owner decision: HOLD** (nothing until the counterparty responds). Thread still ends at the 18:15:37Z correction reply; awaiting counterparty response to `1e75fba`. No asks at any point |
| **v0.5.14 (2026-09-24, this session)** | **ADAL/1 agentic dispute + attestation layer shipped end-to-end** — **`ADAL/1` standard** (`docs/dispute-package-standard.md` — evidence-attestation layout, resolved intents, award slot UNKNOWN/NONE, escrow reference-only, adapter integrationStatus NOT_BUILT, hash pins, one-command CLI `npm run dispute-package -- --case A --out <dir>` `make-dispute-package.mjs` exit 0 `DISPUTE_PACKAGE_OK`/1/2); **`packages/peoples-court-adapter`** fail-closed attestation adapter (real `dispute-package.json` + `dispute-hashes.json` intake, deterministic verdicts, integrationStatus honest `NOT_BUILT`; +regression tests incl. intents head-of-line refusals and burn-path SHOW_WITH_CONSENT); **`examples/reference-tribunal`** — named, offline, deterministic SYNTHETIC adjudicator + mock escrow (scenarios A–E all fail-closed; award only when FULL bilateral assent + pins verify; escrow refuses anything not authority-bound) with pure `adjudicate`/`executeSettlement` APIs; **README protocol-ecosystem restructure** (CGEP/1 → EVP/1 → ADAL/1 → Adapters → Reference tribunal → Conformance → SDK/CLI layer map, quickstart chain: evidence-package → dispute-package → peoples-court:prepare); **integration-surface doc** `docs/integration-surface-map-2026-09.md` (structural mapping to public tribunal surfaces incl. x402, always "never another court"); funding/revenue/IP workstream + publish drafts (article/X/LinkedIn) recorded as repo docs, not posted; **docs-node-contract test repaired** (untracked, pre-existing failure: `<out-dir>` doc-scoped for JS-string + shell argv, `examples/reference-tribunal` staged, `forge` skip-listed as non-Node/CI-owned Solidity) → `npm test` **970/970**; 23 new conformance tests; README, `package.json` (`peoples-court:prepare` script) + `package-lock.json` updated; no new boundary entered |
| **v0.5.15 (2026-09-25, this session)** | **Canonical measured state pinned (owner directive: fix the truth before any external campaign)** — `scripts/current-state.mjs` + `docs/state-snapshot.json` = the single machine-measured source for every number (full-suite pass, boundary audit files/violations, harness readiness, docs-node counts, commits ahead of `v0.6.0`); `scripts/run-tests.mjs` enforces the pass total against the snapshot on every green run (**drift = red**), `test/ci/current-state.test.js` re-measures the fast fields (incl. `NODE_TEST_CONTEXT=child` for the nested docs-node run — recursion guard was silently skipping it); **`npm test` → 1022/1022**; boundary audit **767 files (committed-tree scope, CI-reproducible), 0 violations**; docs-node 70 executed · 53 skip-listed · 18 covered; harness `PEOPLES_COURT_HARNESS_READY`; **current-state audit** `docs/current-state-audit-2026-09-25.md` — the nine buckets (production-ready / demo-ready / integration-ready / structural-offline / sellable now / pilotable / pitchable to courts / pitchable to investors / must-NOT-claim) grounded on the snapshot; **court-neutral launch bundle** — `docs/phase-a-people-court-followup-draft-2026-09-25.md` (copy-ready technical message, owner posts manually, no auto-send, no chasing), `docs/master-launch-adoption-plan-v2-2026-09-25.md` (Phase A → B → C, every step owner-gated, honest KPIs only), `docs/phase-b-court-neutral-expansion-2026-09-25.md` (six-track matrix: Internet-Court ecosystem / agentic tribunals / legacy ODR rails / x402-A2A commerce / Core ecosystem / accelerators); AGENTS.md [C28]/[C29] + nested-`node --test` quirk; canonical count re-synced to **767** after the bundle joined the committed tree (snapshot regenerated post-`git add`, citing surfaces refreshed in the same push); 970-era numbers retired from canonical surfaces; no new boundary entered |
| **v0.5.16 (2026-09-25, this session)** | **Adoption mode entered (owner decision) — no more hardening; returns move to external consumption** — strategy captured in `docs/owner-decisions-and-claimable-facts-2026-09.md` §7 (hardening paused; success = independent external consumption of the evidence package, explicitly NOT replies/likes; People's Court is not a gate; Phase A = one short technical message then hold; **no v0.7.x on commit count** — release requires one of four external triggers: external verifier ran the package / first integration pilot / first real adapter consumer / first paid verification-conformance engagement; Monetize language is phase-C: "evidence + verification boundary", never "buy CoreGuard"); **`docs/campaign-ops-outreach-kit-2026-09-25.md`** = the operating doc of the phase (Phase A posting checklist; **six copy-ready Phase B letters** B1 GenLayer/Internet-Court coalition · B2 tribunal/Polycourt/QE-Court · B3 legacy ODR rails · B4 x402/A2A/marketplaces/escrows · B5 Core ecosystem · B6 accelerators/grants — each artifact-first, stable numbers only, no asks, per-track owner gate; one outreach per track then wait; reply taxonomy table; append-only **outreach truth ledger** with Phase A held by owner and B5 `inquire@coredao.org` retained as already-sent); Phase-3 clarification written in plain words in the decisions doc (§4: L1/L2/L3 = the three live integration steps only; **Decision A = scope — which live steps ever authorized, incl. none**, **Decision B = who is the credential-holding integrator**; nothing promised is blocked while pending — surfaces stay DRY-RUN); `npm test` **1022/1022** via run-tests enforcement; boundary audit **768 files (committed tree), 0 violations**; docs-node 70·53·18; snapshot regenerated post-`git add`; since this row = the decision record, publication of any Phase A/B letter requires the ledger gate, never automation |
| **v0.5.17 (2026-09-25, this session)** | **Phase A POSTED + Live Integration & Adoption Ladder implemented, Decision A/B binding** — **Phase A posted** to #21788 as a reply to the counterparty's last (read-only) critique (`#18570343`): comment `DC_kwDOMT5cIs4BG9ep`, dbId 18601897 (15:45:07Z; verified live on the wire — supersedes a phantom record that claimed dbId 18600613, which did not exist on the thread), https://github.com/elizaOS/eliza/discussions/21788#discussioncomment-18601897 — the two label corrections honored as first-class regression-tested fields (tri-state modeled consent; evidenceStatus/actualStatus split) + 1033 (post-time figure) pinned vs snapshot + 0 violations + fresh-clone reproduction across Node 18/20/22; **no asks; hold indefinitely thereafter**. **Adoption ladder shipped + machine-checked**: `scripts/ladder/` — 13-state space, transition state machine with guards (namedIntegrator · ownerApproval · noSettlementAuthority …), adapter registry (3 real: People's Court · Agentic Escrow Arbitration · Reference Tribunal — ALL DRY_RUN / NOT_BUILT / NOT_PERFORMED, structurally unable to claim live), conformance suite **CG-CS/1** (6 criteria; absent-vs-failed verdicts, badge never endorses), deterministic **Evidence Passport** (`docs/integration-registry.json`), **Adoption Dashboard** (`docs/adoption-dashboard.md`; external counters 0 by policy) — `npm run ladder:*`; `docs/live-integration-and-adoption-ladder-2026-09-25.md` (fence-free); `docs/adoption-milestones.json` = `[]` (append-only); **Decision A/B recorded binding** in decisions doc §4 (L1 sandbox-only-when-integrator · L2/L3 pilot-only when a real partner · settlement NEVER · holder = nobody now) + §7-8; README v0.3 row = first-pass surface shipped (reputation/risk-findings stay designed); `npm test` → **1033/1033** (run-tests enforced, +11 ladder tests); boundary audit **780 files (committed tree), 0 violations**; docs-node 70·53·18; snapshot regenerated post-`git add`; citing surfaces refreshed in the same push; no new boundary entered |
| **v0.5.18 (2026-09-25, this session)** | **v0.3 reputation + risk-findings first-pass shipped (owner directive: finish the roadmap end-to-end)** — `scripts/ladder/risk-findings.mjs` (**CG-RF/1**: 8 findings derived from committed sources, statuses OPEN/OK/UNVERIFIED, fail-closed — any live-status adapter flips the settlement finding OPEN and the live-call finding UNVERIFIED; findings only, never a fuzzy safety score) + `scripts/ladder/reputation.mjs` (**CG-RP/1**: reputation = recorded external milestones only, 1 point per entry never the amount, UNPROVEN today with all six external counters 0) + generated `docs/risk-findings.json` + `docs/reputation-registry.json` (deterministic, hash-stable across number changes) + `test/integrations/ladder-v03.test.mjs` (+10 deterministic + adversarial tests) + dashboard section `## Risk findings & reputation (CG-RF/1 · CG-RP/1)` reading the two new registries (dashboard now reads five committed sources) + ladder doc §10 (fence-free) + README v0.3 row = first-pass shipped; `npm test` → **1043/1043** (run-tests enforced); boundary audit **785 files (committed tree), 0 violations**; docs-node 70·53·18; commits ahead of v0.6.0 = **83** (snapshot canonical, was 77); snapshot regenerated post-`git add`; citing surfaces refreshed in the same push |
| **v0.5.19 (2026-09-26, this session)** | **Continuous Build + Adoption — Verification & Integration Platform shipped (owner directive: never wait for an external milestone; build and adoption in parallel)** — **L0–L4 machine** `scripts/ladder/verification-levels.mjs` (CGEP/1; deterministic commitment; **L1 now requires a chain authority** — a format-valid receipt without confirmation is `UNKNOWN/NO_CHAIN_EVIDENCE` and a contradicting chain is `MISMATCH`, structure alone never VERIFIED; L2 replay MATCH/MISMATCH/UNKNOWN, no partial→MATCH; L3 real sha-256 merkle proofs; L4 interface frozen **RESEARCH**) + **integration machine** `scripts/ladder/integration-states.mjs` (13 doorway states × entry/exit/evidence/verification-command/failure/unknown/audit; `evaluateIntegration` deterministic records; `transitionVerdict` REJECTED on any unauthorized jump — no silent pass; UNKNOWN ≠ FAILED ≠ VERIFIED binding) + **adapter contract** `packages/adapters/contract.mjs` (six-method surface; `execute()` in DRY_RUN returns `NOT_PERFORMED`; `verify()` UNKNOWN; `status()` without credentials UNKNOWN/NOT_BUILT/`NO_CREDENTIALS`) + `packages/adapters/providers.mjs` (4 surfaces: People's Court · Reference Tribunal · Agentic Escrow · x402 — all DRY_RUN, contract-conformant) + **Partner Sandbox** `npm run partner:sandbox` (8 offline scenarios on a mock chain that knows one mined tx: happy VERIFIED · tampered MISMATCH · missing-evidence/partial-consent/unknown-settlement UNKNOWN · replay-mismatch MISMATCH · expired/duplicate REJECTED) + **Attack Lab** `npm run attack-lab` (10 tamper cases, 6→FAIL 4→UNKNOWN, valid control VERIFIED, exit 1 on any miss) + **Observability** `scripts/observability.mjs` (10 events, correlationId/caseId/commitmentId/adapterId/level, memory by default) + **Evidence Passport v2** `npm run passport:v2` → `docs/evidence-passport-v2.json` (deterministic, hash-stable, receipts/proofs `[]`, unknowns explicit) + **reputation milestone taxonomy** (internal kinds TESTS_PASSING/CONFORMANCE_PASS/REPLAY_VERIFIED recorded as evidence **never score**; external kinds EXTERNAL_VERIFIER/SANDBOX_INTEGRATION/LIVE_RECEIPT/PRODUCTION_INTEGRATION/MULTI_PARTNER/COMMERCIAL_USAGE raise it, 1 point each never the amount) + **Control Plane** block in the dashboard (5 verification rows · 4 integration rows · commercial `$0` / `0 verified` / `0 verified`, no percentage ever) + `docs/verification-and-integration-platform-2026-09-26.md` (fence-free map + DoD + KPI funnel) + `test/integrations/verification-platform.test.mjs` (+18 tests); `npm test` → **1061/1061** (run-tests enforced); boundary audit **796 files (committed tree), 0 violations**; docs-node 70·53·18; reputation stays `UNPROVEN`/0, external counters all 0 — no adoption, partner, or revenue number invented |
| **v0.5.20 (2026-09-26, this session)** | **Commercial surfaces built instead of reworded — the two prose-only roadmap rows are now real code** — the platform cycle claimed "webhook AVAILABLE" in the control plane and pointed the X402 provider row at `packages/x402`, and **neither surface existed**: the claim was held up by a sentence, not a module. Fixed at the root instead of in the wording. **(1) `packages/webhook` = CG-WH/1 receiver** (`npm run webhook`): domain-separated HMAC-SHA256 over the exact body bytes plus a sender timestamp, constant-time compare, a replay window that rejects stale AND future-dated deliveries (clock skew is not a replay allowance), and a mandatory `Idempotency-Key` whose redelivery returns the FIRST outcome without re-running the handler; DRY_RUN authenticates then reports `NOT_PERFORMED`, a throwing handler yields `UNKNOWN`, and there is **no keyless mode and no built-in side effect** (the constructor throws without a secret, and LIVE without an `onDelivery`). **(2) `packages/x402` = X402/1 harness** (`npm run x402`): a deterministic canonical 402 challenge whose id is a function of the canonical bytes, signed only with an integrator-injected secret; the admission gate is the feature — no quote, a **zero** quote, and a price the owner has not locked are all `GATED`, an unlocked price is `priceStatus: HYPOTHESIS`, a challenge cannot be signed without a secret, a forged envelope is rejected **before** the settler runs, a settler that names no settlement is `UNKNOWN`, and `settle()` in DRY_RUN books **0 cents** with no code path that increments revenue. **(3) `docs/conformance-report.json` = CG-CR/1** (`npm run conformance:report`): the six CG-CS/1 criteria, the badge contract (`neverMeans`), and `badgeIssuerCount: 0` because no integration has run the suite; deliberately **timestamp-free** so the artifact never churns a diff. **(4) `examples/platform-quickstart/`** (`npm run quickstart`): the three-verb integrator path (commit / capture / verify) running offline in a clean clone, exiting non-zero if any honesty line is wrong. **(5) `docs/commercial-packaging-2026-09-26.md`**: five tiers with delivered-vs-gated per tier, prices **LOCKED**, revenue `$0`, and a test that fails the build if the doc names a file that does not exist or any `$0` amount other than `$0`. `test/integrations/platform-surfaces.test.mjs` (+34) locks all of it, including byte-parity between the committed CG-CR/1 and the machine build. The docs-node contract had to stage the new example tree (its sandbox stages by explicit list) and now **executes 81** documented commands. `npm test` → **1095/1095** (run-tests enforced, +34 tests over the previous cycle); boundary audit **803 files (committed tree), 0 violations**; docs-node **81 · 53 · 18**; snapshot regenerated post-`git add`; the dashboard's webhook row now names CG-WH/1 instead of a wire-proven claim; README v0.3.2 row + commercial quickstart commands. Two honesty defects found and fixed in the same push: a bulk number-sync regex that ate a JSON key quote in a GENERATED artifact (never bulk-edit generated files — regenerate them), and a `$0` sequence inside a JS string-replacement that String.replace read as a backreference (insert with a function replacer) |

| **v0.5.21 (2026-09-26, this session)** | **A–J closed with four honest-default decisions, and the release gate caught the gate** — the roadmap's remaining rows were prose: a claim ceiling nobody could audit, a badge nobody could verify, a partner journey nobody could replay, and a release gate that had never been run. Each is now a module, and each ships at its honest default. **(1) CG-CL/1 claim registry** (`npm run claims`): 28 claims derived from committed sources, six statuses, `UNKNOWN` allowed without evidence but `VERIFIED` never — 11 of 28 depend on an external outcome and sit at `GATED`/`UNKNOWN`/`NOT_PERFORMED`; the audit result travels *inside* the artifact so a reader of the committed file can see it was checked. **(2) CG-BDG/1 badge system** (`npm run badge:verify`): the artwork is the proof — `verifyBadge()` re-derives every digest from its record and compares byte for byte, so a single hand-edit is caught; `brand` is non-enumerable, so a specimen cannot be copied into an issued badge; two specimens ship (6/6 and 2/6) and `issuerCount` is 0. **(3) CG-PJ/1 partner journey** (`npm run partner:journey`): ten legs over one bundle; a clean run is `MATCH`, never `VERIFIED`, because L2 is the weakest link and inflating it would inflate the evidence. **(4) CG-RG/1 release gate** (`npm run release:gate`): 18 legs, and its own source is audited for network, credentials, and external-outcome dependencies on every invocation. **The gate then found four defects in itself, which is the part worth recording.** (a) *Five legs reported `Command failed` with zero output* — `npm.cmd` is a batch shim modern Node refuses to spawn without a shell, so `spawnSync` returned a null status and no error; the child now resolves npm's real JS entry and prints any spawn error. (b) *Four legs reported PASS on an empty denominator* — the counter read `c.pass` while the packages use `[name, boolean]` tuples, so webhook printed `0/8 invariants` **and passed**; cases are now tallied by an explicit shape reader and an unreadable case is a FAILURE. (c) *Three legs passed as "module loaded"* — proving nothing at all; a module that exposes no self-check now FAILs, and pure libraries are proven by naming the committed tests that import them. (d) *The gate's own audit matched its own regex* — the banned credential pattern written as a contiguous literal matches the line defining it, so the gate failed itself forever; the pattern is assembled from fragments. Rule: **a gate that can report green with no assertion behind it is worse than no gate, because it gets trusted** — all four classes are now locked by tests. Also this session: `docs/owner-decisions…` §9 rewritten from "sign-off still required" to the three decisions *closed as held* (prices LOCKED · named integrator NONE · badge NOT ISSUED), with `CL-BUILD-ADOPTION-INDEPENDENT` mechanically failing the build if any of the three is ever marked `VERIFIED` while held; the control plane now reads the claim ceiling, the badge registry, and the committed gate verdict as committed sources; `docs/badge-system-2026-09-26.md` (Arabic-first + English mirror) documents what a badge never means. `npm test` → **1153/1153** (run-tests enforced, +58 over the previous cycle); boundary audit **817 files (committed tree), 0 violations**; release gate **18/18 legs, independence PASS**; docs-node **81 · 53 · 18**. One honesty defect caught in the act of shipping: a blanket number-sync `1095 → 1148` replace also rewrote the **v0.5.20 changelog row**, which would have made a past release report a test count it never measured — history is the one thing a sync script must never touch |

| **v0.5.22 (2026-09-26, this session)** | **The follow-up pass: every remaining stale number, and the gate's self-audit in CI** — shipping A–J left four surfaces still pointing at older measurements, which is the exact failure mode the snapshot exists to prevent, and one real gap: nothing ran the release gate on a push. **(1) Five stale figures found and corrected**: `docs/STATUS.md` §current-state still read `1148/1148` (the earlier sync pass matched `1148/1148` but not the spaced `1148 / 1148` form, so it sailed through); `docs/owner-decisions… §1 still claimed `1061 pass` and `796 files`; `docs/phase-b-court-neutral-expansion… still claimed `1061`; and `AGENTS.md` still carried the ancient `919 ↔ 16 ↔ 919 ↔ 649` reviewer-packet line that its own "Files That Change Together" rule says tracks the latest measured count. Every one of them now reads from the snapshot. **(2) The gate now runs its own audit in CI** — `npm run release:gate:independence` is a step in the CI engine job, so the check that the gate reaches no network, no credential, and no external outcome happens on **every push**, not only when someone remembers to run it. The full 18-leg gate is deliberately not in CI: its `tests` leg re-runs the suite CI already runs, so adding it would double a ~9-minute job to prove nothing new. **(3) README gained a "Claim ceiling, badges & the release gate" section** with the seven honesty commands and the four rules the machine enforces — because the reviewer's first document was the one place the A–J surfaces were still invisible. **(4) `docs/verification-and-integration-platform-2026-09-26.md` §15** documents all five honesty surfaces (CG-CL/1, CG-BDG/1, CG-PJ/1, CG-IR/1, CG-RG/1) with their artifacts, so the canonical map no longer stops at §12 and leaves the gate undocumented. **The freeze record was checked and needed no re-pin**: `README.md` in `freeze-record-4.2.6.json` resolves to the *platform* README (record paths are relative to the record's own directory), and none of the 49 pins — including the three pinned bilingual dashboards — is a file this cycle touched; `validate-freeze` still reports **49/49 MATCH**. Docs-node rose **81 → 94 executed** with 19 docs covered (the new README commands plus `docs/badge-system-2026-09-26.md`), and the count moved with the snapshot in the same push, which is the whole point of the pin. `npm test` → **1153/1153** (unchanged: no test added this cycle); boundary audit **817 files, 0 violations**; docs-node **94 · 53 · 19**; release gate **18/18, independence PASS**. The v0.5.21 row is left reporting `81 · 53 · 18` on purpose — that is what `823cd72` actually measured, and a changelog row is a historical fact, not a live counter |


| **v0.5.23 (2026-09-26, this session)** | **The cycle's own regression: a documented command is an EXECUTED command** — v0.5.22 shipped the A→J commands in the README and went green on five of six workflows; the sixth, Node 18, came back `SIGTERM` after 8m25s with **no assertion, no test name and no output in the log**. Cause: the docs-node contract EXECUTES every documented command, and the new README block listed `npm run release:gate` — whose `tests` leg **is** `npm test`, which is the suite the contract itself lives inside. So documenting the gate made the contract spawn a nested full suite that re-entered the contract, recursively, until the runner was killed. **A timeout is the worst shape this can take**: `tests` leg `npm test` · no failing assertion · only an exit code, and exit-code-only triage on a killed process points at nothing. **(1) The fix is a SKIP entry with a named reason** — the gate is owned by the CI Engine leg's `release:gate:independence` step (v0.5.22) and by `pre-push-check.mjs`, and `npm run release:gate:independence` stays in the executed set because it is fast and self-contained. **(2) Two guards, because the obvious one is wrong twice over.** First, *body-only detection is vacuous*: `release:gate`'s package.json body is `node scripts/release-gate.mjs`, which names no test command at all — the `tests` leg is a string INSIDE that module, so a body-only heuristic classifies the bomb safe and the guard passes on it. The indirect half is now DECLARED and separately asserted to really reach the suite, so the declaration cannot rot into naming something harmless. Second, *mention is not invocation*: classifying a script by searching its whole source for `npm test` flags `claims`, `claims:audit`, `publish:check` and `integration:states` — all of which merely MENTION the suite in a comment or a usage string. A guard that cries wolf on safe commands gets ignored, and then ignored for the real one, so the mechanical half reads only package.json bodies and a test pins those four as NOT runners. **(3) The guard then failed a third way, and only the negative control found it** — it read files without normalizing CRLF, so `extractBashFences` (which matches a `bash` + newline) saw ZERO fences in every CRLF-checked-out file. The guard was therefore green on the bomb in this Windows checkout and would have fired on Linux CI — a check whose behaviour depends on the checkout's line endings is [C3] in miniature. **The rule now written into AGENTS.md as [C31]: a guard is proven by removing the thing it guards, not by passing.** All three defects presented as a green guard; every one surfaced from deleting the SKIP entry and expecting red, then auditing which scripts the classifier actually flagged. Docs-node moves **94 → 93 executed · 53 → 54 skip-listed** ('gate' to the skip table, 2 guard tests added), and the v0.5.22 row keeps its 94/53/19 because that is what `83f851e` measured. `npm test` → **1155/1155** (+2 guard tests); boundary audit **817 files, 0 violations**; release gate **18/18, independence PASS**; prepush **6/6**. The honest reading of this cycle: the A→J work was correct and the *documentation* of it broke CI, which is the mirror image of the lesson the roadmap was built to teach — a claim is only worth what the machine can re-check, and a documented command is a claim the machine will now execute. |
| **v0.5.24 (2026-09-26, this session)** | **Three real defects found by auditing instead of assuming, and the reviewer's first document finally machine-checked** — the roadmap was closed and the suite green, so this pass stopped adding surfaces and went looking for what was still wrong. Three things were. **(1) The partner journey contradicted the committed artifact.** CG-PJ/1's findings leg reported **7 OPEN** while `docs/risk-findings.json` said **4**: the leg called `deriveFindings({ registry })`, and that function takes every committed source as an INPUT and defaults a missing one to `{}` — the absent snapshot silently collapsed RF-006/007/008 (boundary audit, suite pin, docs-node/harness) to OPEN. The module's own `build()` reads all three committed sources exactly as the CLI does; the leg now goes through it. Worth naming what the bug did: it overstated risk, which is the safe direction, and it was still a defect — a reviewer-facing number may not disagree with the recorded one in either direction. Nothing caught it: the artifact is pinned to `build()` by `ladder-v03`, but the journey was never pinned to the artifact, which is the gap a per-file invariant always leaves. **(2) `docs/STATUS.md` had ZERO machine checks.** It calls itself the authoritative source of truth, states that every metric in it is machine-measured, and is the first document a reviewer opens — and all thirteen of its rows were tests and contracts, with the entire claim/badge/gate layer absent. It now carries ten honesty rows (boundary audit · docs-node · CG-CL/1 · CG-BDG/1 · CG-PJ/1 · CG-IR/1 · CG-RF/1 · CG-RP/1 · CG-RG/1 · CG-CR/1), each reading its value from the committed artifact. **(3) The decisions record numbered its sections 1,2,3,4,5,6,7,9,8** — → fixed by moving the '9' block into place, with no renumbering, so every existing '§9' citation stays valid. **The guard for (2) failed three times before it worked, which is the real content of this row.** The first draft asserted `table.includes(String(claims.length))` and could not fail: "28" occurs incidentally in that table and "0" occurs in half of it, so corrupting the claims total to 27 or revenue to $4,200 stayed green; the changelog guard failed identically, because the document still CONTAINED "v0.5.22" in the next row's prose after the row itself was deleted. **A substring is not a location.** Each measurement is now bound to the row whose label names it, that row must state the artifact's value, and exactly one such row may exist so a stale duplicate cannot hide beside a fresh one. Twelve negative controls · corrupt a count, delete a row, duplicate a row, cite a fictional npm script, plant a non-$0 figure, drop a changelog row — now each turn the suite red, and the battery prints "mutation applied" separately from "bit" because a control whose mutation never landed is as worthless as a guard that cannot fail. Two of the twelve did not bite on the first run. The row-scoped rewrite then caught a real omission in the row I had just written (the gate row omitted its 18 self-audited legs) **on its first execution** — the guard found the author's error, not only a future regression. Filed as AGENTS.md [C32], the third face of [C30]/[C31]. `npm test` → **1162/1162** (+6: 5 STATUS-truth, 1 journey/artifact agreement, the latter proven by reverting the fix and watching it report `actual: 7, expected: 4`); boundary audit **818 files, 0 violations**; docs-node **93 · 54 · 19**; release gate **18/18, independence PASS**; prepush **6/6**. The v0.5.21·v0.5.23 rows keep 1153/1155 and their own docs-node figures — they record what each commit measured, and the new test enforces that exemption by requiring each to survive as a ROW rather than as a prose mention. |
| **v0.5.25 (2026-09-26, this session)** | **Two things the tree was owed: a lost branch in the L1 rule, and the AIE-1 incident surface, finished** — **(1) The L1 chain rule was TRUE and INCOMPLETE in all four places it is stated.** The machine has three outcomes · no authority `UNKNOWN/NO_CHAIN_EVIDENCE` · authority asked and does not know the hash `MISMATCH/TX_NOT_FOUND` · evidence too malformed to ask with `UNKNOWN/EVIDENCE_INCONSISTENT` — and every reviewer-facing surface compressed that to two ("a format-valid receipt nobody confirmed is `UNKNOWN`", under a README heading that reads "four rules **the machine enforces, not the prose**"). Every compressed version was true, which is exactly why it survived review: the branch it dropped is `MISMATCH`, the strongest signal the system produces, so the summary filed a real contradiction under its weakest verdict. The rule now hinges on the only question that actually separates them — **was anyone asked** — in `README.md`, §1 and §14 rule 2 and §15.4 of the platform doc, §3 of the decisions record, and the L0-L4 bullet. `test/ci/receipt-semantics-doc.test.js` derives the three codes from `verifyReceipt()` at run time, so the binding is to behaviour and not to a copy of the prose. Its 6 negative controls include a CODE-side mutation (flip the asked-and-contradicted return to `UNKNOWN`), because a doc binding that only reads docs cannot tell a correct rule from a stale one. Filed as AGENTS.md [C33]. **(2) AIE-1, the agent-incident verification surface, was mid-flight in the tree** and is now closed: `docs/agent-incident-evidence.md` (one endpoint, one evidence bundle, one report schema, replayable from a cold clone) with `test/delivery/agent-incident-evidence.test.js` (+4 · the spec's fences are registered in the doc-curl contract, its quoted verdicts match the live engine byte-for-byte, replay is byte-identical across two runs, and a tamper replay names the flipped byte), cross-linked from `INTEGRATION.md`, `docs/delivery-dispute-boundary.md` and the Arabic/EN `docs/index.html`. Two housekeeping defects were also closed with it: 9 `.tmp-aie-*` scratch dumps (a fixture, two `.b64` payloads, a server log) had been swept into the index by a bulk `git add -A` and are now untracked behind a `.tmp-*` ignore rule — a scratch output is not a deliverable — and the docs-node triple moved 93·54·19 → 94·55·20 as the new doc's commands execute. **One process note worth keeping**: mid-cycle the release gate recorded a legitimate `GATE_FAIL` (its `tests` leg was red on snapshot drift), and that record then deadlocked the suite — the gate's `tests` leg runs `npm test`, which asserts the table states what the artifact says, so a failing artifact keeps its own suite red. It is broken the honest way — restore the last real record, get the suite green, then re-run the gate for a fresh one — and the re-run reproduced the committed bytes exactly, which is the timestamp-free contract doing its job. `npm test` → **1171/1171** (+9: 5 receipt-semantics, 4 AIE-1); boundary audit **821 files, 0 violations**; docs-node **94 · 55 · 20**; release gate **18/18, independence PASS**; prepush **6/6**. v0.5.21·v0.5.24 rows keep their own counts — they record what each commit measured |
| **v0.5.26 (2026-09-27, this session)** | **A documented freeze gap that was not a gap: the recovery pointer existed, and nothing read it** — AGENTS.md carried a standing warning that deleting a doc pinned by an older freeze record makes that record "unverifiable for those entries", and flagged the whole thing as an open known gap. Both halves were wrong, and the second was wrong in the interesting direction: the two files `freeze-record-4.2.5.json` pins (`v4.2.5-closure/engine-semantics-contract.md`, `external-evidence-model.md`) **were already deleted**, in `5a89f2b` — the very commit that introduced 4.2.6 — yet both recorded SHA-256 values still match the blobs at `5a89f2b~1`. A pinned file's bytes stay verifiable from history whatever happens to the working tree; deletion costs only *tree-reachability*. The genuine risk is the silent one: bytes reachable only through a ref nobody wrote down. A survey of all 136 pins across 5 records put the real number on the table — **134 in the current tree, 2 absent but hash-verifiable, 0 unverifiable** — and the audit script first reported those 2 as dead because it handed `git show` Windows backslashes out of `path.join`, a failure that reads exactly like a missing file. 4.2.6's `scopeGapsClosed` now names both files and the recovery ref, without touching `frozenAtUtc` or a single pin (49/49 still verify), and `test/verifier-c/freeze-record-reachability.test.mjs` turns that note into a contract: every pin in every record is either in the tree or hash-verifiable from a **named** ref, and any pin absent from the tree must be documented in the active record. `scopeGapsClosed` had **no reader at all** until this change, so the note was previously worth nothing. 5 negative controls (delete a file the active record pins · drop the note · point it at a wrong ref · shrink a pin · corrupt a recorded hash) each turn the suite red, and the control harness now restores every mutated file byte-for-byte — after a first draft ran `git checkout -- .` and silently destroyed the uncommitted record edit. Two stale literals fixed in passing: AGENTS.md's own `47 = 28+19` (real: 49 = 30+19) and `1176`, plus the `46/46` frozen into `validate-freeze.test.mjs`'s header table while its assertions were already deriving the count — documentation that lies right beside a check that cannot. Measured: **1180/1180** · **833 files · 0 violations** · docs-node 94/55/20. |
| **v0.5.27 (2026-09-27, this session)** | **A number I fixed by hand was still an unguarded number — and one of them guarded nothing at all** — v0.5.26 hand-corrected two literals in `AGENTS.md` (`1176`→1187-class drift, and `47 = 28+19` → the record's real `49 = 30+19`) and left them exactly as rot-prone as before. That is the [C32] lesson applied to the file that teaches it: the fix was to the value, not to the class. `test/ci/agents-numbers.test.js` now **derives** each live figure in AGENTS.md from the one committed source that owns it and requires it inside the single line whose label names it — engine version ↔ scenario count ↔ test count ↔ validator checks (from `freeze-record-4.2.6.json` + `negative-tests.json` + `state-snapshot.json`, `649` parsed out of the record's own `cycleEvidence.nodeValidator` rather than retyped), the pin count and its release/quarantine split, the SelfTest count (counted from `selftest.tap`'s `ok ` lines, not read from prose), and the payout i18n dictionary size. Two of these had **already rotted** (`919⇄6⇄` and `47 = 28+19`), so this is the second measured instance, not a hypothetical. It also cross-checks the record's own `cycleEvidence` against the artifacts, so the reviewer-facing claim cannot outrun the bytes. **14 negative controls, each red**, and they cover both directions: the doc rotting (`NC1`-`NC5`: stale count, stale split, a chain trimmed to 2 of 4 values, a **duplicate line** planted beside the fresh one, an anchor renamed away) and the *source* rotting so the doc becomes the liar (`NC6`-`NC10`: snapshot count, engine version, a dropped quarantine pin, a record claiming 24 self-test checks against 21 `ok ` lines, 19 scenarios against 16). The last two (`NC11`, `NC12`) delete the array key and every `ok ` line to prove the guard **refuses to derive 0** rather than asserting a confident false number — the [C30] zero-denominator trap, caught live during this build when a wrong key name made the first draft try to state `0` scenarios. **Separately, a cited invariant turned out not to exist:** AGENTS.md told two sessions that a hand-edit "silently breaks the 637/637 node pairing". Nothing in the tree derives or checks 637; the only enforced pairing is `test/p2/governance-dashboard-i18n.test.js` over the `PAYOUT_GATE_I18N` dictionary (**11 keys**), while the full `coreguard-gate41-visual.html` / `-en.html` pair is **unverified by machine** — the AR file carries 278 `data-i18n` attributes and the EN sister carries zero, holding literal English, so no dictionary exists to pair. Both citations are corrected and that pair is now labelled unguarded rather than falsely guaranteed. Measured: **1187/1187** · **834 files · 0 violations** · docs-node 94/55/20. |
| **v0.5.28 (2026-09-27, this session)** | **"Unguarded" is a finding, not an excuse: the real invariant existed and was 277 keys wide** — v0.5.27 corrected AGENTS.md's dead `637/637` pairing claim and labelled the AR/EN dashboard pair **unverified by machine**. That was the honest reading, and stopping there would have repeated the mistake the repo already documents: *"The fix here was to BUILD the surface — not to reword the claim."* Probing the page found the invariant it actually ships with. `docs/coreguard-gate41-visual.html` has **one runtime dictionary**, `D = {"nodes": {"<id>": {ar, en}}, "attrs": …}`, and `apply()` iterates it replacing `[data-i18n="<id>"]` `.innerHTML` — so the contract is a **bijection**, and it holds perfectly: **277 static markup keys ↔ 277 entries, 0 missing, 0 orphan**. Two candidate defects turned out to be **correct behavior**, and the temptation to "fix" either would have damaged a live investor-facing page. Entries 84/93/104 carry an `.ar` with no Arabic because they are the bare RTL arrows `←`/`→` — flipping the glyph is the point. And **29** entries embed a *nested* `data-i18n` inside their own `.ar` value; the outer entry replaces `innerHTML` wholesale so the inner attribute is redundant and order-dependent, yet every inner key also appears in static markup (the bijection proves it), so nothing is orphaned and rendering is correct. `test/p2/gate41-visual-i18n.test.js` therefore pins the **29 as a count, not as zero** — changing it must be a deliberate act, not an edit that lands unnoticed. Per [C27] it also asserts the **mechanism**, not just the data: `apply()` must still iterate `D.nodes` and still select by the iterated key, because the dictionary can be flawless while the switcher no longer reads it. **9 negative controls, and one of them caught a hole in this very contract**: pasting a whole English sentence into the `.ar` slot did **not** fail, because the first "language-neutral" rule allowed letters, spaces and punctuation — i.e. any ASCII. The rule is now **no WORD** (two consecutive ASCII letters), which catches an untranslated English string while still passing the bare arrows. A guard that cannot fail is not a guard ([C32]); the control is what turned this one real. **Left explicitly unguarded, and labelled as such:** the EN sister `coreguard-gate41-visual-en.html` carries 0 `data-i18n` attributes and no dictionary (literal English), so nothing cross-checks that it says the same thing as the AR dictionary's `en` values. Measured: **1193/1193** · **835 files · 0 violations** · docs-node 94/55/20 · freeze 49/49. |
| **v0.5.34 (2026-10-22, this session)** | **A load number that cannot be faked by a sequential loop** — `scripts/benchmark-dde-load.mjs` (`npm run benchmark:dde-load`) keeps **50 requests outstanding** against `POST /verify` until 200 have completed and reports the latency distribution of that burst, because the sequential wire benchmark measures the friendly case (one request, no sharing of the event loop, the socket pool or the JSON parser). The gate fails closed on four measured facts, not on prose: every response must be `200 VERIFIED` with the decision intact (perf is measured on the real gate), the observed peak in flight must equal the requested depth, **Σ latency / wall time must be ≥ 2** — a `for … await` rewrite reports overlap ≈ 1 no matter how fast the server is, so a sequential loop cannot wear the concurrent label — and p95 must stay under its budget. `--concurrency 1` is refused by name rather than accepted as a load run. Measured on the dev box: **200/200 VERIFIED · peak 50/50 · overlap 48x · 729.8 req/s · median 64.1 ms · p95 93.0 ms** (p99 97.8 · max 98.8) in 274 ms wall time, against the sequential runner's p95 of ~2.4–3.2 ms: the delta is queueing on one shared event loop, which is the number an integrating platform actually experiences under a batch, and the report says so. The first live run failed honestly — 50 × 429 — because the warmup burst shares the fixed window with the measured burst and the granted limiter ceiling had not included it; the limiter is a REAL guard, so it is sized for the run and disclosed in the report (`250 req / 60s`) instead of disabled, and a contract test fails any run whose budget does not cover warmup + burst. `test/delivery/load-runner.test.js` (+5) spawns the runner for a 6-way burst and checks the distribution monotonicity, the sequential refusal, the p95 gate biting at `--p95-budget-ms 0`, and the shipped 50-way default. Not wired into `dde.yml`: a load burst on a shared 2-core runner would report runner contention as product latency — it stays an operator command with the honest local measurement above. `npm test` → **1292/1292**; boundary audit **883 files, 0 violations**; docs-node **94 · 56 · 20** |
 **The job-economy cycle leaves the runner too — a LIVE playground on the real engine bytes, and the browser found what the tests could not** — `docs/PLAYGROUND.html` runs the whole argument in the reader's tab: open a job with a ceiling, lock the escrow at publish, carve sub-agent shares out of the true remainder, meter a model call on the SAME ceiling, race two reserves in one synchronous step, build and sign an x402 challenge only after the cost is reserved, then deliver and watch what ACCEPTED/REJECTED/UNKNOWN do to the money. The engine is not a re-authoring: `scripts/build-playground.mjs` copies the committed `packages/` bytes into `docs/playground/` and makes exactly three mechanical edits (the `node:crypto` import becomes a synchronous pure-JS sha256/hmac shim, package-relative imports flatten, the CLI entry guard is prefixed with `typeof process !== "undefined"`), each one documented in the page footer and in the manifest. `test/delivery/playground-page.test.js` (+16) proves the claim instead of asserting it: the engine copies and the real modules are driven through the SAME scripted run for all three verdicts and compared state-by-state, code-by-code and snapshot-by-snapshot; the x402 gate loop must produce the same HMAC bytes on the shim (refuse-before-sign, `CHALLENGE_ALREADY_RESERVED`, DRY-RUN releases, `settledCents` 0); the shim must match `node:crypto` on the FIPS vectors and edge lengths; `build-playground --check` must find the tree in sync; and the negative battery has 4 page mutations plus an engine-byte tamper that all apply AND bite by name. Run LIVE in a real browser before push, it immediately exposed three defects the green suite could not see: the engine modules threw `ReferenceError: process is not defined` at import (the CLI tail), a scope row rendered `undefined¢ held` (a table cell reading a job-level field), and an honest UNKNOWN wore the failure × glyph. All three are fixed, and the page now shows `held 500¢` after an UNKNOWN delivery in the browser. The public discussion's own boundary is restated in the footer: per-call payments solve the plumbing, "was the work good" stays a judgment question, and UNKNOWN keeps the money HELD — locked, recorded, neither paid nor refunded. `npm test` → **1287/1287**; boundary audit **881 files, 0 violations**; docs-node **94 · 56 · 20** |
 **The perf page leaves the runner too — a LIVE surface, not a static claim** — `docs/DDE-PERF.html` renders what CI actually measured: the latest successful `dde.yml` run and its `dde-runner-reports` artifact from the public API (no token, no clone), the medians/budgets/gates from the committed `benchmarks/perf-history.jsonl` via raw.githubusercontent, and the budgets themselves DERIVED at render time from the trend module's badge table (raw fetch + parse — no retyped budget number on the page; retyped numbers rot, the page renders the module's truth). Three feed chips that go red BY NAME when a feed dies (the page never shows silence, nor an old number wearing a live name), bilingual AR/EN with the repo's switcher pattern, sparklines with the budget drawn as a dashed line, committed `docs/badges/perf-*.svg`, and the artifacts table with the 30-day expiry column. `test/delivery/dde-perf-page.test.js` (+6) executes the page's own JS headlessly in a VM (parseBudgets/latestBySeries/sparkline against the real module bytes and recorded history lines) instead of restating it ([C25]), binds the artifact name to dde.yml's actual uploader, pins the index.html card, and carries 4 page-mutation + 1 module-bump applied-and-bites controls. One honesty defect caught in preview before push: the page handed PARSED objects to a lines-expecting function (`372 entries · 0 series` while trend cards rendered) — the same function worked in the contract because the contract passed the right shape, which is the [C27] two-channel trap in miniature; fixed in the page, the contract now pins the real flow. Found live in the browser (run #188, 737-byte artifact, 3 sparklines) before CI ever saw it. `npm test` → **1271/1271** (+19 job-economy flow battery, +1 committed-bind) ; boundary audit **867 files, 0 violations**; docs-node **94 · 56 · 20** |
| **v0.5.35 (2026-10-23, this session)** | **The concurrency tail joins the sequential median on the live perf page — same code, two depths, and the gap named queueing, not regression** — v0.5.34 shipped the load runner, but its p95 had no reader: the perf page showed only the sequential medians, so a reader opening the live surface would never see the number an integrating platform actually experiences under a batch, and the delta between the two numbers carried no framing — the two most plausible readings are "engine regressed" (wrong) and "nothing changed" (also wrong). **(1) One metric per series, declared at the source.** `benchmark-trend.mjs` now names each series' tracked metric explicitly in its badge table (the always-on three stay `median`; the load row declares `metric: "p95"` + `budget: 600` + `nightly: true`) and every consumer reads that one declaration: the drift gate now gates the tracked metric (the 2× bar bites on the p95 tail, not on the sequential median, which is exactly the failure mode that matters under concurrency), badges render the tracked value, and the appended history row carries `metric: "p95"` **only when non-default** — an explicit metric on a median series is redundant, a p95 series must say so in its own row. The nightly flag also fixes a badge-mode edge the three always-on series never hit: an absent load history is a **notice and exit 0** (the three badges keep regenerating), never a stale-badge refusal against depth that has not recorded its first point yet. **(2) The page derives the pair instead of retyping it**: `parseBudgets()` now captures the declared metric per row, and `pickPair()` picks the concurrent side as "the row the module declares with metric p95" and the sequential sibling as "the largest-budget median-series row" — no series name appears on the page twice, so a module change moves the page in the same push ([C25] applied to the pairing, not only the numbers). `budgetCard`/`trendCard` track each series' declared metric; the pair card renders **sequential median → p95 under concurrency** with the queueing framing in AR and EN, and an unrecorded load point renders an honest "not yet" note — never a zero and never a silent skip, so the nightly depth's absence cannot wear a live name ([C30]/[C27] applied to absence itself). **(3) The contracts bind all three directions**: `dde-perf-page.test.js` grew the budget table to ≥4 series, pins **exactly one** p95-tracked series (`dde-http-load-perf` @ 600ms), pins the sequential sibling by the module rule (`dde-http-wire-perf:wire`), executes `pickPair/pairCard` against the recorded history in both states (absent → em-dash + "No recorded load point yet"; present → the recorded p95 value, never the median) and adds 2 page-mutation negative controls (the queueing framing rewritten to regression by name; the absence note deleted) — each applied and each bites; `perf-badges.test.js` +2 (absent load history waits silently + recorded history renders the p95 badge through the 600/750/1300ms color ladder); `load-runner.test.js` +1 **end-to-end linkage**: the runner's own `--json` report is handed to `benchmark-trend.mjs` in a sandbox and the appended row must carry the load series name, `metric: "p95"` and byte-for-byte the run's own p95 — the recorded tail cannot be a different number wearing the load label. `npm test` → **1296/1296** (+4); boundary audit **883 files, 0 violations** (file count unchanged: this cycle only deepened committed files); docs-node **94 · 56 · 20** |
| **v0.5.36 (2026-10-23, this session)** | **The committed ledger tears itself into a curve — `docs/DDE-TREND.html` plots the engine/wire/SDK medians and the tracker bot's next point lands on the page without a redeploy** — the perf board and the pull-down trend in `DDE-PERF.html` rendered the latest point per series, but the ledger the repo already commits (`benchmarks/perf-history.jsonl`) held the whole history and no live surface drew it: a reader opening the trend page sees the shipped data as numbers per series, not as the shape those numbers move in. **(1) The curves are drawn from the ledger itself**: the page fetches the committed `benchmarks/perf-history.jsonl` over the public raw endpoint (same no-token channel the perf board already uses), parses it line-wise, and plots the engine/wire/SDK median curves; a 60s poll re-fetches both sources (ledger + module) and redraws silently, so the tracker bot's next appended point moves the page with no release in the loop — the poll path is the same tokenizer the loader feeds, so a poll failure names its URL on a red strip instead of corrupting the canvas. **(2) The budgets are the module's, never the page's**: `parseBudgets()` derives each series' budget and declared metric from `scripts/benchmark-trend.mjs` bytes, so a module bump shifts the dashed budget line in the same push, and a curve series the module does not declare does not get a budget from memory — the honest absence renders instead ([C27]/[C25] applied to the curve panel, not only to the pair card). **(3) The contract binds the page to its bytes, not to look-alikes**: `test/delivery/dde-trend-page.test.js` (+8) executes `parseBudgets`, `latestBySeries`, `medianSeries`, `curveBySeries` and `curvePanel` inside a VM against the REAL page bytes and the REAL ledger bytes; docs-node validates the fetcher/polled contract through the same tokenizer; and the battery's five mutations (an invented fetch source, an absent index card, a dark-ledger source without a claim, an unregistered redraw and a deleted poll channel) plus one module-side mutation — each applies AND bites, and `docs/index.html` carries a new card walking users to `DDE-TREND.html` with a back-link from its board column. `npm test` → **1304/1304** (+8); boundary audit **885 files, 0 violations**; docs-node **94 · 56 · 20** |
| **v0.5.37 (2026-10-24, this session)** | **The perf trend gate names its first breach on the failing run's Summary page — series, baseline, ratio, beside the red gate** — the trend gate could go red with only a scrolling log line; a reviewer opening the run saw a red ✗ with the offender buried. `scripts/benchmark-trend.mjs` now captures every drift breach as a structured '{ series, metric, current, baseline, ratio }' row and surfaces the FIRST one three ways: an `alert` object in the `--json` status, a stderr block in every mode, and a Markdown breach row appended to `` (CI) so the run's Summary tab renders the table `series | metric | current | baseline (5-run median) | ratio` beside the red gate — while everything the gate already promised holds: a breached run records NOTHING, the summary channel is append-only and best-effort (a failed append never flips the gate), and a report whose OWN gate is FAIL is a recording error, never a drift alert. `test/ci/perf-drift-alert.test.js` (+5) binds the structured alert's fields exactly (2.5ms against a 0.6ms five-run baseline = 4.17x), the rendered summary row, green-run silence, the FAIL-gate distinction and the append-only property. `npm test` → **1309/1309** (+5); boundary audit **890 files, 0 violations**; docs-node **95 · 56 · 20** |
| **v0.5.38 (2026-10-24, this session)** | **One badge answers 'are we inside the budgets?' — the aggregate perf·all sums the set by its worst case** — the README carried three series badges plus a raw link into the ledger; a reader wanting one glance had to read three numbers against three budgets, and nothing said the load series when its nightly point lands. `benchmark-trend.mjs --badges` now renders a fourth badge, `docs/badges/perf-all.svg` (`perf·all`), from ONLY the badges the run actually rendered — the always-on three tonight, the severity ladder by name: every series inside its budget → **green `all within budget`**; any series past its budget but inside the 2x regression bar → **yellow `N above budget`**; any series beyond the bar → **red `regression detected`** — and the nightly load tail joins automatically the moment it records its first point, so the aggregate can never show a state the set does not, with the same all-or-nothing atomicity (any series unresolvable → nothing written at all). README embeds it beside the three (`DDE perf · all`, same ledger anchor), and the badge contract grew teeth: `perf-badges.test.js` (+3) pins the green/yellow/red ladder through the exact engine budgets (50/75/120ms), pins the README-set equality at FOUR files, and the generation summary must list the aggregate it wrote. `npm test` → **1312/1312** (+3); boundary audit **891 files, 0 violations** (+^`perf-all.svg`); docs-node **95 · 56 · 20** |
| **v0.5.40 (2026-10-24, this session)** | **The badge sync is audited at the tip main SERVES, not only at the checkout's working tree** — v0.5.39's freshness audit read the working tree; a `git cat-file` view of main tells the truth a checkout can hide: the same sync could break on main (Pages/README serve the COMMITTED bytes) while an uncommitted local regen keeps the working tree green. `test/ci/main-badge-sync.test.js` (+4) reads the GIT COMMIT TREE of main — ledger, module badge table and every `docs/badges/*.svg` via `git cat-file -p <ref>:path` and `git ls-tree`, resolved HEAD on main checkouts else `refs/remotes/origin/main`, and FAILS NAMED when neither is reachable (an audit that reported green while auditing nothing would be the exact lie it exists to refuse). The audit core moved to `test/ci/badge-audit.mjs` so both surfaces (working tree + commit tree) consume ONE derivation of the same rules — no duplicated budget regex, per [C25]/[C27]. Three contracts bind it: main's badge set shows main's ledger-latest points (a stale one fails immediately by name), main's badge table parses from the SAME tree it serves (a rewritten table is caught), and a staged newer ledger point bites `STALE` by name — proving the audit reads committed bytes, not checkout files. `npm test` → **1320/1320** (+4); boundary audit **893 files, 0 violations**; docs-node **95 · 56 · 20** |
| **v0.5.39 (2026-10-24, this session)** | **A stale badge can no longer hide — badge freshness is now audited at commit granularity, caught on the local push before GitHub ever sees it** — the trend bot regenerates the badges and appends the medians in the SAME commit, but nothing enforced that pairing: a cycle that moved the ledger without regenerating a badge (or the mirror) would leave the README advertising last cycle's number with today's credibility, and `perf-badges.test.js` could not see it because it tests the generator in sandboxes — staleness is only visible in the COMMITTED bytes. `test/ci/badge-freshness.test.js` (+4) closes it by re-deriving exactly what `--badges` rendered, from the same sources and NO retyped budget: every BADGE_SERIES row is parsed from the module (the same regex the live pages use, per [C25]/[C27]), the committed `docs/badges/*.svg` for each series must show the ledger's LATEST recorded point AND the ladder-verdict color, `perf-all` must be the worst case of exactly the rendered set (nightly absence honored — no badge before its first point), and any committed `perf-*` file the module does not declare is an unregenerable artifact that fails by name (the CG-BDG/1 `specimen-*` SVG family is explicitly carved out — a different system, owned and regenerated by CG-BDG/1). Three mutation controls each apply AND bite by name: a stale engine value (ledger 0.0999ms vs badge 0.105ms → 'STALE (re-run --badges)' named file+series+values), a lying color (green number the ladder calls yellow), and a phantom badge (committed `perf-phantom.svg` no module row declares). This audit wired into `test/ci` means every pre-push and CI run catches badge↔ledger divergence before the run is green. `npm test` → **1316/1316** (+4); boundary audit **892 files, 0 violations**; docs-node **95 · 56 · 20** |
| **v0.5.31 (2026-09-30, this session)** | **The runners' own reports leave the runner** — dde.yml now uploads the SDK + wire perf reports (the `--json` medians) as ONE `dde-runner-reports` artifact per run: `retention-days: 30` PINNED (an unpinned retention silently defaults and drifts), `if-no-files-found: error` (evidence is fail-closed, not best-effort), placed after both benchmarks and BEFORE the trend gate so the evidence lands even when the gate defers or goes red. The workflow-yaml contract grew the artifact clause — exactly one uploader, both report paths, the pinned retention, a major-pinned action, and the ordering — with 6 negative controls each applied-and-bites (retention drift · pin removal · emptiness made silent · wire report dropped · benchmark step renamed · uploader unpinned); the battery is CRLF-normalized per [C3] after the first draft silently applied only 3 of 6 on this Windows checkout. `npm test` → **1245/1245** (+2); boundary audit **861 files, 0 violations**; docs-node **94 · 56 · 20** |
| **v0.5.30 (2026-09-30, this session)** | **The proxy posture now speaks all three front doors** — the boundary doc's production section gained Caddy and Traefik equivalents beside nginx (the section that already carried a structural CI contract): Caddy with its honest build choice spelled out (no standard rate-limit module — claim it and the section names the degenerate shared-budget failure; module build or Traefik are the honest per-client paths), `reverse_proxy` to the documented loopback bind, `request_body max_size` at the 1 MiB cap, ACME/internal/pinned TLS; Traefik with the full translation (`rateLimit` average 10 / burst 20 mirroring the nginx fence, `buffering.maxRequestBodyBytes` = 1048576, entry-point TLS, forwarded headers logging-only) — both with their own "Never do" list. Zero fences executed, zero new start lines, zero nginx fences added: the nginx-conf, doc-curl, and docs-node contracts stay byte-stable, and the doc-freshness contract holds the new sections to the same live-code anchors (loopback socket, the 1 MiB cap, no fresh DNS claims). `npm test` → **1243/1243** (unchanged: docs-only cycle); boundary audit **861 files, 0 violations**; docs-node **94 · 56 · 20** |
| **v0.5.29 (2026-09-27, this session)** | **"The twins are identical" would have been the second dead number in a row** — v0.5.28 pinned the AR page's 277-key dictionary and left the EN sister's cross-file parity unguarded. The obvious fix is to assert the two files match. Measured first, they do **not**, and the divergence is *designed*: the AR page is the interactive twin (it carries the language switcher), the sister is the printable twin (printhead + print button) — which is precisely why the [C5] dictionary walk dropped the EN `printhead` subtree first. So a "they must be equal" test would have been **637 all over again**: a number that reads like a guarantee, matches nothing, and fails the first time a real design decision meets it. `test/p2/gate41-visual-en-parity.test.js` pins the drift that must never happen instead: all **277** dictionary `.en` values appear **verbatim** in the sister (0 absent — the cross-file link is real and it holds); the load-bearing element counts are **identical** (section 10 · h2 10 · h3 12 · tr 30 · td/th 95 · p 19 · a 14 · ids 34), because a row or heading present in one twin only means the sister is a **stale snapshot** — invisible to any per-file test; the only permitted tag differences are `b`/`span`/`div` each **+1** in the sister, pinned **as a set** and re-checked against the `printhead` that causes them, so a new divergence cannot hide beside a sanctioned one; the sister stays **dictionary-free** (0 `data-i18n`, 0 `D.nodes`, 0 `L()`) because it is literal English and a second dictionary would be a second source of truth ([C27]); it leaks **no Arabic** across 539 text runs; and `lang`/`dir` are asserted per twin, since a wrong `dir` silently reverses the whole board's order while every text assertion still passes. Two findings the sweep produced that nobody had asked about: **(a)** **221 of 277** `.ar` values are already literal Arabic in the static markup, so the AR page renders with **JS disabled** — the dictionary is the switcher's payload, not the page's only text source, and that count is now pinned so stripping the literal Arabic (a silent availability regression every dictionary-level check would pass) cannot land unnoticed; **(b)** the role asymmetry (AR `langBtn` ↔ EN `printBtn`) is pinned **as fact**, so a future session neither "fixes" a deliberate difference nor lets a dead button rot. The 12-control battery reports **coverage rather than a count** — all 8 tests had to be *observed failing*, which forced the harness onto `--test-reporter=tap` after the default reporter's glyph output made the extractor silently find zero failures (the ASCII-grep trap, live). Measured: **1201/1201** · **836 files · 0 violations** · docs-node 94/55/20 · freeze 49/49. |
| Channel | State |
|---|---|
| Core Outreach #1 → `inquire@coredao.org` | **SENT** (owner-confirmed; delivery/open timestamp UTC PENDING) |
| Core Ventures (B) | NOT ACTIVATED |
| ElizaOS contact #21788 + email | **SENT** (email unacknowledged; no reply claimed) |
| #21788 public replies (People's Court / Epistemic Labs) | **RECEIVED** 2026-09-16 & 2026-09-19, official (disclosed) account — facts-only record: `docs/elizaos-thread-replies-record-2026-09-23.md` |
| #21788 fixture mapping (result + correction, owner's words) | **RESULT RECEIVED** 2026-09-23 (`#18568567`): schema mapping supported; one clarification — anchored transfer (0.001 CORE) is an execution coupon, NOT settlement of the modeled compensation. **CORRECTION SHIPPED** same day (`ef6a0b8`: `paymentSettled` removed → `compensationSettlement.status = NOT_SETTLED`) and **POSTED** 15:44:22Z UTC (`DC_kwDOMT5cIs4BG1et`) with live RPC re-verification. **CLOSED** 2026-09-23 16:09:40Z (`#18569442`): counterparty confirms the raised issue is resolved; no independent chain verification / no verifier run / no endorsement; package remains a synthetic mapping exercise. **OWNER-DIRECTED FOLLOW-UP** 16:35:17Z UTC (`DC_kwDOMT5cIs4BG1ow`): narrow research invitation (optional shared-vocabulary / evidence-package / failure-mode / test-set tracks), no endorsement assumed, no asks at all. **NEXT-TEST OFFER** 16:37:19Z UTC (`#18569800`): paired synthetic A/B fixture (identical execution+delivery, differing modeled consent; pin version+hashes; per-field attestation; preserve unknowns) with a bounded read-only critique of the evidence labels offered — no commitment to integration/pilot/review/adjudication. **ACCEPTED** 16:47:03Z UTC (`DC_kwDOMT5cIs4BG1qn`). **PAIR PUBLISHED** 17:14:04Z UTC (`DC_kwDOMT5cIs4BG1vQ`): `assent-pair-v1.0.0` at `1c7223f`, verifier 10/10 → `ASSENT_PAIR OK`, CI green. **CRITIQUE RECEIVED** 17:23:37Z UTC (`#18570343`): execution+delivery identical, consent differs as intended, pins match; not run verifier / not chain-checked; two label ambiguities (boolean `modeledAssent` on B vs UNKNOWN assent; NOT_SETTLED read as verified nonpayment). **CORRECTED** at `1e75fba` (CI green): tri-state `modeledAssent` (A=FULL/B=PARTIAL, party fields authoritative) + `compensationSettlement.evidenceStatus`/`actualStatus` split in pair and canonical fixture; verifier 11/11 → `ASSENT_PAIR OK`; 2 regression tests. **REPLY POSTED** 18:15:37Z UTC (`DC_kwDOMT5cIs4BG164`, dbId 18570936): commit + exact changes only. No asks made at any point |

## Gates (locked, non-negotiable)

- Pricing / CP2 / customer claims — LOCKED.
- V2 deployment, Mainnet EvidenceRegistryV2 upgrade — **EXECUTED (Phase 3, this session)**; deploy + intent + proof recorded on-chain.
- Phase transitions — explicit per-phase GO only; first external data that feeds
  the Decision Gate: Core reply + ElizaOS reply, facts-only. The ElizaOS
  public-thread input is **recorded** (People's Court / Epistemic Labs reply,
  2026-09-16/19, official account — `docs/elizaos-thread-replies-record-2026-09-23.md`);
  CoreGuard's §4 fixture submission was **POSTED** on #21788 (2026-09-23,
  owner's words, comment `DC_kwDOMT5cIs4BGzrh`); the counterparty **ACCEPTED**
  the synthetic fixture for the public-thread mapping test and the owner
  delivered the stable anchor (comment `DC_kwDOMT5cIs4BG1R4`, `commit ea59a88`).
  **2026-09-23 mapping result received** (`#discussioncomment-18568567`): schema
  mapping supported; one clarification (the anchored execution coupon must not
  read as compensation settlement) — corrected and re-anchored same day so the
  fixture claims nothing beyond the truth. No pilot/partnership/funding request
  may be made before any follow-up result and the owner's explicit approval
  path. Core email unacknowledged. Pricing stays
  LOCKED until the owner's decision.
- Frozen artifacts, never touched: `docs/ws-5.md`, `scripts/verify-live.json`,
  `packages/verifier-c/*`, `docs/counterparty-*`, `submission/*` evidence,
  `examples/pilot/proof-artifact-1.json`.

## How to refresh this file

Re-run the gates after any change and update every number above in the same
commit. No number here may be inferred — only measured.
## Phase 3 — Core Mainnet (chainId 1116) EXECUTED — ALL GATES COMPLETE

- **3.0 Preflight (zero-gas)**: runtime on-chain == local recompute (PASS).
- **3.1 Deploy**: `EvidenceRegistryV2` → `0x66268a47e81b8f657798d7b5bbedc956df7b13fd` · tx `0x75aabacc…97f597793` · block `38764383`.
- **3.2 commitIntent**: tx `0x0cd2a8c0…7367715c` · block `38764405` · intentId `0xe58574f4…eda9ac17`.
- **3.3 anchorProof**: tx `0x5b9e7d68…3e478d2` · block `38764446` · proofId `0x82f56aae…650452` · result 0 (VALID).
- **3.4 Read-back (zero-gas)**: on-chain intentCommits + proofAnchors match evidence exactly.
- **3.5 Independent verify (zero-gas)**: deployedBytecode recomputed from source == on-chain except the single 32-byte immutable, which equals on-chain `VERSION()` (`0x530b4f34…`).
- **3.6 Freeze (zero-gas)**: `evidence/phase-3-evidence-freeze.json` (SHA-256 per gate artifact).
- All broadcasts `--legacy` (Core is public EVM, no type-2 txs). Key: `.env` only, never printed or committed.

