Skip to content

docs(specs): record the D1 no-op-detector measurement and verdict - #3188

Merged
kyle-sexton merged 6 commits into
mainfrom
claude/work-items-integration-97eo3e
Aug 23, 2026
Merged

docs(specs): record the D1 no-op-detector measurement and verdict#3188
kyle-sexton merged 6 commits into
mainfrom
claude/work-items-integration-97eo3e

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Closes #3121

Summary

#3121 asked whether cut class D1 — content the model already knows — is a scanner shape, a judgment shape, or a routing finding, and required the answer to cite a false-positive rate measured on a real sample rather than estimated. This lands that measurement, its harness, and the verdict as a durable spec record.

The verdict is routing finding: D1 belongs to claude-config:unhobble, which measures the model, not to a text scanner and not to a model-graded lane that grades text.

Fix

Adds docs/specs/d1-model-already-knows-measurement.md, a sibling of the existing briefs in that directory, recording:

  • Method — corpus selectors, sentence-segmentation rules, the instruction test, the predicate's six signal families, sampling seed and stratification, and the five adjudication verdicts.
  • Pinned revision — the measurement is a measurement of a tree, and says which one.
  • Results — flag rate per surface stratum, the adjudicated sample breakdown, the false-positive rate scored both ways.
  • Why it fails — three mechanical predicate defects quantified over the full flagged population, plus the directional failure that is the actual finding.
  • Consequences for feat(claude-config): model-already-knows detector on audit-instructions #3124, D2, and D3.
  • All 185 adjudicated rows in an appendix.

Adds docs/specs/d1-model-already-knows-measurement/ — the three-stage harness (d1_proxy.py, sample.py, adjudication.py) plus a README with the reproduction recipe.

No production code, per the scope #3121 set for itself. Nothing under plugins/ is touched; the added Python is measurement apparatus for a spec record, not a plugin, skill, or CI script.

Verification

The measurement, taken against dff0942917e56929f6146261117a0eceeac502c8:

corpus 895 agent-facing markdown files across 70 plugins
instruction sentences 13,529
flagged by the proposed predicate 6,107 (45.1%)
adjudicated sample 185, random.Random(3121), stratified
genuine no-ops found 0
false-positive rate 94.1% scoring every contested call in the proxy's favour; 100% scoring them against it

