arcane-cli 0.33.5 → 0.33.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@ See also: [[README]], [[DECISIONS]], [[governance/git-conventions|Git Convention
19
19
 
20
20
  2. **No root commands without justification. Enforcement: explicitly advisory prose (ARC-023) — depends on judgment about what justifies root scope; no script inspects generated commands for root usage before they run.** Do not generate or suggest commands that run as root unless explicitly scoped and justified. The agent runtime should run as a dedicated non-root user by design. See [[security/hardening-checklist|Hardening Checklist]].
21
21
 
22
- 3. **No secrets on the command line. Enforcement: explicitly advisory prose (ARC-023) — no secret-scanner exists in this repo yet (tracked as future work, BC-30), so no mechanical check catches a violation.** Never pass API keys, tokens, or secrets on the command line, in chat, or in config files. Use SecretRef (env vars) and `read -s` for interactive input.
22
+ 3. **No secrets on the command line. Enforcement: explicitly advisory prose (ARC-023) for the command-line/chat case this rule is really about — a secret only ever typed there, never written to a file, is invisible to any file scanner by construction, so no mechanical check catches that. The narrower config-file case is stronger: BC-30 shipped a repo-wide credential-pattern scan (`src/modules/secrets-scan.ts`, executable check) enforced at both pre-commit (`doctor:leaks`) and CI, catching a secret that lands in any committed file. (Corrected 2026-09-02, LH-08 — this previously claimed no scanner existed at all, which stopped being true once BC-30 shipped.)** Never pass API keys, tokens, or secrets on the command line, in chat, or in config files. Use SecretRef (env vars) and `read -s` for interactive input.
23
23
 
24
24
  4. **This is a production system. Enforcement: explicitly advisory prose (ARC-023) — the no-shortcuts and rollback-plan requirements depend on engineering judgment; no check evaluates whether a rollback plan exists.** No "fix it later" shortcuts. No experimental changes without rollback plans.
25
25
 
@@ -78,6 +78,31 @@ stale number is invisible until someone tries.
78
78
  it resolves to, say so and cite the ID as plain text rather than inventing a link that
79
79
  looks real but goes nowhere.
80
80
 
81
+ ### Stable-Locator Citation Grammar
82
+
83
+ The same "don't force the reader to go find it themselves" principle applies to citing a
84
+ specific spot inside a file, not just a Decision-ID. A bare `path:NNN` line-number citation
85
+ drifts the moment either file is edited — confirmed live, repeatedly: 13+ instances in one
86
+ program's own corrections record, and three more caught within 24 hours of being written,
87
+ during the very audit that counted the first 13.
88
+
89
+ **Required format, in a living doc** (anything meant to stay accurate as the tree changes —
90
+ `TODO.md`, `IDEAS.md`, `DECISIONS.md`, `ai-context/`, the verification ledger, an active plan,
91
+ or a shipped governance doc/prompt):
92
+ - `path` — the whole file is the referent, no specific spot claimed.
93
+ - `path#anchor` — a heading anchor that slugifies to a real heading in that file.
94
+ - `path ("unique quoted phrase")` — a phrase that occurs exactly once in that file, so a reader
95
+ (or a script) can always re-locate it even after the file has been edited and re-wrapped.
96
+ - `path:NNN` **alone is never sufficient** in a living doc — only acceptable alongside one of
97
+ the three forms above (a secondary, human-convenience pointer next to a quoted phrase or
98
+ anchor), since a bare line number is exactly the kind of static fact this framework exists to
99
+ stop treating as durable. Enforcement: executable check (ARC-023) — `npm run check:citations`
100
+ scans the living-docs set for a bare `path:NNN` with no accompanying anchor or quoted phrase.
101
+
102
+ **Ephemeral output is exempt** (chat, a PR description, a commit message, a session handoff): a
103
+ bare `path:NNN` there is fine — the reader is looking at the current tree in the same sitting,
104
+ so drift has no time to happen before it is read.
105
+
81
106
  ## Merge Strategy
82
107
 
83
108
  All PRs must use **Rebase and fast-forward**. Never squash. Never merge commit. See
@@ -13,7 +13,7 @@ agent: agent
13
13
  - It enforces the rule from `project.md` → Constraints → Self-hosting: "Anything touching
14
14
  `src/assets/` requires a version bump." (Corrected 2026-08-31, BC-06 — this previously cited
15
15
  CLAUDE.md, which now carries only the working protocol; the rule's live prose home moved to
16
- `project.md:56-58`.)
16
+ `project.md ("requires a version bump"):56-58`.)
17
17
 
18
18
  ---
19
19
 
