Storytime Lint — Structural Checks
Fast mechanical validation of storytime artifacts against the process
rules. No prose, no commentary — just pass/fail per check, per artifact.
If you want interpretation, run /storytime-retro. This is the
hygiene pass.
Two Tiers
Lint has two tiers with a hard split:
Mechanical tier (grep/file checks) — runs scripts/check-conventions.sh
for version consistency, schema_version presence, type field, driver
field, thread hygiene, icebreaker existence. Zero model reasoning.
Deterministic. Milliseconds.
Reasoning tier (estimator task force) — spawns the
agents/estimator.md sub-agent for checks that need prose parsing
(P4, P5, P7, T4, B6, NG1, SC1, DR1). Each invocation is scoped to
one check on one artifact, returns one line of PASS/WARN/FAIL.
Checks that violated lint's "grep only" contract in v0.7.2 (P4, P5, T4)
are now in the reasoning tier where reasoning is explicitly allowed.
Arguments
What to lint: $ARGUMENTS (topic, session path, or empty for all)
Scope
- Empty → lint every session under
specs/.storytime/sessions/
<topic> → lint all episodes of that topic
<session-path> → lint one specific directory
Checks
Per-survey (survey.md)
| # |
Tier |
Check |
| S1 |
mechanical |
Has frontmatter with type: survey |
| S2 |
mechanical |
Has a coverage fingerprint (commit, paths, ratios) |
| S3 |
mechanical |
Fingerprint commit resolves via git cat-file -e <sha> |
Per-team (team.md)
| # |
Tier |
Check |
| T1 |
mechanical |
Has frontmatter with type: team |
| T2 |
mechanical |
Every persona references a known archetype |
| T3 |
mechanical |
Same-archetype personas have distinct focus |
| T4 |
reasoning |
Codenames are non-human (warn on common first names) |
Per-breakout (breakout-*.md)
| # |
Tier |
Check |
| B1 |
mechanical |
Has frontmatter with type: breakout |
| B2 |
mechanical |
Frontmatter names a driver |
| B3 |
mechanical |
Body contains ≥1 citation (file:line, [url], commit, RFC) |
| B4 |
mechanical |
Body contains Complexity AND Scale |
| B5 |
mechanical |
Body contains Recommendation: section |
| B6 |
reasoning |
Recommendation is substantive, not a punt |
| DR1 |
reasoning |
Driver actually drove (voice matches attribution) |
Per-plan (plan.md)
| # |
Tier |
Check |
| P1 |
mechanical |
Has frontmatter with type: plan |
| P2 |
mechanical |
Has a Non-goals section with entries |
| P3 |
mechanical |
Has a Success criteria section with entries |
| P4 |
reasoning |
Every plan item states Complexity + Scale in prose |
| P5 |
reasoning |
No plan item has Complexity ≥ 13 as a leaf |
| P6 |
mechanical |
At least one ASCII box-drawn visual |
| P7 |
reasoning |
Citations are substantive (point to specific evidence) |
| NG1 |
reasoning |
Non-goals are specific (not "we won't boil the ocean") |
| SC1 |
reasoning |
Success criteria are measurable (number, threshold, test) |
Per-buildout (buildout-*.md)
| # |
Tier |
Check |
| BO1 |
mechanical |
Has frontmatter with type: buildout |
| BO2 |
mechanical |
Frontmatter names a driver |
| BO3 |
mechanical |
Frontmatter has plan_items and decisions |
| BO4 |
mechanical |
Body contains an Implementation Trace section |
| BO5 |
mechanical |
Every file_created/file_modified listed actually exists |
Per-thread (_thread.md)
| # |
Tier |
Check |
| Th1 |
mechanical |
Has frontmatter type: thread |
| Th2 |
mechanical |
Has last_completed_phase and last_commit |
| Th3 |
mechanical |
last_commit resolves via git cat-file -e <sha> |
Per-icebreaker (icebreaker.md)
| # |
Tier |
Check |
| I1 |
mechanical |
Exists if team.md exists and breakouts are present |
| I2 |
mechanical |
Has frontmatter type: icebreaker |
Per-citation (across all files)
| # |
Tier |
Check |
| C1 |
mechanical |
File citations (path:line) — the file exists |
| C2 |
mechanical |
File citations — the line number is in bounds |
| C3 |
mechanical |
Commit citations — commit exists in the repo |
Stale citations (file moved, line shifted) are warnings, not
failures — the process allows rot but we want visibility.
Decision staleness (across decision log)
| # |
Check |
| D1 |
Each decision cites at least one code reference |
| D2 |
Cited files exist in the current tree |
| D3 |
If decision has a commit pin, check if cited files changed since that commit (⚠ if yes) |
Decision staleness is commit-delta based: compare the decision's
pin commit against HEAD for the cited paths. If the file changed since
the decision was written, it's a staleness warning. The decision may
still be valid — but it needs re-verification.
Repo-level checks
| # |
Tier |
Check |
| R1 |
mechanical |
VERSION, plugin.json, all SKILL.md version-echo lines match |
| R2 |
mechanical |
site/*.html version strings match VERSION |
| R3 |
mechanical |
README.md version strings match VERSION |
Run R1-R3 only when --repo flag is given or scope is empty
(full-repo lint). These catch version drift from manual bumps.
All repo-level checks are delegated to
scripts/check-conventions.sh — run it first, parse its output.
Per-consolidation event (v1.0)
Delegated to references/consolidation-format.md check table.
| # |
Tier |
Check |
| CF1 |
mechanical |
type: consolidation present |
| CF2 |
mechanical |
schema_version: 1 present |
| CF3 |
mechanical |
scale in {phase, commit, nap, shift, session, compact} |
| CF4 |
mechanical |
at parseable as ISO 8601 |
| CF5 |
mechanical |
pause_posture in allowed set |
| CF6 |
mechanical |
signals present when scale ∈ {nap, shift, compact} |
| CF7 |
mechanical |
signals drawn from allowed vocabulary |
| CF8 |
mechanical |
commit resolves via git when scale = commit |
| CF9 |
mechanical |
driver matches @role or @role [codename] pattern |
| CF10 |
mechanical |
No orphan .tmp files older than 5 minutes |
| CF-R1 |
reasoning |
Digest is substantive (phase scale) |
| CF-R2 |
reasoning |
Signals match the event description |
Per-callout (v1.0 cross-topic references)
Delegated to scripts/validate-callouts.sh.
| # |
Tier |
Check |
| CA1 |
mechanical |
Callout line matches sigil regex (Callout-> or Callout<-) |
| CA2 |
mechanical |
<topic> resolves to a session directory |
| CA3 |
mechanical |
<decision-id> resolves to a ### <id> — header |
| CA4 |
mechanical |
<kind> in closed vocabulary (depends-on, affects, supersedes, superseded-by, related) |
| CA5 |
mechanical |
No exact-duplicate (from, to, kind) within one decision |
| CA-W1 |
advisory |
Reverse cache is stale (forward without reverse) |
| CA-W2 |
advisory |
Callout target has status: superseded |
| CA-W3 |
advisory |
Dangling reverse cache (reverse without forward) |
Per-remembrance (v1.0 wakeup document)
| # |
Tier |
Check |
| RM1 |
mechanical |
type: remembrance, schema_version present |
| RM2 |
mechanical |
All three body sections present (Wakeup, Prompt, State) |
| RM3 |
mechanical |
last_commit resolves via git |
| RM4 |
mechanical |
active_threads[].path all exist as files |
| RM5 |
mechanical |
No orphan remembrance.md.tmp older than 5 minutes |
| RM-R1 |
reasoning |
Wakeup narrative substantive (not placeholder) |
| RM-R2 |
reasoning |
Consolidation prompt names specific files |
| RM-R3 |
reasoning |
State pinned captures actual in-flight work |
Per-tutorial-state (v1.0 friction tracking)
| # |
Tier |
Check |
| TS1 |
mechanical |
Valid frontmatter if present |
| TS2 |
mechanical |
Per-skill sections reference known skill names |
| TS3 |
mechanical |
graduated: true paired with graduated_at |
| TS-R1 |
reasoning |
If graduated, log shows sufficient signal evidence |
| TS-R2 |
reasoning |
"would have proposed" entries cluster/disperse tuning hint |
Per-commit-patterns (v1.0 adaptive learning)
| # |
Tier |
Check |
| CD1 |
mechanical |
Valid frontmatter if present |
| CD2 |
mechanical |
Pattern entries have required fields |
| CD3 |
mechanical |
status in {none, quieter-proposed, quieter-active, soft-reset} |
| CD4 |
mechanical |
rolling_window has ≤ 7 entries |
| CD-R1 |
reasoning |
Claimed clean count matches rolling window |
| CD-R2 |
reasoning |
Pattern key is well-formed |
Per-dream (v1.0 ancillary byproduct)
| # |
Tier |
Check |
| DM1 |
mechanical |
type: dream, commit present in frontmatter |
| DM2 |
mechanical |
commit resolves via git |
| DM3 |
mechanical |
Body length ≤ 30 lines (dreams stay small) |
Migration-readiness (M-class, v0.9 → v1.0)
| # |
Tier |
Check |
| M1 |
advisory |
No specs/.storytime/history/decisions.md present |
| M2 |
advisory |
All artifacts have schema_version |
| M3 |
advisory |
Cohort _roster.md uses non-human codenames |
| M4 |
advisory |
_thread.md files have v1.0 fields |
| M5 |
advisory |
.storytime/.version = 1.0 or higher |
Full-repo lint surfaces M1-M5 as advisory warnings. The pre-flight gate
in v1.0 skills (V1-029) is the authoritative block.
Intent graph (IG-class, v1.0.1+)
Per V1-035. Mechanical only; reasoning checks deferred.
| # |
Tier |
Check |
| IG1 |
mechanical |
Every sealed decision with parent: has a resolvable target |
| IG2 |
mechanical |
Every supersedes: has a resolvable target |
| IG3 |
mechanical |
tensions: are symmetric (X tensions Y ↔ Y tensions X) |
Prompt-yield (PY-class, v1.0.1+)
Per V1-036. Mechanical only.
| # |
Tier |
Check |
| PY1 |
mechanical |
Frontmatter type: prompt-yield present |
| PY2 |
mechanical |
originating_user is a @user [codename] reference |
| PY3 |
mechanical |
status in {seeded, hydrating, maturing, crystallized} |
| PY4 |
mechanical |
If status=crystallized, crystallized_into resolves |
Intent tracking (IT-class, v1.0.1+)
Per V1-031, V1-033. Mechanical only.
| # |
Tier |
Check |
| IT1 |
mechanical |
.storytime/intents.md header lines match timestamp+session pattern |
| IT2 |
mechanical |
Each intent entry has required fields (intent, lens, type, source) |
| IT3 |
mechanical |
lens: references known roles only |
| IT4 |
mechanical |
type: is in the closed vocabulary |
| IT5 |
mechanical |
supersedes: resolves to a prior entry |
Process
- Run mechanical tier first: invoke
./scripts/check-conventions.sh
(with $ARGUMENTS if provided). Capture its output and exit code.
If any mechanical check fails, surface those first — they're blockers.
- Enumerate artifacts in scope (sessions, episodes, or the given
path).
- Run per-artifact mechanical checks (S1-S3, T1-T3, B1-B5, P1-P3, P6,
BO1-BO5, Th1-Th2, C1-C3, D1-D3) using Grep/Read/Bash.
- Run reasoning-tier checks via Estimator. For each artifact that
has reasoning checks (P4, P5, P7, T4, B6, NG1, SC1, DR1), spawn the
estimator agent with one check at a time:
agents/estimator.md — scoped to the single check
- Pass: check-id, artifact path, context paths
- Receive: one-line PASS/WARN/FAIL + justification
- Merge results into a single pass/fail table.
- Print summary footer:
N passed, M warnings, K failed.
- Exit 0 if no failures, 1 if any failures (warnings ok).
Output Format
Single pass/fail table. No prose. No "analysis". No "consider revising":
Session: rate-limiting / episode 001
survey.md S1 ✓ S2 ✓ S3 ✓
team.md T1 ✓ T2 ✓ T3 ✓ T4 ✓
icebreaker.md (no checks — informational artifact)
breakout-algo.md B1 ✓ B2 ✗ (no driver) B3 ✓ B4 ✓ B5 ✓
breakout-store.md B1 ✓ B2 ✓ B3 ✓ B4 ✓ B5 ✓
plan.md P1 ✓ P2 ✓ P3 ✓ P4 ✓ P5 ✓ P6 ✓ P7 ✓
Citation hygiene:
breakout-algo.md:23 → src/server.ts:14 ✓
breakout-algo.md:45 → src/config/redis.ts:5 ⚠ line now at :7 (drift 2)
plan.md:67 → commit abc123 ✓
Summary: 21 passed, 1 warning, 1 failed
Rules
- Two tiers, hard split. Mechanical checks are grep/file only —
no interpretation. Reasoning checks delegate to the estimator agent
with one check per invocation.
- Warnings are visibility, not failures. Stale citations warn.
Missing required fields fail.
- Mechanical tier is fast. Grep and file existence only. Zero
Agent calls in this tier.
- Reasoning tier is scoped. Estimator receives one check at a
time, returns one line. No free-form analysis.
- Deterministic for mechanical. Same input → same output.
Reasoning tier may drift at the margins; that's why it returns
justification — so drift is visible.
- Exit code signals status. 0 = clean or warnings only, 1 = failures.
- Checks are listed above. Don't invent new ones without adding
them to the table first.
- Mechanical tier is the primary gate. Reasoning tier is advisory
polish. A session that passes the mechanical tier is releasable.
1---2name: storytime-lint3description: This skill should be used when the user asks to "lint storytime", "validate session", "check the spec", "storytime hygiene", "verify citations", or wants a structural check of storytime artifacts against the process rules. Fast mechanical checks — no prose, no philosophy. Outputs a pass/fail table.4---56<!-- version-echo: display "storytime v1.0.1" at start of execution -->7# Storytime Lint — Structural Checks89Fast mechanical validation of storytime artifacts against the process10rules. No prose, no commentary — just pass/fail per check, per artifact.11If you want interpretation, run `/storytime-retro`. This is the12hygiene pass.1314## Two Tiers1516Lint has two tiers with a hard split:17181. **Mechanical tier** (grep/file checks) — runs `scripts/check-conventions.sh`19 for version consistency, schema_version presence, type field, driver20 field, thread hygiene, icebreaker existence. Zero model reasoning.21 Deterministic. Milliseconds.22232. **Reasoning tier** (estimator task force) — spawns the24 `agents/estimator.md` sub-agent for checks that need prose parsing25 (P4, P5, P7, T4, B6, NG1, SC1, DR1). Each invocation is scoped to26 one check on one artifact, returns one line of PASS/WARN/FAIL.2728Checks that violated lint's "grep only" contract in v0.7.2 (P4, P5, T4)29are now in the reasoning tier where reasoning is explicitly allowed.3031## Arguments3233What to lint: $ARGUMENTS (topic, session path, or empty for all)3435## Scope3637- **Empty** → lint every session under `specs/.storytime/sessions/`38- **`<topic>`** → lint all episodes of that topic39- **`<session-path>`** → lint one specific directory4041## Checks4243### Per-survey (`survey.md`)4445| # | Tier | Check |46|----|------------|------------------------------------------------------------|47| S1 | mechanical | Has frontmatter with `type: survey` |48| S2 | mechanical | Has a coverage fingerprint (commit, paths, ratios) |49| S3 | mechanical | Fingerprint commit resolves via `git cat-file -e <sha>` |5051### Per-team (`team.md`)5253| # | Tier | Check |54|----|------------|------------------------------------------------------------|55| T1 | mechanical | Has frontmatter with `type: team` |56| T2 | mechanical | Every persona references a known archetype |57| T3 | mechanical | Same-archetype personas have distinct `focus` |58| T4 | reasoning | Codenames are non-human (warn on common first names) |5960### Per-breakout (`breakout-*.md`)6162| # | Tier | Check |63|-----|------------|-----------------------------------------------------------|64| B1 | mechanical | Has frontmatter with `type: breakout` |65| B2 | mechanical | Frontmatter names a `driver` |66| B3 | mechanical | Body contains ≥1 citation (file:line, [url], commit, RFC) |67| B4 | mechanical | Body contains `Complexity` AND `Scale` |68| B5 | mechanical | Body contains `Recommendation:` section |69| B6 | reasoning | Recommendation is substantive, not a punt |70| DR1 | reasoning | Driver actually drove (voice matches attribution) |7172### Per-plan (`plan.md`)7374| # | Tier | Check |75|-----|------------|-----------------------------------------------------------|76| P1 | mechanical | Has frontmatter with `type: plan` |77| P2 | mechanical | Has a `Non-goals` section with entries |78| P3 | mechanical | Has a `Success criteria` section with entries |79| P4 | reasoning | Every plan item states Complexity + Scale in prose |80| P5 | reasoning | No plan item has Complexity ≥ 13 as a leaf |81| P6 | mechanical | At least one ASCII box-drawn visual |82| P7 | reasoning | Citations are substantive (point to specific evidence) |83| NG1 | reasoning | Non-goals are specific (not "we won't boil the ocean") |84| SC1 | reasoning | Success criteria are measurable (number, threshold, test) |8586### Per-buildout (`buildout-*.md`)8788| # | Tier | Check |89|-----|------------|-----------------------------------------------------------|90| BO1 | mechanical | Has frontmatter with `type: buildout` |91| BO2 | mechanical | Frontmatter names a `driver` |92| BO3 | mechanical | Frontmatter has `plan_items` and `decisions` |93| BO4 | mechanical | Body contains an `Implementation Trace` section |94| BO5 | mechanical | Every file_created/file_modified listed actually exists |9596### Per-thread (`_thread.md`)9798| # | Tier | Check |99|-----|------------|-----------------------------------------------------------|100| Th1 | mechanical | Has frontmatter `type: thread` |101| Th2 | mechanical | Has `last_completed_phase` and `last_commit` |102| Th3 | mechanical | `last_commit` resolves via `git cat-file -e <sha>` |103104### Per-icebreaker (`icebreaker.md`)105106| # | Tier | Check |107|-----|------------|-----------------------------------------------------------|108| I1 | mechanical | Exists if `team.md` exists and breakouts are present |109| I2 | mechanical | Has frontmatter `type: icebreaker` |110111### Per-citation (across all files)112113| # | Tier | Check |114|----|------------|------------------------------------------------------------|115| C1 | mechanical | File citations (`path:line`) — the file exists |116| C2 | mechanical | File citations — the line number is in bounds |117| C3 | mechanical | Commit citations — commit exists in the repo |118119Stale citations (file moved, line shifted) are **warnings**, not120failures — the process allows rot but we want visibility.121122### Decision staleness (across decision log)123124| # | Check |125|---|-------------------------------------------------------------|126| D1 | Each decision cites at least one code reference |127| D2 | Cited files exist in the current tree |128| D3 | If decision has a `commit` pin, check if cited files changed since that commit (⚠ if yes) |129130Decision staleness is **commit-delta based**: compare the decision's131pin commit against HEAD for the cited paths. If the file changed since132the decision was written, it's a staleness warning. The decision may133still be valid — but it needs re-verification.134135### Repo-level checks136137| # | Tier | Check |138|----|------------|------------------------------------------------------------|139| R1 | mechanical | VERSION, plugin.json, all SKILL.md version-echo lines match |140| R2 | mechanical | site/*.html version strings match VERSION |141| R3 | mechanical | README.md version strings match VERSION |142143Run `R1-R3` only when `--repo` flag is given or scope is empty144(full-repo lint). These catch version drift from manual bumps.145**All repo-level checks are delegated to146`scripts/check-conventions.sh`** — run it first, parse its output.147148### Per-consolidation event (v1.0)149150Delegated to `references/consolidation-format.md` check table.151152| # | Tier | Check |153|-----|------------|----------------------------------------------------------|154| CF1 | mechanical | `type: consolidation` present |155| CF2 | mechanical | `schema_version: 1` present |156| CF3 | mechanical | `scale` in {phase, commit, nap, shift, session, compact} |157| CF4 | mechanical | `at` parseable as ISO 8601 |158| CF5 | mechanical | `pause_posture` in allowed set |159| CF6 | mechanical | `signals` present when scale ∈ {nap, shift, compact} |160| CF7 | mechanical | `signals` drawn from allowed vocabulary |161| CF8 | mechanical | `commit` resolves via git when scale = commit |162| CF9 | mechanical | `driver` matches @role or @role [codename] pattern |163| CF10| mechanical | No orphan `.tmp` files older than 5 minutes |164| CF-R1 | reasoning | Digest is substantive (phase scale) |165| CF-R2 | reasoning | Signals match the event description |166167### Per-callout (v1.0 cross-topic references)168169Delegated to `scripts/validate-callouts.sh`.170171| # | Tier | Check |172|-----|------------|----------------------------------------------------------|173| CA1 | mechanical | Callout line matches sigil regex (`Callout->` or `Callout<-`) |174| CA2 | mechanical | `<topic>` resolves to a session directory |175| CA3 | mechanical | `<decision-id>` resolves to a `### <id> —` header |176| CA4 | mechanical | `<kind>` in closed vocabulary (depends-on, affects, supersedes, superseded-by, related) |177| CA5 | mechanical | No exact-duplicate (from, to, kind) within one decision |178| CA-W1 | advisory | Reverse cache is stale (forward without reverse) |179| CA-W2 | advisory | Callout target has `status: superseded` |180| CA-W3 | advisory | Dangling reverse cache (reverse without forward) |181182### Per-remembrance (v1.0 wakeup document)183184| # | Tier | Check |185|-----|------------|----------------------------------------------------------|186| RM1 | mechanical | `type: remembrance`, `schema_version` present |187| RM2 | mechanical | All three body sections present (Wakeup, Prompt, State) |188| RM3 | mechanical | `last_commit` resolves via git |189| RM4 | mechanical | `active_threads[].path` all exist as files |190| RM5 | mechanical | No orphan `remembrance.md.tmp` older than 5 minutes |191| RM-R1 | reasoning | Wakeup narrative substantive (not placeholder) |192| RM-R2 | reasoning | Consolidation prompt names specific files |193| RM-R3 | reasoning | State pinned captures actual in-flight work |194195### Per-tutorial-state (v1.0 friction tracking)196197| # | Tier | Check |198|-----|------------|----------------------------------------------------------|199| TS1 | mechanical | Valid frontmatter if present |200| TS2 | mechanical | Per-skill sections reference known skill names |201| TS3 | mechanical | `graduated: true` paired with `graduated_at` |202| TS-R1 | reasoning | If graduated, log shows sufficient signal evidence |203| TS-R2 | reasoning | "would have proposed" entries cluster/disperse tuning hint |204205### Per-commit-patterns (v1.0 adaptive learning)206207| # | Tier | Check |208|-----|------------|----------------------------------------------------------|209| CD1 | mechanical | Valid frontmatter if present |210| CD2 | mechanical | Pattern entries have required fields |211| CD3 | mechanical | `status` in {none, quieter-proposed, quieter-active, soft-reset} |212| CD4 | mechanical | `rolling_window` has ≤ 7 entries |213| CD-R1 | reasoning | Claimed `clean` count matches rolling window |214| CD-R2 | reasoning | Pattern key is well-formed |215216### Per-dream (v1.0 ancillary byproduct)217218| # | Tier | Check |219|-----|------------|----------------------------------------------------------|220| DM1 | mechanical | `type: dream`, `commit` present in frontmatter |221| DM2 | mechanical | `commit` resolves via git |222| DM3 | mechanical | Body length ≤ 30 lines (dreams stay small) |223224### Migration-readiness (M-class, v0.9 → v1.0)225226| # | Tier | Check |227|-----|------------|----------------------------------------------------------|228| M1 | advisory | No `specs/.storytime/history/decisions.md` present |229| M2 | advisory | All artifacts have `schema_version` |230| M3 | advisory | Cohort `_roster.md` uses non-human codenames |231| M4 | advisory | `_thread.md` files have v1.0 fields |232| M5 | advisory | `.storytime/.version` = `1.0` or higher |233234Full-repo lint surfaces M1-M5 as advisory warnings. The pre-flight gate235in v1.0 skills (V1-029) is the authoritative block.236237### Intent graph (IG-class, v1.0.1+)238239Per V1-035. Mechanical only; reasoning checks deferred.240241| # | Tier | Check |242|-----|------------|----------------------------------------------------------|243| IG1 | mechanical | Every sealed decision with `parent:` has a resolvable target |244| IG2 | mechanical | Every `supersedes:` has a resolvable target |245| IG3 | mechanical | `tensions:` are symmetric (X tensions Y ↔ Y tensions X) |246247### Prompt-yield (PY-class, v1.0.1+)248249Per V1-036. Mechanical only.250251| # | Tier | Check |252|-----|------------|----------------------------------------------------------|253| PY1 | mechanical | Frontmatter `type: prompt-yield` present |254| PY2 | mechanical | `originating_user` is a `@user [codename]` reference |255| PY3 | mechanical | `status` in {seeded, hydrating, maturing, crystallized} |256| PY4 | mechanical | If status=crystallized, `crystallized_into` resolves |257258### Intent tracking (IT-class, v1.0.1+)259260Per V1-031, V1-033. Mechanical only.261262| # | Tier | Check |263|-----|------------|----------------------------------------------------------|264| IT1 | mechanical | `.storytime/intents.md` header lines match timestamp+session pattern |265| IT2 | mechanical | Each intent entry has required fields (intent, lens, type, source) |266| IT3 | mechanical | `lens:` references known roles only |267| IT4 | mechanical | `type:` is in the closed vocabulary |268| IT5 | mechanical | `supersedes:` resolves to a prior entry |269270## Process2712721. **Run mechanical tier first:** invoke `./scripts/check-conventions.sh`273 (with `$ARGUMENTS` if provided). Capture its output and exit code.274 If any mechanical check fails, surface those first — they're blockers.2752. **Enumerate artifacts in scope** (sessions, episodes, or the given276 path).2773. **Run per-artifact mechanical checks** (S1-S3, T1-T3, B1-B5, P1-P3, P6,278 BO1-BO5, Th1-Th2, C1-C3, D1-D3) using Grep/Read/Bash.2794. **Run reasoning-tier checks via Estimator.** For each artifact that280 has reasoning checks (P4, P5, P7, T4, B6, NG1, SC1, DR1), spawn the281 estimator agent with one check at a time:282 - `agents/estimator.md` — scoped to the single check283 - Pass: check-id, artifact path, context paths284 - Receive: one-line PASS/WARN/FAIL + justification2855. **Merge results** into a single pass/fail table.2866. **Print summary footer:** `N passed, M warnings, K failed`.2877. **Exit 0** if no failures, **1** if any failures (warnings ok).288289## Output Format290291Single pass/fail table. No prose. No "analysis". No "consider revising":292293```294Session: rate-limiting / episode 001295296 survey.md S1 ✓ S2 ✓ S3 ✓297 team.md T1 ✓ T2 ✓ T3 ✓ T4 ✓298 icebreaker.md (no checks — informational artifact)299 breakout-algo.md B1 ✓ B2 ✗ (no driver) B3 ✓ B4 ✓ B5 ✓300 breakout-store.md B1 ✓ B2 ✓ B3 ✓ B4 ✓ B5 ✓301 plan.md P1 ✓ P2 ✓ P3 ✓ P4 ✓ P5 ✓ P6 ✓ P7 ✓302303Citation hygiene:304 breakout-algo.md:23 → src/server.ts:14 ✓305 breakout-algo.md:45 → src/config/redis.ts:5 ⚠ line now at :7 (drift 2)306 plan.md:67 → commit abc123 ✓307308Summary: 21 passed, 1 warning, 1 failed309```310311## Rules3123131. **Two tiers, hard split.** Mechanical checks are grep/file only —314 no interpretation. Reasoning checks delegate to the estimator agent315 with one check per invocation.3162. **Warnings are visibility, not failures.** Stale citations warn.317 Missing required fields fail.3183. **Mechanical tier is fast.** Grep and file existence only. Zero319 Agent calls in this tier.3204. **Reasoning tier is scoped.** Estimator receives one check at a321 time, returns one line. No free-form analysis.3225. **Deterministic for mechanical.** Same input → same output.323 Reasoning tier may drift at the margins; that's why it returns324 justification — so drift is visible.3256. **Exit code signals status.** 0 = clean or warnings only, 1 = failures.3267. **Checks are listed above.** Don't invent new ones without adding327 them to the table first.3288. **Mechanical tier is the primary gate.** Reasoning tier is advisory329 polish. A session that passes the mechanical tier is releasable.