fix(ad-030): retire the promise from the six agent-instruction mirrors - #431
Merged
Conversation
AD-030 retires "gets sharper every day" and "it learns from how you engage with what it shows you" on every surface, enforced by #419's new scripts/check-retired-claims.cjs. #419 updates CLAUDE.md but not its six mirrors — and #421 (mine) rewrote all six, reintroducing the retired line into main after it was absent at #419's merge-base. Running #419's gate logic against main: 61 violations, four of them in files #419 does not touch — .ai/RULES.md, AGENTS.md, CONVENTIONS.md and CHANGELOG.md. Left alone, #419 fails its own gate the moment it rebases. Wording is copied verbatim from #419's CLAUDE.md so the mirrors cannot drift: relevance is attributed to the user's codebase, and improvement to engine updates re-judging the corpus. "Yesterday's noise becomes tomorrow's signal" is deliberately retained — it is true of corpus re-judging and is explicitly not a banned pattern. CHANGELOG.md gets the gate's `retired-ok:` escape hatch rather than a reword: the entry is release history naming the demoted mechanism, and rewriting it would falsify the record. .clinerules, .windsurfrules and .cursor/rules/project.mdc are not scanned by the gate (no matching extension) but are fixed anyway — they teach the retired claim to Cline, Windsurf and Cursor. Verified: my four scanned files drop to zero violations, and every remaining violation on the tree lies inside #419's file set, so the two PRs together take the gate to zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WJ6BP3GX5HYrnjW1nGtrvC
runyourempire
added a commit
that referenced
this pull request
Aug 15, 2026
…pply-chain blind spot (#433) ## The premise, verified first An audit lane claimed the quick-xml suppression in `deny.toml:96-112` / `.cargo/audit.toml:15-29` had gone stale. It rested on this justification: > "NO consumer in our tree has a released version against >=0.41 yet" **Confirmed false.** Read straight out of the registry index (`rust_version` and `deps` per published version): | consumer | we had | latest | quick-xml req | zip req | |---|---|---|---|---| | `calamine` | **0.25.0** | 0.36.1 | `^0.31` → **`^0.41`** | `^1.0` → `^8.6` | | `docx-rs` | **0.4.20** | 0.4.22 | `^0.36` → **`^0.41`** (since 0.4.21) | `^0.6.3` → `^8.6` | | `plist` | **1.9.0** | 1.10.0 | `^0.39.2` → **`^0.41`** | — | All three shipped support. The ignores were suppressing a live, fixable advisory pair on a parser that reads **user-supplied `.xlsx` / `.docx`**. ## What changed **quick-xml (RUSTSEC-2026-0194 / -0195) — resolved, not re-justified.** Bumping the three consumers collapses `quick-xml` **0.31.0 + 0.36.2 + 0.39.4 → a single 0.41.0**. Both advisories stop firing on their own, so both ignores are **deleted** from `deny.toml` *and* `.cargo/audit.toml` (they had diverged; both were checked). `RUSTSEC-2023-0071` (`rsa`) left alone as instructed. **`office.rs` needed no edit** — and that is a verified claim, not an absence of errors: - `sheet_names()` and `worksheet_range()` have byte-identical signatures in 0.25 and 0.36. - `Data` still has exactly the same nine variants with the same payloads. `cell_to_string` matches it **exhaustively with no wildcard arm**, so an added variant could not have compiled. - `ExcelDateTime`'s `Display` impl is byte-identical (`write!(f, "{}", self.value)`), so `DateTime` cells format the same. - Same for `docx-rs`: `TableChild` / `TableRowChild` are destructured irrefutably, so a new variant there could not have compiled either. The documented decompression-bomb weakness (the 100 MB cap is on the **compressed** size) is untouched — separate work, not regressed. **zip — partial.** `zip 1.1.4` retired as hoped. **`zip 0.6.6` did not** — it is our own direct `zip = "0.6"`, so retiring it is an 8-major API migration across `osv/cache.rs`, `extractors/archive.rs` and `embeddings_providers/fastembed.rs`. No advisory attaches to it, so it is staleness, not exposure. Left as follow-up rather than smuggled into a security PR. Tree is now `zip` 0.6.6 (ours) + 4.6.1 (tauri-plugin-updater) + 8.6.0 (calamine/docx-rs). **`relay/` — 5 vulnerabilities → 0.** A TLS-terminating server with no Dependabot entry, no cargo-audit, no CI. | crate | change | advisory | |---|---|---| | `rustls-webpki` | 0.103.9 → **0.103.14** | RUSTSEC-2026-0049 / -0098 / -0099 / -0104 (cert validation) | | `spin` | 0.9.8 → **0.9.9** | 0.9.8 was **yanked** | | `anyhow` | 1.0.102 → 1.0.104 | RUSTSEC-2026-0190 | | `event-listener` | 5.4.1 → 5.4.2 | RUSTSEC-2026-0221 | | `rand` | 0.8.5 → 0.8.7 | RUSTSEC-2026-0097 | `rsa 0.9.10` remains with no fix available, and is recorded in a new `relay/.cargo/audit.toml` with evidence that it is **not in the build graph**: it reaches `Cargo.lock` only via sqlx's optional `mysql` backend, which relay never enables — `cargo tree -i rsa` and `cargo tree -i sqlx-mysql` both report *nothing to print*. **Coverage, so it stops recurring.** `dependabot.yml` gains a `cargo` entry for `/relay` (not a `src-tauri` workspace member, so the existing entry never saw it), and `nightly-audit.yml`'s cargo-audit step now loops every `Cargo.lock` in the repo. **Workflow footprint is deliberately limited to those two files** — `validate.yml` is being reshaped by peer PRs and is untouched here. **`relay/Dockerfile`.** `cargo build --release --locked 2>/dev/null || cargo build --release` silently dropped lockfile enforcement and swallowed the reason. Fallback removed. Its base image also had to move **1.82 → 1.95**: the lockfile already required 1.88 via `time 0.3.47` (`jsonwebtoken` → `simple_asn1`), so that image could not have built this crate at all — the fallback was hiding a hard failure, not surviving a soft one. ## Two things found on the way **1. `main` was un-committable — independently confirmed, now fixed by #430.** `scripts/check-file-sizes.cjs` exits 1 on `src-tauri/src/analysis_rerank.rs` (**1032 lines against a 1000 hard limit**, arrived with #423). The gate scans the whole repo rather than staged paths, so `.husky/pre-commit` failed for *every* terminal on *every* commit — including this one. I hit it, diagnosed it, and fixed it the same way a peer did in **#430** (lift the test module into a sibling `analysis_rerank_tests.rs` via `#[path]`, 1032 → 866). #430 landed first, so **that commit has been dropped from this branch by rebase** — this PR now contains only the dependency work. Recording it here as an independent second confirmation of both the diagnosis and the chosen fix. **2. `cargo clippy --all-targets -- -D warnings` does not pass on `main`** (255 pre-existing errors at my branch point, ~all `unwrap_used`/`expect_used` in test code). This is **not** the gate — CI runs `cargo clippy ${{ matrix.cargo-features }} -- -D warnings` *without* `--all-targets`, so the numbers below are from the CI-equivalent invocation. Reported as an observation, not touched. ## Verification | check | result | |---|---| | `src-tauri` `cargo audit` | **exit 0** — zero vulnerabilities, zero warnings | | `src-tauri` `cargo deny check` | **exit 0** — `advisories ok, bans ok, licenses ok, sources ok` | | `relay` `cargo audit` | **exit 0** (was 5 vulns + 4 warnings + 1 yanked) | | `relay` `cargo check --locked --all-targets` | clean | | `cargo clippy -- -D warnings` (CI-equivalent, default) | **exit 0** | | `cargo clippy --features experimental -- -D warnings` | **exit 0** | | `cargo fmt --check` | **exit 0** | | `cargo test --lib` | **4300 passed, 0 failed, 10 ignored** | All re-run after rebasing onto `c1fd348c` (#425, #426, #427, #429, #430, #431 all landed mid-flight). `--features team-sync` and `--features enterprise` fail to compile — **pre-existing rot on `main`** (`chacha20poly1305::aead::OsRng` unresolved, then cascading `__cmd__*` macro failures), which is what #424 exists to repair. My lockfile diff touches no crypto crate. #424 is still open as of this push, and the CI clippy matrix on `main` still carries only the `default` and `experimental` legs — so the two legs verified above are exactly the gate. ### The extractor tests were `#[ignore]`d and had never run There are no `.xlsx`/`.docx` fixtures anywhere in the repo, so `test_real_docx_extraction` / `test_real_xlsx_extraction` were no-ops that returned early. To gain real confidence in an 11-minor-version parser bump I generated **real OOXML documents** — shared strings, an inline string, numeric and boolean cells, paragraphs and a table — confirmed both `#[ignore]`d tests pass against them, and separately asserted the extracted text matches the pre-bump formatting contract exactly: ``` === Sheet: Budget === Hello from 4DA Item | Cost Second paragraph Widget | 42 A1 | B1 Gadget | 3.50 | TRUE ``` That exercises every arm of `cell_to_string` that a document can reach (shared/inline string, integral float → `42`, fractional float → `3.50`, bool → `TRUE`) plus the docx paragraph and table paths. The scratch harness was deleted; **no test-file changes ship in this PR**. ## Deliberately left - **`zip 0.6.6`** — direct dep, 8-major API migration, no advisory. Follow-up. - **`office.rs` decompression bomb** — the 100 MB cap is on the compressed size. Out of scope, not regressed. - **`--all-targets` clippy backlog** — pre-existing, not the CI gate. - **`validate.yml`** — peer-owned right now, untouched on purpose. - **`--features team-sync` / `enterprise`** — pre-existing rot, #424's job. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
runyourempire
added a commit
that referenced
this pull request
Aug 16, 2026
…de that does not exist (#466) Closes the documentation-truth findings from the forensic audit that were verified still open at `f26da1ea`. Every change makes a document match the code; where the code is the problem, this PR records the divergence rather than pretending it away. ## `CLAUDE.md` never received #431's drift correction #431 corrected five of the six agent-instruction mirrors. `CLAUDE.md` — the propagation root — got none of it, so the file every session loads first has been the wrong one. - **Design tokens.** `CLAUDE.md` listed `--bg-primary`, `--text-primary`, `--accent-gold`. The real names are `--color-`-prefixed (`src/App.css:8-26`). An agent following the doc verbatim produced CSS that silently did nothing. Verified independently: `--color-bg-primary` at `App.css:8`, and a light theme at `:49+` overrides the same token names, so the added "never hard-code a hex" note is load-bearing rather than decorative. - **The 60-line Rust function rule** was presented as enforced. It is not implemented anywhere, and `src-tauri/Cargo.toml:252` explicitly sets `too_many_lines = "allow"`. Now stated as a convention. - **`ts-rs` was wrong in all seven files**, not just `CLAUDE.md` — every one said v10; `src-tauri/Cargo.toml:27` pins `"12"`. - **Source count.** Every mirror said "20+". `build_all_sources()` registers **22** (counted: 22 `Box::new` entries). Mastodon and Lemmy were missing from every list, and `CVE/OSV` was written as one entry when it is two — which is exactly how 22 came to read as 20. ## Five INVARIANTS entries describe mechanisms that do not exist Verified by repo-wide grep. Each is now either corrected to what the code does or retired with its reason. | | Claimed | Actual | |---|---|---| | INV-001 | "precision MUST be >85%" | No 85% threshold exists. Real enforced floors: aggregate precision >= 0.70, F1 >= 0.40, per-persona noise rejection >= 80% (`scoring/simulation/reality.rs`) | | INV-023 | `STATIC_/ACTIVE_/LEARNED_LAYER_WEIGHT` | **Zero `.rs` hits.** Also still stale in `specs/ACE-STONE-TABLET.md` | | INV-041 | "ALL persistent state MUST live in SQLite" | Contradicted by four subsystems — `settings.json`, the OS keychain, `data/calibrations/`, `data/signal_terminal_token.txt` | | INV-060 | `ExclusionStrength` enum, "percentages are CANONICAL" | **Zero `.rs` hits** | | INV-071 | ">=5 exposures" | See below — it is worse than "3 not 5" | | INV-090 | warn at TS 350 / RS 600 | Gate uses ts 300 / tsx 350 / rs 700 | `.ai/FAILURE_MODES.md` documented the 2026-08-11 poisoned-curve incident as caused by state living outside SQLite **without naming the invariant that forbids it**. That cross-reference is now there. **INV-071 turned out to be three disagreeing gates, not one wrong number:** compute uses `>= 3` (`ace/behavior/tracking.rs:37`), read defaults to `>= 5` (`ace/behavior/queries.rs:11-12`), display uses `> 3` (`ace_commands/interactions.rs:429`) — and the explicit-rejection arm sits ahead of all three with **no exposure floor at all**, so a single dismissal of a never-engaged topic yields a negative affinity from one exposure. All four are recorded. The code is unchanged; this needs a decision, not a doc edit. ## Three in-code comments assert security properties the code does not have Comments only — zero behaviour change. False security comments are worse than none, because they stop the next reader from checking. - `settings/types.rs` — *"Must be true before cloud providers can be used."* No call site gates on `cloud_llm_disclosure_accepted`. INV-031 now says explicitly that consent is informed-disclosure, not an enforced gate; the comment now agrees. - `src-tauri/Cargo.toml` — *"debug-only dependency, stripped from release builds"* about `victauri-plugin`, which sits in `[dependencies]`, not `[dev-dependencies]`, under no `cfg(debug_assertions)` table. True only via the crate's own internal gating, which is now what it says. - `src-tauri/src/osv/sync.rs` — *"it never sends the user's dependency set anywhere."* True of the ZIP-mirror fallback only. `sync_ecosystem` POSTs the user's package names to `OSV_BATCH_URL` (up to 1000/request) and is attempted **first** on every cycle, so reaching that branch means disclosure already happened. ## Two things this PR deliberately does not do **AD-030 is out of scope.** PR #419 already contains the AD-030 entry, `scripts/check-retired-claims.cjs`, and the promise removal across 67 files. This PR touches none of it — `CLAUDE.md` edits here are confined to lines 46+ and do not go near the tagline. A trial merge against #419 is conflict-free. `specs/ACE-STONE-TABLET.md` gets not-built notes at the three blocks the false invariants were transcribed from, but is otherwise left intact as the historical design record rather than rewritten. ## Something that needs settling `.ai/RULES.md`'s own header says it is *"Generated from `CLAUDE.md` — the maintained source of truth"*, and explains `sync-ai-rules.sh` was deleted because it ran the other way and would clobber `CLAUDE.md`. That is the opposite of how the mirror set is usually described. All seven files are now consistent either way, so nothing is blocked — but one of those two statements is wrong and someone should decide which. ## Still open, for #419 `src/locales/en/ui.json` `firstRun.scanningDescription` still says "20 sources", as do all 12 other locales. Left alone because #419 owns the locale pass; fold 20→22 into it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Fq96xWyPQjx2bCCzWtsnC9 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
runyourempire
added a commit
that referenced
this pull request
Aug 17, 2026
…d but never ran (#477) ## The residual this closes `scripts/check-retired-claims.cjs` + its 9 tests merged in #469 as the AD-030 enforcement gate — but nothing ever invoked them. Not `test:scripts`, not the `validate` chain, so the gate never ran in CI. Meanwhile `.ai/RULES.md` / `AGENTS.md` (via #431) already assert this enforcement exists. This was the priority residual of the AD-030 retirement arc (tracked in `.claude/plans/PENDING-DECISION.md` item 1); it was blocked on #470's lane holding `package.json` and is unblocked now that #470 merged. ## Change (3 lines, package.json only) - `validate:retired-claims` script → `node scripts/check-retired-claims.cjs` - `scripts/check-retired-claims.test.cjs` added to `test:scripts` - Gate inserted at the front of the `validate` chain, right after the size check — it is sub-second, so it fails fast before the heavy steps ## Verification - `node scripts/check-retired-claims.cjs` — OK repo-wide (0 violations) - `node --test scripts/check-retired-claims.test.cjs` — 9 pass / 0 fail - Pre-push gate (typecheck + suite) passed locally 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01LBY5q2MskiKMkTm6NmB49L Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completes AD-030 on the surfaces #419 does not reach. Blocks a failure in #419 itself.
Why this is needed
#419 ships
scripts/check-retired-claims.cjs, wired intotest:scriptsandvalidate, which bansgets sharper every day,learns from how you engage,compound intelligence,behavioural learningand friends.I extracted that gate from #419 and ran its real logic against
main: 61 violations, four of them in files #419 does not touch..ai/RULES.mdAGENTS.mdCONVENTIONS.mdCHANGELOG.mdLeft alone, #419 fails its own gate the moment it rebases onto main.
These are my regression: they were absent at #419's merge-base, and #421 rewrote all six mirrors, syncing them to CLAUDE.md's then-current line — which was the retired promise.
What changed
The six agent-instruction mirrors of
CLAUDE.md—.ai/RULES.md,AGENTS.md,CONVENTIONS.md,.clinerules,.windsurfrules,.cursor/rules/project.mdc— now carry the new line copied verbatim from #419'sCLAUDE.md, so they cannot drift from the source of truth. They feed Cline, Windsurf, Cursor, Codex and Aider; stale copies re-teach the retired claim to every other agent working this repo..clinerules,.windsurfrulesand.cursor/rules/project.mdcare not scanned by the gate (no matching file extension), so they are not CI-blocking — fixed anyway, because the point is the claim, not the gate.CHANGELOG.mdgets theretired-ok:escape hatch instead of a reword. That entry is release history naming the mechanism that was demoted; rewriting it would falsify the record. The hatch exists for exactly this."Yesterday's noise becomes tomorrow's signal" is deliberately kept. #419 retains it in the new reserved beat, re-attributed to engine updates re-judging the corpus rather than to user engagement, and explicitly exempts it from the banned patterns. It is not a leftover.
Verification
mainafter fix(pipeline): four silent production failures — dead sources, notification storm, lobotomised reranker, lying metrics #423, fix(scheduler): contain panics so a bad cycle skips instead of wedging background refresh #428 and URGENT unblock: split analysis_rerank tests to clear the 1000-line commit gate (fleet cannot commit) #430 landed. AD-030: retire the gets-sharper-every-day promise + last behavioral scoring path #419 + this PR = zero.Note for #419
The gate will also want a look at
src/types/i18n-resources.d.ts— except it does not, because that file is gitignored and untracked. Confirmed, no action needed. Nothing else outside your file set violates.🤖 Generated with Claude Code
https://claude.ai/code/session_01WJ6BP3GX5HYrnjW1nGtrvC