@@ -46,6 +46,7 @@ Concrete detectors to run (in addition to general contradiction/stale-date check
46
46
  - **Journal chronology** — journal entries and their dates must be in sane order. Flag out-of-order entries, duplicate session numbers, and any future or otherwise contradictory dates.
47
47
  - **Done vs. carry-forward consistency** — items marked done must not still appear as open or carry-forward items, and items listed as open/carry-forward must not also be marked done elsewhere.
48
48
  - **Decision-ID existence** — decision IDs referenced in TODO, journal, or other docs must exist in `DECISIONS.md`, and the IDs in the decisions log must be sequential and unique (no gaps that imply a missing entry, no duplicates).
49
+ - **Shipped-state staleness** (LH-08; only when this repo has its own `scripts/check-stale-claims.ts` — Arcane's own repo, or one that adopted the same convention; skip gracefully otherwise) — run `npm run check:stale-claims -- --report` and triage its Class B output (occurrences of "not yet built"/"not yet supported"/"tracked as future work" and similar phrases in shipped or living content): each hit is a prompt to verify the claim against the real tree, not proof of staleness by itself. Class A (`ARC-NNN (Status)` claims vs. `DECISIONS.md`) is already a separate, mechanically-enforced CI gate — do not re-litigate its findings here, only Class B needs this judgment pass.
49
50
  - **Canonical vs. installed-copy parity** — for every managed root file that has a canonical counterpart under `src/assets/`, compare bytes first. If bytes differ, normalize `CRLF` and lone `CR` to `LF` in both files and compare again:
50
51
  - If normalized content differs, report **real content drift** with normal severity grading.
51
52
  - If normalized content matches, report **line-ending-only drift** separately. Do not count these paths as real content findings and do not include them in severity totals or the Go / No-Go decision.
@@ -62,11 +63,11 @@ For each drift finding include:
62
63
  - Severity (`Critical`, `High`, `Medium`, or `Low`)
63
64
  - Severity rationale (one line: why this severity — e.g. work-integrity/duplicate-work risk → HIGH; confidence/correctness gap → MEDIUM; cosmetic → LOW)
64
65
  - Drift statement
65
- - Canonical source file (cite `file:line` — or the nearest locator such as a heading or section — wherever a specific location applies)
66
- - Affected file (cite `file:line` — or the nearest locator — wherever a specific location applies)
66
+ - Canonical source file (cite by stable locator — a heading anchor or a unique quoted phrase, e.g. `path#anchor` or `path ("unique phrase")` — never a bare line number, since findings routinely get promoted into TODO.md or another living doc afterward, where a line number drifts the moment the file is next edited)
67
+ - Affected file (same stable-locator citation)
67
68
  - Exact recommended fix
68
69
 
69
- Every finding that points to a specific location MUST be pinpointable: cite `file:line` (or a line range, e.g. `TODO.md:42-45`). If no precise line exists, cite the nearest available locator (heading, section, or list item) instead of omitting it.
70
+ Every finding that points to a specific location MUST be pinpointable: cite by stable locator (a heading anchor or a unique quoted phrase, e.g. `path#anchor` or `path ("a unique phrase from the target")`). A bare line number may accompany a stable locator as a convenience (this report is read once, in the current tree), but never replace one — a citation promoted into a living doc later must survive on its own. If no precise anchor or phrase exists, cite the nearest available locator (heading, section, or list item) instead of omitting it.
70
71
 
71
72
  Behavior:
72
73
 
@@ -85,7 +86,7 @@ Output format:
85
86
 
86
87
  ## Real Content Drift Findings
87
88
 
88
- - One line per finding with `file:line` references (or nearest locator) and its severity rationale.
89
+ - One line per finding with stable-locator references (heading anchor or unique quoted phrase — nearest locator if neither applies) and its severity rationale.
89
90
 
90
91
  ## Line-Ending-Only Drift
91
92
 
@@ -83,9 +83,9 @@ In `ai-context/system-prompt-context.md`, replace the existing `## Next Session
83
83
  > Auto-generated by spell-close-session. Consumed by spell-open-session. Do not edit manually.
84
84
  > Generated: YYYY-MM-DD
85
85
 
86
- - **Active task:** One-line description of the task that was in progress when this session closed. If incomplete, name where step 4b registered it (e.g. `TODO.md:NNN`).
86
+ - **Active task:** One-line description of the task that was in progress when this session closed. If incomplete, name where step 4b registered it (e.g. `path ("the item's own quoted title")` — a stable locator naming the actual file and its bold title, never a bare line number that drifts the moment that file is next edited).
87
87
  - **Last completed step:** The final concrete action taken — include file path or command text. If that action was async work step 1b classified as anything other than `succeeded`, do not describe it as done here — name the action in `dispatched`/in-progress terms (e.g. "Pushed the fix and opened PR #NN" is fine; "Merged PR #NN" is not, unless step 1b confirmed the merge) and let `Pending Verification` carry the actual state.
88
- - **Next concrete action:** The exact first thing to do at next session start. Be specific: file, command, or decision. Never write "continue work." Name where step 4b registered it (e.g. `TODO.md:NNN`).
88
+ - **Next concrete action:** The exact first thing to do at next session start. Be specific: file, command, or decision. Never write "continue work." Name where step 4b registered it (e.g. `path ("the item's own quoted title")` — a stable locator naming the actual file and its bold title, never a bare line number that drifts the moment that file is next edited).
89
89
  - **Active files:** Files with uncommitted changes or the focus of the last edit (comma-separated).
90
90
  - **Branch:** Output of `git branch --show-current`.
91
91
  - **Blockers:** Known unresolved blockers or dependencies. Write "None" if clear.
@@ -37,7 +37,7 @@ Check `ai-context/system-prompt-context.md` for a `## Next Session Handoff` sect
37
37
 
38
38
  - If present and **not yet marked consumed** (no `> ✓ Consumed:` line): surface it immediately as `## Picking Up From Last Session` at the very top of your output, before all other sections — include `Last completed step`, `Blockers`, and `Notes` verbatim alongside the rest (session handoff durability: these three are written by close-session but were previously never read back). Use the `Next concrete action` field as the first item in `## Next Session Plan`. Use the `Active task`, `Active files`, and `Branch` fields to pre-populate the State Snapshot.
39
39
  - **If the handoff's `Pending Verification` field lists anything other than "None" (EF-21):** surface each listed item explicitly, then actively re-check its current status (per the item's stated verification action) rather than treating the state recorded at close-session time as still current — a `dispatched`/`pending` item may have since succeeded, failed, or still be running, and carrying it forward as inert text would repeat the exact failure mode this field exists to prevent. Report what you found (resolved succeeded / resolved failed / still pending / still unverifiable) before relying on anything downstream that depended on it.
40
- - After surfacing it, apply the Mutation Guard below, then run the **Durability check** (session handoff durability, ARC-040): confirm that an incomplete `Active task`, the `Next concrete action`, and any task-bearing `Notes` content each name a durable location that genuinely exists (the cited `TODO.md` line, or tracker work item). If a named location is missing, or close-session's own step 4b was skipped when it shouldn't have been, register the missing content now — on this session's own branch — before proceeding. Only then append `> ✓ Consumed: YYYY-MM-DD` (today's date); the marker write is a repository mutation. If the Durability check cannot complete, leave the handoff unconsumed so the next open-session retries the same check idempotently, rather than silently losing the gap.
40
+ - After surfacing it, apply the Mutation Guard below, then run the **Durability check** (session handoff durability, ARC-040): confirm that an incomplete `Active task`, the `Next concrete action`, and any task-bearing `Notes` content each name a durable location that genuinely exists (the cited `TODO.md` item — by stable locator, not a line number that may have already drifted — or tracker work item). If a named location is missing, or close-session's own step 4b was skipped when it shouldn't have been, register the missing content now — on this session's own branch — before proceeding. Only then append `> ✓ Consumed: YYYY-MM-DD` (today's date); the marker write is a repository mutation. If the Durability check cannot complete, leave the handoff unconsumed so the next open-session retries the same check idempotently, rather than silently losing the gap.
41
41
  - If the section is absent or already marked consumed: skip this step and proceed with the normal workspace scan.
42
42
 
43
43
  ## Mutation Guard (run lazily before the first repository write)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arcane-cli",
3
- "version": "0.33.5",
3
+ "version": "0.33.7",
4
4
  "description": "Arcane framework CLI — scaffold and manage governance files in consuming repositories",
5
5
  "keywords": [
6
6
  "arcane",
@@ -46,6 +46,8 @@
46
46
  "fix:spell-catalog": "tsx scripts/spell-catalog.ts --fix",
47
47
  "check:adr-references": "tsx scripts/check-distributed-adr-references.ts",
48
48
  "check:version-bump": "tsx scripts/check-version-bump.ts",
49
+ "check:citations": "tsx scripts/check-citations.ts --report",
50
+ "check:stale-claims": "tsx scripts/check-stale-claims.ts --check",
49
51
  "check:review-round": "tsx scripts/check-review-round.ts",
50
52
  "doctor:leaks": "tsx src/index.ts doctor --leaks",
51
53
  "prepare": "husky"