DECISION NEEDED: canonical REPO_POLICIES.md is missing the in-repo memory bullet that stale vendored copies still carry — retired, or lost? #31

Open
opened 2026-08-09 12:02:11 +02:00 by clawbot · 0 comments
Collaborator

Found by the sfdupes manager while re-vendoring REPO_POLICIES.md, verified independently by the dispatcher against ~/dev/prompts/prompts/REPO_POLICIES.md.

Blocking request to every repo manager: pause blind re-vendoring of REPO_POLICIES.md until this is answered. Several repos almost certainly carry the same stale copy, and re-vendoring silently deletes the paragraph below in each one.

The finding

The drift is bidirectional, which is not what anyone expected. The stale 368-line vendored copy in sfdupes was not simply an old prefix of the 408-line canonical file: it also contained an 11-line bullet that canonical does not have — the one requiring repo memory to be versioned in-repo as .claude/memory/*.md files imported from .claude/CLAUDE.md, and declaring a root MEMORY.md a violation.

Verified: canonical is 408 lines and contains zero occurrences of that vendor directory name; the old vendored copy contained eight.

Why it needs an owner decision

Two readings, with opposite consequences, and no way to tell which from the file alone:

  1. The bullet was retired upstream deliberately. Then every repo still carrying an old copy is silently governed by a rule that no longer exists, and each re-vendoring quietly deletes it. That wants a sweep, but re-vendoring is otherwise correct.
  2. The bullet was lost from canonical by accident. Then re-vendoring is actively propagating a regression across the fleet, and every repo "fixed" this way makes it worse.

This is not academic — repos on this fleet do have .claude/ directories, and the dispatcher maintains committed memory under _PROJECTS/.claude/memory/ on the strength of that rule.

The sfdupes manager copied canonical wholesale rather than re-adding the paragraph, which was the right call for a vendored file — re-adding something upstream lacks recreates exactly the drift the work was meant to kill — but it correctly refused to guess which direction is authoritative.

What is needed

  • A ruling on whether the in-repo memory requirement is current policy.
  • If current: restore it to canonical, then re-vendoring is safe and repos that already re-vendored need it back.
  • If retired: say so here, and the managers can re-vendor freely knowing the deletion is intended.

Separate finding from the same work, no decision needed

Canonical line 97 requires Dockerfiles to install prerequisites by running script/bootstrap rather than inline, copying script/ and the manifests first so the bootstrap layer caches. sfdupes' Dockerfile did the opposite (RUN apk add --no-cache make, never invoking bootstrap) and nothing caught it, because that requirement was among the 40 lines missing from its stale copy.

This matters beyond style: script/bootstrap is what pins and verifies the linter version (see #28), so a Dockerfile that bypasses it maintains a second, independent notion of the toolchain — reintroducing the local-versus-CI divergence #28 exists to close, one layer down. If the canonical Go Dockerfile template also does an inline install, every Go repo has this. Worth checking alongside #26.

Trap in the fix, worth carrying into any implementation: the COPY --from=lint /usr/bin/golangci-lint line doubles as the BuildKit stage dependency that forces the lint stage to complete first. If bootstrap installs the linter in the build stage and someone removes that copy as now-redundant, the fail-fast design dies silently and lint stops gating the build.

Found by the sfdupes manager while re-vendoring `REPO_POLICIES.md`, verified independently by the dispatcher against `~/dev/prompts/prompts/REPO_POLICIES.md`. **Blocking request to every repo manager: pause blind re-vendoring of `REPO_POLICIES.md` until this is answered.** Several repos almost certainly carry the same stale copy, and re-vendoring silently deletes the paragraph below in each one. ## The finding The drift is **bidirectional**, which is not what anyone expected. The stale 368-line vendored copy in sfdupes was not simply an old prefix of the 408-line canonical file: it also contained an 11-line bullet that canonical does **not** have — the one requiring repo memory to be versioned in-repo as `.claude/memory/*.md` files imported from `.claude/CLAUDE.md`, and declaring a root `MEMORY.md` a violation. Verified: canonical is 408 lines and contains **zero** occurrences of that vendor directory name; the old vendored copy contained eight. ## Why it needs an owner decision Two readings, with opposite consequences, and no way to tell which from the file alone: 1. **The bullet was retired upstream deliberately.** Then every repo still carrying an old copy is silently governed by a rule that no longer exists, and each re-vendoring quietly deletes it. That wants a sweep, but re-vendoring is otherwise correct. 2. **The bullet was lost from canonical by accident.** Then re-vendoring is actively **propagating a regression across the fleet**, and every repo "fixed" this way makes it worse. This is not academic — repos on this fleet do have `.claude/` directories, and the dispatcher maintains committed memory under `_PROJECTS/.claude/memory/` on the strength of that rule. The sfdupes manager copied canonical wholesale rather than re-adding the paragraph, which was the right call for a vendored file — re-adding something upstream lacks recreates exactly the drift the work was meant to kill — but it correctly refused to guess which direction is authoritative. ## What is needed - A ruling on whether the in-repo memory requirement is current policy. - If current: restore it to canonical, then re-vendoring is safe and repos that already re-vendored need it back. - If retired: say so here, and the managers can re-vendor freely knowing the deletion is intended. --- ## Separate finding from the same work, no decision needed Canonical line 97 requires Dockerfiles to install prerequisites by running `script/bootstrap` rather than inline, copying `script/` and the manifests first so the bootstrap layer caches. sfdupes' Dockerfile did the opposite (`RUN apk add --no-cache make`, never invoking bootstrap) and nothing caught it, because that requirement was among the 40 lines missing from its stale copy. **This matters beyond style:** `script/bootstrap` is what pins and verifies the linter version (see #28), so a Dockerfile that bypasses it maintains a second, independent notion of the toolchain — reintroducing the local-versus-CI divergence #28 exists to close, one layer down. If the canonical Go Dockerfile template also does an inline install, every Go repo has this. Worth checking alongside #26. **Trap in the fix, worth carrying into any implementation:** the `COPY --from=lint /usr/bin/golangci-lint` line doubles as the BuildKit stage dependency that forces the lint stage to complete first. If bootstrap installs the linter in the build stage and someone removes that copy as now-redundant, the fail-fast design dies silently and lint stops gating the build.
sneak was assigned by clawbot 2026-08-10 14:29:52 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/prompts#31