The failure is directional rather than merely noisy: 54.8% of the flagged population is in hard-boundary register (never, must, do not, don't, cannot), because the house style writes its load-bearing rules as bare imperatives. Sentences the predicate flags include A human merges — this skill never auto-merges and Do not silently fall back to training data. Over this corpus the proxy is closer to an inverse detector for its target class, and #3124's remediation is whole-sentence deletion.

Reproduction proven, not asserted. The harness was re-run end-to-end in a clean detached worktree at the pinned revision: 895 files, 13,529 sentences, 6,107 flagged, the same 185 sampled rows in the same order, 94.1% / 100%.

Gates run locally against the source checkout:

  • ruff check / ruff format --check — all checks passed, 3 files already formatted
  • markdownlint-cli2 --config .markdownlint-cli2.jsonc — 0 issues
  • typos --config _typos.toml — clean
  • editorconfig-checker — clean
  • gitleaks detect --config .gitleaks.toml — no leaks
  • scripts/check-detector-findings-crosswalk.sh --check — exit 0
  • scripts/check-fleet-audit-doc-grammar.sh --check — exit 0
  • exec-bit sweep — no tracked shebang file left at mode 100644

Review history

Three findings, all correct, all fixed. They are one class: prose asserting something the shipped code did not do, in a record whose whole purpose is making a number checkable.

  1. Codex, P2 — the record promised a reimplementation it could not deliver. The measured revision was unpinned, and was dff09429 (the session checkout), never origin/main; the fixed word lists were summarised rather than shipped; the sampling order was omitted, so seed=3121 alone did not fix the rows. Fixed in 5ce7eb08 by committing the harness and pinning the revision.
  2. MODALS mismatch. The doc listed 13 modal tokens where the code matches 20, omitting shall, require, requires, may not, can't, needs to, be sure — the test gating entry to the 13,529-sentence denominator. Fixed in 41863bbb by naming the constant rather than restating it.
  3. A wrong published number. The hard-boundary regex also matched bare no , which fires on ordinary prose (no proper noun, no path). Measured: 57.0% as shipped, 54.8% with the corrected token set, 2.2 points contributed by bare no alone across 134 sentences. Fixed in d7eb8cc0; the figure is 54.8%.

The verdict is unchanged by all three. A clear majority of the flagged population is still hard-boundary register, which is what makes the failure directional rather than merely noisy. 94.1% is untouched — it comes from the hand adjudication of the 185 sampled sentences, not from any regex — so the bar #3124 is held to does not move.

One latent issue was raised and deliberately not filed: segment() would misread a 4-space-indented ordered-list item as code and drop it. Checked all 895 corpus files at the pinned revision — zero instances, so it moved no reported number.

Related

claude added 2 commits August 23, 2026 15:38
#3121 asked whether cut class D1 — "content the model already knows" — is a
scanner shape, a judgment shape, or a routing finding, and required the answer
to cite a false-positive rate measured on a real sample rather than estimated.

Measured it: 895 agent-facing markdown files, 13,529 instruction sentences, the
proposed predicate implemented verbatim. It flags 6,107 of them (45.1%). A
seeded, stratified sample of 185 flagged sentences, hand-adjudicated against the
protected-content list, yields a 94.1% false-positive rate scoring every
contested call in the proxy's favour, and 100% scoring them against it. Zero
unambiguous true positives.

The failure is directional, not just noisy: 57.0% of the flagged population is
in hard-boundary register, because the house style writes its load-bearing rules
as bare imperatives. Over this corpus the proxy is closer to an inverse detector
for its target class.

Verdict: routing finding — D1 belongs to claude-config:unhobble, which measures
the model, not to a text scanner or a model-graded lane that grades text. The
boundary is one audit-instructions already states in its own Scope section.

Records the method precisely enough to reimplement, the results, and all 185
adjudicated rows, so the 94.1% bar #3124 is held to stays checkable.

Closes #3121
@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 3m 39s —— View job


Claude finished the code review

  • Gather context (PR diff, CLAUDE.md, skill instructions)
  • Run skip-gate checks — PR is open, not draft, and has real review surface (390-line docs addition); proceeded with full review
  • Review changed file against code-review criteria
  • Post findings

Summary

This PR adds a single docs-only file, docs/specs/d1-model-already-knows-measurement.md, recording the D1 "content the model already knows" measurement and routing-finding verdict for #3121. No production code, plugin, skill, or script is touched, matching the PR's stated scope.

Verification performed

Per the code-review lane's rule against restating author-claimed verification, I independently checked what I could from the diff itself rather than trusting the PR description:

  • Arithmetic in the Results tables (flag-rate table, adjudicated-sample table) — recomputed every percentage and sum; all check out (e.g. 6,107/13,529 = 45.1%, 174/185 = 94.1%, 185/185 = 100%).
  • Appendix vs. summary consistency — hand-tallied the verdict column across all 185 appendix rows: 11 contested, 110 FP·directive, 47 FP·protected, 17 FP·artifact, 0 genuine no-op — matches the Results table exactly.
  • Quote fidelity — spot-checked ~10 appendix rows across strata (S1/S2/S3/S4/S5) by grepping the cited sentence against the actual source file (e.g. plugins/coupling/skills/reduce/SKILL.md:124-125, plugins/ai-slop/skills/audit/reference/catalog.md:616, plugins/session-flow/reference/observer.md:24-25). All quoted sentences exist verbatim in the named files, including one labeled FP · artifact that turned out to be a genuine mid-sentence line-wrap segmentation defect, confirming that classification.
  • Cross-referenced quotes from audit-instructions/SKILL.md (the "Scope boundary" and "Recommended-follow-through" text quoted at L172-L176) — both match the source (plugins/claude-config/skills/audit-instructions/SKILL.md:59-60 and :441-442) verbatim, modulo dropped emphasis markers around "text"/"model" (cosmetic, not a factual error).
  • Corpus selector plausibility — the live plugins/**/SKILL.md glob currently returns 235 files vs. the recorded 232 (S1 stratum). This is a small delta most plausibly explained by corpus drift (new skills merged after the measurement's snapshot, e.g. recent commits like feat(docs-hygiene): audit-noise gains three residue shapes (0.20.0) #3162 landed on this same branch) rather than a defect in the record — not raised as a finding.
  • File paths cited in the appendix and Results section resolve to real files in the repo; no dead links or fabricated paths found.

Findings

None. No correctness or maintainability issues that would block this PR — the arithmetic is internally consistent, the appendix reconciles with the summary tables, and every sampled quote traces back to real source text. The doc-only nature of the change and its explicit "no production code" scope (confirmed against docs/specs/ deliberately being outside the docs-only fast-path allowlist per the PR description) are consistent with what's in the diff.
· Branch

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db05375646

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/specs/d1-model-already-knows-measurement.md Outdated
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Claude has reviewed this PR 4 times. The lane skips further automatic reviews after 5; deleting this comment resets the count.

Codex review on #3188 found the record could not actually be reproduced from
its own prose, and it was right on all three counts.

The revision was unpinned. The corpus selectors are relative to a working
tree, so they drift as the fleet grows: applying them to current main yields
904 files against the 895 measured. The measurement was taken at dff0942,
the session's checkout — now stated, with the reason the pin is load-bearing.

The fixed lists were summarised rather than given. IMPERATIVE_OPENERS (125
verbs), NOT_PROPER (197 words), ABBREV, and PATHISH's extension set each
change what gets flagged, so "a fixed opener list" does not determine the
13,529 / 6,107 totals the way the prose implied.

The sampling order was omitted. The draw is order-sensitive; the seed alone
does not fix the rows without the (file, sentence) sort.

Rather than enumerate all of it in prose, the harness is committed under
docs/specs/d1-model-already-knows-measurement/ with a reproduction recipe.
Verified end-to-end against the pinned revision in a clean worktree: 895
files, 13,529 instruction sentences, 6,107 flagged (45.1%), the same 185
sampled rows in the same order, 94.1% / 100%, 57.0% hard-boundary register.

This matters because #3124's acceptance criteria bind any future
implementation to the 94.1% bar, and a bar nobody can recompute is not a bar.

Refs #3121
@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 4m 34s —— View job


Code review complete

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Run skip-gate checks — PR open, not draft, real review surface (new commit adds a 3-script harness responding to the prior Codex reproducibility finding); proceeded with full review
  • Review changed files (d1-model-already-knows-measurement.md, d1-model-already-knows-measurement/{README.md,adjudication.py,d1_proxy.py,sample.py})
  • Post findings

Summary

This commit responds to Codex's prior reproducibility finding by pinning the measured revision and committing the harness (d1_proxy.py, sample.py, adjudication.py) behind the D1 measurement. I checked whether the record's prose description of the method now actually matches the code it ships, since that consistency is the entire point of this commit.

Findings (posted inline)

Two internal-consistency defects, both concrete and checkable from the diff itself — the doc's prose defines a test, the shipped code implements a materially different one, and the doc's key numbers derive from the code, not the prose:

  1. d1_proxy.py's MODALS regex matches 20 tokens; the doc's "Unit" section documents only 13. shall, require, requires, may not, can't, needs to, be sure are used by the script but absent from the doc's backtick-quoted list. This is the test gating entry into the 13,529-sentence instruction count, so a reader reimplementing per the prose (the stated purpose of this record) gets a different denominator than the shipped numbers.
  2. adjudication.py's hard-boundary regex matches don't and bare no , which the doc's 57.0%-register claim attributes to only four words (never, must, do not, cannot). no alone is a very common word in ordinary prose and not a hard-boundary marker by itself, so the reported 57.0% isn't reproducible from the method as stated — the actual regex is measuring something broader than what the prose says it's measuring.

Everything else checked out: arithmetic in the flag-rate and adjudicated-sample tables is internally consistent, IMPERATIVE_OPENERS is exactly 125 entries as claimed, PATHISH's extension list is exactly the 12 claimed, and sample.py's TARGET=180 + floor-of-5 allocation does correctly work out to the claimed n=185 (verified by hand: 69+89+17+5+5=185).

No other correctness or maintainability issues found in the new scripts.

Branch ·

The hygiene job's exec-bit check went red on 5ce7eb0: all three harness
scripts carry a `#!/usr/bin/env python3` shebang but were committed 100644.

Every other shebang-bearing .py tracked in this repo is 100755, and these
three were the only shebang+644 files in the tree — so this is the repo's
existing convention, not a new one. Mode change only; the blob hashes are
unchanged, so the reproduction verified at dff0942 still holds.

Every other hygiene check on that run was green (markdown, typos, gitleaks,
editorconfig, shellcheck, comment-hygiene, machine-specific-paths,
eol-renormalize, schemas, hook-wiring-liveness).

Refs #3121
Comment thread docs/specs/d1-model-already-knows-measurement/d1_proxy.py
Comment thread docs/specs/d1-model-already-knows-measurement/adjudication.py Outdated
@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 4m 16s —— View job


Claude finished the code review

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Run skip-gate checks — PR is open, not draft, this push (5ce7eb0, 2de4959) has real review surface (pinning the measured revision, committing the harness, fixing the exec bit); proceeded with full review
  • Review changed files against code-review criteria
  • Post findings

Summary

This push responds to Codex's P2 from the first commit (unpinned revision, summarized-not-shipped word lists, unfixed sampling order) by committing the harness (d1_proxy.py, sample.py, adjudication.py, README.md) alongside the record, and a follow-up commit fixes the scripts' exec bit. I re-reviewed the full set of 5 changed files, focusing on whether the harness now actually delivers the reproducibility the record claims.

Verification performed

This lane's Bash access is scoped to gh pr diff/view/comment/review, Read, Glob, Grep — I could not execute the Python harness myself, so the reported reproduction figures (895 files / 13,529 sentences / 6,107 flagged / 94.1%·100% / 57.0%) remain author-claimed and unverified by me. What I could and did check statically:

  • Fixed word lists match what's claimed. Counted entries in d1_proxy.py: IMPERATIVE_OPENERS = 125 (L144-L270), NOT_PROPER = 197 (L297-L495), ABBREV = 16 (L98-L115), and PATHISH's extension alternation (L289-L291) = 12 extensions — all match the counts kyle-sexton's reply gives (125/197/16/12), so the lists actually shipped rather than just being re-asserted.
  • Appendix reconciles with the harness's own verdict sets. adjudication.py's CONTESTED/ARTIFACT/PROTECTED sets (L23-L75) have exactly 11/17/47 members (110 fall through to FP-directive), matching both the main doc's Results table and the 185-row appendix verdict-by-verdict for the sample_ids I spot-checked (9/14/25/35/46/72/86/119/129/157/164 → contested; 18/24/29/36/41 → artifact; 2/6/13/20/21 → protected).
  • README's reproduction recipe matches the actual script signatures. d1_proxy.py's sys.argv[1], sys.argv[2] (L598-L599), sample.py's 3-arg main (L65-L66), and adjudication.py's 3-arg main (L131-L132) all line up with the invocations shown in the README. No argument-order mismatch that would break a reader's copy-paste.
  • Stratum selectors in stratum_of() (d1_proxy.py L538-L547) precedence-match the find pipeline in the README exactly (agents before SKILL.md, SKILL.md before generic /skills/, root/output-styles first).
  • Exec bit fix verified directly against the index: git ls-files -s shows all three scripts at mode 100755 with the same blob SHAs listed in the PR's changed-files metadata — the last commit's claimed fix is actually in the tree, not just described.
  • Looked for a segmentation gap in segment() (an indented ordered-list continuation under 4+ spaces would misclassify as a code block and get dropped, since the indented-code exclusion only special-cases [-*+] bullets, not \d+\.L49-L53). Grepped the actual corpus for 4-space-indented numbered items (^ [0-9]+\.\s) across plugins/**/*.md: one hit, in a CHANGELOG.md that isn't part of any corpus selector. Not filing this — the pattern doesn't occur anywhere the harness actually reads, so it can't have moved a reported number.

Findings

None. Everything I could check without executing the harness — arithmetic, appendix-to-verdict-set reconciliation, script/README argument agreement, exec-bit fix — is internally consistent, and the specific gap I went looking for in the segmentation code doesn't have a live instance in the corpus it scans. I was not able to independently re-run the harness end-to-end (this lane's Bash access doesn't extend to arbitrary script execution), so I can't personally confirm the headline 895/13,529/6,107/94.1%/100%/57.0% figures — that verification is author-claimed, per kyle-sexton's reply describing a clean detached-worktree rerun at the pinned revision.
· Branch

claude added 2 commits August 23, 2026 16:01
…bset

Automated review found the Unit section's modal-directive list claimed 13
tokens where MODALS matches 20 — omitting shall, require, requires, may not,
can't, needs to, and be sure.

Not cosmetic: that test gates whether a sentence enters the 13,529-sentence
denominator at all, so "Configuration changes shall be reviewed." is counted
by the script and would not be by a reader reimplementing the documented rule.

Same defect class as the reproducibility finding two commits ago — prose
drifting from the shipped predicate in a record whose whole purpose is letting
#3124 recompute the 94.1% bar. Fixed the same way: name the constant rather
than restate it, matching how IMPERATIVE_OPENERS, NOT_PROPER, ABBREV, and
PATHISH are already handled. The one place an inline enumeration survived is
the one place that drifted.

Swept the rest of the Method section against the code while here: the six
signal families, the 12 PATHISH extensions, the 125 openers, and the 12-char
fragment floor all match.

Refs #3121
Automated review found the register regex broader than what the record said it
measured. It attributed the 57.0% figure to four words but also matched bare
"no " — which fires on ordinary prose ("no proper noun", "no path", "there is
no reason to") and is not a boundary marker.

Measured the difference rather than assuming it small:

  57.0%  as shipped, including bare "no "
  54.8%  never | must | do not | don't | cannot     <- corrected
  50.5%  strictly the four words the doc named
   2.2pt contributed by bare "no " alone, across 134 sentences

Dropped bare "no " and kept don't, which is a genuine boundary marker the
prose had omitted; the doc and README now state the exact token set and point
at the constant. The figure is 54.8%.

The argument is unchanged: a clear majority of the flagged population is still
hard-boundary register, which is the claim the number supports. The 94.1%
false-positive rate — the bar #3124 is held to — is untouched, since it comes
from the hand adjudication and not from this regex.

Third finding in this PR of one class: prose asserting something the shipped
code did not do. The first two were unverifiable claims; this one moved a
published number, which is why it is worth stating plainly rather than
quietly amending.

Refs #3121
@claude

claude Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Claude finished @kyle-sexton's task in 1m 30s —— View job


Code review complete

  • Gather context (PR diff, CLAUDE.md, /review:code-review skill instructions)
  • Invoke /review:code-review and follow its instructions
  • Review changed files against code-review criteria
  • Post findings

Summary

This update (commits 2de4959, 41863bb, d7eb8cc) directly addresses the two findings from my prior review on 5ce7eb08 — the MODALS list mismatch and the hard-boundary-register regex mismatch. I re-reviewed the diff since that commit (git diff 5ce7eb0..d7eb8cc, 5 files, +16/-7) to check whether the fixes actually close the gaps rather than just reword them.

Verification performed

  • MODALS fix (d1-model-already-knows-measurement.md:74-77): the doc no longer restates a stale 13-token subset — it now says "MODALS, 20 tokens" and points at the constant instead of enumerating it. I counted the actual regex alternatives in d1_proxy.py:136-141: must, never, always, should, shall, do not, don't, avoid, prefer, ensure, required, require, requires, may not, cannot, can't, need to, needs to, make sure, be sure — exactly 20. This closes the finding: the prose no longer diverges from the shipped predicate.
  • Hard-boundary regex fix (adjudication.py:121-131): bare no and the redundant must not alternative were dropped from the regex, leaving \b(never|must|do not|don't|cannot)\b — exactly the five tokens the doc now names at d1-model-already-knows-measurement.md:170 (never, must — noted as subsuming must not, do not, don't, cannot). Prose and code now agree.
  • Figure update, cross-checked for stray leftovers: 57.0% was replaced with 54.8% in both d1-model-already-knows-measurement.md:170 and README.md:52 — grepped both files for 57.0/54.8 and found no orphaned references to the old figure.
  • Self-consistency of the new number: the code comment at adjudication.py:124-127 claims removing bare no "inflated this figure by 2.2 points over 134 sentences." That's arithmetically consistent with the two published figures: 6,107 flagged × 2.2pp ≈ 134, and 57.0% − 54.8% = 2.2pp exactly. (I can't re-run the harness against the pinned revision's corpus in this environment, so I can't independently regenerate 54.8% from scratch — but the numbers the diff publishes are internally consistent with each other and with the stated cause.)
  • Exec-bit commit (2de4959): mode-only change, d1_proxy.py/sample.py/adjudication.py100755. Cosmetic; the documented reproduction recipe invokes them via python3 "$H/script.py" either way, so this doesn't fix or break anything functionally.

Findings

None. Both P2/informational issues from the prior review round are substantively fixed, not just reworded — the doc's stated method now matches the shipped code for both the modal-directive test and the hard-boundary regex, and the updated 54.8% figure is propagated consistently everywhere it's cited.
· Branch

@kyle-sexton
kyle-sexton merged commit 49c3d37 into main Aug 23, 2026
52 checks passed
@kyle-sexton
kyle-sexton deleted the claude/work-items-integration-97eo3e branch August 23, 2026 16:12
kyle-sexton added a commit that referenced this pull request Aug 23, 2026
Closes #3118

## Summary

Closes the #3118 work-map by recording what each child actually shipped.
The brief lived in the issue body; the spec is the durable map so a
later reader does not have to reconstruct it from closed children.

## Fix

Adds `docs/specs/agent-doc-register-detectors.md` and points the D1
measurement spec at it:

- D1 (#3124): closed unbuilt; measurement lives in `unhobble` (#3188)
- D2 (#3120): `audit-instructions` I28 coercive-emphasis /
blanket-tool-default
- D3 (#3123): `docs-hygiene:audit-noise` negation-without-positive
- D4 (#3186): sibling restatement — separate PR

Docs-only; no plugin version bump, so it cannot collide with #3186's
`claude-config` detector work.

## Verification

- Spec exists and matches shipped rule ids
- D1 measurement spec now points at this register
- `check-lane-coverage.sh --check` — clean on this branch
- markdownlint on the two changed specs — 0 issues

## Related

- Refs #3120, #3121, #3123, #3124, #3186, #3188

Co-authored-by: Kyle Sexton <kyle-sexton@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

investigate: is "content the model already knows" a scanner shape or a judgment shape?

2 participants