Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .harness-hash
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
7c51b2422a2578ab34c9415f1bcb9456bf2ca0c6f6dbe6d828c35d2dbd7dc8b4 000-docs/000-INDEX.md
bcfa54f647187b02bfc8caa23e2e89672e52ef877b988d7705c6c02b86c114a8 000-docs/000-INDEX.md
a95f7d4b328f506d53ccc028486f80e79cd7854b7985e838ec6913af21a47f33 000-docs/001-PP-PLAN-buzz-adoption-master-blueprint.md
def765bd4f637f1b2cfe5abdb508837e3247b771c8530d0ef394a587c6adc250 000-docs/002-DR-DECR-buzz-adoption-decision-record.md
5030aaf8545985489095cc6f48badee6981f4f2db7b2ba9879877f4bb6bfb755 000-docs/003-OD-DEPL-deploy-posture-public.md
9bcad2b30288a04687745e989a9779823ed16891c1e3c5fa8ae544fa3d814ca7 000-docs/004-DR-DECR-fork-gate-wiring.md
75b5b1253248fd4f04aebfae36efeb2ce48323a567d4ca63d59e0d67667789f6 000-docs/005-DR-DECR-dedicated-vps-topology.md
27bf0d046df299a1662b8c86b4b8a9da1e0c8e14e98c0919d2873014c1080b47 000-docs/006-DR-STND-authoritative-naming-and-boundaries.md
d47f82f7f176ad3fbd87d6e6d6acd8248a2347439de6df6ed3d16f643669088f 000-docs/007-AA-AUDR-fork-contract-breach-2026-08-03.md
fbeaab57a0f6fe0ab1cb876154b1b356e69e88f2803440eeeeb26689723eafdf 000-docs/008-AA-AUDR-fork-allowlist-lockstep-2026-08-08.md
d1c85ad5bafc4b6eb1f78ec888746f66f45e87cb9fd9d84122cfdd59994821c4 FORK.md
43f3750a570e82cfa0c0cdef6ff51d962f7dbd98f892b590c0a30955043c0ab4 TEST_AUDIT.md
da2d266381d9209da59fcc6b06ca351e8eaf0b56470b5353557cc5eb48354761 lefthook-local.yml
fa65f444d630a5eb6db9aa2e306bb389aefd08837a6c696793dc29579369b03c scripts/fork-gates/check-additive-only.sh
f7a59e4016e8ebecf175be942fd2a021327641b8834ed59af4568896a82fb214 scripts/fork-gates/check-additive-only.sh
5fce5778878475c456ad90fdd1a0d559b5b9bc44cfa583dddd7a783f09397930 scripts/fork-gates/check-must-survive.sh
1 change: 1 addition & 0 deletions 000-docs/000-INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ This directory is an Intent Solutions **addition** to the fork — upstream
| 005 | [DR-DECR — Dedicated production VPS topology](005-DR-DECR-dedicated-vps-topology.md) | Owner decision (2026-07-29): production on a dedicated VPS; the shared-host stack becomes permanent staging. Supersedes the one-server answer in `001`/`003`. |
| 006 | [DR-STND — Authoritative naming & boundaries](006-DR-STND-authoritative-naming-and-boundaries.md) | **CANONICAL** (owner amendment 2026-07-29, FINAL): the six Buzz assets, the host-vs-repo disambiguation rule, the four-plane flow, and the two gates (contribution vs deployment). Any doc naming a Buzz asset defers to this. |
| 007 | [AA-AUDR — Fork-contract breach audit 2026-08-03](007-AA-AUDR-fork-contract-breach-2026-08-03.md) | PR #16 merged 14 upstream-owned paths onto fork `main` (process breach only; prod untouched). Divergence inventory, causal chain (gates never in CI), remediation: revert → repair-branch sync → upstream via the contribution lane → gates as a required CI check. |
| 008 | [AA-AUDR — Fork allowlist lockstep audit 2026-08-08](008-AA-AUDR-fork-allowlist-lockstep-2026-08-08.md) | The `ALLOW` array granted `.gitleaksignore`, a path `FORK.md` never declared, that does not exist and that no tool uses. Removed rather than documented, per `decision-log/048` D170/D171 — removal fails closed. No breach, no divergence change. |
108 changes: 108 additions & 0 deletions 000-docs/008-AA-AUDR-fork-allowlist-lockstep-2026-08-08.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# 008 — AUDIT: the fork allowlist granted a path the contract never declared

**Date:** 2026-08-08
**Type:** Audit record (AA-AUDR)
**Trigger:** A handover readiness pass on the Buzz documentation set. Carter Gray is taking over Buzz
management, so `FORK.md` was re-read as the contract a new maintainer is handed, and checked against
the code that enforces it rather than accepted as written.
**Severity:** Low. No breach, no divergence, no production impact. Recorded because the defect class
— the human contract and its machine form disagreeing — is exactly what `007` cost us.
**Status:** Fixed in this change.

---

## 1. The claim under test

`scripts/fork-gates/check-additive-only.sh`, immediately above the `ALLOW` array:

> ```text
> # The fork allowlist — every path prefix this fork is allowed to differ on.
> # Keep in lockstep with the FORK.md must-survive table (that table is the
> # human contract; this array is its machine form).
> ```

