Skip to content

docs: consolidate the infrastructure backlog and record the starter-set outcome - #79

Merged
twistedmelonman merged 7 commits into
mainfrom
claude/docs-infra-backlog-spec-d8d9b8e2
Sep 3, 2026
Merged

docs: consolidate the infrastructure backlog and record the starter-set outcome#79
twistedmelonman merged 7 commits into
mainfrom
claude/docs-infra-backlog-spec-d8d9b8e2

Conversation

@twistedmelonman

Copy link
Copy Markdown
Member

What

Seven commits of design and planning work: the consolidated infrastructure backlog design, the starter-set implementation plan, and a series of corrections made while the design was under review. Docs only — no code changes.

The final commit records the starter set's outcome, which is now complete.

The design

docs/superpowers/specs/2026-09-01-infrastructure-backlog-design.md consolidates infrastructure work that had accumulated across three trackers that do not talk to each other: open GitHub issues, design docs in docs/plans/, and defects that were found, verified, and never filed at all. It puts them in one dependency-ordered list.

Scope is deliberately infrastructure-only. Product repos were surveyed and excluded, with counts, so the exclusion is auditable rather than assumed.

Starter set — landed

Task Item Outcome
1 nvm default off EOL Node 20 Done — lts/krypton (v24.19.0)
2 claude-code-workflows-agents CI off Node 20 Merged — smartwatermelon/claude-code-workflows-agents#16
3 Withdrawn before execution
4 Retire the .git/config uchg tripwire Done — follow-up smartwatermelon/dotfiles#304
5 Fail closed when GH_TOKEN overrides resolved identity Merged — smartwatermelon/dotfiles#302, follow-up #303

The part worth reading

Several commits here are retractions, and that is the point rather than an embarrassment. The design originally asserted things that turned out to be wrong, and the audit commits walk each one back with evidence:

  • docs(specs): retract the identity-leak claim and audit every verified assertion — an asserted defect that did not survive checking, plus a re-audit of every other claim in the document rather than just the one that failed.
  • docs(specs): the 403 protection group is an org-migration artifact — a symptom that had been read as a defect.
  • docs(specs): record that repo-template re-seeds the pre-policy pin shape — new repos being born non-conformant, which reframes the fleet migration as incomplete rather than done.

The execution surfaced two more instances of the same pattern, both now recorded in the design's status section. Both are false OKs — checks that report success while proving nothing — and both appeared inside the work meant to fix false OKs:

  1. Task 4's first proof was vacuous. It ran the test suite from a linked worktree via a direct bash call. Git exports GIT_DIR into a hook's environment only when git itself dispatches the hook, so the run never saw the condition it claimed to test — it would have passed identically with the guard deleted. Caught in review, confirmed by isolated measurement rather than argument, then redone with an injected GIT_DIR and a negative control proving the trap was live.

  2. Task 5's regression test had never been observed failing. The test and its fix were written together, so the "known-bad case" was assumed rather than demonstrated. Proven retroactively against a pristine pre-fix copy of the wrapper. That guard then exposed a genuine gap in test-gh-wrapper-identity.sh, which sandboxed HOME but inherited the developer's ambient GH_TOKEN.

Also recorded

What was deliberately not filed: the git-identity.sh org-blindness item that the design lists under "Items needing GitHub issues". The 2026-09-02 audit disproved it as an active defect. If it is ever filed, it is a latent-hazard note, not a bug report.

Advances #78.

https://claude.ai/code/session_01RBvPRMFfep4ktSDfGe9uHq

Claude Code Bot added 7 commits September 1, 2026 11:57
…-mapped design

Survey open issues, plan/design docs, and verified-but-unfiled defects across
the eight infrastructure repos, and order them into a single dependency graph.
Scope is development-environment stability only; product work is excluded.

Three findings came from testing live state rather than reading the existing
reports, and each one changes the plan:

- The GH_TOKEN defect is inverted from how it was carried. The gh wrapper
  never assigns GH_TOKEN; GH_TOKEN overrides the wrapper. The fail-closed
  check reads back hosts.yml, which the wrapper just wrote, so it verifies
  its own output rather than the auth gh will use.
- git-identity.sh sets GIT_AUTHOR_* unconditionally to a smartwatermelon
  address, and git env vars outrank includeIf. Beacon commits made through
  Claude Code carry a personal-org identity. Never filed.
