원클릭으로
maintenance
Workspace maintenance — audit integrity, clean up stale context, suggest merges. Run periodically or before /release.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Workspace maintenance — audit integrity, clean up stale context, suggest merges. Run periodically or before /release.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Finalize a work session — rebase, synthesize release notes from spec/plan/session tracker/commits, create PRs with unified presentation. Handles all project repos and workspace repo. Use when work on a session is done.
Suspend current work — updates session tracker, captures state to the tracker body, pushes all repos, creates draft PRs. Use when stepping away from work that isn't finished.
First-time workspace initialization. Clones repos, installs template components, extracts team knowledge from documentation sources and Claude chat history, activates rules, configures user identity. Run once after scaffolding with --init.
Prepend a new CHANGELOG.md entry per project repo by synthesizing unreleased branch notes. Deletes consumed branch notes and synthesizes workspace-context into canonical (locked) entries. Use at release time.
Apply a staged template update to an initialized workspace. The CLI stages a payload in .workspace-update/; this skill processes it. Runs maintenance audit before and after.
Capture a drive-by idea without interrupting your current work. Dispatches a background researcher by default, or use --quick for a simple note. Usage: /aside [--quick] <your thought>
| name | maintenance |
| description | Workspace maintenance — audit integrity, clean up stale context, suggest merges. Run periodically or before /release. |
Keep the workspace healthy. Combines integrity auditing with active cleanup recommendations.
/maintenance — full run (audit + cleanup)/maintenance audit — integrity checks only (read-only)/maintenance cleanup — stale context, suggested merges, reconciliation onlyRead-only integrity checks. Reports problems but never modifies files.
Scan all workspace-context files against each other:
For each workspace-context .md file and each work-sessions/*/workspace/session.md:
branch field references a branch that still exists?repo/repos field references repos that exist in workspace.json?lifecycle: active on a file not updated in 7+ days? (stale candidate)lifecycle: resolved files that should have been processed by /complete-work?status: active but the workspace worktree at work-sessions/{name}/workspace/ is missing? (orphaned)confidence field present? Must be one of high, medium, low if set.repos/?git -C repos/{repo} worktree list for each repo and flag any prunable markers. These usually come from a workspace-first teardown (the unsafe order) leaving stale admin records behind. Suggest git worktree prune on the affected repo.workspace-context/index.md, workspace-context/canonical.md, and each workspace-context/team-member/{user}/index.md are auto-generated from frontmatter and locked content. Run the check:
node .claude/scripts/build-workspace-context.mjs --check --root .
The script reports per-artifact status as JSON and uses three exit codes to distinguish what's wrong:
0 — all artifacts current and the rendered canonical fits inside workspace.canonicalBudgetBytes.1 — at least one artifact is missing or stale. Run --write to regenerate. missing means the artifact does not exist yet; stale means it exists but no longer matches its sources (a file was added or deleted, a description: changed, a shared/locked/ file was edited, an .indexignore rule was added).2 — artifacts are current but canonical body bytes exceed the budget after the trim and stub stages have already run. Regeneration cannot fix this; the locked content itself needs triage. Stale wins over over-budget when both apply, so a 1 can hide an over-budget condition until you regen.The JSON payload always includes a canonical block summarizing the budget outcome:
{
"status": "current",
"missing": [],
"stale": [],
"canonical": {
"budget": 40960,
"current": 47802,
"overBy": 6842,
"selectionStatus": "stubbed",
"trimmedFiles": ["post-release-discipline"],
"stubbedFiles": ["project-status", "release-flow-recipes"]
}
}
selectionStatus walks ok → trimmed → stubbed → over-budget as the script gives up progressively more reference content trying to fit the budget. trimmedFiles lists reference files whose <!-- canonical:trim --> ... <!-- canonical:end-trim --> spans were dropped; stubbedFiles lists reference files whose entire body was replaced with a one-line breadcrumb. overBy is present only when selectionStatus === 'over-budget' and reports the bytes still over after stubbing.
Audit mode reports the status verbatim. When selectionStatus is over-budget, audit emits the budget violation and recommends /maintenance cleanup to triage — regeneration will not resolve it. Cleanup mode runs --write when missing or stale, re-checks, and then enters the budget triage flow described in cleanup step 9 if the post-regen check still reports over-budget.
While the indexes are being read, also flag entries with weak fallbacks: filename-slug-only descriptions (e.g., "project status" with no period) usually indicate the underlying file is missing a description: or has no usable opening sentence. Suggest adding description: to those source files — the index will pick it up on the next regeneration.
Compare the workspace's pinned template version against the latest published on npm.
Always invoke refreshIfStale from the audit (regardless of workspace.versionCheck.ambient — the user explicitly ran /maintenance):
import { refreshIfStale } from './.claude/lib/freshness.mjs';
const result = await refreshIfStale({
workspaceRoot: process.cwd(),
ttlMs: 24 * 60 * 60 * 1000,
});
Report one of:
outdated → ✗ Template v{current} → v{latest} available. Run npx @ulysses-ai/create-workspace --upgrade.current → ✓ Template is up to date (v{latest}).unknown (with cache) → ⚠ Could not reach npm registry; last cached latest was v{latest} as of {checkedAt}.unknown (no cache) → ⚠ Could not reach npm registry; no cached version on file. Try again when online.skipped: 'uninitialized' → ⚠ Workspace not initialized; freshness check unavailable.Active recommendations. Flags problems and suggests fixes, but asks before acting.
Scan the following file sets for a YAML frontmatter updated: field:
.claude/rules/*.md (active rules only — .md.skip files are included too, since the rule content can still drift).claude/skills/*/SKILL.md.claude/agents/*.md.claude/hooks/*.mjsFor each file that has an updated: field, compute the age in days from today. If the age exceeds 180 days, flag the file as a stale component candidate. Print the file name, the updated: date, and the age in days so the contributor knows how far the file has drifted.
Files without an updated: field are skipped — the check is opt-in and activates the discipline incrementally as contributors add frontmatter to the files they own. To start tracking a file, add updated: <today> to its frontmatter; the check will surface it if it goes stale.
When stale candidates are found, surface them as warnings in the output format and link to config-review.md.skip (in .claude/rules/) as the opt-in rule that documents the review cadence and rationale.
work-sessions/{name}/ folders whose worktrees are gone — suggest cleanup/complete-work post-flight cleanupThis step runs only when the post-regen --check from step 9 still reports selectionStatus: 'over-budget'. If the regular regen pass cleared the budget — or if --check was already ok, trimmed, or stubbed after step 9 — skip this step entirely.
The rest of cleanup is suggestion-list-with-confirmation: surface a candidate, ask before applying, move on. Triage is the one meaningfully more interactive surface in /maintenance. It runs as a small REPL: present the budget state and a triage menu, take one action, re-run --check, present the menu again with the new state. No suggestion is auto-applied; every action is the user's choice.
Inputs to gather before the first menu render:
canonical block from the --check JSON: budget, current, overBy, selectionStatus, trimmedFiles, stubbedFiles.workspace-context/shared/locked/*.md file with its on-disk byte size and frontmatter priority.## Section heading spans with byte sizes — use a simple ^## boundary scan, not a full markdown AST. Locked files are short and shallow enough that the naive split is sufficient; if a file ever has nested headings that confuse it, fall back to opening the file in an editor (option [c] below).Render the state and present this menu:
Canonical budget: 40960 bytes. Current: 47802 bytes. Over by 6842 bytes.
Locked files by size:
1. project-status.md (priority: reference, 18432 bytes) ← stubbed in canonical
2. post-release-discipline.md (priority: critical, 12104 bytes)
3. naming-conventions.md (priority: critical, 4218 bytes)
4. cross-platform.md (priority: critical, 702 bytes)
5. product-bias-risk.md (priority: critical, 1346 bytes)
Largest sections in priority:critical files (eligible for promotion to reference or trim markers):
- project-status.md > "What's Built" (5120 bytes)
- post-release-discipline.md > "Backstop: branch protection" (3892 bytes)
- post-release-discipline.md > "Why" (2104 bytes)
Triage (one at a time):
[a] Demote a file from critical to reference
[b] Add canonical:trim markers around a specific section
[c] Open a locked file in the editor for manual edits
[d] Skip — accept the over-budget warning
[q] Done
For each chosen action:
[a] Demote. Ask which file. Rewrite its frontmatter priority: critical → priority: reference. No body changes. Re-run --check, re-render the menu with the new state.[b] Add trim markers. Ask which file > section. Wrap the section by inserting <!-- canonical:trim --> on its own line just before the section heading and <!-- canonical:end-trim --> on its own line just after the section's last line (the line before the next ^## heading or EOF). Re-run --check, re-render.[c] Open in editor. Print the file path and pause. The user edits manually, returns, and confirms — then re-run --check and re-render.[d] Skip. Accept the over-budget state for this run; record the acknowledgement in the run summary. Audit will continue to surface the warning on subsequent runs.[q] Done. Exit triage. Report the final --check status as the run result.Trim markers and demotions only matter for priority: reference files — <!-- canonical:trim --> spans on a priority: critical file are inert until the file is demoted. The triage flow never auto-decides which file to demote or which section to wrap; it surfaces the data, presents options, and waits.
Read workspace.json. If workspace.tracker?.type === 'github-issues' and workspace.forge is unset, emit a notice (not an error):
ℹ workspace.json has tracker.type='github-issues' but no workspace.forge field.
Skills default to GitHub forge operations; add `"forge": {"type": "github"}`
to workspace.json to make the choice explicit. See .claude/rules/forge-operations.md.
This is migration guidance for workspaces created before the forge field landed — the field is back-compat with a sensible default, so the unset case is not a bug, just an opportunity to make the implicit explicit. If workspace.forge.type is set to a value with no adapter at .claude/scripts/forges/{type}.mjs, that IS an error and goes in the Issues section.
--check invocation as step 5. Reported as current / budget bytes with the selection status (e.g., full, 2 reference files trimmed). Over-budget cases are deferred to the cleanup triage flow rather than re-reported here.workspace-scratchpad/session-log.jsonl exists):
/maintenance results:
Issues (3):
✗ workspace-context/team-member/alice/old-handoff.md references branch feature/old
but that branch was deleted
✗ 2 inflight files exist but no active work session (orphaned?)
✗ Canonical exceeds budget: 47 KB / 40 KB. 2 reference files were stubbed;
canonical is still 6.8 KB over. Run /maintenance cleanup to triage.
Warnings (2):
⚠ workspace-context/team-member/alice/workspace-analytics.md not updated in 8 days
⚠ Worktree work-sessions/old-feature/workspace has no commits in 5 days
Cleanup suggestions (2):
⊕ workspace-branching.md and persistent-work-sessions.md overlap
significantly — merge into one?
⊕ migration-recipes.md still says "/sync handles dogfood" but
/sync was replaced by /sync-work — update?
OK (5):
✓ All CLAUDE.md skill references valid
✓ Workspace structure matches rule
✓ workspace.json repos all present
✓ Canonical: 17 KB / 40 KB (full)
✓ Template is up to date (v0.14.0)
.md files and their frontmatter.claude/rules/, .claude/skills/, .claude/agents/ against referencesnode .claude/scripts/build-workspace-context.mjs --check --root . — capture status. Exit 0 = clean and within budget, 1 = artifact missing or stale, 2 = artifacts current but canonical body over budget. The canonical block in the JSON output drives both the audit budget line and the cleanup triage decision.--check reports over-budget, enter the canonical-budget triage flow described in cleanup step 10.