@alecsibilia/luca 13.0.0-alpha.1

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.
Files changed (128) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +47 -0
  3. package/bin/luca.js +3 -0
  4. package/dist/chunks/branch.mjs +47 -0
  5. package/dist/chunks/bun-runtime.mjs +46 -0
  6. package/dist/chunks/checks.mjs +53 -0
  7. package/dist/chunks/claim-verify.mjs +465 -0
  8. package/dist/chunks/classify.mjs +105 -0
  9. package/dist/chunks/confidence.mjs +199 -0
  10. package/dist/chunks/doctor.mjs +158 -0
  11. package/dist/chunks/hook.mjs +696 -0
  12. package/dist/chunks/init.mjs +715 -0
  13. package/dist/chunks/muninndb-health.mjs +66 -0
  14. package/dist/chunks/phase.mjs +38 -0
  15. package/dist/chunks/pr-review.mjs +122 -0
  16. package/dist/chunks/preferences.mjs +61 -0
  17. package/dist/chunks/repair.mjs +111 -0
  18. package/dist/chunks/repo.mjs +58 -0
  19. package/dist/chunks/retro.mjs +86 -0
  20. package/dist/chunks/roadmap.mjs +58 -0
  21. package/dist/chunks/rules.mjs +527 -0
  22. package/dist/chunks/stale-mcp-server.mjs +90 -0
  23. package/dist/chunks/state.mjs +57 -0
  24. package/dist/chunks/stray-local-install.mjs +200 -0
  25. package/dist/chunks/telemetry.mjs +165 -0
  26. package/dist/chunks/todo.mjs +151 -0
  27. package/dist/chunks/vault-init.mjs +300 -0
  28. package/dist/chunks/verification.mjs +95 -0
  29. package/dist/chunks/version.mjs +70 -0
  30. package/dist/chunks/workflow.mjs +47 -0
  31. package/dist/claude/.claude/agents/architect.md +410 -0
  32. package/dist/claude/.claude/agents/build.md +111 -0
  33. package/dist/claude/.claude/agents/discuss.md +93 -0
  34. package/dist/claude/.claude/agents/discussion.md +149 -0
  35. package/dist/claude/.claude/agents/execute.md +416 -0
  36. package/dist/claude/.claude/agents/executor.md +161 -0
  37. package/dist/claude/.claude/agents/fast.md +84 -0
  38. package/dist/claude/.claude/agents/finalize.md +484 -0
  39. package/dist/claude/.claude/agents/learner.md +160 -0
  40. package/dist/claude/.claude/agents/plan-reviewer.md +129 -0
  41. package/dist/claude/.claude/agents/plan.md +96 -0
  42. package/dist/claude/.claude/agents/research.md +327 -0
  43. package/dist/claude/.claude/agents/researcher.md +78 -0
  44. package/dist/claude/.claude/agents/review.md +283 -0
  45. package/dist/claude/.claude/agents/reviewer.md +163 -0
  46. package/dist/claude/.claude/agents/shadow-scanner.md +257 -0
  47. package/dist/claude/.claude/agents/triage.md +230 -0
  48. package/dist/claude/.claude/agents/verifier.md +131 -0
  49. package/dist/claude/.claude/commands/bug-diagnose.md +12 -0
  50. package/dist/claude/.claude/commands/gh-issue-triage.md +14 -0
  51. package/dist/claude/.claude/commands/gh-pr-address.md +235 -0
  52. package/dist/claude/.claude/commands/gh-prepare.md +12 -0
  53. package/dist/claude/.claude/commands/grill-me.md +12 -0
  54. package/dist/claude/.claude/commands/lu-review.md +51 -0
  55. package/dist/claude/.claude/commands/lu.md +75 -0
  56. package/dist/claude/.claude/commands/luca-init.md +14 -0
  57. package/dist/claude/.claude/commands/luca-telemetry-report.md +12 -0
  58. package/dist/claude/.claude/commands/memory-audit.md +12 -0
  59. package/dist/claude/.claude/commands/milestone-new.md +122 -0
  60. package/dist/claude/.claude/commands/phase-discuss.md +45 -0
  61. package/dist/claude/.claude/commands/phase-execute.md +39 -0
  62. package/dist/claude/.claude/commands/phase-plan.md +53 -0
  63. package/dist/claude/.claude/commands/repo-cleanup.md +80 -0
  64. package/dist/claude/.claude/commands/todo-add.md +28 -0
  65. package/dist/claude/.claude/commands/todo-check.md +36 -0
  66. package/dist/claude/.claude/hooks/context-refresher.ts +285 -0
  67. package/dist/claude/.claude/hooks/continuation-messages.ts +215 -0
  68. package/dist/claude/.claude/hooks/pipeline-guard.ts +182 -0
  69. package/dist/claude/.claude/settings.json +41 -0
  70. package/dist/claude/skills/arch-audit/SKILL.md +161 -0
  71. package/dist/claude/skills/autopilot/SKILL.md +1299 -0
  72. package/dist/claude/skills/bug-diagnose/SKILL.md +102 -0
  73. package/dist/claude/skills/choose/SKILL.md +124 -0
  74. package/dist/claude/skills/gh-issue-triage/SKILL.md +97 -0
  75. package/dist/claude/skills/gh-pr-address/SKILL.md +235 -0
  76. package/dist/claude/skills/gh-prepare/SKILL.md +209 -0
  77. package/dist/claude/skills/grill-me/SKILL.md +46 -0
  78. package/dist/claude/skills/lu/SKILL.md +112 -0
  79. package/dist/claude/skills/lu-review/SKILL.md +51 -0
  80. package/dist/claude/skills/luca-init/SKILL.md +91 -0
  81. package/dist/claude/skills/luca-telemetry-report/SKILL.md +145 -0
  82. package/dist/claude/skills/luca-write-surface/SKILL.md +213 -0
  83. package/dist/claude/skills/memory-audit/SKILL.md +217 -0
  84. package/dist/claude/skills/milestone-audit/SKILL.md +545 -0
  85. package/dist/claude/skills/milestone-complete/SKILL.md +168 -0
  86. package/dist/claude/skills/milestone-gaps/SKILL.md +60 -0
  87. package/dist/claude/skills/milestone-new/SKILL.md +125 -0
  88. package/dist/claude/skills/note/SKILL.md +162 -0
  89. package/dist/claude/skills/phase-add/SKILL.md +91 -0
  90. package/dist/claude/skills/phase-assumptions/SKILL.md +92 -0
  91. package/dist/claude/skills/phase-discuss/SKILL.md +165 -0
  92. package/dist/claude/skills/phase-execute/SKILL.md +1786 -0
  93. package/dist/claude/skills/phase-insert/SKILL.md +100 -0
  94. package/dist/claude/skills/phase-plan/SKILL.md +461 -0
  95. package/dist/claude/skills/phase-remove/SKILL.md +113 -0
  96. package/dist/claude/skills/phase-research/SKILL.md +80 -0
  97. package/dist/claude/skills/post-init-tour/SKILL.md +58 -0
  98. package/dist/claude/skills/progress/SKILL.md +271 -0
  99. package/dist/claude/skills/project-new/SKILL.md +609 -0
  100. package/dist/claude/skills/quick/SKILL.md +256 -0
  101. package/dist/claude/skills/rename-audit/SKILL.md +52 -0
  102. package/dist/claude/skills/repo-audit/SKILL.md +88 -0
  103. package/dist/claude/skills/repo-cleanup/SKILL.md +80 -0
  104. package/dist/claude/skills/seed-memory/SKILL.md +235 -0
  105. package/dist/claude/skills/session-pause/SKILL.md +126 -0
  106. package/dist/claude/skills/session-plan/SKILL.md +112 -0
  107. package/dist/claude/skills/session-resume/SKILL.md +75 -0
  108. package/dist/claude/skills/todo-add/SKILL.md +85 -0
  109. package/dist/claude/skills/todo-check/SKILL.md +77 -0
  110. package/dist/claude/skills/workflow-save/SKILL.md +277 -0
  111. package/dist/index.d.mts +33 -0
  112. package/dist/index.d.ts +33 -0
  113. package/dist/index.mjs +69 -0
  114. package/dist/shared/luca.B3Mimc0P.mjs +52 -0
  115. package/dist/shared/luca.B3saVjJm.mjs +163 -0
  116. package/dist/shared/luca.BYdjkfnz.mjs +217 -0
  117. package/dist/shared/luca.BmhNkYe2.mjs +56 -0
  118. package/dist/shared/luca.C4gMUoBd.mjs +358 -0
  119. package/dist/shared/luca.CQ3g1xrD.mjs +19 -0
  120. package/dist/shared/luca.CRmaAfXR.mjs +713 -0
  121. package/dist/shared/luca.CrXzXueR.mjs +57 -0
  122. package/dist/shared/luca.DTomPq7I.mjs +91 -0
  123. package/dist/shared/luca.DjDTeDCi.mjs +1904 -0
  124. package/dist/shared/luca.HZxBTBgD.mjs +201 -0
  125. package/dist/shared/luca.TSMg1t7I.mjs +10 -0
  126. package/dist/shared/luca.dM-MKlNE.mjs +25 -0
  127. package/dist/shared/luca.naWEcQ4B.mjs +7 -0
  128. package/package.json +76 -0
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: luca-write-surface
3
+ description: |-
4
+ Reference for the `luca` CLI write surface — the deterministic command track for structured and operational mutations of the .luca/ workflow directory (state, roadmap, preferences, todos, checks, pr-review, repo-cleanup, workflow-reset, branch-guard, confidence). Each command is a noun/verb pair invoked via Bash; payloads are small flags or a --file JSON path. Documents every subcommand, its arguments, and its pipelineStep rules.
5
+
6
+ Use when a Luca skill or agent needs to read or mutate .luca/ workflow state, advance the pipeline, manage the backlog, or run verification — i.e. anything that is NOT a freeform phase artifact file.
7
+ ---
8
+
9
+ # luca-write-surface Skill
10
+
11
+ The `luca` CLI is the **structured / operational** track of the Luca write
12
+ surface. It is invoked via `Bash` and mutates `.luca/` through validated,
13
+ deterministic handlers — never a raw file write.
14
+
15
+ The 9 freeform phase artifact files (research, context, plan, plan-review,
16
+ summary, wave, verify, audit, learn) have **no CLI command** — they are
17
+ written with the native `Write` tool to their canonical path. That
18
+ convention is documented in the "Artifact files" section below; the CLI
19
+ commands are documented after it.
20
+
21
+ ## Invocation shape
22
+
23
+ ```
24
+ luca <noun> <verb> [--flags] [--file <path>]
25
+ ```
26
+
27
+ - **Small scalar params** are passed as flags.
28
+ - **Large structured payloads** (arrays, objects) are passed as a `--file`
29
+ pointing at a JSON file you stage first. The CLI reads and `JSON.parse`s
30
+ it.
31
+ - Output: the command prints a human/JSON result to stdout and exits `0` on
32
+ success, `1` on error (validation failure, phase refusal, handler error).
33
+ - Run `luca <noun> <verb> --help` for the authoritative argument schema.
34
+
35
+ ## Phase rules
36
+
37
+ Some commands are restricted to specific `pipelineStep`s. Before running, the
38
+ CLI reads `.luca/state.json` and **refuses with exit 1** if the current step
39
+ is not allowed. Pure reads have no restriction.
40
+
41
+ | Command | Allowed pipelineSteps |
42
+ |---|---|
43
+ | `roadmap create` | `idle`, `triage` |
44
+ | `checks run` | `execute`, `checks` |
45
+ | all other commands | any (pure reads or phase-agnostic mutations) |
46
+
47
+ ## Artifact files — the `Write`-tool track
48
+
49
+ The 9 freeform phase artifacts are **not** mutated through the CLI. They
50
+ are written with the agent's native **`Write` tool**, directly to a
51
+ canonical path under the active phase directory. Content travels in
52
+ `Write`'s structured `content` field and never touches the shell.
53
+
54
+ ### Get the phase directory
55
+
56
+ The canonical path is computed from the active phase directory. Obtain it
57
+ by running:
58
+
59
+ ```
60
+ luca phase current
61
+ ```
62
+
63
+ which prints `{ active, NN, slug, dir }` (or `{ active: false }` when no
64
+ phase is active). Use the `dir` field as the base path — e.g.
65
+ `.luca/phases/03-ws-reconnect`. Never hand-construct the slug.
66
+
67
+ ### The 9 canonical artifact paths
68
+
69
+ Given `<dir>` from `luca phase current`:
70
+
71
+ | Artifact | Canonical path | Written during step |
72
+ |---|---|---|
73
+ | research | `<dir>/research.md` | `research` |
74
+ | context | `<dir>/context.md` | `discuss` |
75
+ | plan | `<dir>/plan.md` | `plan` |
76
+ | plan-review | `<dir>/plan-review.md` | `plan-review` |
77
+ | summary | `<dir>/execute/summary.md` | `execute` |
78
+ | wave | `<dir>/execute/waves/<NN>.md` | `execute` |
79
+ | verify | `<dir>/verify.json` | `verify` |
80
+ | audit | `<dir>/audits/<reviewer>.md` | `review` |
81
+ | learn | `<dir>/learn.md` | `learn` |
82
+
83
+ - `<NN>` in the wave path is the **zero-padded** wave number (`00.md`,
84
+ `03.md`, `42.md`).
85
+ - `<reviewer>` in the audit path is the reviewer perspective in
86
+ kebab-case (`code-review`, `architect`, `dx`, `security`,
87
+ `simplification`, `test-quality`).
88
+ - `verify.json` is **JSON**, not markdown — write the verification
89
+ result object as a JSON string.
90
+
91
+ ### Phase gating — the stage-gate hook
92
+
93
+ The Phase C stage-gate hook (PreToolUse) computes the legal artifact
94
+ path(s) for the current `pipelineStep` and allows a `Write` **only** when
95
+ the path is an exact match for that step. Each artifact has exactly one
96
+ legal `pipelineStep` (the "Written during step" column above):
97
+
98
+ - A `Write` to `<dir>/plan.md` is allowed only while
99
+ `pipelineStep === "plan"`; the same write is **blocked** in any other
100
+ step.
101
+ - A `Write` to any other `.luca/` path — including `.luca/` root files
102
+ (`state.json`, `config.json`, `roadmap.md`, `ledger.jsonl`) — is
103
+ **always blocked**. Root files are mutated only through the `luca` CLI.
104
+ - A `Write` to a code file or any non-contract path is blocked
105
+ (unchanged behavior).
106
+
107
+ This makes the native `Write` tool the safe content channel: the agent
108
+ *proposes* the path, the hook *computes* the canonical path for the
109
+ current step and rejects anything else. Do not attempt to work around a
110
+ block — advance the pipeline to the correct step first.
111
+
112
+ ## Commands
113
+
114
+ ### `state` — workflow state machine
115
+
116
+ - **`luca state read`** — read the full `.luca/state.json` (pipelineStep,
117
+ currentPhase, iteration counters, roadmap). Pure read.
118
+ - **`luca state advance --to-step <step>`** — atomically advance the
119
+ pipelineStep. The transition is validated against the pipeline-transitions
120
+ table; illegal jumps are rejected.
121
+
122
+ ### `phase` — active phase inspection (read only)
123
+
124
+ - **`luca phase current`** — report the active phase as
125
+ `{ active, NN, slug, dir }`, or `{ active: false }` when none is active.
126
+ Use the `dir` field as the base path when writing artifact files with the
127
+ native `Write` tool. Pure read.
128
+
129
+ ### `roadmap` — workflow roadmap
130
+
131
+ - **`luca roadmap read`** — read the roadmap array plus currentPhase /
132
+ totalPhases. Pure read.
133
+ - **`luca roadmap create --file <path>`** — replace the roadmap. The file
134
+ holds the phases array: `[{ name, deps?, status?, complexity? }, ...]`.
135
+ Resets currentPhase to 0. Allowed only in `idle` / `triage`.
136
+
137
+ ### `preferences` — project preferences in config.json
138
+
139
+ - **`luca preferences read`** — read the validated `preferences` section of
140
+ `.luca/config.json`. Pure read.
141
+ - **`luca preferences write --file <path>`** — section-level shallow merge
142
+ into the preferences. The file holds the partial preferences object. The
143
+ merged result is validated against `ProjectPreferencesSchema`.
144
+
145
+ ### `todo` — backlog (MuninnDB-backed)
146
+
147
+ Todos live in MuninnDB; these commands validate the shape and emit a
148
+ `muninn_*` instruction for the agent to execute (delegation pattern).
149
+
150
+ - **`luca todo add --title <t> [--body <b>] [--status pending|backlog]
151
+ [--source <s>] [--id <id>] [--metadata-file <path>]`** — create a todo.
152
+ - **`luca todo list [--status <s>] [--limit <n>]`** — list todos
153
+ (limit 1-200, default 50).
154
+ - **`luca todo update --id <id> --title <t> --status <s> [--body <b>]
155
+ [--source <s>] [--verification-criterion <id>] [--metadata-file <path>]`**
156
+ — update a todo. Promoting `--status done` requires
157
+ `--verification-criterion` pointing at a met PASS criterion in the active
158
+ phase's verify.json.
159
+
160
+ ### `pr-review` — PR-review analysis (read only)
161
+
162
+ Used by the gh-pr-address flow. Each takes a JSON `--file` payload.
163
+
164
+ - **`luca pr-review filter-stale --file <path> [--head-sha <sha>]
165
+ [--max-drift-lines <n>]`** — file holds the comments array; drops comments
166
+ whose cited code was rewritten.
167
+ - **`luca pr-review detect-convergence --file <path>
168
+ [--line-tolerance <n>]`** — file holds the findings array; promotes
169
+ cross-perspective clusters to must-fix.
170
+ - **`luca pr-review regression-check --file <path>`** — file holds the full
171
+ payload `{ before, after, touched_paths?, from_sha?, to_sha? }`. Exits 1
172
+ when regressions are present.
173
+
174
+ ### `repo` — repository housekeeping
175
+
176
+ - **`luca repo cleanup-apply --file <path> [--confirm]`** — apply one
177
+ shadow-scan remediation finding (file holds a single `ShadowScanFinding`).
178
+ Without `--confirm` it is a no-op preview — nothing is deleted or moved.
179
+
180
+ ### `checks` — verification commands
181
+
182
+ - **`luca checks run --file <path> [--timeout-ms <ms>]`** — run an ordered
183
+ list of commands sequentially with per-command timeouts. File holds the
184
+ commands array `[{ argv: string[], label? }, ...]`. Allowed only in
185
+ `execute` / `checks`.
186
+
187
+ ### `branch` — git branch guard
188
+
189
+ - **`luca branch guard [--default-branch <name>]`** — exits 1 when the
190
+ current branch equals the default branch (default `main`). Use before
191
+ committing.
192
+
193
+ ### `workflow` — workflow lifecycle
194
+
195
+ - **`luca workflow reset [--confirm]`** — reset `.luca/state.json` to idle
196
+ defaults and clear the pipeline lock. Destructive but recoverable;
197
+ requires `--confirm`.
198
+
199
+ ### `confidence` — confidence logging
200
+
201
+ - **`luca confidence log --score <0..1> --stage <s> --rationale <r>
202
+ [--metadata-file <path>]`** — append a confidence entry to the active
203
+ phase's confidence.jsonl.
204
+
205
+ ## Error handling
206
+
207
+ - **Phase refusal** — exit 1, message names the allowed pipelineSteps. Do
208
+ not work around it; advance the pipeline correctly first.
209
+ - **Invalid arguments** — exit 1, message lists each schema violation.
210
+ - **Handler error** — exit 1 with the handler's message verbatim.
211
+
212
+ Always check the exit code; a non-zero exit means the mutation did not
213
+ happen.
@@ -0,0 +1,217 @@
1
+ ---
2
+ name: memory-audit
3
+ description: |-
4
+ Paginated, LLM-judged retro-pass over a MuninnDB vault that classifies each engram against the trust-tier rule and applies corrections via `mcp__muninn__muninn_trust`. Resumable via a `memory-audit:cursor` memory stored in the audited vault. Per-run audit reports are emitted inline.
5
+
6
+ Use when user says "audit memory", "audit muninn", "audit vault", "memory audit", "retro tier pass", or invokes `/memory-audit`. Default mode is `--dry-run` (no mutations). Pass `--apply` to commit trust-tier changes. Pass `--auto` with `--apply` to skip per-promotion confirmation prompts.
7
+ ---
8
+
9
+ # memory-audit Skill
10
+
11
+ Audit a MuninnDB vault. Walk every reachable engram. For each, judge whether its current trust tier matches the discipline. Promote or demote via `mcp__muninn__muninn_trust`. Persist a resumable cursor so re-invocations pick up where the previous run stopped.
12
+
13
+ ## Scope guard — read first
14
+
15
+ This skill is **read-then-trust**. It mutates trust tiers via `mcp__muninn__muninn_trust`, and it writes exactly ONE bookkeeping memory — its own resumable cursor under the concept `memory-audit:cursor`. It mutates nothing else.
16
+
17
+ The following MuninnDB tools are FORBIDDEN inside this skill. Do not call them under any circumstance, even if the audit surfaces a "duplicate" or "stale" engram:
18
+
19
+ - `mcp__muninn__muninn_remember_batch`
20
+ - `mcp__muninn__muninn_forget`
21
+ - `mcp__muninn__muninn_consolidate`
22
+ - `mcp__muninn__muninn_evolve`
23
+ - `mcp__muninn__muninn_link`
24
+ - `mcp__muninn__muninn_state`
25
+ - `mcp__muninn__muninn_decide`
26
+ - `mcp__muninn__muninn_add_child`
27
+ - `mcp__muninn__muninn_remember_tree`
28
+ - `mcp__muninn__muninn_restore`
29
+
30
+ `mcp__muninn__muninn_remember` is permitted ONLY to write the `memory-audit:cursor` memory (Step 6). It must never be used to create content memories. If a memory looks wrong, log it in the inline report. Do not delete, link, decide, restore, transition state, or otherwise mutate it.
31
+
32
+ ## Tier rule (canonical)
33
+
34
+ The skill judges each engram against this rule. The rule is the single source of truth — do not invent additional tiers.
35
+
36
+ - **`verified`** — content cites a specific source (file:line+SHA, PR id, user-message id, external URL) AND the claim is testable from that source AND the content is factual not interpretive. Promotion to `verified` requires citation evidence to be present in the engram content.
37
+ - **`inferred`** — DEFAULT. Patterns, lessons, opinions, predictions, recommendations, AI-derived findings. This is the engine default; assigning `inferred` is always safe.
38
+ - **`external`** — imported from outside this repo (rare; e.g. a seeded preferences memory). Leave untouched.
39
+ - **`untrusted`** — never assigned by an agent. Reserved for human override. Do not emit.
40
+
41
+ ### Citation-presence check (gate for `verified`)
42
+
43
+ A memory may be promoted to `verified` only if its content (or `summary` field) contains at least one of:
44
+
45
+ 1. A file path with a line number — `\b\w[\w/.\-]+\.(?:ts|tsx|js|jsx|py|go|rs|md|json):\d+\b`
46
+ 2. A commit SHA, PR id, ULID, or issue id — `\b[a-f0-9]{7,40}\b` OR `#\d+` OR `01[A-Z0-9]{24}`
47
+ 3. An absolute URL — `\bhttps?://\S+`
48
+ 4. A quoted source attribution AND a verifiable reference (e.g. `"per user @alec on 2026-05-07 in PR #143"` — bare quoted prose without a verifiable anchor does NOT pass).
49
+
50
+ If none of these are present, the proposed tier is `inferred` regardless of how factual the content sounds.
51
+
52
+ ## Arguments
53
+
54
+ - `--dry-run` (default ON) — judge memories, emit the report, **do not call** `mcp__muninn__muninn_trust`.
55
+ - `--apply` — required to actually mutate trust tiers. If `--dry-run` is also present, dry-run wins (apply is suppressed; a warning is logged).
56
+ - `--auto` — only meaningful with `--apply`. Skips per-promotion confirmation. Without `--auto`, every `verified` promotion AND every `verified → inferred` demotion requires explicit user approval.
57
+ - `--vault <name>` — override the resolved vault. Must match `^[a-zA-Z0-9_\-]{1,64}$`.
58
+ - `--resume` — load the cursor from the `memory-audit:cursor` memory and continue from there.
59
+ - `--limit <n>` — max engrams to process this invocation (default 50, max 200; bounded by the underlying MCP tool).
60
+
61
+ Vault resolution: `.luca/config.json` → `muninn.vault`, fallback `"default"`.
62
+
63
+ ### Pre-flight argument validation
64
+
65
+ Before Step 1, validate the arguments:
66
+
67
+ 1. If both `--dry-run` and `--apply` are present: clear `--apply`, log the warning "dry-run wins; mutations suppressed". Do not abort.
68
+ 2. If `--limit <n>` is set: clamp to `[1, 200]`. If `n < 1`, error and abort.
69
+ 3. If `--vault <name>` is set: assert `name` matches `^[a-zA-Z0-9_\-]{1,64}$`. If not, error and abort.
70
+ 4. If `--auto` is set without `--apply`: log the warning "`--auto` is a no-op without `--apply`" and proceed.
71
+
72
+ ## Cursor memory schema
73
+
74
+ The resumable cursor is a single MuninnDB memory in the audited vault — concept `memory-audit:cursor`, with a JSON content body:
75
+
76
+ ```json
77
+ {
78
+ "vault": "<resolved-vault-name>",
79
+ "cursor": "<opaque-string-or-empty>",
80
+ "lastRunAt": "<ISO-timestamp-or-empty>",
81
+ "judgedByTier": { "verified": 0, "inferred": 0, "external": 0, "untrusted": 0 },
82
+ "appliedByTier": { "verified": 0, "inferred": 0 },
83
+ "totalProcessed": 0,
84
+ "complete": false
85
+ }
86
+ ```
87
+
88
+ Field semantics:
89
+
90
+ - `vault` — pinned at first run. Compared against the resolved vault on every resume; a mismatch aborts the run.
91
+ - `lastRunAt` — empty string `""` on a fresh seed. Set to the current ISO timestamp in Step 6 immediately before persisting. The 24-hour idempotency guard in Step 1 reads this field and only fires when it is non-empty.
92
+ - `judgedByTier` — count of judgments emitted (incremented for every engram processed, regardless of mode).
93
+ - `appliedByTier` — count of `mcp__muninn__muninn_trust` calls that returned successfully (only `verified`/`inferred` tiers are mutated, so only those keys exist).
94
+ - `totalProcessed` — running total of engrams visited.
95
+ - `complete` — set `true` when both the primary and semantic passes exhaust their cursors.
96
+
97
+ ## Step 1 — Resolve vault and load the cursor
98
+
99
+ 1. Resolve the vault: read `.luca/config.json` → `muninn.vault`; fall back to `"default"`. If `--vault <name>` was passed and differs from the config-derived value, prefer `--vault` and log: "Using --vault override; differs from .luca/config.json".
100
+ 2. Recall the cursor: `mcp__muninn__muninn_recall({ vault: <resolvedVault>, context: ["memory-audit:cursor"], mode: "recent", limit: 1 })`. If `--resume` is set and a `memory-audit:cursor` memory is found, parse the latest one's JSON content as the cursor state. Otherwise seed a fresh state:
101
+ ```
102
+ { vault: <resolvedVault>, cursor: "", lastRunAt: "",
103
+ judgedByTier: {verified:0,inferred:0,external:0,untrusted:0},
104
+ appliedByTier: {verified:0,inferred:0},
105
+ totalProcessed: 0, complete: false }
106
+ ```
107
+ 3. **Vault drift guard (always-on)**: if a cursor was loaded AND `cursor.vault` is non-empty AND `cursor.vault !== resolvedVault`, abort with: "Vault mismatch: the memory-audit:cursor was created for vault '<cursor.vault>' but current resolution is '<resolvedVault>'. Pass --vault <cursor.vault> to resume against the original vault."
108
+ 4. Validate the parsed cursor shape: `vault` a non-empty string matching the vault regex, `cursor` a string with `length <= 4096`, `complete` a boolean, `totalProcessed` a non-negative integer. On a validation failure, treat the cursor as corrupt: seed a fresh state and log a warning in the report. Do not abort — re-scanning is safer than propagating a tampered cursor.
109
+ 5. Idempotency guard: if `cursor.complete === true` AND `cursor.lastRunAt !== ""` AND parsing `cursor.lastRunAt` yields a timestamp within the last 24 hours, emit a no-op report ("vault was fully audited at <lastRunAt>; no work to do; new memories added since then may not have been audited") and exit. Do not call any MCP tool.
110
+
111
+ ## Step 2 — Pre-apply confirmation gate
112
+
113
+ If `--apply` is in effect AND `--auto` is NOT set, before paginating, prompt with `AskUserQuestion`:
114
+
115
+ > About to mutate trust tiers in vault '<resolvedVault>' with `--apply`. Trust changes are last-write-wins and effectively irreversible. Proceed (asking before each verified promotion or demotion), or abort and rerun with `--dry-run` to preview?
116
+
117
+ Options: **Proceed** (continue; confirm per promotion) / **Abort** (stop now).
118
+
119
+ If the user aborts, exit cleanly. If `--auto` is set, skip this gate and proceed.
120
+
121
+ ## Step 3 — Paginate the vault (hybrid cursor + semantic)
122
+
123
+ The MCP surface does **not** expose a generic `muninn_list`. Use a hybrid pass:
124
+
125
+ 1. **Primary cursor pass** — call `mcp__muninn__muninn_get_enrichment_candidates({ vault, cursor: <cursor.cursor>, limit: <argLimit> })`. Iterate via `next_cursor` until exhausted or `--limit` reached. Walks under-enriched memories in ULID order.
126
+ 2. **Semantic complement pass** (optional, only when the primary is exhausted in this run) — `mcp__muninn__muninn_recall({ vault, context: ["audit-coverage"], mode: "deep", limit: <argLimit>, threshold: 0.1 })` plus a few diverse contexts to surface enriched memories the primary pass would miss. The `trust` field is included on each result — read it directly.
127
+
128
+ For each batch, collect `{id, concept, content, summary, currentTrust}` tuples. **Skip any memory whose `concept` starts with `memory-audit:`** — that is the skill's own bookkeeping, not vault content. Cap each LLM-judging round at 15 memories — if `argLimit > 15` or the MCP call returns more, split into sub-batches of 15 before judging.
129
+
130
+ ## Step 4 — LLM-judge the batch against the tier rule
131
+
132
+ For each batch, judge each engram against the tier rule above. Produce per-memory:
133
+
134
+ ```json
135
+ {
136
+ "id": "<ULID>",
137
+ "concept": "<short label>",
138
+ "previousTrust": "verified|inferred|external|untrusted",
139
+ "proposedTrust": "verified|inferred|external|untrusted",
140
+ "rationale": "<one-sentence explanation citing the rule>"
141
+ }
142
+ ```
143
+
144
+ Rules:
145
+
146
+ - If `previousTrust === "external"`: emit `proposedTrust: "external"` (untouched).
147
+ - If `previousTrust === "untrusted"`: emit `proposedTrust: "untrusted"` (untouched; reserved for human).
148
+ - If the engram passes the citation-presence check: `proposedTrust: "verified"`.
149
+ - Otherwise: `proposedTrust: "inferred"`.
150
+
151
+ Increment `judgedByTier[proposedTrust] += 1` for every emitted judgment. `judgedByTier` tracks all four tiers; `appliedByTier` tracks only `verified` and `inferred` because Step 5 only calls `mcp__muninn__muninn_trust` when `proposedTrust !== previousTrust` AND `proposedTrust ∈ {verified, inferred}`.
152
+
153
+ When `--apply` is set AND `--auto` is NOT set, before applying a `verified` promotion OR a `verified → inferred` demotion, prompt with `AskUserQuestion`:
154
+
155
+ > `<promote|demote>` engram `<id>` ('<concept>') from `<previousTrust>` to `<proposedTrust>`? Cited evidence: `<quote>`
156
+
157
+ Options: **Approve** (apply the trust change) / **Skip** (leave at `previousTrust`).
158
+
159
+ If `--auto` is set, the citation-presence check is the sole gate.
160
+
161
+ ## Step 5 — Apply trust corrections (gated)
162
+
163
+ For each judgment where `proposedTrust !== previousTrust` AND the proposed tier is `verified` or `inferred`:
164
+
165
+ - If `--apply` is NOT in effect (dry-run): **do not call** `mcp__muninn__muninn_trust`. Log the proposed change in the report only. Do not increment `appliedByTier`.
166
+ - If `--apply` is in effect: call `mcp__muninn__muninn_trust({ id, trust: proposedTrust, vault })` for each id, sequentially. After each call returns successfully, increment `appliedByTier[proposedTrust] += 1`.
167
+
168
+ Increment `totalProcessed += batchSize` regardless of mode.
169
+
170
+ ## Step 6 — Persist the cursor and emit the report
171
+
172
+ **Ordering invariant**: write the cursor only AFTER all `mcp__muninn__muninn_trust` calls in the batch return. The cursor is **batch-granular** — if any trust call fails, log the failure in the report, do not advance the cursor, and exit. The next `--resume` re-processes the entire batch; `mcp__muninn__muninn_trust` is last-write-wins, so re-trusting the same tier is a no-op.
173
+
174
+ 1. Update `cursor.cursor` to the latest `next_cursor`. If the primary pass is exhausted and the semantic complement is also done, set `cursor.complete = true`.
175
+ 2. Set `cursor.lastRunAt` to the current ISO timestamp. Required — without it, the 24-hour idempotency guard in Step 1 cannot fire on the next run.
176
+ 3. Persist the cursor: `mcp__muninn__muninn_remember({ vault, concept: "memory-audit:cursor", content: JSON.stringify(cursor) })`. This is the ONLY permitted `muninn_remember` call. The latest `memory-audit:cursor` memory wins on the next `--resume` recall.
177
+ 4. Emit the per-run report **inline** in your response (the `.luca/` contract has no slot for audit report files):
178
+
179
+ ```markdown
180
+ # Memory Audit — <lastRunAt>
181
+
182
+ **Vault**: <vault>
183
+ **Mode**: <dry-run|apply>
184
+ **Batch processed**: <N>
185
+ **Cursor advanced**: <fromCursor> → <toCursor>
186
+
187
+ ## Judgments
188
+
189
+ | id | concept | previousTrust | proposedTrust | rationale |
190
+ |----|---------|---------------|---------------|-----------|
191
+ | 01KR... | research:foo | inferred | verified | Content cites src/foo.ts:42 + URL https://... |
192
+
193
+ ## Totals
194
+
195
+ - Judged this run: verified=<n>, inferred=<n>, external=<n> (untouched), untrusted=<n> (untouched)
196
+ - Applied this run: verified=<n>, inferred=<n>
197
+ - Cumulative processed: <totalProcessed>
198
+ ```
199
+
200
+ ## Step 7 — Resume / completion
201
+
202
+ - If `cursor.complete === false` and the user did not pass `--limit`: print "More work remaining; run `/memory-audit --resume` to continue."
203
+ - If `cursor.complete === true`: print "Audit complete. The vault was walked at <lastRunAt>. New memories added since then may not have been audited; rerun after 24 h for a delta re-audit."
204
+ - On any error from an MCP call, persist the current cursor (Step 6) and exit with the error context in the report. Do not silently retry.
205
+
206
+ ## Failure modes
207
+
208
+ | Symptom | Cause | Fix |
209
+ |---------|-------|-----|
210
+ | `memory-audit:cursor` recalled with a different `vault` than the current resolution | Vault changed under the skill (config drift or `--vault` override) | Abort per Step 1.3; instruct the user to pass a matching `--vault` |
211
+ | `mcp__muninn__muninn_remember` fails for the cursor | MuninnDB write error | Report the failure; the next `--resume` re-recalls the last good cursor and re-processes the batch (idempotent re-trust makes this safe) |
212
+
213
+ ## Caveats
214
+
215
+ - The audit is non-exhaustive — it covers under-enriched memories via the cursor plus a semantic-recall complement. Fully-enriched memories not surfaced by recall queries may not be visited until a `muninn_list_all` surface exists.
216
+ - Trust corrections are last-write-wins. The durable record is the trust tier in MuninnDB itself plus the cumulative counters on the `memory-audit:cursor` memory; per-run judgment detail is shown inline only.
217
+ - Re-running on a complete vault produces a no-op summary; the skill does not re-walk unless 24 h have elapsed since `lastRunAt`. Memories added after `complete` was set will not be visited until then.