Two artifacts, one asserted to be the other's machine form. That assertion is testable, and nothing
tests it — `check-must-survive.sh` asserts the *paths exist*, not that the two lists agree.

## 2. Finding — one entry in `ALLOW` has no row in `FORK.md`

Comparing the 13 `ALLOW` entries against the 10 path rows of `FORK.md` § *Must-survive set*:

| `ALLOW` entry | `FORK.md` row |
|---|---|
| `FORK.md`, `TEST_AUDIT.md`, `000-docs/`, `.beads/` | present |
| `scripts/fork-gates/`, `scripts/audit-harness`, `.audit-harness/` | present |
| `.harness-hash`, `.harness-hash-extra-patterns`, `lefthook-local.yml` | present |
| `CLAUDE.md`, `.github/workflows/fork-gates.yml` | present (declared divergences) |
| **`.gitleaksignore`** | **absent** |

Three further facts settle what to do about it:

- **The file does not exist.** Not in the worktree, not in `git diff upstream/main...HEAD`.
- **Nothing would use it.** `gitleaks` does not run anywhere in this repository — the only workflow
is `fork-gates.yml`, whose two steps are the additive-only and must-survive checks. The single
occurrence of the string `gitleaks` in the entire repo was that `ALLOW` entry.
- **It is a permission, not a claim.** `ALLOW` means *"if this path differs from upstream, that is
allowed"*. So the entry was standing permission for a file nobody needs, that no gate would
notice appearing.

## 3. Why removal, rather than adding a row to `FORK.md`

Both fixes restore lockstep. Adding a `FORK.md` row would have documented a file that does not
exist — and `decision-log/048` (D170/D171, 2026-08-07) ratified the opposite instinct four weeks
into exactly this problem: *docs should describe things that exist*, and a name held in reserve is
indistinguishable, to a reader six months later, from something they cannot find. That ruling
retired two phantom repositories and deleted the disambiguation rule they had forced.

The same reasoning applies to a permission held in reserve, with an extra argument on top:
**removal fails closed.** If a `.gitleaksignore` is ever genuinely wanted, the additive-only gate
will refuse the diff until `FORK.md` and `ALLOW` are updated together — which is the contract doing
its job, and precisely the review step that `007` found had been missing.

## 4. What changed

- `scripts/fork-gates/check-additive-only.sh` — `.gitleaksignore` removed from `ALLOW` (13 → 12).
- `.harness-hash` re-pinned, because `scripts/fork-gates/*.sh` is inside the hash-pinned policy
surface (`.harness-hash-extra-patterns:7`). An unpinned edit to a gate script is the thing that
pin exists to catch.

`FORK.md` is unchanged — it was already correct; the array had drifted away from it.

**Incidental finding, surfaced by the re-pin and worth naming rather than letting it ride in
silently:** `.harness-hash` was missing an entry for `000-docs/007-AA-AUDR-fork-contract-breach-2026-08-03.md`.
That file is inside the pinned surface, so it should have been pinned when it was added on 2026-08-03
and `scripts/audit-harness init` was evidently not re-run then. Re-pinning here picked it up, so the
manifest now covers 14 files rather than 12. Nothing was tampered with — an unpinned file is simply
one the verify step was silently not watching, which makes this the second instance in this same
audit of *enforcement whose scope quietly stopped matching its subject*.

## 5. Verified

`check-additive-only.sh upstream/main` and `check-must-survive.sh` both pass against the reduced
array, and `scripts/audit-harness verify` passes on the re-pinned manifest. The divergence set is
byte-for-byte what it was before this change.

## 5b. A correction to this record, and it proves the point

The first draft of this audit stated "14 `ALLOW` entries" and "11 rows", and listed `REVIEW.md`
among the matched entries. **Those numbers were read off the wrong branch** — the unmerged
`chore/retire-phantom-lab-repos`, which adds `REVIEW.md` to `ALLOW` *and* to `FORK.md` (correctly, in
lockstep). On `main`, the base this change targets, `REVIEW.md` exists in neither list and the file is
not in the divergence set at all. The correct counts are **13 → 12** against **10** `FORK.md` rows.

Caught in review by CodeRabbit, verified against `git show origin/main:…` before accepting. Recorded
rather than silently amended, because an audit about two lists disagreeing that itself miscounted the
lists is the strongest available argument for the follow-up in § 6: **counts asserted by a human are
exactly the thing a gate should be computing.**

## 6. Method note

This was found by diffing the two lists rather than by reading either one. `007`'s causal chain was
*"the gates existed but were never in CI"* — enforcement that is present but not wired. This is the
adjacent failure: enforcement that is wired, but whose scope no longer matches the contract it
claims to enforce. A comment saying *"keep these in lockstep"* is an unenforced assertion, and this
repository's own history is the argument for not trusting those.

**Worth considering as a follow-up, deliberately not done here:** a check that parses the `FORK.md`
table and asserts set-equality with `ALLOW`, so the lockstep comment becomes a gate. It is a small
script; it is not this change, because this change should be reviewable as a one-line removal.
1 change: 0 additions & 1 deletion scripts/fork-gates/check-additive-only.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ ALLOW=(
"TEST_AUDIT.md"
"000-docs/"
".beads/"
".gitleaksignore"
"lefthook-local.yml"
"scripts/fork-gates/"
"scripts/audit-harness"
Expand Down
Loading