Skip to content

install: preflight operator-only prerequisites (secrets + bot access) upfront and hard-block until present - #708

Open
usurobor wants to merge 16 commits into
mainfrom
cycle/706
Open

install: preflight operator-only prerequisites (secrets + bot access) upfront and hard-block until present#708
usurobor wants to merge 16 commits into
mainfrom
cycle/706

Conversation

@usurobor

@usurobor usurobor commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Refs #706

Summary

  • cn repo install --dispatch cds now runs a preflight check (secrets-by-name presence + push-access check, both via net/http against the GitHub API, never reading secret values) before any label/render/commit — missing prerequisites exit non-zero with the operator's exact acquisition steps, and leave no partial .cn//.github/workflows/ artifacts.
  • Renamed the workflow PAT secret SIGMA_WORKFLOW_PATCN_DISPATCH_PAT everywhere (renderer, install command, live rendered workflow, golden fixtures, docs).
  • Deleted the cosmetic bot_name/bot_id default injection from the cn-install-wake renderer — a fresh install emits neither key unless explicitly passed via --bot-name/--bot-id.
  • Revised docs/guides/INSTALL-CDS.md in place: defines every term (PAT, repo secret, default branch, "bot") before use, states plainly there's no bot account to create today, documents the bot-less two-own-account-secrets default.
  • New Go module src/packages/cnos.core/commands/install-preflight (presence-only GitHub secrets + push-access checks).

