| name | audit-intent |
| description | Migrate the project's ACTIVE chunks to the present-tense, intent-owning standard. Audits each chunk's goal against the code it claims to govern; rewrites retrospective framing inline; logs over-claims that need operator triage; historicalizes chunks with no enduring intent. Designed for full-corpus migrations — fans out across many parallel sub-agents at 5 chunks per agent. |
Tips
- The
ve command is an installed CLI tool. Run via Bash.
- This skill spawns parallel sub-agents (10 per wave, 5 chunks each). Use it on substantial chunk corpora.
- The skill is idempotent: clean chunks stay clean, rewritten chunks don't trigger again. Safe to re-run.
Purpose
This skill enforces the four principles in docs/trunk/CHUNKS.md against the existing chunk corpus:
- Code owns implementation; chunks own intent.
- Chunks exist only for intent-bearing work.
- A chunk's GOAL.md describes intent in present tense.
- Status answers a single question — how much of the intent does this chunk own?
It performs five categories of action per chunk:
- Rewrite tense in place when the goal is retrospectively framed but the post-state is genuinely realized in code.
- Log over-claims when the goal asserts behaviors the code doesn't implement (operator triage required).
- Fix broken
code_paths / code_references when the correct target is unambiguous (typically post-refactor drift).
- Historicalize chunks with no enduring intent (Pattern A: bug-fix-only; Pattern B: intent fully superseded).
- Log cross-artifact inconsistencies discovered along the way (template-vs-template, doc-vs-code mismatches).
Prerequisites
Before running, verify the project has the required infrastructure. Run these checks; if any fail, stop and direct the operator to the fix.
test -f docs/trunk/CHUNKS.md || echo "MISSING: docs/trunk/CHUNKS.md — run 've init' to install."
grep -q "COMPOSITE" src/templates/chunk/GOAL.md.jinja2 2>/dev/null || \
echo "MISSING: COMPOSITE in chunk GOAL template — upgrade ve and run 've init'."
python3 -c "from models import ChunkStatus; assert ChunkStatus.COMPOSITE" 2>&1 | grep -q AttributeError && \
echo "MISSING: ChunkStatus.COMPOSITE — upgrade ve."
If any check reports MISSING, stop and tell the operator what's needed. Do not proceed with the audit on an unprepared project.
Step 1: Bootstrap the inconsistencies log if absent
The audit writes findings to docs/trunk/INCONSISTENCIES/. If that directory doesn't exist, create it with this README:
mkdir -p docs/trunk/INCONSISTENCIES
Then write docs/trunk/INCONSISTENCIES/README.md with the schema documentation:
# Inconsistencies Log
A running log of discovered mismatches between what the project's chunks (or
trunk docs) claim about the system and what the code or runtime actually does.
## When to add an entry
Whenever you discover that a chunk's GOAL.md, a trunk doc, a template comment,
or a skill description claims something the code or runtime contradicts:
- A doc says behavior X is supported; the runtime rejects it.
- A chunk's GOAL.md asserts the system does X; grepping shows it doesn't.
- A chunk's `code_references` admit `status: partial` while the GOAL claims completeness.
## Filename convention
YYYYMMDD_HHMMSS_microseconds_.md
Microsecond precision plus a descriptive slug makes collisions effectively
impossible across concurrent writers. Generate timestamps with:
python3 -c "from datetime import datetime; print(datetime.now().strftime('%Y%m%d_%H%M%S_%f'))"
## Entry format
YAML frontmatter:
- `discovered_by`: agent name or "operator"
- `discovered_at`: ISO 8601 timestamp
- `severity`: low | medium | high
- `status`: open | resolved
- `resolved_by`: chunk name, commit SHA, or null
- `artifacts`: list of file paths involved
Body sections: **Claim**, **Reality**, **Workaround**, **Fix paths**.
## Lifecycle
Entries land with `status: open`. When a chunk or commit resolves the
inconsistency, set `status: resolved` and `resolved_by:` to the resolution
reference. Resolved entries stay indefinitely as archaeological record.
Step 2: Build the audit pool
Enumerate ACTIVE chunks. Exclude any that have been recently audited (those would have committed prose changes mentioning "audit" — operators can use a different filter if their commit history doesn't follow this convention):
uv run ve chunk list --status ACTIVE 2>&1 | sed 's| \[ACTIVE\].*||' | sed 's|docs/chunks/||' > /tmp/audit_pool.txt
wc -l /tmp/audit_pool.txt
Decide whether to audit fresh (all ACTIVE chunks) or resume an in-progress audit (skip chunks already touched). For a fresh run, the pool is the entire ACTIVE list.
Tell the operator the pool size and confirm before proceeding. For corpora over 200 chunks, expect ~5 minutes of wall-clock per wave of 50.
Step 3: Wave-based parallel execution
For each wave of 50 chunks:
-
Partition the next 50 chunks into 10 batches of 5.
-
Spawn 10 sub-agents in parallel via the Agent tool, subagent_type general-purpose. All 10 calls must be in a single message so they run concurrently.
-
Each sub-agent receives the full audit protocol (see "Sub-agent prompt template" below) plus its specific 5-chunk scope.
-
Collect summaries when all 10 sub-agents return.
-
Verify the working tree (git status --short); flag anything outside expected scope.
-
Commit. Typically 2-3 commits per wave:
audit: wave N — rewrites + codepath fixes (X chunks) for chunk modifications
audit: log Y inconsistency entries (wave N) for new entries in docs/trunk/INCONSISTENCIES/
audit: historicalize <names> (wave N) if any chunks went HISTORICAL
-
Update the audit pool (remove the 50 audited chunks) and continue.
Stop when the pool is empty.
Step 4: Final report
Produce a cumulative summary:
- Total chunks audited
- Counts per action (rewrote, logged, historicalized, codepath-fixed, clean)
- Number of inconsistency entries (open vs resolved)
- Top patterns (refactor-related stale references, half-shipped chunks, quantitative-criteria slips)
- Recommendations for follow-up (mechanical sweep chunks, per-chunk operator triage)
Sub-agent prompt template
Each sub-agent receives this prompt with the chunk list and batch ID substituted in. Keep the prompt self-contained — the sub-agent works in a fresh context with no session memory.
You are sub-agent <BATCH_ID> in `audit-intent`'s parallel fan-out (10 sub-agents running concurrently).
## Your scope (5 chunks)
<list of 5 absolute paths to GOAL.md files>
## Detection criteria
**Retrospective framing tells (case-insensitive grep):**
- `Currently,`, `currently`, `was`, `we added`, `this chunk fixes`, `this chunk adds`, `the fix:`, `will change to`
- Markdown headers: `^#+\s+The\s+fix\b`, `^#+\s+The\s+bug\b`, `^#+\s+The\s+problem\b`
- Soft tells: `Replace the current\b`, `\bnot the old\b`, `Find all\b`, `but did not`, planning lists like `The command should:` / `Three fixes needed:`
Apply judgment: would changing this passage to present tense make it false? Yes → retrospective. No → leave it. Past-tense narration of one-time events ("Observed: 7 zombies") is true forever — leave alone.
**Over-claimed scope tells:**
- Any `code_references[].status: partial`
- `implements:` text containing `does NOT implement`, `partial`, `only Step N of M`, `TODO`, `not yet`
- Success-criteria count meaningfully exceeding `code_references` count after filtering generic criteria (`tests pass`, `no regressions`, `lint passes`)
**Broken `code_paths`:** `ls` every entry; if any don't exist and a clearly-correct alternative is identifiable (same directory, name similarity, content match) → fix in place. Ambiguous → log inconsistency entry.
## Action rules
- **Retrospective framing only** → rewrite the prose in place to present-tense, system-centric framing. Prefer `The schema template now distinguishes X from Y` over `This chunk extends the schema template to add X vs Y`. Don't change the chunk's intent. Success criteria, code_paths, code_references, and architectural claims are off-limits to rewrites.
- **Over-claimed scope** → write inconsistency entry only. Veto rule fires (see below).
- **No enduring intent** → historicalize. Two patterns (all signals required for either):
- **Pattern A — bug-fix-only:** (a) Fix-X / Resolve-Y framing or one-time defect; (b) success criteria are all "the bug no longer reproduces" style; (c) code references are tactical (one or two functions); (d) `bug_type: implementation` if present.
- **Pattern B — intent fully superseded:** (a) veto fired (multi-axis drift); (b) the code sites referenced carry 3+ successor chunk names in `# Chunk:` backreferences; (c) every load-bearing claim is contradicted by current code OR owned by a named successor/subsystem (no claim uniquely held); (d) nothing about the architecture would become unclear if the chunk's content disappeared.
- When historicalizing: **do not edit the goal text** — HISTORICAL semantically means "archaeology, not canon". Just flip status. Then scan `docs/trunk/INCONSISTENCIES/` for open entries naming the chunk; mark them `status: resolved`, `resolved_by: "audit batch <BATCH_ID> — historicalized"`.
- **Cross-artifact inconsistency** discovered while verifying (mismatch outside the chunk being audited — README contradicting workflow, two skill templates disagreeing) → write inconsistency entry. Slug: `<area>_<short-description>`.
- **Clean** → no action.
## Veto rule (load-bearing)
If over-claimed scope is detected on a chunk, **do not rewrite its prose for tense, even if retrospective framing is also detected.** The two failure modes interact: a chunk that over-claims has no truthful present-tense form available. Any rewrite would substitute one false claim for another. Write the inconsistency entry, leave the GOAL.md prose untouched, set `action_taken: logged`, note the veto in your summary.
## Symmetric verification (mandatory before any rewrite)
- Read `code_references` and grep the named symbols in the source files.
- `ls` every `code_paths` entry.
- Confirm the named symbols exist and behave as the prose asserts.
If the post-state doesn't match → treat as undeclared over-claim: log instead of rewrite.
## Inconsistency entry format
Read `docs/trunk/INCONSISTENCIES/README.md` for the schema. Filename:
YYYYMMDD_HHMMSS_microseconds_<chunk_or_area>_<failure_mode>.md
Generate timestamps with `python3 -c "from datetime import datetime; print(datetime.now().strftime('%Y%m%d_%H%M%S_%f'))"`.
Frontmatter required: `discovered_by: claude`, `discovered_at` (ISO 8601), `severity` (low/medium/high), `status: open`, `resolved_by: null`, `artifacts:` list. Body: **Claim**, **Reality**, **Workaround**, **Fix paths**. Use the five-status taxonomy in fix paths (FUTURE / IMPLEMENTING / ACTIVE / COMPOSITE / HISTORICAL). **Do NOT suggest SUPERSEDED** — it's not a valid current status.
## Return format
For each of your 5 chunks:
<chunk_name>
- action_taken: rewrote | logged | historicalized | clean | skipped
- evidence: <one-line description of what triggered the detector, or "no tells found">
- entry_filename:
- veto_fired: true | false
- verification_did:
- codepath_fixes: <list of broken→fixed entries, if any>
- notes: <judgment calls, edge cases>
Then an overall summary: counts per action, vetoes fired, code_paths fixed, cross-artifact entries logged, anything surprising, suggestions for the parent's logic.
## Constraints
- Working tree only. Do NOT commit.
- Don't run `ve init` or `pytest`.
- Don't touch chunks outside your assigned 5 (cross-artifact logging is fine — that creates new entries, doesn't edit other chunks' GOAL.md files).
- 9 sibling sub-agents are running concurrently. Filename collisions are prevented by microsecond timestamps + chunk-name slugs.
Notes for the orchestrating agent
- Quality over speed. Each sub-agent reads several files, verifies symbol existence, and applies judgment. A 5-chunk batch typically takes 2-3 minutes of agent time. Don't reduce the batch size below 5 (overhead per agent dominates) or above 10 (context overload reduces quality).
- The veto rule is non-negotiable. Sub-agents that over-aggressively rewrite chunks with over-claimed scope produce false-on-false: a tense fix that papers over a real implementation gap. The veto is the only thing preventing this.
- Symmetric verification catches what the metadata hides. Many chunks have honest
code_references but stale prose, or honest prose but stale code_references. Both shapes need the symbols to actually exist before any rewrite is safe.
- HISTORICAL chunks keep their goal text. This is intentional — HISTORICAL semantically means "archaeology", and the goal becomes the historical record. A rewrite would erase that record.
- The cross-artifact rule is opportunistic. Sub-agents are auditing a chunk; they shouldn't go hunting for unrelated inconsistencies. But when verification crosses paths with a real mismatch (README vs workflow, two templates disagreeing), logging it is cheap and the alternative is the inconsistency staying invisible until someone trips on it again.
- Patterns to expect. Most projects with substantial chunk corpora will surface these patterns:
- Refactor-related stale references (file moved, package split, CLI modularized)
- Half-shipped chunks with quantitative success criteria that drifted (file size targets, line counts)
- Bug-fix chunks that should have been HISTORICAL when the bug was fixed
- Chunk-centric framing in older chunks ("This chunk adds...") that hasn't been updated to system-centric
If the audit catches none of these, the corpus is suspiciously clean — spot-check a few rewrites manually before trusting the run.