Skip to content

docs(campaign): correct the workspace-retention claim in board-campaigns - #49

Merged
bketelsen merged 1 commit into
mainfrom
docs/campaign-workspace-retention
Aug 28, 2026
Merged

docs(campaign): correct the workspace-retention claim in board-campaigns#49
bketelsen merged 1 commit into
mainfrom
docs/campaign-workspace-retention

Conversation

@bketelsen

Copy link
Copy Markdown
Contributor

Summary

docs/design/board-campaigns.md's Lifecycle section still claimed that
"Already-launched workers and every source and workspace remain retained for
explicit operator action." That has been untrue since #42 ("clean terminal
worker workspaces automatically"): a running campaign sweeps cleanup
candidates on its own.

This change is documentation only — no Go, script, workflow, or contract file
is touched.

  • Keeps the true stop boundary explicit: stop cancels future setup,
    preflight, observation, and launch calls, but stops no already-launched
    worker and deletes no source, terminal, or workspace.
  • Adds the implemented in-campaign behavior: a worker becomes a cleanup
    candidate only when its provider process exited cleanly (never one reported
    failed) and its exact attempt correlation reached a terminal Snowcat
    outcome, or it was a stabilized worker whose lane found nothing to claim
    (markCleanupCandidate call sites in internal/campaign/campaign.go).
  • Names SNOWCAT_COCKPIT_RETAIN_WORKSPACES and its parsing: a non-negative
    integer count of the newest candidates to keep, defaulting to 20
    (defaultRetainWorkspaces in cmd/snowcat-cockpit/main.go), or a duration
    such as 6h; an explicit 0 cleans every eligible candidate on each sweep.
  • Records the retention exceptions: a failed worker, a worker whose lane never
    reached a terminal outcome, and any candidate whose cleanup is refused (an
    unclean tree, for example) stay retained, and a refused candidate is
    reconsidered on the next tick. Names the workspacesCleaned and
    lastCleanupAt record fields.

Wording is kept consistent with README.md and clause 12 of
docs/specs/repositories-and-board-campaigns.md, which already describe this
behavior correctly.

Resolves Snowcat item docs-drift-fix (e5b46e65-3b06-4574-a4bc-40e5d8e26f6f).

Risk tier

Risk tier: Tier 1 (Low) — a single design document's prose. No runtime
behavior, credential projection, worker authority, networking, lifecycle,
workflow, or protected boundary changes; the diff removes a stale claim and
describes code that already shipped in #42.

Boundary check

  • Snowcat's MCP contract and databases remain untouched
  • No provider, MCP, GitHub, or lease credential enters args, logs, or state
  • Writable terminal surfaces remain loopback-only
  • Cleanup remains an explicit operator action — unchanged by this PR. The
    automatic candidate sweep this text now documents was introduced by fix(campaign): clean terminal worker workspaces automatically #42
    and is a caller of the explicit cleanup contract, not a change to it:
    a cleanup refusal still leaves the workspace retained exactly as manual
    cleanup does, and every non-eligible worker still awaits explicit
    operator action.

Docs housekeeping

  • New docs started from their category TEMPLATE.md — n/a, no doc added
  • Every new canonical doc is indexed in docs/README.md — n/a, no doc added
  • ADR, design, spec, and plan links run both ways — the doc's existing
    ADR-0008/ADR-0009, spec, and plan links are unchanged and still resolve
    (node scripts/check-docs.mjs: 32 docs, 315 links, 10 symlinks, all ok)
  • Conformance aliases in ADR-0007 were not edited as content

Verification

  • make ci — exit status 0 on this branch. Tail:

    GOOS=linux GOARCH=amd64 ... go build -trimpath -o /tmp/snowcat-cockpit-linux-amd64 ./cmd/snowcat-cockpit
    GOOS=linux GOARCH=arm64 ... go build -trimpath -o /tmp/snowcat-cockpit-linux-arm64 ./cmd/snowcat-cockpit
    node scripts/check-docs.mjs
    ok   docs_index_coverage: 1.000 (required 1)
    ok   link_integrity: 1.000 (required 1)
    ok   symlink_resolution: 1.000 (required 1)
    checked: 32 docs, 315 links, 10 symlinks
    actionlint
    
    Earlier stages observed green in the same run: tidy-check, fmt-check,
    vet, lint-version-check, lint, test (incl. test-spike/tmux and the
    cockpit lifecycle shell tests), test-race, build-cross.
    
  • go test ./cmd/snowcat-cockpit ./internal/campaign

    ok  github.com/frostyard/snowcat-cockpit/cmd/snowcat-cockpit  0.005s
    ok  github.com/frostyard/snowcat-cockpit/internal/campaign    0.026s
    
    With `-run 'TestRetainWorkspacesFromLookup|TestSweepCleanupCandidates' -v`:
    TestRetainWorkspacesFromLookup, TestSweepCleanupCandidatesEnforcesCountRetention,
    ...EnforcesExplicitZeroCount, ...EnforcesAgeRetention,
    ...RetainsOnCleanupFailure, ...DisabledByDefault — all PASS.
    
  • Workflow changes pass actionlint — n/a, no workflow changed;
    actionlint ran green as part of make ci anyway.

  • Every action is SHA-pinned with a version comment and checkout disables
    persisted credentials — n/a, no action or workflow touched.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UigLsmd17TVDuaaSN4yfdU

The Lifecycle section claimed that every already-launched worker, source,
and workspace remains retained for explicit operator action. That has been
untrue since #42: a running campaign sweeps cleanup candidates on its own,
bounded by SNOWCAT_COCKPIT_RETAIN_WORKSPACES.

Keep the true stop boundary (stop stops no worker and deletes no source,
terminal, or workspace) and state the implemented in-campaign behavior:
candidate eligibility, the count/duration bound and its default of 20, the
explicit-zero sweep, and the failed-worker and cleanup-refusal exceptions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UigLsmd17TVDuaaSN4yfdU
@bketelsen
bketelsen marked this pull request as ready for review August 28, 2026 02:03
@bketelsen
bketelsen added this pull request to the merge queue Aug 28, 2026
Merged via the queue into main with commit b75568e Aug 28, 2026
11 checks passed
@bketelsen
bketelsen deleted the docs/campaign-workspace-retention branch August 28, 2026 02:06
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