| name | quarterly-hygiene |
| description | Quarterly deep vault maintenance: context-file review, CRM staleness, session-log archiving, skill-library flywheel audit, and panel model-currency checks. |
Quarterly Hygiene - Deep Vault Maintenance
You are running the quarterly deep-maintenance pass. This is the mechanical companion to $quarterly-review (which handles strategy), exactly as $weekly-hygiene is to $weekly-review.
It does the heavy structural checks that are too slow or too rarely-needed for the weekly pass. It does NOT repeat $weekly-hygiene's work — broken links, orphans, dead-ends, project-doc health, Tickler, Working Memory, and the temporal context-staleness scan all belong to weekly-hygiene. This skill consumes weekly-hygiene's report and layers the quarterly-only deep passes on top.
Instructions
-
Resolve Vault Path
"$VAULT_PATH/.claude/scripts/resolve-vault.sh"
"$VAULT_PATH/.claude/scripts/check-archive-layout.sh" --enforce "$VAULT_PATH"
If error, abort. Read ${CODEX_HOME:-$HOME/.codex}/skills/_shared-rules.md and apply its rules throughout this skill. All code below uses {VAULT} as a placeholder — substitute the resolved vault path.
-
Check date and calculate quarter using bash date:
- Current date:
date +"%Y-%m-%d"
- Quarter: Q1 (Jan-Mar), Q2 (Apr-Jun), Q3 (Jul-Sep), Q4 (Oct-Dec). File naming:
YYYY-QN.md.
- Boundary rule: if today falls in the first 2 weeks of a quarter, ask the user once whether this run covers the just-ended quarter or the current one — a quarterly pass run 2 Jul almost always covers Q2. Use the answer for the report filename and every "current quarter" comparison. If no interactive reply can be obtained, use the just-ended quarter and record
unattended boundary default in the report's Quarter selection line. ($quarterly-review carries the same interactive rule; keep the two runs on the same quarter when both run interactively.)
-
Consume the latest weekly-hygiene report (do NOT re-run its checks):
- Find the latest file in
{VAULT}/06 Archive/OpenCairn/Hygiene Reports/ (filename descending).
- Compare its ISO week to the current week (
date +%G-W%V; last week is date -d "7 days ago" +%G-W%V — compare the strings, don't reason about week-53 year-boundary cases yourself):
- Current or last week: read and carry its unresolved structural findings into this quarterly report's "Carried from weekly-hygiene" section. Mapping:
Vault Consistency → broken links / orphans / dead-ends; Projects Folder → tier mismatches; Actions Routed → unresolved routed items. Counts-only metrics (Vault Structural Metrics) are not carried — snapshots, not open work.
- Older than last week, or absent: warn — "Latest weekly-hygiene report is [week / none] — vault structural state may be stale. Recommend running
$weekly-hygiene before this pass." If a stale report exists, still carry its findings per the same mapping, labelled stale in the report's source line. Continue regardless; this skill's own deep checks run independently and never require a fresh weekly run.
Quarterly-only deep passes
-
Deep context-file accuracy re-read (non-temporal drift).
$weekly-hygiene step 12 scans only temporal markers (dates, "currently", "soon"). This is the heavier pass that catches durable facts which never trip a temporal scan and so silently rot for years:
- Read each
{VAULT}/07 System/Context - *.md file end-to-end.
- Check durable claims for drift: job title / role, location, hardware specs and model numbers, active subscriptions, default tools and workflows, named collaborators/clinics. Evidence source: skim the weekly reviews inside the evidence window (Synthesis + Projects Active sections) for events that contradict a claim. Flag a claim only when that evidence contradicts it or another concrete inconsistency makes it suspect. Absence from the reviews is not a flag and does not trigger a claim-by-claim "still true?" quiz; record those claims collectively as not independently revalidated — this skill gathers no other activity data, and
$quarterly-review's full gather runs after it.
- Evidence window — the run cadence is not the calendar quarter (mid-quarter and standalone runs are expected), so anchoring on the quarter start leaves reviews between the last pass and the boundary permanently unread. Window start = the
**Generated:** date in the latest {VAULT}/06 Archive/OpenCairn/Quarterly Hygiene Reports/*.md (filename descending; take the date from that content header, never from mtime — _shared-rules.md §22), falling back to the quarter start when no prior report exists. Window end = today. State the window in the report so the next run's start is unambiguous.
- Guardrail (inherited from
$weekly-hygiene's context-file staleness step): edit a context file ONLY with user-provided replacement text. Never rewrite, rephrase, or infer an update autonomously — these are high-trust prose documents; wrong corrections are worse than stale content. Present each flagged claim, ask, then edit only what the user supplies, using locked-edit.sh --replace after re-reading a unique literal OLD block.
-
CRM stale-entry review. (if {VAULT}/07 System/CRM/ exists)
$weekly-hygiene step 6 scans for new names to add. This reviews existing entries for decay:
- Read the CRM index and range files.
- Flag entries with outdated roles, superseded contact details, or context that this quarter's events have overtaken.
- Don't auto-modify — present findings and let the user decide.
Output
-
Write the quarterly hygiene report:
mkdir -p "{VAULT}/06 Archive/OpenCairn/Quarterly Hygiene Reports"
Draft outside the vault, then write {VAULT}/06 Archive/OpenCairn/Quarterly Hygiene Reports/YYYY-QN.md through "{VAULT}/.claude/scripts/locked-edit.sh". When missing, immediately confirm the path is absent and create it with --replace-whole MISSING; exit 2 means another writer created it, so re-read that file and continue through the existing-report path. When the file already exists, it remains the quarter's canonical mutable hand-off: before replacement, carry every unresolved report-only corrections-fold proposal, flywheel proposal and pending panel-model action into the new draft unless the user resolved or rejected it this run; routed items stay in their destination SSOTs. Re-read the old report and use its full contents as literal OLD with --replace. Never create the report with --append or write it directly.
⛔ Cite report items by stable identifier, not line number — see _shared-rules.md §13. Reference any project-doc / Tickler.md item by title/heading/content, never by line number; structural maintenance this run shifts line numbers, so an Lnn reference is stale on write.
# Quarterly Hygiene Report - YYYY QN
**Generated:** YYYY-MM-DD
**Quarter selection:** [calendar current quarter / user-confirmed just-ended or current / unattended boundary default: just-ended]
**Status:** [Clean / N issues found]
## Carried from Weekly-Hygiene
*Source: Hygiene Reports/YYYY-Wnn (current / stale — re-run recommended / not found)*
- [Unresolved broken links, orphans, dead-ends, tier mismatches from the weekly report — not re-derived]
## Context Files (deep, non-temporal)
*Evidence window: YYYY-MM-DD → YYYY-MM-DD (previous report's Generated date / quarter start — no prior report)*
| File | Status | Durable claim flagged | Resolution |
|------|--------|----------------------|------------|
| Context - X.md | Stale | [claim] | [user-provided fix / pending] |
## CRM Stale Entries
- [Entry — what's outdated]
## Corrections-Log Fold
Entries folded into rules since last fold: N (or "no distilled rules section present")
New rules added: N · merged into existing: N · marked superseded: N
"Last fold" date bumped: [YYYY-MM-DD / n/a]
Fold pending approval: [summary of proposed changes / none]
Flat session logs: N (keeping last ~90 days flat)
Archived this run: N logs → YYYY/ subfolders (or "none — nothing older than 90 days")
Skipped (already archived): N — flat copies whose year folder already holds that basename; duplication surfaced, nothing deleted [list or "none"]
Link integrity: before N → after M; moved dates unresolved: [none / list / n/a — nothing moved]
Proposed new index entries (≥2 reuses, unindexed): [list or "none"]
Divergent reimplementations of indexed patterns: [list or "none"]
Dead/cold index entries (never surfaced): [list or "none"]
| Seat | Resolved model | Pin source | Current? | Proposed action |
|------|---------------|------------|----------|-----------------|
| [seat] | [model id] | [config path / CLI default / session] | [yes / stale / unstable alias] | [bump to X — pending / applied + smoke-tested / none] |
(or "no cross-model panel configured — model-currency check skipped")
[Confirmed edits applied this run]
[Unresolved items the user didn't engage with → the relevant project/area doc, else Tickler +7d via , back-linked: ]
[Flywheel proposals stay in this report as pending user decisions — they are not routed]
✓ Quarterly hygiene report: 06 Archive/OpenCairn/Quarterly Hygiene Reports/YYYY-QN.md
✓ Weekly-hygiene report: [carried / carried (stale — re-run recommended) / not found]
✓ Context files re-read: N, M durable-drift flags
✓ CRM stale entries: N flagged
✓ Corrections-log fold: [applied (N entries folded) / pending approval / no distilled rules section / no log]
✓ Session logs: N flat; archived M → YYYY/ (or "none aged out"); K skipped as duplicates
✓ Link integrity: before N → after M; moved dates unresolved: [none / list / n/a — nothing moved]
✓ Flywheel audit (draft): [N proposed entries, M divergences, K dead / skipped]
✓ Panel model currency: [N seats checked, M stale/unstable pins flagged / no panel configured]
✓ Skill self-review: [no gaps / N observations logged]
Quarterly hygiene complete. Run $quarterly-review to fold these findings into the strategic review.
Guidelines
- Mechanical, not reflective. Structural checks and flags only.
$quarterly-review handles strategy, alignment, and planning.
- No re-doing weekly-hygiene. Broken links, orphans, dead-ends, tier reconciliation, temporal context-staleness — all weekly's job. This command reads weekly's report; it does not re-scan.
- User confirmation for context files and CRM. High-trust; wrong corrections beat stale content only if the user supplied them. Never infer an update.
- Bound tree-walk cost on the vault — don't ban tools by name. The expensive case is reading content across untracked mass (an unbounded
--no-ignore sweep at the vault root, an unfiltered grep -r); an ignore-respecting rg or a metadata-only find usually is not. Structural queries still route to the Obsidian CLI. Check the vault's search-routing doc for the permitted/prohibited split before assuming any tool is barred outright.
- Portability note.
date -d is GNU-only — on macOS/BSD substitute date -v-90d +%F (same caveat family as weekly-hygiene's Guidelines).
- Report is consumable.
$quarterly-review reads this report so findings flow into the strategic review without re-gathering — the same contract $weekly-review has with $weekly-hygiene.
Frequency
Quarterly (last week of March, June, September, December), or as a precursor to $quarterly-review. Can also run standalone for a mid-quarter deep clean.
Integration
- Feeds
$quarterly-review: the strategic review consumes this report for its Vault Health section.
- Consumes
$weekly-hygiene: carries forward unresolved structural findings rather than re-scanning.
- Archives session logs: inventories logs older than 90 days and rolls confirmed files into
Session Logs/YYYY/ through locked-edit.sh --move; unattended runs stop after the dry run.