- The active token lacks admin:org, which blocks dev-env#54 Phase 4 --
  the org-level secret management the migration exists to enable.

Six defects share one shape: a check reports success while the thing it
checks is not happening. That pattern drives the plan's central methodological
constraint -- validate every fix against a known-bad case.

Decisions recorded from the design session: cheap-tier GH_TOKEN guard now with
the full router deferred; org migration early, before the fleet passes; zizmor
propagation and branch-protection normalization folded into the standards-check
rollout as one pass per repo; the nightowlstudiollc ruleset deliberately left
out pending a test PR.

Claude-Session: https://claude.ai/code/session_019Yfvqsrzx2ib2a6gRGSiGu
repo-template was not readable when the design was written. Reading it adds
three edges that were missing:

- It ships claude-blocking-review.yml, so it is a source of the workflow W3
  retires. Retiring the reviewer without updating the template seeds every
  subsequently-created repo with a dead caller.
- All three of its workflow callers carry smartwatermelon/* refs, and its
  README hardcodes a gh api repos/smartwatermelon/<name> call. The org
  migration has to rewrite the template, not only the existing fleet.
- Its README documents branch protection as "optional but recommended",
  which is how the fleet reached 6 repos with no protection and 5 with
  strict: true gating nothing. The creation-time fix belongs here.

The three manual steps otherwise match the 2026-08-31 settings-app
evaluation, so the rest of the fold-in scope is unchanged.

Claude-Session: https://claude.ai/code/session_019Yfvqsrzx2ib2a6gRGSiGu
Reading the template's workflow files shows it pins its first-party callers
exactly -- claude-blocking-review.yml@v3.2.1 and claude-assistant.yml@v3.1.1
-- against the settled ref-pin policy of floating @V3.

That policy exists because a first-party security fix reaches consumers by
repointing one tag: GHSA-8q5r-mmjf-575q reached consumers that way while
~19 repos pinned to exact @v3.1.0 received nothing. The fleet already
migrated (claude-wrapper #112/#116/#118, scripts #119/#121, docs corrected
in github-workflows#138); the template was missed. Every repo created from
it is therefore seeded with the shape the fleet moved away from, at two
different stale versions, so a fix reaches neither.

Also records that the template carries no zizmor.yml or pre-commit config,
so it must seed standards-check.yml once that is the fleet's required check.

CLAUDE.md checked and needs no change: an 11-line scaffold with fill-in
prompts, unrelated to the 0-byte github-workflows/CLAUDE.md in L4.

Claude-Session: https://claude.ai/code/session_019Yfvqsrzx2ib2a6gRGSiGu
…issue delta

Sweeps both orgs for issues opened since the design was written (six found)
and records the disposition of each. dev-env#78 (Node 20 past EOL) is the
only new scope; it becomes N1, covering product repos as well as
infrastructure ones by decision, since runtime EOL is a property of the whole
fleet rather than of a repo's category. That exception is stated explicitly
against the design's product-exclusion boundary rather than left to contradict
it silently.

Adds the implementation plan for the starter set only — N1a, F2, F3, and the
remainder of L1. These four are the items with no unresolved upstream
decision, so every task is written with real code instead of placeholders.
Blocked tracks are listed with the specific decision each waits on.

Re-verifying live state before planning found two design items already
implemented in the intervening day:

- F1's shared owner-resolver exists and is already shared by both callers.
- L1's isolation fix has landed with a known-bad-validated regression test;
  only the manual uchg tripwire removal remains.

Both are corrected in the design rather than left to be re-planned as
unstarted work — the same doc-drift the L4 item exists to fix.

Also records the F4 decision: route org-level operations to the keyring
identity rather than widening the CCCLI PAT, which would add admin:org to the
one credential exported into every session unconditionally.

Advances #78

Claude-Session: https://claude.ai/code/session_012yVgeNiQARufjPhKnFZUVZ
… assertion

Andrew disproved the cross-org identity leak by inspection: his beacon commits
author correctly as andrew.rich@beacon.bio. Checking the mechanism confirms he
is right and the design was wrong.

Measured on arich-mac.local: claude-wrapper is not installed there, so the code
that exports the bot identity does not exist on the only machine holding beacon
checkouts. Bot-authored commits across all five beacon repos: zero.
~/.gitconfig-beacon exists and the includeIf block resolves. The design called
that block dead; it works.

The precedence fact underneath is real and now measured rather than assumed:
in a scratch repo configured as arich@beacon.bio, the wrapper's GIT_AUTHOR_*
variables do override it. But nothing is exposed to that. Reclassified as a
latent hazard conditional on installing the wrapper on the work machine, and
withdrawn from the starter-set plan.

The original claim cited dev-env and tensegrity as its evidence — personal
repos on the personal machine, which confirm the bot identity applies where it
should. The beacon consequence was inferred from that and written as though
measured. Neither the beacon directory nor ~/.gitconfig-beacon exists on the
machine where the claim was written, so it could not have been checked there.

Since one verified claim was an inference, all of them needed re-testing. The
audit re-measured every such assertion, over SSH where it concerned the work
machine. Eleven hold, including the GH_TOKEN scope split and the admin:org 403
that F4 and I3 depend on. Two more are false:

- claude-config's .pre-commit-config.yaml is not repos:[] — fixed 2026-08-26,
  and its header documents the empty version as the mistake the design accuses
  it of. L3 is two bugs, not three.
- "6 repos with no protection, including scripts" is wrong twice: 8 repos are
  unprotected, and scripts is not one of them. It returns 403 Pro-gated, so its
  protection is unreadable rather than absent.

Fleet totals have drifted: 44 non-archived repos, not 39; 26 with one required
check, not 27.

A first pass of the audit matched the bare check name claude-review, returned
zero repos, and would have read as a fleet-wide regression. The real context is
claude-review / run-review — a gotcha this very document records, which caught
the auditor anyway.

Also resolves the L5 open question: all five dotfiles junk files are untracked.

Advances #78

Claude-Session: https://claude.ai/code/session_012yVgeNiQARufjPhKnFZUVZ
Andrew identified the cause the audit had only measured the symptom of: the
three repos returning 403 on branch protection are private repos owned by the
user account rather than an organization. GitHub does not offer branch
protection there at this tier.

Verified: scripts, claude-config-backup and cleanroom are all private=true
owner.type=User and return 403. The private repos that do carry readable
protection — kebab-tax, financial-agent — are owner.type=Organization. Private
under a user account is the whole predicate.

This reclassifies the group from a gap to close into a category I3 dissolves.
Once these repos move to the new org, protection becomes settable and they join
the normal fleet, so no separate remediation is warranted and W2 should not
treat them as a branch-protection gap.

Two downstream corrections follow from it:

- The W2 pilot rationale picks scripts because its claude-review check is
  "Pro-gated and therefore not enforced". That is right about the effect and
  wrong about the cause, and it expires at I3 — W2 runs after the migration,
  by which point scripts is org-owned and its checks enforce. The safe-pilot
  choice has to be re-made then.

- I3 gains an argument the design never credited it with: migration is the only
  way those three repos can ever be protected at all. That strengthens the
  migrate-early decision independently of the conflict-ambiguity reasoning
  already recorded.

Claude-Session: https://claude.ai/code/session_012yVgeNiQARufjPhKnFZUVZ
…ings

The status line claimed no implementation had started, which stopped being
true on 2026-09-02. Replaces it with a per-task outcome table pointing at the
merged PRs and the two follow-up issues.

Carries forward the two findings worth more than their tasks were: Task 4's
first proof was vacuous (a direct `bash` run never receives the GIT_DIR git
exports only when dispatching a hook, so it would have passed with the guard
deleted), and Task 5's regression test had never been observed failing before
its fix existed. Both are the false-OK pattern this design was written to
attack, found inside the work meant to fix it.

Also records what was deliberately NOT filed: the git-identity.sh
org-blindness item, which the 2026-09-02 audit disproved as an active defect.

Claude-Session: https://claude.ai/code/session_01RBvPRMFfep4ktSDfGe9uHq
@twistedmelonman
twistedmelonman merged commit ef3e889 into main Sep 3, 2026
2 checks passed
@twistedmelonman
twistedmelonman deleted the claude/docs-infra-backlog-spec-d8d9b8e2 branch September 3, 2026 04:23
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.

1 participant