Skip to content

Commit 2d1b467

Browse files
wshallwshallclaude
andcommitted
Merge origin/main (#831) into the #1317 branch
Clean auto-merge, no resolution decisions. origin/main advanced under this worktree while the first merge was being verified -- the fleet shares one repository, so another worktree's fetch moved the ref. Nothing here touches #1317. The only ledger overlap is #1435's own new row, which git merged textually and which sits nowhere near #1317. The row reconciliation stays isolated in c8f9569, which is what a scripted row-merge needs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 parents c8f9569 + b9f4f38 commit 2d1b467

5 files changed

Lines changed: 190 additions & 20 deletions

File tree

.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,25 @@ scripts/security/scan-tokens.local.txt
290290
# directory itself readable so the negation binds. Do not "simplify" it back.
291291
/docs/testing/*
292292
!/docs/testing/VERIFY.md
293+
# docs/testing/README.md is the SECOND negation, and it is a marker rather than QA material.
294+
#
295+
# The rule above works, and its success is the problem: from an engine checkout the directory holds
296+
# one file, so a path cited under it is INDISTINGUISHABLE from work that was never done. A reader
297+
# greps a cited path, finds nothing, and concludes the document does not exist -- when it does, in
298+
# the vault. Measured 2026-09-03: BACKLOG #1011 step 6 instructed a reader to mark a disposition
299+
# discharged in a path under this tree and called that file "the only place in the repo that records
300+
# the true state", a sentence that is false from any engine checkout because the file is not in the
301+
# repo at all. A builder acting on it would have claimed a criterion it could never read.
302+
#
303+
# The marker is the checkout-side answer: standing in the directory, or browsing to it on GitHub,
304+
# you are told the material moved and told not to read absence as evidence. It is a POINTER, never
305+
# an index -- it names no vaulted document, because a path-to-document map over a closed set
306+
# discloses what is NOT covered by subtraction. Keep it that way if you edit it.
307+
#
308+
# This negation and the VERIFY.md one are the ONLY two permitted here, and
309+
# tests/test_private_paths_stay_ignored.py pins the pair as an exact set. A third fails there until
310+
# someone writes down why. See BACKLOG #1435.
311+
!/docs/testing/README.md
293312
# DO NOT ADD docs/benchmarks/ OR docs/quality-gates/ HERE. Both are DELIBERATELY ABSENT. ADR 0160 D6.2
294313
# considered both and left them: the 21 bench handoffs carry the measurement narrative for the ~133
295314
# data files beside them, so untracking either half strips the rationale from records that stay.

docs/BACKLOG.md

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4876,15 +4876,15 @@ Retiring the tree costs the engine nothing operationally: **`tests/test_ech_egre
48764876
3. **Rewrite the `SECURITY.md` 12.1.5 paragraph** so the residual rests on the true ground: not "infeasible", but *buildable off-stdlib and deliberately not owned, because no partner endpoint publishes an ECHConfig and the engine's own TLS stack cannot originate ECH until OpenSSL 4.0*. Same accepted residual; a premise that survives inspection.
48774877
4. **Re-point `rest.py`'s docstring** — `ech_sidecar_url_from_settings` names `tools/ech-sidecar/` by path and asserts it is "proven to hide the SNI". After deletion that path resolves to nothing; the reference becomes the historical commit, and the "proven" claim needs whatever evidence actually backs it or should go.
48784878
5. **Decide `samples/ech-sidecar/README.md`** — the operator recipe (the only file under that sample dir) describes running a sidecar the repo no longer contains. Re-aim it at the generic contract (any loopback ECH-terminating proxy) or retire it with the tree.
4879-
6. **Mark SEC-71 discharged** in `docs/testing/master-test-plan/16-security-phi-and-supply-chain.md`, which specifies this exact disposition and is currently the only place in the repo that records the true state.
4879+
6. **Mark SEC-71 discharged** in `docs/testing/master-test-plan/16-security-phi-and-supply-chain.md`, which specifies this exact disposition. **Corrected 2026-09-03 (BACKLOG #1435): that path is NOT in this repository and this step is not reachable from an engine checkout.** `docs/testing/` is gitignored except `VERIFY.md`, so the document lives in the vault clone and whoever holds it performs this step. The clause this replaces said the file "is currently the only place in the repo that records the true state" — false from any checkout, since the file is not in the repo at all, and a builder acting on it would have claimed a criterion it could never read. See [`testing/README.md`](testing/README.md).
48804880

48814881
**Migration cost: none.** MessageFoundry is a not-yet-deployed beta with zero production instances, and `tools/` has never been in an sdist or a wheel — so no consumer of any published artifact is affected by deleting it. There is no deprecation window to run and nothing to sequence.
48824882

48834883
**Trigger:** already fired — not the ECH build trigger (ADR 0139's is *a partner endpoint begins publishing ECH configs*, and it has not), but this item's own: **an unowned tree is in the repository and two security documents contradict it today**. The ruling is owed now and does not wait on ECH deployment.
48844884

48854885
**Related:** #1010 (split from the same draft — the licence-header gate; `main.go` is 1 of the 196 headerless sources and gets a header only if this rules *keep*), #272 (ADR 0139's owning item), #353 (an ungated compliance artifact — same "nothing compares it to the record" shape), #1000 (a gate that has never been watched fail; here the failure is a *language* nothing gates at all).
48864886

4887-
**Source:** master test plan **SEC-71** (`docs/testing/master-test-plan/16-security-phi-and-supply-chain.md`), which specifies this disposition; escalated 2026-08-04 when the SPDX half of the original draft was found to rest on a false claim and was split out as **#1010**. Every fact above was re-executed against `origin/main` at `df9c4d54`.
4887+
**Source:** master test plan **SEC-71** (`docs/testing/master-test-plan/16-security-phi-and-supply-chain.md` — vault-only, unreadable from an engine checkout; see [`testing/README.md`](testing/README.md)), which specifies this disposition; escalated 2026-08-04 when the SPDX half of the original draft was found to rest on a false claim and was split out as **#1010**. Every fact above was re-executed against `origin/main` at `df9c4d54`.
48884888

48894889
## 1002. AG-rig validation: prove the multi-subnet failover reconnect
48904890

@@ -22025,6 +22025,65 @@ The other four are posture, inherited from the tripwire as it already stood:
2202522025

2202622026
---
2202722027

22028+
## 1435. docs/testing has no checkout-side marker, so a vaulted path reads as unstarted work
22029+
22030+
> 🚧 **Filed 2026-09-03. The marker is built; the gate is researched and deliberately NOT built.** Value **5/10** · Difficulty **2/10** for what shipped, **6/10** for what is left. A documentation and process defect, not a product exposure: MessageFoundry has zero deployments, nothing here reaches an operator, and no impact claim below is present-tense about a running site.
22031+
22032+
**The defect, in one sentence: from an engine checkout, work that is UNREADABLE is indistinguishable from work that is UNSTARTED.**
22033+
22034+
`git ls-files docs/testing` returns one file, and `/docs/security/` is blanket-ignored at `.gitignore:177`. The real documents live in the vault clone. So a reader who greps a cited path, finds nothing, and concludes the work was never done is reasoning correctly from everything the tree shows them, and reaching a false conclusion.
22035+
22036+
**The measured instance, and it carries its own proof.** #1011 step 6 told a reader to mark SEC-71 discharged in a path under `docs/testing/`, and called that file *"currently the only place in the repo that records the true state"*. That sentence is false from any engine checkout, because the file is not in the repo at all. A builder acting on it would have claimed a criterion it could never read. Corrected in the same change that filed this item; both citations in #1011 now name the unreadability in the same breath as the path.
22037+
22038+
Two peer fleets hit the same wall independently on 2026-09-03, on #1152 and on #1193, and a third case put half an availability strategy in a vaulted document under #1191. Three sessions worked it out unaided. The next one may not, and a better brief does not fix it, because the brief author hits the same blind spot.
22039+
22040+
### What shipped here
22041+
22042+
`docs/testing/README.md`, tracked through a second negation under `/docs/testing/*`. A reader standing in the directory, or browsing to it on GitHub, is told the material moved and told not to read absence as evidence. `docs/README.md` carries the same warning at the front door.
22043+
22044+
**It is a POINTER and never an index.** It names no vaulted document. A path-to-document map over a closed set discloses what is NOT covered by subtraction, which is the disclosure the gitignore exists to prevent. Keep it that way. The `docs/security/` half already has its rule in [`SECURITY-DOCS-POLICY.md`](SECURITY-DOCS-POLICY.md) and the marker links there rather than restating it.
22045+
22046+
`tests/test_private_paths_stay_ignored.py` pins the pair as an exact set, so a third negation fails until someone writes down why, and the marker cannot be silently dropped from fresh clones.
22047+
22048+
### The gate: researched, measured, and NOT built. This is the finding, not a shortfall.
22049+
22050+
A test that reds when a ledger body cites a vaulted path without flagging it is the most durable shape and was the first choice. It does not survive contact with the corpus. All figures measured 2026-09-03 against `46ea10a78`, and they are measurements rather than targets.
22051+
22052+
| Granularity | Detection | Result on the corpus |
22053+
|---|---|---|
22054+
| Per line | path pattern | 55 lines cite, 23 carry no flag on the same line |
22055+
| Per line, about three lines of context | path pattern plus `THREAT-MODEL` and `asvs-scorecard` | 75 lines cite, 22 carry no signal (measured independently, two readers agreeing to the line) |
22056+
| Per item body | path pattern | 27 items cite, 2 unflagged |
22057+
| Per item body | path pattern plus `master-test-plan` | 32 items cite, 5 unflagged |
22058+
| Per citation, plus or minus 300 to 1200 characters | path plus name | 15 to 21 items carry at least one unflagged citation |
22059+
22060+
**Three findings, each independently enough to stop the build.**
22061+
22062+
1. **An unscoped gate reds about 22 times on day one**, against a corpus nobody repairs in one pull request. It needs a grandfather baseline or a changed-lines-only scope before it is shippable at all.
22063+
2. **The item-granularity gate is quiet and measures the wrong thing.** At 2 unflagged it would ship comfortably, and it MISSES #1152 — the case that motivated this item. #1152's body flags a different vaulted document (the scorecard) while leaving its master-test-plan clause unflagged, so the item passes while the defect stands. A gate that is quiet because it is aimed slightly wrong is worse than no gate.
22064+
3. **"Cites a vaulted path" overfires, and the real predicate may not be expressible as a pattern.** Line 22 is prose ABOUT the arrangement, not a citation anyone must follow. A table row giving a cell count is permitted vocabulary. Neither is a defect. The actual predicate is **a citation a reader must FOLLOW in order to act**, which is a judgement about intent, and no regex tried here expresses it.
22065+
22066+
**The window parameter is undefended.** Three lines is arbitrary; nobody has a reason for it, and a single-block rule already missed a stale assertion in `docs/SERVICE.md` on a peer's item. Treat 53 against 22 as an order of magnitude, not a threshold.
22067+
22068+
**IF SOMEONE BUILDS THIS, THE FAILURE MESSAGE IS ALSO A DISCLOSURE SURFACE.** A message naming WHICH paths are vaulted publishes the map into CI logs and into the workflow file, both public. That is the enumerating-marker defect wearing different clothes, and the helpful-error-message instinct walks straight into it. A message of the shape *"this item body cites a maintainer-internal path; state in the body that it is unreadable from an engine checkout"* tells the author exactly what to do and discloses nothing. Do not echo the offending path into the message, the summary, or the annotation.
22069+
22070+
### The two-sided controls, named, so nobody re-derives them
22071+
22072+
A gate proven on one side proves nothing: one that fires on everything and one that fires on nothing both look green against a single-sided test.
22073+
22074+
**Fires side (must red), and it is on `main` today:** `docs/BACKLOG.md` lines 4763 and 4771 before the correction in this change. Both named a `docs/testing/master-test-plan/` chapter, and 4763 instructed the reader to act in it. The cleanest true positive in the corpus, and independent of #1152. Recover the pre-correction text from this item's own commit.
22075+
22076+
**Quiet side (must pass):** the remedy bodies on PR 804 (#1191) and PR 812 (#1193). **Both were still unmerged on 2026-09-03**, so a builder calibrating against `main` alone sees the UNFLAGGED versions and draws the wrong conclusion about what the remedy looks like. Read them with `gh pr diff 804` and `gh pr diff 812`. #1191 is the sharper of the two: it records that the availability inventory is vaulted AND records that its builder deliberately did not add a read-side anchor to the public `_RESOURCE_ANCHORS` registry, because the registry is public and the document is not, so the anchor would red a tree nobody in an engine checkout can see or repair.
22077+
22078+
Both are the shape a gate must PERMIT. An unflagged citation is the defect; a flagged one is the remedy the gate exists to produce.
22079+
22080+
### What is left
22081+
22082+
- Decide whether the follow-to-act predicate is expressible. If it is not, that is a finding and this item closes on the marker.
22083+
- If it is, scope the gate to changed lines or grandfather the day-one population, and prove it on both controls above.
22084+
- The `docs/security/` half has no marker of its own. `/docs/security/` is a blanket rule, so a placeholder there needs a deliberate gitignore negation. Judged not worth it here: [`SECURITY-DOCS-POLICY.md`](SECURITY-DOCS-POLICY.md) already states that rule in a tracked file and says how to request the material, and a second marker would restate a load-bearing fact instead of linking to it.
22085+
22086+
**Related:** #1011 (the corrected instance), #1152, #1191 and #1193 (the three peer cases), #1244 (an engine change breaking a vault anchor produces no attribution — the same public-repo-cannot-see-the-vault shape, from the other direction).
2202822087
## 1439. webconsole_seam_snapshot.py resolves messagefoundry from sys.path, not from its own repo
2202922088

2203022089
> 🔢 **Filed 2026-09-03 - BUILT IN THIS COMMIT, not yet landed.** Found while building #1139, by a session that spent its debugging on the gate instead of the generator. The census in LIMB 3 is the reason this is filed as one defect and not a class.

docs/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ different repositories for opposite audiences. `docs/ASVS-L2-PHASE0-CHANGES.md`
88
`docs/testing/VERIFY.md` is an operator tool, not a test plan. Where a name misleads, this index says so
99
rather than repeating it.
1010

11+
**A path you cannot open is not proof the work was never done.** Parts of `docs/` are kept in a separate
12+
maintainer repository, so a citation elsewhere in the tree can be real and still not resolve here.
13+
[`testing/README.md`](testing/README.md) covers `docs/testing/`, and
14+
[`SECURITY-DOCS-POLICY.md`](SECURITY-DOCS-POLICY.md) states the separate rule for `docs/security/` and
15+
`docs/reviews/`, including how to request the withheld material.
16+
1117
> **Reporting a security vulnerability?****[`.github/SECURITY.md`](../.github/SECURITY.md)**, the
1218
> disclosure policy. **Not** `docs/SECURITY.md`, which despite the identical filename is the
1319
> authentication and RBAC reference. Two files, same name, different jobs.

docs/testing/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Most of this directory is not in this repository
2+
3+
Only [`VERIFY.md`](VERIFY.md) is tracked here. Everything else under `docs/testing/` is
4+
maintainer QA planning, and it is kept in a separate maintainer repository.
5+
6+
**So a path under `docs/testing/` that you cannot open says nothing about whether the work
7+
exists.** Unreadable and unstarted look identical from an engine checkout, and that is the
8+
mistake this page exists to stop.
9+
10+
## Why you are probably reading this
11+
12+
You followed a citation. `docs/BACKLOG.md`, an ADR, a test docstring or a source comment names a
13+
path under `docs/testing/`, you went looking for it, and it is not on disk. That citation is real.
14+
It names a document that exists, and it is written for provenance: it records where a decision or
15+
a test row came from, not a file you can open here.
16+
17+
`git ls-files docs/testing` returns one file. That is the rule working, not a gap.
18+
19+
## What this means when you are grading work
20+
21+
Do not treat an unreadable document as an absent one.
22+
23+
If an item asks you to satisfy a criterion, discharge a row, or check a claim in a document under
24+
`docs/testing/`, you cannot verify that half from an engine checkout. Say so in those words. Record
25+
the limb as unverified, not as satisfied and not as missing. Claiming you met a criterion you could
26+
not read is the failure mode; it happened, and it is why this file is here.
27+
28+
The same caution applies to the reverse move. A limb that looks undone may simply be graded in a
29+
document you do not have.
30+
31+
## Why the split
32+
33+
[ADR 0160](../adr/0160-public-repo-content-policy-operator-and-security-review-material-only.md)
34+
sets the test: a tracked file must be something an operator running MessageFoundry needs, or
35+
something a security reviewer assessing it needs. QA planning for a maintainer build box is
36+
neither, so it moved. `VERIFY.md` stayed because it documents `messagefoundry verify`, the on-box
37+
acceptance check a real deployment runs.
38+
39+
None of this is a confidentiality control and it must never be described as one. This material was
40+
never secret. It is process noise, and moving it was subject-matter tidying.
41+
42+
The `.gitignore` block that implements the split carries the full reasoning. Search it for
43+
`/docs/testing/*`.
44+
45+
## The neighbouring case, which is a different rule
46+
47+
`docs/security/` and `docs/reviews/` are also absent, and they are held back for their own reasons.
48+
[`SECURITY-DOCS-POLICY.md`](../SECURITY-DOCS-POLICY.md) states that rule, says what is public, and
49+
tells adopters, evaluators and security reviewers how to request the withheld material. Read it
50+
there. Do not assume the reasoning on this page carries over.
51+
52+
## What this page will not do
53+
54+
It will not list what is in the other repository. A path-to-document map over a closed set hands out
55+
what is not covered by subtraction, so this is a pointer and never an index. If you need something
56+
named here, ask a maintainer through the route `SECURITY-DOCS-POLICY.md` documents.
57+
58+
## If you are writing a citation
59+
60+
Name the unreadability in the same breath as the path. One clause is enough, for example that the
61+
path is vault-only, gitignored, or unreachable from an engine checkout. A reader who meets your
62+
citation months later gets the same warning you would have wanted, without having to find this page
63+
first.

0 commit comments

Comments
 (0)