Skip to content

docs(fleet): replace the stale fifteen-repo count in cloud-fleet-setup - #4181

Merged
kyle-sexton merged 4 commits into
mainfrom
docs/fleet-count-drift
Sep 15, 2026
Merged

kyle-sexton merged 4 commits into
mainfrom
docs/fleet-count-drift

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

No related issue: adjacent drift found while landing the CLOUD-FLEET-SETUP inventory fix (#4163)

Summary

docs/cloud-fleet-setup.md, under ## Bootstrap adoption (2026-08-16), asserted a hardcoded
repository count in the present tense:

Adoption is complete and no longer a per-repo decision surface: all fifteen non-archived
melodic-software repositories (gh repo list melodic-software --json name,isArchived) carry
.claude/cloud-bootstrap.sh, register it as a startup|resume SessionStart hook, and declare the
melodic-software marketplace.

The org has 16 non-archived repositories today, so the number is stale. A present-tense count of a
set that grows whenever someone creates a repository will rot again the next time it grows.

Fix

Remove the number, scope the claim to the date the pass was actually run (2026-08-16, which is the
section's own heading date and already the date recorded in the doc's basis paragraph), and name the
gap class the date introduces instead of enumerating repositories. The paragraph already closes with
"Read adoption state from the repos rather than from a table here; a per-repo enumeration in this doc
can only lag them", so the fix leans on that pointer rather than duplicating it.

The cited query is also tightened from --json name,isArchived to --no-archived --json name, which
returns exactly the set the sentence describes rather than requiring the reader to filter it.

Before:

Adoption is complete and no longer a per-repo decision surface: all fifteen non-archived
melodic-software repositories (gh repo list melodic-software --json name,isArchived) carry
.claude/cloud-bootstrap.sh, register it as a startup|resume SessionStart hook, and declare the
melodic-software marketplace.

After:

Adoption is no longer a per-repo decision surface: as of 2026-08-16, every non-archived
melodic-software repository (gh repo list melodic-software --no-archived --limit 100 --json name; the --limit matters, since gh repo list returns only 30 by default) carried
.claude/cloud-bootstrap.sh, registered it as a startup|resume SessionStart hook, and declared
the melodic-software marketplace; a repository created after that pass is not covered by it.

The --limit 100 and its explanatory clause came from Codex review feedback on the first commit
(see the resolved thread); the cited query originally omitted the flag. gh repo list returns only
30 repositories by default, so a reader running the cited command once the org passes 30 would
enumerate a truncated fleet while the prose claims fleet-wide coverage — the same rot class this PR
exists to remove. Confirmed on this host:

$ gh repo list --help | grep -i limit
  -L, --limit int           Maximum number of repositories to list (default 30)

No count is asserted in the new text. There is no repo-inventory file to point at instead: the
"standards fleet list" this doc references elsewhere is
components/cloud-environment/fleet-plugins.json, which is a plugin list, not a repository list. The
authoritative definition of the set is the gh repo list query, which the sentence already cites
inline.

Verification

Current non-archived repository count. Every number in this PR comes from these commands.

$ gh repo list melodic-software --no-archived --limit 100 --json name,isArchived -q '.[].name' | tr -d '\r' | sort | cat -n
     1	.github
     2	agent-plugins
     3	ci-runner
     4	ci-workflows
     5	claude-code-account-rotation
     6	claude-code-plugins
     7	claude-code-proxy
     8	codex-plugins
     9	cursor-plugins
    10	dotfiles
    11	github-iac
    12	knowledge-corpus
    13	medley
    14	provisioning
    15	songwriting
    16	standards

$ gh repo list melodic-software --no-archived --limit 100 --json name -q '.[].name' | tr -d '\r' | sort | wc -l
16

Sixteen, not fifteen.

Which repositories postdate the 2026-08-16 pass:

$ gh repo list melodic-software --no-archived --limit 100 --json name,createdAt -q '.[] | "\(.createdAt) \(.name)"' | tr -d '\r' | sort | tail -5
2026-07-30T19:18:53Z claude-code-proxy
2026-07-30T23:54:52Z cursor-plugins
2026-08-04T22:12:16Z codex-plugins
2026-08-17T20:02:14Z agent-plugins
2026-09-05T18:24:03Z claude-code-account-rotation

Two repositories (agent-plugins, claude-code-account-rotation) were created after 2026-08-16.
This is what the new "a repository created after that pass is not covered by it" clause names.

Whether each repository carries .claude/cloud-bootstrap.sh today (16 of 16):

$ for r in .github agent-plugins ci-runner ci-workflows claude-code-account-rotation claude-code-plugins claude-code-proxy codex-plugins cursor-plugins dotfiles github-iac knowledge-corpus medley provisioning songwriting standards; do
    s=$(gh api "repos/melodic-software/$r/contents/.claude/cloud-bootstrap.sh" --jq '.name' 2>/dev/null | tr -d '\r')
    echo "$r: ${s:-MISSING}"
  done
.github: cloud-bootstrap.sh
agent-plugins: cloud-bootstrap.sh
ci-runner: cloud-bootstrap.sh
ci-workflows: cloud-bootstrap.sh
claude-code-account-rotation: cloud-bootstrap.sh
claude-code-plugins: cloud-bootstrap.sh
claude-code-proxy: cloud-bootstrap.sh
codex-plugins: cloud-bootstrap.sh
cursor-plugins: cloud-bootstrap.sh
dotfiles: cloud-bootstrap.sh
github-iac: cloud-bootstrap.sh
knowledge-corpus: cloud-bootstrap.sh
medley: cloud-bootstrap.sh
provisioning: cloud-bootstrap.sh
songwriting: cloud-bootstrap.sh
standards: cloud-bootstrap.sh

Whether each repository's .claude/settings.json registers the hook and declares the marketplace
(15 of 16):

$ for r in <same list>; do
    j=$(gh api "repos/melodic-software/$r/contents/.claude/settings.json" --jq '.content' 2>/dev/null | tr -d '\r\n' | base64 -d 2>/dev/null)
    echo "$r: bootstrap-hook-ref=$(echo "$j" | grep -c cloud-bootstrap.sh) SessionStart=$(echo "$j" | grep -c SessionStart) marketplace=$(echo "$j" | grep -c extraKnownMarketplaces)"
  done
.github: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
agent-plugins: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
ci-runner: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
ci-workflows: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
claude-code-account-rotation: bootstrap-hook-ref=0 SessionStart=0 marketplace=0
claude-code-plugins: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
claude-code-proxy: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
codex-plugins: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
cursor-plugins: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
dotfiles: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
github-iac: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
knowledge-corpus: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
medley: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
provisioning: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
standards: bootstrap-hook-ref=1 SessionStart=1 marketplace=1
songwriting: bootstrap-hook-ref=1 SessionStart=1 marketplace=1

The 0 0 0 row is not a parse of an empty settings file: base64 was decoding a 404 body. The
direct listing confirms the file is simply absent:

$ gh api repos/melodic-software/claude-code-account-rotation/contents/.claude --jq '.[].name'
cloud-bootstrap.sh
rules

This is the finding that made the present-tense phrasing untenable and the dated phrasing correct:
claude-code-account-rotation carries the script but has no .claude/settings.json, so it neither
registers the SessionStart hook nor declares the marketplace. Writing "every non-archived repository
carries / registers / declares" in the present tense would have replaced a stale number with a false
claim. See ## Related for the follow-up.

Standards PR #572, confirmed merged and diffed before editing:

$ gh pr view 572 -R melodic-software/standards --json state,mergeCommit,mergedAt
{"mergeCommit":{"oid":"c9daa106868c64c49be22d3b1617f5bb3b71789d"},"mergedAt":"2026-09-15T14:20:53Z","state":"MERGED"}

$ gh pr diff 572 -R melodic-software/standards
...
-DOTNET_FALLBACK_VERSIONS='10.0.302 10.0.400'
+DOTNET_FALLBACK_VERSIONS='10.0.400 10.0.401'
...

Lints:

$ npx markdownlint-cli2 docs/cloud-fleet-setup.md
markdownlint-cli2 v0.23.2 (markdownlint v0.41.1)
Finding: docs/cloud-fleet-setup.md !**/node_modules/** !**/.venv/** !**/bin/** !**/obj/**
Linting: 1 file
Summary: 0 issues in 0 files

$ typos docs/cloud-fleet-setup.md
(no output; clean)

package.json declares no scripts block, so npx markdownlint-cli2 is the repo's lint entry point
for this file. npm ci was run in the worktree so the pre-commit hooks resolved.

Swept for sibling occurrences of the same stale number; the only hit in this doc is the one fixed,
and the other hits across the repo are unrelated uses of the word:

$ grep -rn "fifteen" docs prompts
docs/adr/0008-admit-only-present-text-defects-to-the-instruction-audit-catalog.md:8:...four of its fifteen
docs/adr/0029-admit-a-second-findings-producer-behind-a-targeted-run-clause.md:51:...full fifteen it would record...
docs/cloud-fleet-setup.md:77:...all fifteen non-archived            <- fixed here
docs/conventions/detector-findings/CHANGELOG.md:89:...two of its fifteen...
docs/conventions/detector-findings/README.md:522,733,743:...two of fifteen... (ai-slop rule counts)
docs/specs/extract-ssot-sweep-2026-08-28.md:375:...is fifteen rather than three.

Related

Two follow-ups for the orchestrator, neither fixed here (both are outside this item's scope):

  1. claude-code-account-rotation bootstrap adoption gap. It has .claude/cloud-bootstrap.sh and
    .claude/rules, but no .claude/settings.json, so the startup|resume SessionStart hook is
    unregistered and the melodic-software marketplace undeclared. It is the newest repository in the
    org (created 2026-09-05, after the 2026-08-16 adoption pass).

    Checked whether this is already tracked; it is not. Standards
    distribution/sync-manifest.yml does carry the repo, and cloud-bootstrap is in its managed
    list (which is why the script is present), but no component in that list delivers a
    .claude/settings.json — compare the claude-settings-github-iac entry the manifest's own
    comment describes as "that target's own settings file", which has no counterpart here. The one
    open PR on the repo (#60 chore: sync standards components) touches only
    .github/workflows/managed-files-guard.yml and lychee.toml. So the hook registration and
    marketplace declaration are delivered by nothing, in flight in nothing. Worth a tracked issue.

  2. The original count may never have been right. Sixteen non-archived repositories minus the two
    created after 2026-08-16 is fourteen, not fifteen, so either a repository has been archived since
    the pass or the count was already off by one when written. Not chased; flagging it because it
    argues for the dated-record phrasing this PR adopts over any re-counted number.

Optional and deliberately not done: the doc's recheck-trigger list in the basis paragraph could gain
"a repository is created in the org" as a trigger. The date-scoping plus the paragraph's existing
"read adoption state from the repos" pointer already prevent this specific rot, so it was left alone.

🤖 Generated with Claude Code

https://claude.ai/code/session_011mbb3nkTfMrT9vDmoUnQuj

The bootstrap adoption paragraph claimed "all fifteen non-archived
melodic-software repositories". `gh repo list melodic-software
--no-archived --limit 100 --json name` returns 16 today, so the count
had already rotted.

Drop the hardcoded number and scope the claim to the date the pass was
actually run (2026-08-16, the section's own heading date), so the
sentence records a dated verification instead of asserting an
ever-changing present-tense count. Name the gap class the date
introduces -- a repository created after that pass is not covered by it
-- rather than enumerating repos, which the paragraph's closing sentence
already rules out. Also tighten the cited query to `--no-archived --json
name`, which returns exactly the set the sentence describes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mbb3nkTfMrT9vDmoUnQuj
@kyle-sexton
kyle-sexton marked this pull request as ready for review September 15, 2026 14:09
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-15T14:11:54.307995Z 75703d7 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

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


Code review — docs/cloud-fleet-setup.md

  • Gather context (PR body, diff vs origin/main, surrounding doc section)
  • Understand the request (/review:code-review lane, correctness/maintainability only)
  • Review the changed lines
  • Report findings

Scope: this is the CI code-review lane (/review:code-review); security findings are out of scope here since this repo carries a claude-security-review workflow.

No findings. This is a 5/-4 prose-only edit to ## Bootstrap adoption (2026-08-16) in docs/cloud-fleet-setup.md. Checked:

  • The new sentence's claim ("every non-archived repository... carried the script, registered the hook, declared the marketplace" as of 2026-08-16, "a repository created after that pass is not covered by it") is internally consistent with the surrounding doc — it matches the basis paragraph's own re-verification date (line 16: "Bootstrap adoption was re-verified on 2026-08-16") and doesn't introduce a new number to go stale.
  • gh repo list melodic-software --no-archived --json name is a valid invocation (--no-archived is a real gh repo list flag) and, unlike the old --json name,isArchived citation, returns exactly the filtered set the sentence describes without requiring the reader to post-filter.
  • Tense shift (present → dated past) is applied consistently across all three verbs in the sentence (carried, registered, declared).
  • No other occurrence of the stale "fifteen" count remains in this file (the PR body's own grep -rn "fifteen" sweep confirms this — author-claimed, not independently re-run by me, but the diff itself shows only the one sentence touched).

The PR body's verification section (repo counts, per-repo .claude/cloud-bootstrap.sh / settings.json checks, lint/typos output) is author-claimed; I did not re-run those commands myself and am not asserting them as independently verified.

Nothing here rises to a block/flag-worthy issue — no inline comments posted.

@github-actions

Copy link
Copy Markdown
Contributor

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

@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: 75703d7fd6

ℹ️ 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/cloud-fleet-setup.md Outdated
kyle-sexton and others added 3 commits September 15, 2026 10:15
Codex review raised a valid P2 on the query this PR cites: `gh repo list`
returns only 30 repositories by default (`gh repo list --help`: "-L,
--limit int  Maximum number of repositories to list (default 30)"). At
16 non-archived repos it does not bite today, but a reader who runs the
cited command once the org passes 30 would silently enumerate a truncated
fleet while the prose claims fleet-wide coverage.

That is the same rot class this PR exists to remove, so pin `--limit 100`
in the doc to match the command the verification actually ran, and say in
one clause why the flag is there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mbb3nkTfMrT9vDmoUnQuj
…572

DOTNET_FALLBACK_VERSIONS in components/cloud-environment/setup.sh moved
from 10.0.302 10.0.400 to 10.0.400 10.0.401 (standards PR #572, merged
2026-09-15). The fallback list now matches the fleet's pinned .NET
versions instead of trailing them.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mbb3nkTfMrT9vDmoUnQuj
…k list

The bullet still said 10.0.401 was in neither fallback slot after standards
#572 added it to DOTNET_FALLBACK_VERSIONS, contradicting the sentence right
below it. Rewrite to state github-iac's 10.0.401 (rollForward: disable) is
now covered by the fallback list, matching the rest of the bullet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011mbb3nkTfMrT9vDmoUnQuj
@kyle-sexton
kyle-sexton merged commit cf6d15d into main Sep 15, 2026
12 checks passed
@kyle-sexton
kyle-sexton deleted the docs/fleet-count-drift branch September 15, 2026 14:52
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