[mine-blindspots hyperthrive corpus] duplicated-authority charter recall gaps: cross-file, frontmatter-paraphrase, See-also restatement #164

Closed
opened 2026-07-27 15:07:12 +00:00 by jared · 5 comments
Owner

This is a Tier-2 charter-amendment proposal (bucket (b): wording strengthening of an existing catalog entry) — NOT a routine catalog ticket and NOT a proposal for a fourth smell. It requires maintainer sign-off per the tier2-charter.md change-control banner and ADR-0060/ADR-0068, not autonomous application.

Problem

Three verified recall gaps in the existing duplicated-authority charter entry, surfaced by an external-corpus mine-blindspots run against hyperthrive-websites, none a new smell shape — all instances the current entry's own definition already covers in principle, but the judge did not test for in practice:

(i) Cross-file duplication systematically missed, 5 pairs, despite AuthoritySourceResolver making each counterpart available:

  • CLAUDE.md (locked-decisions section) ↔ context/stack/decisions.md — the same settled decisions (niche, stack, hosting, volume, video, revisions) stated independently in both files.
  • context/business/offer-ladder.mdcontext/business/pricing-discipline.md — the Tier-1 price stated in both.
  • context/business/offer-ladder.mdcontext/business/recurring-revenue.md — the hosting/retainer price stated in both.
  • context/stack/tools.mdcontext/workflow/outreach.md — mailbox provisioning status and the Leadsmonkey tool both stated in both files.

(ii) Frontmatter-vs-body paraphrase missed: context/open-questions.md frontmatter load-when: ...not for blocking current work (line 3) vs. body line 14, **None of these block sending emails today.** — the same claim, paraphrased, not verbatim, one in frontmatter metadata and one in prose body.

