Context
Empirical audit 2026-05-09 17:00Z: resources/content/issues/ contains 985 items — 15 below GitHub's 1000-item folder cap. At recent ticket cadence (~3-5/day), 4-5 days of headroom before the cap blocks future ticket creation.
Root-cause analysis of why we hit this:
- gh-workflow MCP sync writes a markdown snapshot for ALL closed issues, including those closed
NOT_PLANNED (dropped/duplicate/invalid). Empirical: of last 100 closed ai-labeled tickets, 11 were NOT_PLANNED and ALL 11 have snapshots in active resources/content/issues/. These snapshots have zero operational value — they're noise.
- No on-release archival automation. Pattern exists at
resources/content/issue-archive/{v9.9.0, v10.0.0, v10.0.0-alpha.1, v10.0.0-alpha.2, v10.0.0-alpha.3, v10.0.0-alpha.4, ...} (manual archival per release), but the gh-workflow sync doesn't drive it.
Prescription
Two-part enhancement to gh-workflow MCP sync logic:
Part A: Skip snapshot writes for NOT_PLANNED closures.
Modify the snapshot-write step in gh-workflow's services/sync*.mjs (specific service TBD by implementer; likely sync_all or its child IssueSyncService):
- At sync-time, filter out tickets where
state === 'CLOSED' && stateReason === 'NOT_PLANNED' from the snapshot-write step
- One-shot cleanup migration: existing
NOT_PLANNED snapshots in resources/content/issues/ are pruned on next sync run (idempotent — re-running sync does nothing once cleaned)
Part B: On-release archival automation.
When a release tag is pushed, gh-workflow sync moves all state === 'CLOSED' && stateReason === 'COMPLETED' issues into resources/content/issue-archive/<version>/:
- Trigger options: (1) release-tag webhook listener, (2)
npm run ai:archive-on-release vX.Y.Z operator script, (3) detect tag during boot-sync
- Operator picks trigger shape during implementation (3 options outlined; not blocking on scope decision since structure is settled)
- After archival,
resources/content/issues/ contains only OPEN issues + a configurable buffer of most-recent N closed-completed (for in-context active-PR work)
Acceptance Criteria
Avoided Traps
- ❌ Year-based partition (
issues/2025/, issues/2026/) — operator pattern is release-versioned, not calendar-versioned; calendar partition fights the existing issue-archive/<version>/ shape
- ❌ Keeping all closed-completed in active folder forever — operator's "repurpose existing tickets" + "smarter remove dropped tickets" framing works against this; archived tickets stay readable in
issue-archive/
- ❌ Per-batch manual archival — automation is the entire point; manual-only would replicate today's tribal-knowledge pattern that produced the 985 figure
- ❌ Cap-bump as the fix — GitHub's 1k cap is the structural constraint; budget management beats cap-evasion
Provenance
- Operator directive 2026-05-09: "we have issue archives. once we do a release => all closed issues get moved out. more breathing room: repurpose existing tickets, enhance gh-workflow server to smarter remove dropped tickets."
- Empirical anchor:
ls resources/content/issues/ | wc -l = 985 at 2026-05-09 17:00Z
- Empirical anchor:
gh issue list --state closed --limit 100 --search "label:ai" shows 11 NOT_PLANNED of 99 ai-labeled — 11% of recent closures are noise
Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — chief-architect lane, Phase 0.C of post-quad coordination round.
Context
Empirical audit 2026-05-09 17:00Z:
resources/content/issues/contains 985 items — 15 below GitHub's 1000-item folder cap. At recent ticket cadence (~3-5/day), 4-5 days of headroom before the cap blocks future ticket creation.Root-cause analysis of why we hit this:
NOT_PLANNED(dropped/duplicate/invalid). Empirical: of last 100 closed ai-labeled tickets, 11 wereNOT_PLANNEDand ALL 11 have snapshots in activeresources/content/issues/. These snapshots have zero operational value — they're noise.resources/content/issue-archive/{v9.9.0, v10.0.0, v10.0.0-alpha.1, v10.0.0-alpha.2, v10.0.0-alpha.3, v10.0.0-alpha.4, ...}(manual archival per release), but the gh-workflow sync doesn't drive it.Prescription
Two-part enhancement to gh-workflow MCP sync logic:
Part A: Skip snapshot writes for
NOT_PLANNEDclosures.Modify the snapshot-write step in gh-workflow's
services/sync*.mjs(specific service TBD by implementer; likelysync_allor its childIssueSyncService):state === 'CLOSED' && stateReason === 'NOT_PLANNED'from the snapshot-write stepNOT_PLANNEDsnapshots inresources/content/issues/are pruned on next sync run (idempotent — re-running sync does nothing once cleaned)Part B: On-release archival automation.
When a release tag is pushed, gh-workflow sync moves all
state === 'CLOSED' && stateReason === 'COMPLETED'issues intoresources/content/issue-archive/<version>/:npm run ai:archive-on-release vX.Y.Zoperator script, (3) detect tag during boot-syncresources/content/issues/contains only OPEN issues + a configurable buffer of most-recent N closed-completed (for in-context active-PR work)Acceptance Criteria
NOT_PLANNEDfrom snapshot-write at write-timeNOT_PLANNEDsnapshots fromresources/content/issues/on next sync (idempotent)closed-completedtoresources/content/issue-archive/<version>/resources/content/issues/count drops to (open issues + N most-recent closed-completed buffer); folder budget restoredNOT_PLANNEDissue, writesCOMPLETEDissuelearn/agentos/GitHubWorkflow.md(or equivalent guide) documents the new behaviorAvoided Traps
issues/2025/,issues/2026/) — operator pattern is release-versioned, not calendar-versioned; calendar partition fights the existingissue-archive/<version>/shapeissue-archive/Provenance
ls resources/content/issues/ | wc -l= 985 at 2026-05-09 17:00Zgh issue list --state closed --limit 100 --search "label:ai"shows 11 NOT_PLANNED of 99 ai-labeled — 11% of recent closures are noiseSelf-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code) — chief-architect lane, Phase 0.C of post-quad coordination round.