Parent Epic
#11831 — Sub 11 of Epic (folder-structure cleanup; ai/scripts/ thematic categorization).
Scope
After Sub 8/9 move daemon entries OUT of ai/scripts/, remaining 30 files get thematic subfolder categorization. 7 categories: lifecycle / maintenance / migrations / diagnostics / runners / setup / lint.
(buildScripts/ai/ collapse is Sub 12 separately.)
Source moves (within ai/scripts/)
ai/scripts/lifecycle/ (13 files): wake/idle/sunset/harness/locks/orchestrator-spawned workers:
- checkAllAgentIdle.mjs, checkSunsetted.mjs, harnessLifecycle.mjs, heartbeatLock.mjs, idleOutNudge.mjs, inflightLock.mjs, resumeHarness.mjs, revalidationSweep.mjs, summarize-sessions.mjs, sweepExpiredTasks.mjs, trioWakeCooldown.mjs, wakeSafetyGate.mjs, windowsBatchSpawn.mjs
ai/scripts/migrations/ (7 files): one-shot data migrations:
- backfillChromaSharedUserId.mjs, bootstrapWorktree.mjs, migrate-discussions-b1.mjs, migrateWakeSubscriptions.mjs, normalizeGraphIdentities.mjs, priorityBackfill.mjs, refetchTruncatedIssues.mjs
ai/scripts/diagnostics/ (7 files): read-only inspection:
- analyzeNlTelemetry.mjs, check-retired-primitives.mjs, check-substrate-size.mjs, detectTruncatedTimelines.mjs, diagnoseMcpConcurrency.mjs, review-cost-meter.mjs, validateConceptEdges.mjs
ai/scripts/setup/ (1 file): one-time setup:
ai/scripts/lint/ (2 files): CI-enforced static analysis:
- lint-agents.mjs, lint-skill-manifest.mjs
(maintenance/ and runners/ folders created by Sub 12 with the buildScripts/ai/ collapse; ai/scripts/ doesn't contribute files to those buckets.)
Test moves (mirror source structure where unit specs exist)
Per-script audit: for each script, if a unit spec exists at test/playwright/unit/ai/scripts/X.spec.mjs, move to test/playwright/unit/ai/scripts/{category}/X.spec.mjs.
package.json
Affected npm scripts (all paths updated to include category subfolder):
"ai:prune-worktrees" → ./ai/scripts/migrations/bootstrapWorktree.mjs --prune-stale
"ai:lint-agents" → ./ai/scripts/lint/lint-agents.mjs
"ai:lint-skill-manifest" → ./ai/scripts/lint/lint-skill-manifest.mjs
"ai:revalidation-sweep" → ./ai/scripts/lifecycle/revalidationSweep.mjs
"ai:check-retired-primitives" → ./ai/scripts/diagnostics/check-retired-primitives.mjs
"ai:check-substrate-size" → ./ai/scripts/diagnostics/check-substrate-size.mjs
"ai:analyze-nl-telemetry" → ./ai/scripts/diagnostics/analyzeNlTelemetry.mjs
.github/workflows
agent-pr-review-body-lint.yml — review for any ai/scripts/ path filters
substrate-size-guard.yml — path filter ai/scripts/check-substrate-size.mjs → ai/scripts/diagnostics/check-substrate-size.mjs
skill-manifest-lint.yml — path filters + run commands for ai/scripts/lint-skill-manifest.mjs + ai/scripts/lint-agents.mjs → ai/scripts/lint/{lint-skill-manifest,lint-agents}.mjs
check-retired-primitives.yml — path filter ai/scripts/check-retired-primitives.mjs → ai/scripts/diagnostics/check-retired-primitives.mjs
Integration tests
Audit + update any integration tests dynamically importing from ai/scripts/ flat paths.
Acceptance Criteria
- 30 source files moved into 5 thematic subfolders (lifecycle/migrations/diagnostics/setup/lint).
- All test mirrors moved.
- 7 npm script paths updated.
- 4 GitHub workflow YAML files updated (paths + run commands).
- All affected specs + workflows pass.
ai/scripts/ root has no .mjs files left (all categorized).
Depends on
Sub 8 + Sub 9 (must merge first to free ai/scripts/ of daemon entry files).
Authored by: [Claude Opus 4.7] (Claude Code)
Parent Epic
#11831 — Sub 11 of Epic (folder-structure cleanup; ai/scripts/ thematic categorization).
Scope
After Sub 8/9 move daemon entries OUT of
ai/scripts/, remaining 30 files get thematic subfolder categorization. 7 categories: lifecycle / maintenance / migrations / diagnostics / runners / setup / lint.(buildScripts/ai/ collapse is Sub 12 separately.)
Source moves (within ai/scripts/)
ai/scripts/lifecycle/(13 files): wake/idle/sunset/harness/locks/orchestrator-spawned workers:ai/scripts/migrations/(7 files): one-shot data migrations:ai/scripts/diagnostics/(7 files): read-only inspection:ai/scripts/setup/(1 file): one-time setup:ai/scripts/lint/(2 files): CI-enforced static analysis:(maintenance/ and runners/ folders created by Sub 12 with the buildScripts/ai/ collapse; ai/scripts/ doesn't contribute files to those buckets.)
Test moves (mirror source structure where unit specs exist)
Per-script audit: for each script, if a unit spec exists at
test/playwright/unit/ai/scripts/X.spec.mjs, move totest/playwright/unit/ai/scripts/{category}/X.spec.mjs.package.json
Affected npm scripts (all paths updated to include category subfolder):
"ai:prune-worktrees"→./ai/scripts/migrations/bootstrapWorktree.mjs --prune-stale"ai:lint-agents"→./ai/scripts/lint/lint-agents.mjs"ai:lint-skill-manifest"→./ai/scripts/lint/lint-skill-manifest.mjs"ai:revalidation-sweep"→./ai/scripts/lifecycle/revalidationSweep.mjs"ai:check-retired-primitives"→./ai/scripts/diagnostics/check-retired-primitives.mjs"ai:check-substrate-size"→./ai/scripts/diagnostics/check-substrate-size.mjs"ai:analyze-nl-telemetry"→./ai/scripts/diagnostics/analyzeNlTelemetry.mjs.github/workflows
agent-pr-review-body-lint.yml— review for anyai/scripts/path filterssubstrate-size-guard.yml— path filterai/scripts/check-substrate-size.mjs→ai/scripts/diagnostics/check-substrate-size.mjsskill-manifest-lint.yml— path filters + run commands forai/scripts/lint-skill-manifest.mjs+ai/scripts/lint-agents.mjs→ai/scripts/lint/{lint-skill-manifest,lint-agents}.mjscheck-retired-primitives.yml— path filterai/scripts/check-retired-primitives.mjs→ai/scripts/diagnostics/check-retired-primitives.mjsIntegration tests
Audit + update any integration tests dynamically importing from
ai/scripts/flat paths.Acceptance Criteria
ai/scripts/root has no.mjsfiles left (all categorized).Depends on
Sub 8 + Sub 9 (must merge first to free
ai/scripts/of daemon entry files).Authored by: [Claude Opus 4.7] (Claude Code)