Skip to content

Promote the onboarding and host-setup fixes to main - #486

Merged
ptr727 merged 5 commits into
mainfrom
develop
Aug 1, 2026
Merged

Promote the onboarding and host-setup fixes to main#486
ptr727 merged 5 commits into
mainfrom
develop

Conversation

@ptr727

Copy link
Copy Markdown
Owner

Forward promotion of five commits. main carries no content beyond the merge-base (8771e62, #478), so this is a clean forward merge with no conflicts.

This one has a consumer waiting. The Blog standup (#456) is mid-correction and has been told to carry its instruction set from main, because main is the audit ground truth. Every fix for the failure it just hit is currently on develop only: main's STANDUP.md still begins at "1. Classify and Catalog", with no step 0 and no step 1A, and main does not yet require OPERATIONS.md. Until this promotes, a repo following the corrected instructions re-runs the uncorrected procedure.

What promotes

Verification on the merged develop

The full 180-case scripts/ suite, scripts/repo_gate.py, spec/validate.py and spec/audit.py --selftest all pass. The blocking prose run (charset, dupword, spelling) is clean tree-wide, markdownlint reports 0 issues over 39 files, and editorconfig-checker is clean.

Release

A human merge never auto-publishes, so this fires no release, as designed. The latest release stays 2.0.108.

Re-vendor debt

#481 changed GOVERNANCE.md "Git and Commit Rules", a verbatim section, so this promotion re-vendors it across the fleet. That was accepted deliberately when the change was made. The debt is pre-existing and still untracked, and spec/audit.py --branch <ref> checks a repo's convergence before it promotes.

Known backlog, not in this promotion

The hub's own .editorconfig, .gitattributes and .gitignore carry 44 comment-shape findings, which downstream repos inherit by copying them and reading them for house style. #485 works around it by telling agents to trust the rule text over a carried file's formatting. Cleaning those three files is owed and deliberately separate.

🤖 Generated with Claude Code

ptr727and others added 5 commits July 31, 2026 13:14
STANDUP.md step 2 said to copy the spec/files.json entries and stopped, so it covered what a repo carries and left no destination for what only that repo knows. The destinations exist in spec/section-model.md, but nothing on the scaffolding path pointed at them: STANDUP.md never mentioned them, AGENTS.md has no arrow to them, and the one pointer from spec/files.json is framed as a per-section fidelity question rather than as where a runbook lives.
By this file's own cold-start self-test standard that is a documentation defect. A context-free agent cannot stand up an operational repo from these docs alone if nothing tells it where the deploy runbook goes. Blog is the first operational repo with substantial runbooks and would have hit it, putting repo-specific prose into a carried file and creating drift to reconcile.
Step 2 now names the three destinations (CODESTYLE.md, ARCHITECTURE.md, OPERATIONS.md), with the rule that the choice is decided by what the content is, plus the note that OPERATIONS.md takes the inline-link exception. AGENTS.md is deliberately untouched: its "Where the Rules Live" section is verbatim fleet-law, so adding the pointer there would re-vendor across the fleet and is a separate decision.
Review found two more instances of the same species in the new text, both fixed here. The baseline read as "(main.json plus develop.json), or operational/develop.json", which parses as though an operational repo carries no main.json at all; it carries one, since repo-config/main.json is appliesTo "*" and only the develop payload is model-scoped. And step 2 filtered on the repo's types, which are one of four disjoint selector namespaces rather than the whole filter. A repo's selector set is its types plus workflowModel, releaseTrigger and consumerModel, so a type-only reading drops repo-config/operational/develop.json, the appliesTo ["operational"] entry this change exists to surface. AUDIT.md section 3 already stated that rule correctly.
All three defects sent an operational repo to the wrong files, which is worth noting as a pattern: this file had drifted toward treating the release model as the default.
The second of those arrived as a suppressed review comment carrying no thread, so a thread-only poll would have reported the PR clean while the defect stood. That is the gap the suppressed-findings digest was built to close, catching a real defect on its second outing.
STANDUP.md is hub-only, so none of this adds re-vendor debt, and the file's own dash and semicolon backlog is cleared per the standing rule that existing prose is corrected as each file is next edited. Both headings that took a colon were checked for inbound anchors first and have none.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…S.md (#481)
Two onboarding gaps, both surfaced by the Blog standup (#456).
The Blog agent set a repo-local user.email while scaffolding, then caught it
itself when verifying the first commit was signed. The rule was never
missing: GOVERNANCE.md "Git and Commit Rules" states it and AGENTS.md routes
to it. STANDUP.md, the procedure an agent standing up a repo actually
follows, never mentioned identity, signing, or the first commit, and
docs/host-setup.md modeled the failure by telling the reader to set
user.email to a placeholder with no pointer to the rule. There is an
ordering trap too: the first commit of a new repo happens before that repo
contains AGENTS.md or GOVERNANCE.md, because the agent is creating them.
The window is unforgiving. A repo whose initial history carries the wrong
identity or no signature blocks its own first develop -> main release, and
repairing it needs a maintainer force-push that repo-config-carry.md forbids
an agent to run.
STANDUP.md gains a step 0 that verifies identity and signing before git
init. The framing is verify, never set: the host carries the identity
globally, so a repo-local user.email is redundant where the global is right
and wrong where it is not, and it shadows the global silently. A mismatch is
a host fault to surface, not a per-repo patch, since patching locally hides
a broken host that then commits wrongly everywhere else on that machine.
GOVERNANCE.md's "fix it if not" is narrowed to match, which re-vendors.
The checks read the --global scope explicitly, because the effective value
depends on where the command runs and inside any existing repository a local
override wins. The agent check branches on gpg.format, since signing is SSH
or GPG and running the wrong check fails on a correctly configured host. The
local-override check runs after git init, because --local fails outside a
repository, and its finding is a printed value rather than an exit code. The
post-commit check reads author and committer, since the rule covers both and
GitHub verifies against the committer, which a rebase rewrites while leaving
the author intact.
Second, OPERATIONS.md becomes required for an operational repo, declared
appliesTo ["operational"] and presence-checked like README.md and
HISTORY.md, so its content stays entirely the repo's own. The evidence for
mandating rather than advising is that the convention was already emerging
unevenly: of four operational repos two wrote one unprompted, while another
scattered the same material across Hardware.md and ZFS.md, which is the
improvisation these destinations exist to prevent. ARCHITECTURE.md stays
advisory, because "a code repo" is not one selector token and mandating it
would produce genuinely empty files.
Review found eleven defects, all in step 0, every one a claim about tool
behavior asserted without running it. Each command in the step is now
executed as written before commit: from a non-repo directory, from inside a
repo carrying a bogus override, under set -e, and with gpg absent from PATH.
The GPG branch's passing output is documented rather than observed, since
this host signs over SSH.
The dash and semicolon backlog in spec/section-model.md and
docs/host-setup.md is cleared, per the corrected-as-next-edited rule. Both
are hub-only. reports/conformance-matrix.md keeps its backlog, since only
one table cell is touched here.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
#482)
STANDUP.md step 0 now expects a configured host, but nothing stated what a
host must provide. The repo invokes python3 at fifteen call sites, docker for
the four linters, uvx for coverage, plus git and gh, and a fresh host
discovered each of those by failure.
docs/host-setup.md gains the contract: which tool, which procedure stops
without it, and how to see it is present. It names no installer, because
winget, brew and apt differ per platform while the requirement does not,
which keeps the table true on every host and keeps per-machine specifics out
of a public repo. Per-platform install commands are tracked in #483, filled
in only by someone who has run them on that platform. Two facts are worth
reading off the table rather than learning later: python3 needs no packages,
since every script here is standard library only, and the linters need only
docker, since each runs as the pinned image CI uses, which is what keeps a
local run and CI the same check.
The write-safety kit was unreachable from this document, even though its own
README calls it the first thing to deploy on a new system. It is now a step
here, with the host-versus-repo distinction stated: the carried GOVERNANCE.md
rules reach fleet repos, while the hook and the CLAUDE.md block cover every
session on the machine, including work in no project at all, which is where
the incident behind the kit happened.
A closing table maps the finished host to what it can then do, so a failed
row names the procedure it blocks rather than reading as a bare checklist.
Adding the kit step introduced the first powershell block in the file, which
falsified the opening note that every snippet assumes a POSIX shell, in
exactly the place a Windows reader needs it to be true. The note now carries
the exception. That sentence also ended on a clause-joining semicolon the
linter exempts, because a colon earlier in the line makes the whole line read
as a list, which is the documented limit of that rule and is caught by
reading the diff rather than by the gate.
Every command was run as written before committing, and the referenced
installer paths were confirmed to exist. The one claim not backed by a run is
the PowerShell invocation form, which cannot be executed from this host and
is queued for verification on a real Windows host in #483.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rm (#484)
Two corrections from the #483 Windows and WSL2 testing, both of which
disproved something the contract merged in #482 asserted.
The PowerShell installer invocation needs the .\ prefix. PowerShell does not
load a command from a relative path without it, and warns that it does not
assume the current location. This was declined during the #482 review on the
argument that a multi-segment path resolves where a bare filename does not,
flagged at the time as reasoning rather than a run because PowerShell cannot
be executed from the Linux host. The maintainer's direct experience is that
both forms need either .\ or an absolute path. Both files that carried the
line are corrected, since docs/host-setup.md and the kit README shipped the
same unprefixed form. Worth recording that the Windows column of #483 was
filled by an agent, so the tool installs around install.ps1 were exercised
while the documented invocation itself never was.
The interpreter is not called python3 everywhere, so the contract's presence
check failed on the platform it most needed to be right about. On native
Windows the installer registers python, py and python3.13 but not python3,
where that name resolves to a Microsoft Store alias stub that reports the
interpreter as missing, so a correctly set-up host read as broken. Stock
Debian is the mirror image, carrying python3 and no bare python. The row now
names py -3 for native Windows, and the consolidated verify block carries
the same translation, including the Git Bash case: it inherits the Windows
PATH, so python3 reaches the stub there too, which the shell note's advice
to use WSL2 or Git Bash would otherwise appear to cover.
A PowerShell equivalent of the verify block is deliberately absent. It has
not been run on a Windows host, and this change exists because an unverified
PowerShell invocation shipped and was wrong. #483 carries the request under
its rule that a cell is filled only by someone who has run it.
Three findings from the same testing are deliberately not carried, recorded
so they are not re-proposed. Docker Desktop performs the WSL2 enabling
itself and exposes the per-distro integration toggle the matrix already
documents. The WSL interop credential-helper failure was an upstream bug
since fixed, leaving only that Docker Desktop must be quit rather than
paused before wsl --update. And the /mnt/c permission behavior does not
apply to a workflow that treats WSL2 as an ordinary Debian host.
The kit README's dash backlog is cleared, per the corrected-as-next-edited
rule. It is hub-only, so no re-vendor debt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Blog standup carried four mechanical config files and none of the
authorities, then authored its tooling and imported its content under no
rules. AGENTS.md, GOVERNANCE.md, CODESTYLE.md, WORKFLOW.md, AUDIT.md,
README.md, HISTORY.md, copilot-instructions.md, markdownlint-cli2.jsonc,
cspell.json and version.json were all absent from the live tree, and the
result is 237 comment-shape findings across its 28 authored files.
Step 2 permitted that by treating the baseline as one undifferentiated list.
It is two kinds of file. Most are deliverables, where carrying them late
costs nothing, but the instruction set is the rules for producing every other
file, so carrying it late means everything authored beforehand was authored
against unknown rules, and the cost is rework rather than a warning.
Step 1A now stops the procedure until the instruction set is carried and
read, before any repo content is authored. The rationale is the same shape as
step 0: signing must be live before the first commit, governance must be
loaded before the first authored file, and in both cases the window closes
quietly while the repair is expensive out of proportion to the prevention.
The step also requires markdownlint-cli2.jsonc and cspell.json as the
mechanical half, since a repo that carries the prose authorities without the
linter configs has guidance and no gate. Their absence is why the comment
style drifted unchecked in Blog rather than failing a run. It asks the agent
to read the rules rather than only place the files, because comment shape,
one sentence per line, US spelling and the character rules all govern the code
about to be written.
One caution addresses a contributing cause that is the hub's rather than the
agent's. The hub's own .editorconfig, .gitattributes and .gitignore carry 44
comment-wrap and comment-case findings, so a repo that copies them and reads
them for house style learns the shape the rules forbid. Blog's copies carry
37 of the same, inherited rather than introduced. The step says to treat the
rule text as the authority and never to infer style from a carried file's
formatting. Cleaning those three files stays a separate hub backlog item.
Not addressed here, and recorded so it is not mistaken for an omission: there
is no spelling problem to fix. Blog's authored tree carries zero British
spellings, and its imported content carries two instances of one word across
113 files. That corpus is a sixteen-year archive including third-party
comments, deliberately out of scope, where a sweep would corrupt provenance
rather than improve style.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CopilotAI review requested due to automatic review settings August 1, 2026 02:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Promotes the onboarding and host-setup documentation fixes from develop to main, ensuring the fleet’s “cold standup” path and host tooling contract reflect the corrected procedures (identity/signing verification, instruction-set-first workflow, and required operational runbook destination).

Changes:

  • Extend STANDUP.md with a pre-git init identity/signing verification step and a new “carry the instruction set before authoring” gate.
  • Make OPERATIONS.md an explicit required baseline file for operational repos and document the repo-specific content destinations (CODESTYLE.md / ARCHITECTURE.md / OPERATIONS.md).
  • Update host setup docs and the write-safety kit README to clarify tool prerequisites and correct the Windows PowerShell invocation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
STANDUP.mdAdds step 0 identity/signing verification, step 1A instruction-set gating, selector-set clarification, and repo-specific doc destinations.
spec/section-model.mdDocuments repo-specific content destinations and makes OPERATIONS.md required for operational repos.
spec/files.jsonAdds OPERATIONS.md as a baseline file scoped to appliesTo: ["operational"].
reports/conformance-matrix.mdUpdates the operational shape row to note required OPERATIONS.md and the new standup prerequisite.
host-setup/agent-safety/README.mdFixes Windows install invocation by requiring .\ and clarifies install notes.
GOVERNANCE.mdTightens the identity rule to “verify, do not set” to avoid repo-local identity overrides.
docs/host-setup.mdAdds the host tooling contract table, documents the write-safety kit install, and updates identity guidance to the noreply form.

Comment threadSTANDUP.md
@ptr727
ptr727 merged commit 1d5b076 into mainAug 1, 2026
7 checks passed
Sign up for freeto 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.

2 participants

@ptr727