All 10 acceptance criteria (per the issue's "CONSOLIDATED FINAL SPEC" comment) pass, independently re-verified by β — tests actually re-run, greps actually re-run, both golden fixtures and the live workflow re-rendered and byte-diffed. Full detail: .cdd/unreleased/706/{gamma-scaffold,self-coherence,beta-review,alpha-closeout,beta-closeout,gamma-closeout}.md.

⚠️ Required pre-merge operator action (do not skip)

This PR renames every secret reference in the live .github/workflows/cnos-cds-dispatch.yml and cnos-agent-admin.golden.yml from secrets.SIGMA_WORKFLOW_PAT to secrets.CN_DISPATCH_PAT. GitHub Actions resolves a reference to a nonexistent secret as an empty string, not a parse error — so if the CN_DISPATCH_PAT repo secret is not provisioned on usurobor/cnos before/at merge, the next scheduled firing of the live cds-dispatch and agent-admin wake workflows will run with an empty token and degrade or hard-fail (checkout auth, the recovery scanner, the claude-code-action step, and the finalizer all use this token).

Before merging, do ONE of:

  1. Create CN_DISPATCH_PAT as a new repo secret holding the same PAT value SIGMA_WORKFLOW_PAT currently holds (or a fresh equivalent fine-grained PAT: Contents + Issues + Pull requests + Workflows = write), then merge; or
  2. Sequence the merge so there is no window where the new workflow YAML is live without the secret.

This is intentionally not something this PR's code does — secret values are never handled by this cycle's code, by design (AC3). Full trace: .cdd/unreleased/706/beta-review.md §R0 Finding F1, and .cdd/unreleased/706/gamma-closeout.md §"Required pre-merge operator action".

Non-blocking follow-up (can happen after this merges): remove SIGMA_WORKFLOW_PAT from the repo's secrets once CN_DISPATCH_PAT is confirmed working.

Test plan

  • cd src/go && go build ./... && go vet ./... && go test ./... — clean
  • cd src/packages/cnos.core/commands/install-preflight && go build ./... && go vet ./... && go test ./... — clean
  • Renderer re-run independently by β; both golden fixtures and the live workflow byte-identical to fresh render output
  • Operator: confirm CN_DISPATCH_PAT secret exists on usurobor/cnos before merging (see above)

🤖 Cell #706, dispatched and executed by the cds-dispatch wake (γ scaffold → α implement → β independent review, verdict: converge).

sigma@cnos.cn-sigma.cnos and others added 15 commits August 6, 2026 00:57
Scaffolds cycle/706 from the consolidated final spec in the issue's
last comment (authoritative per its own text, supersedes the original
issue body's superseded design): per-AC oracle list for AC1-AC10,
source-of-truth table grounded in repoinstall.go / cn-install-wake /
the rendered dispatch workflow / label-doctor's GitHub-API precedent,
and alpha/beta dispatch prompts.

Refs #706
Per gamma-scaffold.md Friction note 6: this FSM claim-transition
record (status:todo -> status:in-progress) was staged on main before
cycle/706 was cut and carried into the cycle branch uncommitted.
Committing it now so the cycle branch's working tree matches what was
staged at claim time.
…ss check (cnos#706)

New sibling go.work module mirroring label-doctor's dependency-free
net/http idiom (github.go: ghRequest/ghListSecrets/ghCheckPushAccess;
resolve.go: resolveRepoFromGitRemote). Check() verifies GitHub Actions
repo secrets exist BY NAME via GET .../actions/secrets (never decodes
a value field — ghSecret has none) and push access via
GET /repos/{owner}/{repo}'s permissions.push field (single call, per
gamma-scaffold.md Friction note 3). Not yet wired into
cn repo install --dispatch cds — that lands in the next commit.
…drop cosmetic bot (cnos#706)

- Wire installpreflight.Check into repoinstall.Run(): for --dispatch
  cds (non-dry-run), operator prerequisites (CLAUDE_CODE_OAUTH_TOKEN +
  CN_DISPATCH_PAT presence, push access) are verified strictly before
  resolveIndex/applyInstall/runDispatchCds (AC1/AC2) — a missing
  prerequisite exits nonzero with what/why/exact-acquisition-steps per
  item (AC7, operator's verbatim final wording) and leaves no partial
  .cn/ or .github/workflows/ artifact.
- Rename the sigma-default workflow-PAT secret SIGMA_WORKFLOW_PAT ->
  CN_DISPATCH_PAT in repoinstall.go's display value, cmd_repo_install.go's
  help text, cn-install-wake's default binding, the live rendered
  .github/workflows/cnos-cds-dispatch.yml, and both golden fixtures
  (regenerated via the renderer, byte-identical on re-render) (AC6).
- Delete cn-install-wake's per-agent bot_name/bot_id cosmetic-identity
  lookup table (agent_bot_name()/agent_bot_id(), sigma@cnos.cn-sigma.cnos
  / 41898282); bot_name/bot_id are now strictly opt-in via
  --bot-name/--bot-id for any agent, and a fresh render (sigma default
  included) emits neither key (AC9).
- cmd_repo_install.go help text: documents the preflight gate + links
  docs/guides/INSTALL-CDS.md (AC5).

Tests for the new preflight gate + updated fixtures for the existing
dispatch-cds suite land in the next commit.
…on (cnos#706)

- Add a §Terms section (PAT, repo secret, default branch, "bot") at
  the very top, before any term is used anywhere in the doc.
- New §Preflight subsection under Autonomous dispatch: what the
  operator provides, why, and that nothing is written until every
  prerequisite is satisfied.
- Tier 3 runbook rewritten: no bot account to create; two own-account
  secrets (CLAUDE_CODE_OAUTH_TOKEN via 'claude setup-token',
  CN_DISPATCH_PAT as a fine-grained PAT with exact scopes + Settings
  path) using the operator's verbatim final wording from the issue
  thread, matching repoinstall.go's formatPreflightFailure text.
- Tenant-secrets table's Tier 3 row updated to the two-secret default;
  dedicated bot explicitly named as future/deferred (cnos#449/#702).
- All SIGMA_WORKFLOW_PAT / sigma@cnos.cn-sigma.cnos / 41898282
  references removed; example commands drop the now-unnecessary
  --bot-name/--bot-id flags.
- Troubleshooting table: new preflight-failure row; corrected the
  stale non-sigma-agent advice (bot flags are optional, not required).
- GITHUB_TOKEN-suffices claims remain scoped to Tier 2 (--engine) only.
…os#706)

- setPreflightSatisfiedEnv/setPreflightMissingEnv: httptest-server
  fixtures wired via CN_INSTALL_PREFLIGHT_API_BASE_URL/
  CN_INSTALL_PREFLIGHT_REPO, deliberately bypassing git-remote
  resolution so label-doctor's own (unrelated) downstream resolution
  stays exactly as before across every existing dispatch-cds test.
- Every pre-existing --dispatch cds test updated with the fixture that
  satisfies its own required secret names, preserving each test's
  original downstream assertions unchanged.
- New: TestRun_DispatchCds_PreflightRunsBeforeAnythingElse_
  NoPartialArtifacts (AC1/AC2) — proves preflight fires before
  resolveIndex even touches an invalid IndexPath, and that no .cn/ or
  .github/ artifact exists on a missing-prerequisites failure.
- New: TestFormatPreflightFailure_ContainsOperatorWording (AC7) —
  asserts the operator's verbatim final wording appears in the wired
  error.
- New: TestRun_DispatchCds_SigmaDefault_NoIdentityFlagsRequired
  extended + TestRun_DispatchCds_BotFlags_StillOptIn (AC9) — a fresh
  sigma-default render carries no bot_name/bot_id by default;
  --bot-name/--bot-id remain available as opt-in.
…5 help link (cnos#706)

- setPreflightSatisfiedEnv mirrors repoinstall_test.go's helper
  (t.Setenv-based; the real subprocess test inherits it automatically
  via exec.Command's nil-Env os.Environ() fallback).
- Applied to all three existing --dispatch cds CLI-level tests
  (RendererNotVendored, MissingIdentity, IdentityFlagsWireThrough),
  preserving each one's original downstream assertions.
- TestRepoInstall_HelpFlag now asserts --help mentions INSTALL-CDS.md
  (AC5).
…cnos#706 AC6)

AC6's mechanical oracle greps repoinstall.go/cmd_repo_install.go/
cn-install-wake for zero SIGMA_WORKFLOW_PAT matches. Two explanatory
rename-history comments still carried the literal old name; reworded
to describe the rename without repeating it. No functional change —
confirmed by re-rendering both goldens + the live workflow (all three
report "unchanged").
TestRun_DispatchCds_PreflightSatisfied_SecondRunByteIdentical: calling
Run twice against the same repoRoot with prerequisites satisfied
produces byte-identical .cn/deps.json and rendered workflow output
both times, mirroring the base-install idempotency precedent
(TestRun_Idempotent_ByteIdenticalArtifacts) for the --dispatch cds
path. Strengthens AC4's re-run-resumes-cleanly evidence beyond the
already-documented label-doctor-network-call limitation (see
self-coherence.md §Debt).
…s#706 R0)

Branch CI verified green (11/11 check runs) at head commit
79ed10b immediately before this
signal. R0 ready for β review.
Re-derived all 10 ACs from the issue's consolidated-spec comment
directly (not gamma/alpha paraphrase), re-ran every cited test and
grep myself, and independently re-rendered cds-dispatch + agent-admin
via cn-install-wake to confirm both goldens and the live workflow are
byte-identical to a fresh render (not hand-edited).

F1 (high, merge-blocking, not alpha-fixable): the live
cnos-cds-dispatch.yml and cnos-agent-admin.golden.yml now bind every
runtime token to secrets.CN_DISPATCH_PAT. Could not confirm via `gh
api repos/usurobor/cnos/actions/secrets` (403, insufficient token
scope) whether that secret actually exists yet on usurobor/cnos.
Merging without it breaks every future scheduled firing of both live
wakes. Flagged as a pre-merge operator/delta coordination gate.
alpha-closeout.md and beta-closeout.md record the cycle-level and
review-side retrospectives for R0 (verdict: converge, no fix round).
gamma-closeout.md carries the process-gap audit plus a dedicated
pre-merge operator-action gate: CN_DISPATCH_PAT must be confirmed
provisioned as a repo secret on usurobor/cnos before/at merge, per
beta-review.md Finding F1, or the next scheduled firing of the live
cnos-cds-dispatch.yml / cnos-agent-admin.yml wakes will break.
REVIEW-REQUEST.yml requests the status:in-progress -> status:review
transition for issue #706.
@usurobor usurobor changed the title cycle/706 install: preflight operator-only prerequisites (secrets + bot access) upfront and hard-block until present Aug 6, 2026
@usurobor
usurobor marked this pull request as ready for review August 6, 2026 01:46

@usurobor usurobor left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

κ review (cn-sigma@cnos) — verdict: converge / approve, modulo the one pre-merge operator action

This is a COMMENT (single-account can't self-APPROVE); the gate is operator-honored. Verdict verified independently — I did not trust the cell's self-report. Re-ran builds/tests, re-rendered and byte-diffed the workflows, and grepped the rename for completeness on a fresh cycle/706 worktree.

Verified against the #706 CONSOLIDATED FINAL SPEC (all 10 ACs)

  • Build/testsrc/go build/vet/test ./... all clean (incl. internal/cli, internal/repoinstall); install-preflight module clean. No failures.
  • AC1 (preflight before any write)repoinstall.go:318 runs runPreflight before resolveIndex/applyInstall/runDispatchCds; on failure return nil, err. Proven, not asserted: TestRun_DispatchCds_PreflightRunsBeforeAnythingElse_NoPartialArtifacts feeds a nonexistent index path and asserts the error is the preflight error, not an index-read error — so preflight genuinely fired first.
  • AC2 (non-zero + no partial artifacts) — same test asserts .cn/.github do not exist on the failure path; CLI returns the error unchanged → non-zero exit.
  • AC3 (presence-only, no secret values)install-preflight/github.go decodes only secret names + permissions.push; the token only ever sets the Authorization header, never logged. Structural test TestGhSecret_HasNoValueField locks this in. No path reads or logs a secret value.
  • AC6 + migration completeness (the merge-risk item) — the SIGMA_WORKFLOW_PATCN_DISPATCH_PAT rename is complete on every live surface: re-ran the renderer → byte-identical to cnos-cds-dispatch.golden.yml, which is byte-identical to the live .github/workflows/cnos-cds-dispatch.yml (4× CN_DISPATCH_PAT, 0 SIGMA). Every remaining SIGMA_WORKFLOW_PAT string in the repo is a negative-oracle test assertion or a leak-detector grep pattern — zero in any live workflow binding, renderer template, or golden fixture.
  • AC9 (no cosmetic bot by default) — the default table is deleted; keys emit only when --bot-name/--bot-id are passed. Default render + both goldens + live workflow contain zero bot_name/bot_id/41898282/sigma@cnos.

Defects

None. The tests are genuine (real ordering, real artifact-absence, structural no-value guarantee), not tautological.

One accuracy correction to the PR description

The description and δ-return say the rename touches the live cnos-cds-dispatch.yml and cnos-agent-admin.yml. Verified: there is no live cnos-agent-admin.yml — only a golden fixture (already on CN_DISPATCH_PAT). The sole live PAT-binding workflow is cnos-cds-dispatch.yml. So the merge-risk surface is one workflow, not two — slightly smaller than stated, not larger.

The one gate before merge (unchanged, operator-only)

Provision the repo secret CN_DISPATCH_PAT on usurobor/cnos before merging (same value as SIGMA_WORKFLOW_PAT, or a fresh fine-grained PAT: Contents + Issues + Pull requests + Workflows = write). GitHub resolves an undefined secret ref to an empty string, so merging without it would run the next cds-dispatch wake on an empty token. This is out-of-band by design (AC3 — the code never handles secret values) and cannot be verified from the repo.

Note on CI: no checks are reported on head b7b0dbef, so this verdict rests on the re-run above, not on green status. Recommend merge once CN_DISPATCH_PAT is confirmed present; drop SIGMA_WORKFLOW_PAT as the documented non-blocking follow-up.


Generated by Claude Code

usurobor pushed a commit that referenced this pull request Aug 6, 2026
… per κ review (10/10 ACs, rename complete, 0 defects); hard precondition = provision CN_DISPATCH_PAT first
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