| name | intent-status |
| description | Read-only guidance skill that reads the current state of .intent/ and recommends a summary of where you are plus exactly one "next move". Never creates, modifies, or deletes any file. |
intent-status Skill
Core Mission
Shared temperature for matching checks (defined once here; each check refers to it as "shared temperature"): the orphan-spec / intent-tree-unfiled / Candidate / conformance matching checks are all done within what is machine-observable from files (Read/Glob/Grep only; git history and code diffs are not consulted), stay at candidate presentation, not an assertion, treat non-matchability as the normal case and tolerate false positives, and never take away the next-move first-match. When the target file is absent, the check is omitted (not an error).
- Success Criteria (success if achieved; the detailed check procedures are consolidated into Execution Steps, and only the outcomes are declared here):
- The existence and fill state of the deliverables under
.intent/ (mode, intent-tree, intent-compass, the packets index/files, the per-packet export drafts, deltas) are read and a summary of the current position is presented (read-only; never creates, modifies, or deletes any file)
- Packets integrity (index ↔ active/ divergence, done / superseded_by lingering, the latest export-log row's packet absent from active/) is checked and violations are reported in the current-position summary
- Orphan spec (no Packet) and intent-tree unfiled (discover skip) are reported in the details at the "shared temperature", and both plus writeback omission (downstream layer) are partitioned into three layers — tree layer → packet layer → downstream layer — with each spec presented only in the single most-upstream layer so no double warning is emitted
- A leading mini progress rail (all packets laid out vertically with the five signals ✅/🔵/⚪/🔴/◻ plus
[current stage → next stage(s) to pass through]) is placed at the top so "which packet is 🔵 you are here now, where the remaining work ⚪ / unreflected 🔴 are" is visible at a glance. Internal terms (matching, integrity check, enforcement) are pushed into the details
- The default output is slimmed into three layers (default = one human decision + three separate readings + progress rail + Candidate count/names + a one-line Ice box notice / details = the folded position / option = only on a natural-language trigger), and the one-line summary of the next move is never folded and is always emphasized at the lead
- The "dangerous notices" (freshness warning, packets integrity violations, unreflected
🔴) are shown in full as bare glyphs in the actual-impact context (never folded), with a one-line summary "⚠ N present (see details)" also left on the details side. In the explanatory context (legend, 0-count summary, etc.) they are toned down to inline code / words rather than bare glyphs (INV32)
- The L4 "future addition candidates" that are unconsumed (neither packeted nor implemented) are presented as a permanent default display of count + names (frozen-marked ones excluded; "shared temperature")
- Ice box candidates with a frozen mark are not shown in the body in the default; instead a one-line notice "Frozen (Ice box): N. Show them with 'show me the icebox'" is included, and on a natural-language trigger they are expanded as count + names + freeze reason
- When a natural-language trigger such as "understanding map", "pre-start briefing", or "understanding gap sorting" appears, status preserves its read-only nature and guides the user to the corresponding
intent-overview derived views (.intent/overview/agent-understanding-map.md / active-packet-briefing.md / understanding-gaps.md)
- Exactly one "next move" is recommended via the first-match of
rules/decision-table.md (from discover / compass / packets / export / validate / improve / writeback / "no action needed"), accompanied by the reason and judgment basis. Only the presentation is changed; the first-match selection logic is untouched
- When enforcement is remind / gate, a freshness check via intent-check is performed, and on a violation a freshness warning quoting the intent-check stdout is included (when off, unstated, an invalid value, or not executable, none is shown)
- When drift-watch is
on, drift-log is read and a light tally (prevented N / caught N / missed N / false-positive N / not-applicable N / unjudged N) is included (otherwise none; read-only)
- The compass section update dates (Invariants / Decision Rules) and the active packets'
updated_at are cross-checked, and when "not yet caught up after a compass update" reaches the threshold or more, intent-validate is recommended as the right moment (decision table row 12; estimate only; "shared temperature")
- When parallel-implementation claims exist (
.intent/assignments/), the claimed packets, the double-claim warning on the same packet, and the stale-claim elapsed observation are included read-only (Step 3.8; with zero claims not included and unchanged from current behavior; warn-only; no machine threshold; "shared temperature")
- Major terms in the output carry a one-line plain-language explanation in the
term (explanation) form (two layers: lead = first occurrence / table headers only; details = every time; the glossary is kept and not abolished)
Execution Steps
Step 1: Confirm that .intent/ exists
- If
.intent/ does not exist, guide the user through the setup procedure (running npx intent-planner) and finish.
- Read mode state in order: the inherited issue directory's
discovery/<slug>-<rand>/mode.md (A34; inherit the issue name that discover output) → else the single .intent/mode.local.md (legacy) → else the old .intent/mode.md (the CONTRACT.md read fallback contract). If neither exists, continue with the standard default and add "mode undetermined; intent-discover recommended" to the Open Questions (do not stop). Enforcement / Drift-watch read from .intent/mode.md.
Step 2: Read the deliverables
- The Intent Tree target L1 is the only source for an approved current outcome: use its human-approved
Outcome learning: line. A pending delta is not a confirmed outcome.
- Read
.intent/intent-tree.md / .intent/intent-compass.md / .intent/packets/index.md plus the target packet files (under .intent/packets/active/; in normal processing read only these two kinds and never bulk-read the bodies of every packet file) / .intent/cc-sdd/<slug>/*.md / .intent/openspec/<slug>/*.md / .intent/speckit/<slug>/*.md (the per-packet drafts for the selected route) / deltas (the split form .intent/deltas/*.md set if present, else the old .intent/deltas.md mirror; the split-form cross-read of rules/decision-table.md footnote 10) and grasp, for each, its present/absent/unfilled state and notable points (unresolved Questions, deltas with Status: pending, declined items tagged "on-hold", etc.). If the split store .intent/compass/ exists, you may read index.md (one symbol per line; derived) as the symbol overview (otherwise as before; DR133). For intent-tree case records (機能追記/機能撤去/履歴/再起案), if the split store .intent/tree/ exists you may read index.md (one case per line; derived) as the overview (otherwise from the body tail as before; the skeleton L0–L4 is read from the body; tree-normalize / DR133).
- Packets integrity check: cross-check
.intent/packets/index.md against the entities under .intent/packets/active/ (reading only the frontmatter of each entity file) and grasp divergences — a packet missing from the index, a row without an entity, mismatches in name / state / summary — as integrity violations. Additionally, when a packet file with state: done or a filled superseded_by lingers under active/, grasp that lingering as an integrity violation too (report only; never auto-repair).
- Read the canonical journey files (
.intent/packets/journeys/*.md, excluding README.md and archive/, when present) frontmatter-only and read-only. Derive each journey's progress/completion every time from its packets list and the packets' state (each packet's frontmatter is canonical), and never write back to the journey side (DR200; the reader contract is "The journey reading contract" in skills/CONTRACT.md). If a listed packet_id cannot be found, state "not found" and skip it (never guess a match). Journeys with lifecycle: archived are not shown in the progress block (even before they are moved to ; the same field-based judgment as the roadmap bundling). With absent or empty, skip this reading and behave as before (a permanent fallback; INV103; the default output is unchanged).
Step 3: Check freshness (enforcement-linked)
- Check the
enforcement value in the ## Enforcement (user-managed) section of .intent/mode.md read in Step 1. When it is off, unstated, or an invalid value, do not perform this Step (do not run intent-check and show no freshness warning; current behavior is preserved).
- When it is
remind or gate, run node .intent/scripts/intent-check.mjs via Bash. When it cannot run (Bash unavailable, script absent, or exit 2), omit this Step and continue with the existing behavior.
- Trust the judgment line on the first line of stdout —
intent-check: result=<ok|stale|not-applicable> enforcement=<off|remind|gate> commits=<N|-> threshold=<M> grace=<in-implementation|-> pending=<K> block=<yes|no> — as is, and never re-derive it. Treat it as a violation when result=stale or pending is 1 or more.
- When a violation is detected, include in the current-position summary of Step 5 a freshness warning quoting the intent-check stdout (the judgment line + the human-readable evidence lines). intent-check is a read-only script (it creates, modifies, and deletes no files), so the read-only nature of this skill is preserved.
Step 3.5: Drift Summary (drift-watch-linked)
- Check the
drift-watch value in the ## Drift-watch (user-managed) section of .intent/mode.md read in Step 1. When it is not on (off, unstated, an invalid value, the section absent, or mode.md absent), do not perform this Step (do not add a drift block and continue as before; current behavior is preserved).
- When it is
on, read the drift-log only via Read / Grep (never Write; do not change the principle that Bash is limited to launching intent-check) and tally it. The read target follows the split-form cross-read: the split form .intent/drift-log/*.md set (source of truth if present; do not count archive/) → read-fallback to the old .intent/drift-log.md if absent (when they coexist, treat the split form as the source of truth and do not double-count the same entry). Tally the outcome and user-verdict of each entry. Count prevented / caught / missed / false-positive / not-applicable from the outcome values, and unjudged from the number of user-verdict=unjudged. If outcome is missing or outside those five values, do not guess a known category; count it separately as unknown N.
- Present the tally lightly, at the same position and temperature as the freshness warning, as one block
prevented N / caught N / missed N / false-positive N / not-applicable N / unjudged N in the current-position summary of Step 5. Always show all six counts, including zeroes, so runs can be compared in a stable shape. Only when unknown is nonzero, append unknown N so unclassified entries are never silently dropped. When decision-table row 13 (accumulated unjudged drift) applies, append the per-pattern breakdown (count per pattern) to this block as the rationale for the next move (the presentation follows the decision-table result; a temperature that avoids assertion; never auto-run intent-improve). When neither the split form nor the old single file exists, omit this block (do not error).
- drift-log is read only and never written (read-only preserved). Read
missed=0 as "a suspicion of missing records," not as "it worked," and present it without asserting.
Step 3.6: Estimate the right moment for conformance staleness (read-only)
- Purpose: estimate the "right moment" where compass (Invariants / Decision Rules) was updated but a packet has not yet caught up, as material for recommending
intent-validate in decision table row 12. The definitive diagnosis (must-fix/recommended) is made by validate's invariant-stale-vs-compass etc.; status stays at an estimate.
- Perform the reads with Read / Glob / Grep only (do not use Bash = intent-check; like drift-log, do not widen the read-only scope):
- Read the ISO 8601 values of the
Updated (Invariants): / Updated (Decision Rules): lines of .intent/intent-compass.md (— is unstamped).
- Read the frontmatter
updated_at of each packet under .intent/packets/active/ (archive/ is out of scope).
- Determination: count, as "not yet caught up after a compass update," each active packet for which any compass section update date > that packet's
updated_at. The comparison is the lexicographic order of the ISO 8601 strings. Target only pairs where both ends are actually stamped, and exclude packets with no updated_at (do not fill in by guessing = backward-compatibility discipline). When both compass section update dates are —, do not perform this Step (produce no right-moment).
- When the not-caught-up count reaches the threshold (default 1, made explicit in decision table row 12) or more, include in the Step 5 (3) Details, as the basis, "which compass section was updated, and how many packets are not caught up". When below the threshold, do not include it (avoid the boy-who-cried-wolf effect). This Step writes nothing (read-only preserved).
Step 3.8: Include parallel-implementation claims (assignments; read-only)
- Purpose: when implementing in parallel across several agents/sessions, read
.intent/assignments/*.md (claims = "which packet is being implemented by whom"; 1 claim = 1 file; the reader contract is governed by CONTRACT.md's "state sharing between skills") read-only and include in the current-position summary: (1) claimed packets, (2) double-claims on the same packet (double implementation), (3) stale claims. Do not create or delete claims (read-only preserved).
- Perform the reads and comparison with Read / Glob / Grep only (do not use Bash = intent-check; do not widen the read-only scope):
- From each claim file under
.intent/assignments/*.md (excluding README.md), read the frontmatter packet_id / declared_at / session.
- Match the
<packet_id> portion of the file-name pattern <packet_id>-<session-rand>.md against the frontmatter packet_id (a simple file-name match that needs no semantic judgment).
- Determination: (1) claimed = the active packet corresponding to a claim file's
packet_id is "being implemented (a claim exists)" (do not rewrite or re-read state = separate layer). (2) double-claim (warn) = if two or more claim files carry the same packet_id, name it as a double implementation (warning only; do not change the decision-table next-move result; do not stop). (3) stale claim = for a packet whose claim lingers while progress has stalled, show only "elapsed since the claim date (declared_at)" (no auto-determination or auto-release by a machine threshold such as elapsed days = INV2/INV66). (4) drafting claim (phase: drafting; packet_id is empty and issue_dir is the key — DR164) = surface it as "this issue is still being drafted (no packet raised yet)", given exactly the same treatment as (3): show only the time elapsed since the claim date. A drafting run abandoned before it ever reached the packets step also shows up here, but there is no cleanup command, expiry, or auto-archive — a human decides whether to delete it (the deletion trigger lives in the packets step's completion handling, where that session deletes it).
- When there are no claims (
.intent/assignments/ absent, or no claim files other than README.md), do not perform this Step (skip the check and continue; do not error = backward compatible; with zero claims, unchanged from current behavior). Detected claims, double-claims, and stale claims are included in the Step 5 (3) Details (candidate presentation, not an assertion; warn-only). This Step writes nothing (read-only preserved).
Step 4: Decide on one next move with the decision table
- Read
rules/decision-table.md and decide exactly one "next move" via first-match (evaluate top-down and adopt only the first matching row).
- Never copy the decision table's slash notation into user-facing output; give the guidance in a natural sentence such as "run
intent-improve."
- Never list multiple candidates side by side (the reason and basis are listed alongside). Even ambiguous cases where multiple recommendations seem visible are folded mechanically into one by the priority order of the decision table.
Step 5: Report
Structure the report in the order that gets the reader to "where am I, and what do I do next" by the shortest path, and slim down the default output. Compose the output in three layers — default (never folded) / details (the folded position) / option (only on a natural-language trigger). The default carries only the essentials ((1)–(4)) and the "dangerous notices"; push internal terms (the matching procedure, the integrity check, enforcement terms) and check details down into (5) details. The output target is the terminal. The "folded position" in this SKILL is a positional concept — pushing the details below the default so they are skippable — not a renderer-dependent collapsible UI. Use no raw HTML (<details> / <summary>, etc.) in the output; separate (5) Details and (6) Open Questions with plain Markdown headings (e.g. ## (5) Details / ## (6) Open Questions) instead (in a terminal the raw tags are shown literally and become unreadable).
[Default] essentials that are never folded
-
What the human decides next (first; exactly one): put the decision-table first-match result from (2) below at the very top under this heading. Show only that one item; warnings and candidates must not create additional next moves.
-
Three separate readings: after that decision, show Process health (packet state, progress rail, and dangerous notices), Unresolved design decisions (explicit Open Questions / decision candidates; "none" when none exist, "unobserved" when evidence is insufficient), and User outcomes separately. When a current result exists on the target L1, show value delivered | value not delivered | not known yet and its summary. With no current result, when Outcome measure: exists show awaiting post-release results; when neither exists, show no outcome measure (unobserved). A pending delta is not a confirmed outcome. Awaiting results and a current result are never shown together; they are not displayed at the same time. Never infer successful User outcomes from healthy Process health, and never collapse the three readings into an overall PASS, overall score, or "everything is healthy." Supporting detail may move to (5), but these three readings remain in the default.
-
(1) Progress rail (leading mini-rail): lay out all packets vertically and assign each one of the five signals (✅ reflected / 🔵 you are here / ⚪ not started / 🔴 unreflected / ◻ merged), followed by [current stage → next stage(s) to pass through]. Both the signal determination and the stage annotation follow the same discipline as overview's progress-readout.md "Progress rail" (the five signals cross-check state × whether export-log has a row × whether deltas has a corresponding entry via first-match; the stage annotation re-reads packet state as a position on the fixed pipeline discover→compass→packets→export→implement→verify→writeback; neither computes nor infers). Examples: P2 🔵 you are here [implementing → next: verify→writeback] / P3 ⚪ not started [ready → next: export→implement]. This makes "which P is you-are-here now, which stages remain after this, and where the ⚪ remaining work / 🔴 unreflected items are" visible at a glance on a single sheet. Annotate each signal's meaning per the glossary. The rail is a read-only mirror; status changes nothing.
- Order each row as
<short ID> <Packet name> <signal> [stage]. Show the canonical in full when it is at most 32 characters; when longer, show its first 32 characters followed by ( is not included in the 32). Always retain the ID. Only when no name can be read, omit the Packet name; never have the AI summarize or reword it. Details shows the short-ID-to-full- mapping. Example: . Signal determination, the decision-table first-match, and the next move remain unchanged.
[Details] pushed down to the folded position
- (5) Details (the folded position): each deliverable's present/absent/unfilled state and notable points that back the signals in (1); the current Source Packet (the packet name based on the latest row of export-log) and whether its export directory exists under
.intent/cc-sdd/, .intent/openspec/, or .intent/speckit/. The dangerous notices shown in the default at ⊕ also leave a one-line summary "⚠ N present (see details)" here to connect to the detail body (without removing them from the default). When index.md is absent, include the regeneration prompt; when drift-watch is on in Step 3.5, include the drift-log light tally (prevented N / caught N / missed N / false-positive N / not-applicable N / unjudged N; when decision-table row 13 applies, also append the per-pattern breakdown) as one block here; when conformance staleness's right moment (the not-caught-up count at or above the threshold) was detected in Step 3.6, include the basis "which compass section was updated, and how many packets are not caught up" here. When an intent-tree unfiled state (a suspected discover skip) was detected in Step 2, include one block with its spec name and the guidance "Design/implementation has advanced, but it could not be text-matched to any L0–L4 node of .intent/intent-tree.md. The discover phase itself may have been skipped. File it into intent-tree (L0–L4) via intent-discover, then raise a Packet with intent-packets, and return the implementation reality to canonical via intent-writeback — that is the order", at the candidate-presentation temperature that avoids assertion (it does not change the decision-table result for the next move). When an orphan spec (a suspected un-drafted implementation) was detected in Step 2, include one block with its spec name and the guidance "This may have been implemented without going through a Packet. Even after the fact, raise a Packet with intent-packets (making the unfixed spec explicit as Open Questions / Deferred), then return the implementation reality to canonical via intent-writeback — that is the order", at the candidate-presentation temperature that avoids assertion (it does not change the decision-table result for the next move). These two checks and the writeback omission (the freshness warning) are partitioned from upstream into three layers — tree layer → Packet layer → downstream layer — and when one spec matches multiple layers it is presented only in the single most-upstream layer so that no double warning is emitted (do not re-emit a spec that matched upstream in the downstream orphan-spec / freshness warning; guide it as a staged remedy of discover → packets → writeback). When parallel-implementation claims () were read in Step 3.8, include as one block, at the same position and temperature as the drift note (the candidate-presentation temperature that avoids assertion; warn-only): (1) claimed packets (being implemented; a claim exists), (2) double-claims on the same packet (the double-implementation warning; named), (3) stale claims (the observation of elapsed time since the claim date) (it does not change the decision-table result for the next move). When there are no claims, do not emit this block (with zero claims, unchanged from current behavior). When Step 2 read the canonical journey files (), include one block of per-journey progress (how many member packets are done, which are underway) at the same position and temperature as the claims block (derived from the member packets' only; never written back to the journey; with no journeys at all this block is not shown = unchanged).
[Option] only on a natural-language trigger
-
(7) Ice box expansion: only when the user requests via a natural-language trigger ("show me the icebox", etc.), expand the frozen candidates of (4) as count + names + a short note of the freeze reason. The expansion is also read-only with Read / Grep only; status changes nothing.
-
(8) Understanding-support view guidance: only when the user requests via a natural-language trigger ("show the understanding map", "I need a pre-start briefing", "sort the understanding gaps", etc.), status writes no files and guides the user to the corresponding derived view that intent-overview can generate. State the mapping explicitly: understanding map → .intent/overview/agent-understanding-map.md; pre-start briefing → .intent/overview/active-packet-briefing.md; understanding gap sorting → .intent/overview/understanding-gaps.md. Even if the corresponding file already exists, status does not update it; say to regenerate it with intent-overview when needed.
-
Unset-or-absent display: when a deliverable is unset or absent, show it in the term (explanation): state form — e.g. Intent Tree (the hierarchical map of what you want to do): not created — in plain English so that a reader who does not know the term can tell that the deliverable does not yet exist / has no content. Consistency-check violations (a stuck superseded_by, divergence from the index, an item remaining in archive, etc.) are shown the same way: annotate the term with its explanation and present in plain English what is stuck / diverging and how.
Always-annotate rule for terms
The terms that appear in the output are annotated with their meaning in the term (explanation) parenthetical form, by referring to the "Glossary" below. The annotation is split into two layers — the lead (default) and the details (the folded position). The concrete conventions are as follows.
- Two-layer annotation rule (lead = first occurrence / headers only; details = every time): the intent-planner-specific terms that appear in status output (deliverable names, state values, check terms, command names) are kept in English as the canonical form and are never replaced by a translation. Each term is annotated with a short plain-language explanation of its meaning, written in the
term (explanation) parenthetical form. The annotation density is split by output layer: in the lead (the slimmed-down default essentials), the annotation is limited to the first occurrence and table headers only (to avoid lead redundancy and not bury "the next move"). In the details (the folded position), the term is annotated every time it appears (the details are a fragmentary report whose visible items vary with the situation, so "first occurrence" is not stable; the priority is that the meaning is clear on the spot, every time). The glossary itself is kept and the annotation is not abolished (the status-readability value of "readable even without knowing the term" is preserved on the details side).
- Avoiding redundancy in practice: even when the same term recurs within a single output and full annotation would be redundant, no item is left as the bare term. In list / table item headers, keep the parenthetical annotation; in repeated in-prose mentions, the form may be tightened as long as the meaning remains traceable from context. When tightening the form, the condition is that the term's meaning stays traceable.
Glossary
The terms that status refers to when producing output, with a one-line explanation (this glossary is kept self-contained within this SKILL).
Deliverable names
| Term | One-line explanation |
|---|
| Intent Tree | the hierarchical map of what you want to do (L0 = purpose … L4 = candidate work units) |
| Intent Compass | the decision criteria for preventing local optimizations |
| Packets / packet | the work unit before handing off to the next stage (broader than an Issue, just before a spec) |
| Source Packet | the packet a draft originated from (identifies the export origin) |
| delta | the diff record used to update a canonical deliverable after the fact |
state (5 values)
| Term | One-line explanation |
|---|
| state: draft | drafting / undetermined |
| state: ready | ready to start (dependencies resolved, awaiting implementation) |
| state: implementing | under implementation |
| state: verifying | implemented, awaiting verification (Evidence undetermined) |
| state: done | evidence obtained / complete |
Progress rail (5 signals + stage annotation) (cross-check a packet by state × whether export-log has a row × whether deltas has a corresponding entry, and assign one via first-match. Further, annotate each row with [current stage → next stage(s) to pass through], re-reading packet state as a position on the fixed pipeline discover→compass→packets→export→implement→verify→writeback. The canonical determination lives in overview's progress-readout.md "Progress rail," not in rules/decision-table.md, but status's leading mini-rail uses the same five-signal vocabulary + stage annotation)
The signals in the legend are toned down to inline code (do not line up bare warning colors in the explanatory context = INV32). In the actual-impact context where a matching packet exists, they are shown in full as bare glyphs per INV31.
| Signal | One-line explanation |
|---|
✅ reflected | implementation complete and written back into intent (state: done and a corresponding delta is promoted/closed) |
🔵 you are here | the one stage currently being worked on (of the exported-not-yet-reflected, the current Source Packet = the latest export-log row) |
🔴 unreflected | evidence of implementation exists but not yet reflected (of the exported-not-yet-reflected, those other than the current Source Packet = past leftovers) |
⚪ not started | not yet exported to the next stage (no row in export-log) |
◻ merged | merged into a successor packet and done with its role (superseded_by is non-empty) |
Replacement axis
| Term | One-line explanation |
|---|
| superseded_by | the ID of the successor packet that replaced this packet (a separate axis denoting replacement, not a state) |
enforcement / staleness
| Term | One-line explanation |
|---|
| enforcement | the strength of writeback enforcement (off = no checks / remind = warning only / gate = stops export · push) |
| stale (staleness) | the writeback is out of date (implementation moved on but it has not been reflected back into intent) |
| conformance staleness | compass (Invariants/Decision Rules) was updated but a packet has not yet caught up (status estimates the right moment; the definitive diagnosis is made by intent-validate) |
drift-watch
| Term | One-line explanation |
|---|
| drift-watch | monitoring of drift (deviation) from intent (off = does nothing / on = matching warnings and recording; both warn only and never stop) |
assignments (parallel-implementation claims)
| Term | One-line explanation |
|---|
| claim (assignment) | a declaration of "which packet is being implemented by whom (which session)" (.intent/assignments/<packet_id>-<session-rand>.md; 1 claim = 1 file; a separate layer from the packet's state) |
| double-claim (double implementation) | a state where a single packet has two or more claims (several sessions touching the same packet at once; warn only, never stops) |
The 6 fields of the drift tally (prevented / caught / missed / false-positive / not-applicable are outcome values, unjudged is a user-verdict value; do not confuse the kinds)
| Term | Kind | One-line explanation |
|---|
| prevented | outcome | the drift was prevented before implementation handoff |
| caught | outcome | the drift was captured at export (capture succeeded) |
| missed | outcome | the drift could not be prevented and got through |
| false-positive | outcome | it was a false alarm |
| not-applicable | outcome | the case was checked, but the drift pattern did not apply |
| unjudged | user-verdict | a human has not yet judged the validity of the drift (a value of user-verdict, not an outcome) |
Output Description
Reader: a human developer who wants to know, by the shortest path, "where am I now and what should I do next".
What this makes them grasp first: exactly one "What the human decides next" item → the three separate readings of Process health, Unresolved design decisions, and User outcomes → (1) the progress rail → (3) Candidate Packets → (4) the Ice box notice. Dangerous notices remain in full; internal terms and check details move to (5) details.
The output composition, the content of each layer, and the relegation discipline are governed by Step 5 "Report" (not re-listed here). Skeleton only: default (one human decision / three separate readings / (1) progress rail / (3) Candidate / (4) Ice box notice / ⊕ dangerous notices) → (5) details (the folded position) → (6) Open Questions → (7) Ice box expansion (only on a natural-language trigger) → (8) understanding-support view guidance (only on a natural-language trigger).
Plainness check for reports (user-facing reports; right before output; shared)
Right before emitting a user-facing report (progress, completion, items needing confirmation — including the end-of-turn summary), run this check (INV105, DR208). It applies only to user-facing report text, not to how internal records (canonical files and logs under .intent/) are written.
- Do not transcribe internal documents verbatim: text you just read or wrote in internal artifacts (tree, compass, packets, Open Questions) is written in internal vocabulary. In the report, restate that content in words a first-time reader understands (without changing facts or meaning).
- Identifiers must not be the subject of the sentence: when presenting an item to confirm or a unit of work, first write one sentence that stands on its own ("what and why"), then append identifiers (Open Question numbers, packet names, symbols, stage names) after it as references (e.g. "... please verify this before starting (ref: OQ-xxx-1)"). Do not delete identifiers or references to records for the sake of plainness (the trail back to the record is lost).
- Signal for overload: three or more unexplained internal terms in one sentence signal overload (read by meaning, not by mechanical count). If a sentence does not stand on its own, rewrite it in plain words before sending (without changing facts or meaning).
- Do not convey meaning only through a metaphor or a vague qualifier: the foundation of a report is precision — write so the meaning reads unambiguously (plain language is a means of staying easy to read while preserving it). Do not report results only with ungrounded qualifiers (e.g. "significantly", "nicely"); state observable facts. If you use a metaphor, pair it immediately with a precise restatement (do not force established technical terms, or ordinary words in their everyday sense, into strained paraphrases).
- This check works as a pair with the after-the-fact record (prevention alone is never enough): when a report failed to get through, log the case to the drift log while drift-watch is on, and feed the next prevention.
Safety & Fallback
- Read-only declaration: never create, modify, or delete any file (the frontmatter does not carry Write; Bash is limited to launching the read-only script
node .intent/scripts/intent-check.mjs and does not change this property). drift-log is read via Read / Grep only (without widening what Bash launches and without writing to drift-log), and this read-only property is not changed.
- When
.intent/ is absent, guide the user through the setup procedure and finish.
- The absence of mode.md does not stop; continue with the standard default and announce it.
- When enforcement is
off, unstated, or an invalid value, do not run intent-check and show no freshness warning (current behavior). Even under remind or gate, when intent-check cannot run (Bash unavailable, script absent, or exit 2), omit the freshness check and continue.
- When drift-watch is not
on (off, unstated, an invalid value, the section absent, or mode.md absent), do not add the drift block and continue byte-equivalent to the current behavior. Even when on, when the drift-log is absent (neither the split form .intent/drift-log/*.md set nor the old .intent/drift-log.md exists), omit the drift block (do not error).
- When
.intent/export-log.md is absent or its latest row cannot be interpreted, fall back in order to the drafts' ## Source Packet heading and then to text matching against index.md / the packet files (text matching stays at presenting candidates; do not assert), and include the fallback fact in the report.
- Works even in environments without
.kiro/specs/ (the applicable row follows the proviso-worded recommendation of rules/decision-table.md).