(iii) "See also" restatement missed: docs/smartlead-api.md:80 (the ramp-rule explanation inline) vs. docs/smartlead-api.md:284 (a "See also" bullet that restates the same ramp rule's substance rather than just pointing at it) — a single file, two distinct locations, one framed as a pointer but actually carrying a restated claim.

Charter language

Closest existing entry: duplicated-authority in tier2-charter.md (exact wording not reproduced here — maintainer should locate the live entry). The current exemplar shape tests only for near-verbatim duplication of a claim across two prose locations. It needs strengthening, not replacement, in three specific instructions:

  1. Enumerate-and-diff resolved sources: when AuthoritySourceResolver makes a counterpart file available for a subject (e.g., a decisions/pricing/tooling file), the judge should explicitly enumerate each resolved source and diff it section-by-section against the file under review, rather than relying on incidental recall of a duplicate claim.
  2. Paraphrase-not-verbatim generalization: the charter's exemplar should be explicitly generalized beyond verbatim-shape duplication to cover a frontmatter-field claim restated as body prose (or vice versa) in materially the same substance, even when wording differs.
  3. See-also restatement check: the charter's clean-pointer counter-example (a See also bullet that only points at another file/section) needs a companion check: is the "See also" bullet's own text restating the pointed-to claim's substance, rather than just naming where to find it? If so, it's a duplication instance, not a clean pointer.

Correction

Before/after is not directly demonstrable without editing the live tier2-charter.md (out of scope for this filing — filing-only, no code/charter edits). Validation path: a charter-judge agent, given the proposed strengthened language, should flag all three "Problem" instances above and should NOT flag existing clean-pointer or single-source cases already exempted by the current charter.

Pass/fail examples

  • Must be flagged (judge-fixture prompt): CLAUDE.md's locked-decisions list plus context/stack/decisions.md's decisions table, both stating "Sending volume: 9 mailboxes, 5/day/box opening ramp" independently — finding: duplicated-authority, both files.
  • Must be flagged: context/open-questions.md frontmatter load-when: ...not for blocking current work vs. body None of these block sending emails today. — finding: duplicated-authority (paraphrase, frontmatter vs. body).
  • Must be flagged: docs/smartlead-api.md:284's "See also" bullet restating the ramp rule's mechanism (max_leads_per_day vs. message_per_day) rather than only pointing at line 80 — finding: duplicated-authority (See-also restatement).
  • Must NOT be flagged: a genuine clean pointer, e.g. context/stack/repo-structure.md's See also: [decisions.md](decisions.md) — the settled decisions this structure encodes, which names the target and its role without restating any specific claim — finding: NONE.

Provenance

/os-aidd-lint:mine-blindspots run, external corpus hyperthrive-websites, bucket (b) (existing-entry wording gap, not a new smell), cited against the duplicated-authority catalog entry in tier2-charter.md and AuthoritySourceResolver (plugins/os-aidd-lint, ticket #107 per its own header comment). All three instances independently verified by a second agent pass reading the live corpus files (CLAUDE.md, context/stack/decisions.md, context/business/offer-ladder.md, context/business/pricing-discipline.md, context/business/recurring-revenue.md, context/stack/tools.md, context/workflow/outreach.md, context/open-questions.md, docs/smartlead-api.md). 2026-07-27.

Catalog-amendment gate

This ticket implements nothing on its own. A wording strengthening of an existing entry still needs the eval re-run and hash update tier2-charter.md's own change-control banner requires (per ADR-0060/ADR-0068), plus human review of the diff. This is explicitly NOT a fourth-smell proposal — no ADR amendment for a new catalog entry is being requested, only wording precision on the existing duplicated-authority entry.

Two owners, named separately per the template's requirement (same person may hold both, but must be stated explicitly): who approves the charter wording change and re-run: Jared Swanson (maintainer). Who edits the charter file: Jared Swanson (maintainer) or a delegated implementer agent under his review — not to be applied autonomously by this filing agent or any mine-blindspots run.


Discoverer: hyperthrive-websites, session id unavailable, 2026-07-27. Filed from a mine-blindspots run against this repo as external corpus.

This is a Tier-2 charter-amendment proposal (bucket (b): wording strengthening of an existing catalog entry) — NOT a routine catalog ticket and NOT a proposal for a fourth smell. It requires maintainer sign-off per the tier2-charter.md change-control banner and ADR-0060/ADR-0068, not autonomous application. ### Problem Three verified recall gaps in the existing `duplicated-authority` charter entry, surfaced by an external-corpus `mine-blindspots` run against `hyperthrive-websites`, none a new smell shape — all instances the current entry's own definition already covers in principle, but the judge did not test for in practice: **(i) Cross-file duplication systematically missed, 5 pairs, despite `AuthoritySourceResolver` making each counterpart available:** - `CLAUDE.md` (locked-decisions section) ↔ `context/stack/decisions.md` — the same settled decisions (niche, stack, hosting, volume, video, revisions) stated independently in both files. - `context/business/offer-ladder.md` ↔ `context/business/pricing-discipline.md` — the Tier-1 price stated in both. - `context/business/offer-ladder.md` ↔ `context/business/recurring-revenue.md` — the hosting/retainer price stated in both. - `context/stack/tools.md` ↔ `context/workflow/outreach.md` — mailbox provisioning status and the Leadsmonkey tool both stated in both files. **(ii) Frontmatter-vs-body paraphrase missed:** `context/open-questions.md` frontmatter `load-when: ...not for blocking current work` (line 3) vs. body line 14, `**None of these block sending emails today.**` — the same claim, paraphrased, not verbatim, one in frontmatter metadata and one in prose body. **(iii) "See also" restatement missed:** `docs/smartlead-api.md:80` (the ramp-rule explanation inline) vs. `docs/smartlead-api.md:284` (a "See also" bullet that restates the same ramp rule's substance rather than just pointing at it) — a single file, two distinct locations, one framed as a pointer but actually carrying a restated claim. ### Charter language Closest existing entry: `duplicated-authority` in `tier2-charter.md` (exact wording not reproduced here — maintainer should locate the live entry). The current exemplar shape tests only for near-verbatim duplication of a claim across two prose locations. It needs strengthening, not replacement, in three specific instructions: 1. **Enumerate-and-diff resolved sources:** when `AuthoritySourceResolver` makes a counterpart file available for a subject (e.g., a decisions/pricing/tooling file), the judge should explicitly enumerate each resolved source and diff it section-by-section against the file under review, rather than relying on incidental recall of a duplicate claim. 2. **Paraphrase-not-verbatim generalization:** the charter's exemplar should be explicitly generalized beyond verbatim-shape duplication to cover a frontmatter-field claim restated as body prose (or vice versa) in materially the same substance, even when wording differs. 3. **See-also restatement check:** the charter's clean-pointer counter-example (a `See also` bullet that only points at another file/section) needs a companion check: is the "See also" bullet's own text restating the pointed-to claim's substance, rather than just naming where to find it? If so, it's a duplication instance, not a clean pointer. ### Correction Before/after is not directly demonstrable without editing the live `tier2-charter.md` (out of scope for this filing — filing-only, no code/charter edits). Validation path: a `charter-judge` agent, given the proposed strengthened language, should flag all three "Problem" instances above and should NOT flag existing clean-pointer or single-source cases already exempted by the current charter. ### Pass/fail examples - **Must be flagged** (judge-fixture prompt): `CLAUDE.md`'s locked-decisions list plus `context/stack/decisions.md`'s decisions table, both stating "Sending volume: 9 mailboxes, 5/day/box opening ramp" independently — finding: `duplicated-authority`, both files. - **Must be flagged:** `context/open-questions.md` frontmatter `load-when: ...not for blocking current work` vs. body `None of these block sending emails today.` — finding: `duplicated-authority` (paraphrase, frontmatter vs. body). - **Must be flagged:** `docs/smartlead-api.md:284`'s "See also" bullet restating the ramp rule's mechanism (`max_leads_per_day` vs. `message_per_day`) rather than only pointing at line 80 — finding: `duplicated-authority` (See-also restatement). - **Must NOT be flagged:** a genuine clean pointer, e.g. `context/stack/repo-structure.md`'s `See also: [decisions.md](decisions.md) — the settled decisions this structure encodes`, which names the target and its role without restating any specific claim — finding: `NONE`. ### Provenance `/os-aidd-lint:mine-blindspots` run, external corpus `hyperthrive-websites`, bucket (b) (existing-entry wording gap, not a new smell), cited against the `duplicated-authority` catalog entry in `tier2-charter.md` and `AuthoritySourceResolver` (`plugins/os-aidd-lint`, ticket #107 per its own header comment). All three instances independently verified by a second agent pass reading the live corpus files (`CLAUDE.md`, `context/stack/decisions.md`, `context/business/offer-ladder.md`, `context/business/pricing-discipline.md`, `context/business/recurring-revenue.md`, `context/stack/tools.md`, `context/workflow/outreach.md`, `context/open-questions.md`, `docs/smartlead-api.md`). 2026-07-27. ### Catalog-amendment gate This ticket implements nothing on its own. A wording strengthening of an existing entry still needs the eval re-run and hash update `tier2-charter.md`'s own change-control banner requires (per ADR-0060/ADR-0068), plus human review of the diff. This is explicitly NOT a fourth-smell proposal — no ADR amendment for a new catalog entry is being requested, only wording precision on the existing `duplicated-authority` entry. Two owners, named separately per the template's requirement (same person may hold both, but must be stated explicitly): **who approves the charter wording change and re-run**: Jared Swanson (maintainer). **Who edits the charter file**: Jared Swanson (maintainer) or a delegated implementer agent under his review — not to be applied autonomously by this filing agent or any mine-blindspots run. -------- **Discoverer:** hyperthrive-websites, session id unavailable, 2026-07-27. Filed from a mine-blindspots run against this repo as external corpus.
Author
Owner

Analysis in progress (decision-prep only — no charter edit, no label change). Preliminary finding: the resolver reachability claim holds (every cited pair is reachable from at least one side), but the primary causal object for gap (i) appears to be references/tier2-judge-prompt.md, not the charter entry — the only text explaining what the appended ### Authority source: blocks are for lives in that file's HTML comment, which PromptTextFilter strips before assembly. Decision memo to follow.

Analysis in progress (decision-prep only — no charter edit, no label change). Preliminary finding: the resolver reachability claim holds (every cited pair is reachable from at least one side), but the primary causal object for gap (i) appears to be `references/tier2-judge-prompt.md`, not the charter entry — the only text explaining what the appended `### Authority source:` blocks are for lives in that file's HTML comment, which PromptTextFilter strips before assembly. Decision memo to follow.
Author
Owner

Approved by maintainer (Jared): C1 prompt-template instruction block, an opt-in tier2 config flag gating the counterpart diff, and C2 (See-also companion check) through the full change-control gate. Implementation in progress on branch feat/164-tier2-cross-file-authority (isolated worktree). Issue stays open.

Approved by maintainer (Jared): C1 prompt-template instruction block, an opt-in tier2 config flag gating the counterpart diff, and C2 (See-also companion check) through the full change-control gate. Implementation in progress on branch `feat/164-tier2-cross-file-authority` (isolated worktree). Issue stays open.
Author
Owner

Shipped, awaiting sign-off

Branch feat/164-tier2-cross-file-authority (isolated worktree at /home/jared/dev/cc-os-164), 2 commits off e9e2d84. Issue stays open.

  • 8e918c2 — C1 + opt-in flag
  • 2a505f5 — C2 charter edit through the change-control gate

Root cause (differs from the ticket's premise)

The charter was not the broken part for gaps (i) and (ii). It already names cross-file duplication as a structural scale with a verbatim exemplar, and already carries a frontmatter-vs-body exemplar plus an explicit note that paraphrase is the gap the smell exists to close.

The actual cause was prompt assembly: the only sentence explaining what the appended ### Authority source: blocks were for lived in tier2-judge-prompt.md's HTML comment, which PromptTextFilter strips before assembly — and the blocks landed after "NONE is a complete answer". Verified empirically: real judge, real prompt for hyperthrive-websites/CLAUDE.md with 18 counterparts attached, returned NONE. Same charter, same haiku model, plus the instruction block: 5 duplicated-authority findings, including 39: duplicated-authority: The locked decisions are duplicated from context/stack/decisions.md.

Gap (iii) See-also restatement was a genuine charter-wording gap and is what C2 fixes.

Flag

tier2.cross_file_authority, off by default. Off means the instruction block is stripped from the template, no counterparts are attached, and the resolver never runs. The fast path is now cheaper than pre-#164, not merely equal:

prompt lines bytes counterparts instruction
off (default) 380 21,865 0 no
on 1,284 92,536 18 yes

(pre-#164 was 1,264 lines — counterparts attached, instruction absent, i.e. paying the input cost for zero recall.)

Instruction and bodies always travel together by construction; either without the other is cost with no recall.

Gate evidence

309 runs, 762 assertions, 0 failures, 0 errors, 0 skips

Eval fixtures re-run live (eval/bin/run, haiku) against the new charter wording — all three returned well-formed in-catalog findings, no over-firing on clean pointers. RECORDED_SHA25650f0995…, RECORDED_LINE_COUNT 255 → 257. A new charter_test case asserts the See-also bound is present so it cannot be dropped silently.

Notes for the reviewer

  • One near-miss worth knowing: writing the marker delimiters literally inside the template's maintainer comment closes that comment early and leaks maintainer text into the live prompt. Caught by a test; the comment now warns about it.
  • Separate, unverified, not part of this issue: CLAUDE_MD_CHARTER_PATH (judge.rb:16) has no caller in lib/ or bin/charter_path: is only ever defaulted. The ADR-0062 CLAUDE.md-only catalog may never load in production. Worth its own ticket.
  • Not rebased or merged; the concurrent cop work on fix/162-… was left untouched.
## Shipped, awaiting sign-off Branch `feat/164-tier2-cross-file-authority` (isolated worktree at /home/jared/dev/cc-os-164), 2 commits off e9e2d84. Issue stays open. - `8e918c2` — C1 + opt-in flag - `2a505f5` — C2 charter edit through the change-control gate ### Root cause (differs from the ticket's premise) The charter was not the broken part for gaps (i) and (ii). It already names cross-file duplication as a structural scale with a verbatim exemplar, and already carries a frontmatter-vs-body exemplar plus an explicit note that paraphrase is the gap the smell exists to close. The actual cause was prompt assembly: the only sentence explaining what the appended `### Authority source:` blocks were for lived in `tier2-judge-prompt.md`'s HTML comment, which `PromptTextFilter` strips before assembly — and the blocks landed *after* "NONE is a complete answer". Verified empirically: real judge, real prompt for hyperthrive-websites/CLAUDE.md with 18 counterparts attached, returned `NONE`. Same charter, same haiku model, plus the instruction block: 5 duplicated-authority findings, including `39: duplicated-authority: The locked decisions are duplicated from context/stack/decisions.md`. Gap (iii) See-also restatement was a genuine charter-wording gap and is what C2 fixes. ### Flag `tier2.cross_file_authority`, off by default. Off means the instruction block is stripped from the template, no counterparts are attached, and the resolver never runs. The fast path is now *cheaper* than pre-#164, not merely equal: | | prompt lines | bytes | counterparts | instruction | |---|---|---|---|---| | off (default) | 380 | 21,865 | 0 | no | | on | 1,284 | 92,536 | 18 | yes | (pre-#164 was 1,264 lines — counterparts attached, instruction absent, i.e. paying the input cost for zero recall.) Instruction and bodies always travel together by construction; either without the other is cost with no recall. ### Gate evidence ``` 309 runs, 762 assertions, 0 failures, 0 errors, 0 skips ``` Eval fixtures re-run live (`eval/bin/run`, haiku) against the new charter wording — all three returned well-formed in-catalog findings, no over-firing on clean pointers. `RECORDED_SHA256` → `50f0995…`, `RECORDED_LINE_COUNT` 255 → 257. A new `charter_test` case asserts the See-also bound is present so it cannot be dropped silently. ### Notes for the reviewer - One near-miss worth knowing: writing the marker delimiters literally inside the template's maintainer comment closes that comment early and leaks maintainer text into the live prompt. Caught by a test; the comment now warns about it. - Separate, unverified, not part of this issue: `CLAUDE_MD_CHARTER_PATH` (judge.rb:16) has no caller in `lib/` or `bin/` — `charter_path:` is only ever defaulted. The ADR-0062 CLAUDE.md-only catalog may never load in production. Worth its own ticket. - Not rebased or merged; the concurrent cop work on `fix/162-…` was left untouched.
Author
Owner

Addendum — shipped-path verification and how to turn it on

Verified through bin/aidd-lint --tier2-prepare (the path the check skill actually drives), not just the unit-test seam:

# default (flag off)
$ ruby bin/aidd-lint --tier2-prepare .../hyperthrive-websites/CLAUDE.md
380 tmp/aidd-tier2/00.prompt.md
authority headers: 0     instruction block: 0

# with tier2.cross_file_authority: true
1284 tmp/aidd-tier2/00.prompt.md
authority headers: 18    instruction block: 1

How to enable it: Config.load_for walks up from the target file and stops at .git, so the switch lives with the repo being linted — drop an .aidd-lint.yml at that project's root with tier2.cross_file_authority: true. (Flipping the plugin's own shipped .aidd-lint.yml also works, since that is the fallback when no project config is found, but it changes the default for every repo.)

Caveat, pre-existing and not introduced here: a project-level .aidd-lint.yml replaces the shipped config rather than deep-merging with it. A project that adds one only to set this flag silently loses the shipped paths:/gate:/cop settings. Worth its own ticket; I did not change merge semantics under a charter-amendment issue.

Third commit e18b6b8 adds: the dispatch.md / check/SKILL.md corrections (both asserted counterparts are always in the prompt file, which is false in the default config, and dispatch.md's version was the stated rationale for the never-batch safety rule), the missing regression assertion for the comment-truncation bug, and a test rename that was asserting something false.

Final: 309 runs, 764 assertions, 0 failures, 0 errors, 0 skips. Main worktree's concurrent cop work untouched; nothing rebased or merged.

### Addendum — shipped-path verification and how to turn it on Verified through `bin/aidd-lint --tier2-prepare` (the path the `check` skill actually drives), not just the unit-test seam: ``` # default (flag off) $ ruby bin/aidd-lint --tier2-prepare .../hyperthrive-websites/CLAUDE.md 380 tmp/aidd-tier2/00.prompt.md authority headers: 0 instruction block: 0 # with tier2.cross_file_authority: true 1284 tmp/aidd-tier2/00.prompt.md authority headers: 18 instruction block: 1 ``` **How to enable it:** `Config.load_for` walks up from the *target file* and stops at `.git`, so the switch lives with the repo being linted — drop an `.aidd-lint.yml` at that project's root with `tier2.cross_file_authority: true`. (Flipping the plugin's own shipped `.aidd-lint.yml` also works, since that is the fallback when no project config is found, but it changes the default for every repo.) **Caveat, pre-existing and not introduced here:** a project-level `.aidd-lint.yml` *replaces* the shipped config rather than deep-merging with it. A project that adds one only to set this flag silently loses the shipped `paths:`/`gate:`/cop settings. Worth its own ticket; I did not change merge semantics under a charter-amendment issue. Third commit `e18b6b8` adds: the `dispatch.md` / `check/SKILL.md` corrections (both asserted counterparts are always in the prompt file, which is false in the default config, and `dispatch.md`'s version was the stated rationale for the never-batch safety rule), the missing regression assertion for the comment-truncation bug, and a test rename that was asserting something false. Final: `309 runs, 764 assertions, 0 failures, 0 errors, 0 skips`. Main worktree's concurrent cop work untouched; nothing rebased or merged.
Author
Owner

Deferred findings filed

The two items flagged in the notes above are now separate issues, so they don't ride along on this one's sign-off:

  • #166CLAUDE_MD_CHARTER_PATH has no production caller; ADR-0062's CLAUDE.md-only catalog may never load. Grep scope and the limits of what I checked are stated in the ticket; it may be known deferral rather than regression, so it needs a maintainer intent call before anyone wires it.
  • #167 — project-level .aidd-lint.yml replaces rather than merges the shipped config. Sharper than I first described it: a minimal project config leaves paths.include empty and Scope.in_scope? returns false for everything, so the linter silently lints nothing. This matters directly for #164 because dropping a project .aidd-lint.yml is the documented way to enable cross_file_authority — a user turning the flag on from a repo with no existing config gets a silent no-op that looks like a clean scan.

Neither is a blocker for merging this branch. Both are pre-existing and were left untouched here deliberately.

### Deferred findings filed The two items flagged in the notes above are now separate issues, so they don't ride along on this one's sign-off: - **#166** — `CLAUDE_MD_CHARTER_PATH` has no production caller; ADR-0062's CLAUDE.md-only catalog may never load. Grep scope and the limits of what I checked are stated in the ticket; it may be known deferral rather than regression, so it needs a maintainer intent call before anyone wires it. - **#167** — project-level `.aidd-lint.yml` replaces rather than merges the shipped config. Sharper than I first described it: a minimal project config leaves `paths.include` empty and `Scope.in_scope?` returns `false` for everything, so **the linter silently lints nothing**. This matters directly for #164 because dropping a project `.aidd-lint.yml` is the documented way to enable `cross_file_authority` — a user turning the flag on from a repo with no existing config gets a silent no-op that looks like a clean scan. Neither is a blocker for merging this branch. Both are pre-existing and were left untouched here deliberately.
jared closed this issue 2026-07-27 17:05:59 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#164
No description provided.