@ctxr/skill-llm-wiki 1.0.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 (75) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/LICENSE +21 -0
  3. package/README.md +484 -0
  4. package/SKILL.md +252 -0
  5. package/guide/basics/concepts.md +74 -0
  6. package/guide/basics/index.md +45 -0
  7. package/guide/basics/schema.md +140 -0
  8. package/guide/cli.md +256 -0
  9. package/guide/correctness/index.md +45 -0
  10. package/guide/correctness/invariants.md +89 -0
  11. package/guide/correctness/safety.md +96 -0
  12. package/guide/history/diff.md +110 -0
  13. package/guide/history/hidden-git.md +130 -0
  14. package/guide/history/index.md +52 -0
  15. package/guide/history/remote-sync.md +113 -0
  16. package/guide/index.md +134 -0
  17. package/guide/isolation/coexistence.md +134 -0
  18. package/guide/isolation/index.md +44 -0
  19. package/guide/isolation/scale.md +251 -0
  20. package/guide/layout/in-place-mode.md +97 -0
  21. package/guide/layout/index.md +53 -0
  22. package/guide/layout/layout-contract.md +131 -0
  23. package/guide/layout/layout-modes.md +115 -0
  24. package/guide/operations/index.md +76 -0
  25. package/guide/operations/ingest/build.md +75 -0
  26. package/guide/operations/ingest/extend.md +61 -0
  27. package/guide/operations/ingest/index.md +54 -0
  28. package/guide/operations/ingest/join.md +65 -0
  29. package/guide/operations/maintain/fix.md +66 -0
  30. package/guide/operations/maintain/index.md +47 -0
  31. package/guide/operations/maintain/rebuild.md +86 -0
  32. package/guide/operations/validate.md +48 -0
  33. package/guide/substrate/index.md +47 -0
  34. package/guide/substrate/operators.md +96 -0
  35. package/guide/substrate/tiered-ai.md +363 -0
  36. package/guide/ux/index.md +44 -0
  37. package/guide/ux/preflight.md +150 -0
  38. package/guide/ux/user-intent.md +135 -0
  39. package/package.json +55 -0
  40. package/scripts/cli.mjs +893 -0
  41. package/scripts/commands/remote.mjs +93 -0
  42. package/scripts/commands/review.mjs +253 -0
  43. package/scripts/commands/sync.mjs +84 -0
  44. package/scripts/lib/chunk.mjs +421 -0
  45. package/scripts/lib/cluster-detect.mjs +516 -0
  46. package/scripts/lib/decision-log.mjs +343 -0
  47. package/scripts/lib/draft.mjs +158 -0
  48. package/scripts/lib/embeddings.mjs +366 -0
  49. package/scripts/lib/frontmatter.mjs +497 -0
  50. package/scripts/lib/git-commands.mjs +155 -0
  51. package/scripts/lib/git.mjs +486 -0
  52. package/scripts/lib/gitignore.mjs +62 -0
  53. package/scripts/lib/history.mjs +331 -0
  54. package/scripts/lib/indices.mjs +510 -0
  55. package/scripts/lib/ingest.mjs +258 -0
  56. package/scripts/lib/intent.mjs +713 -0
  57. package/scripts/lib/interactive.mjs +99 -0
  58. package/scripts/lib/migrate.mjs +126 -0
  59. package/scripts/lib/nest-applier.mjs +260 -0
  60. package/scripts/lib/operators.mjs +1365 -0
  61. package/scripts/lib/orchestrator.mjs +718 -0
  62. package/scripts/lib/paths.mjs +197 -0
  63. package/scripts/lib/preflight.mjs +213 -0
  64. package/scripts/lib/provenance.mjs +672 -0
  65. package/scripts/lib/quality-metric.mjs +269 -0
  66. package/scripts/lib/query-fixture.mjs +71 -0
  67. package/scripts/lib/rollback.mjs +95 -0
  68. package/scripts/lib/shape-check.mjs +172 -0
  69. package/scripts/lib/similarity-cache.mjs +126 -0
  70. package/scripts/lib/similarity.mjs +230 -0
  71. package/scripts/lib/snapshot.mjs +54 -0
  72. package/scripts/lib/source-frontmatter.mjs +85 -0
  73. package/scripts/lib/tier2-protocol.mjs +470 -0
  74. package/scripts/lib/tiered.mjs +453 -0
  75. package/scripts/lib/validate.mjs +362 -0
package/guide/cli.md ADDED
@@ -0,0 +1,256 @@
1
+ ---
2
+ id: cli
3
+ type: primary
4
+ depth_role: leaf
5
+ focus: "complete CLI subcommand reference for scripts/cli.mjs"
6
+ parents:
7
+ - index.md
8
+ covers:
9
+ - "top-level operations: build, extend, validate, rebuild (+ --review), fix, join"
10
+ - "rollback and migrate: reversible history, legacy .llmwiki.vN auto-migration"
11
+ - "hidden-git plumbing: log (+ --op), show, diff (+ --op), blame, reflog, history"
12
+ - "remote mirroring: remote add/list/remove, sync with tag-only default refspec"
13
+ - "layout mode flags (--layout-mode sibling|in-place|hosted, --target)"
14
+ - "tiered-AI flags (--quality-mode tiered-fast|claude-first|tier0-only)"
15
+ - "UX flags (--no-prompt, --json-errors, --accept-dirty, --accept-foreign-target, --review)"
16
+ - "internal helpers: ingest, draft-leaf, draft-category, index-rebuild, index-rebuild-one, shape-check"
17
+ - "exit code summary (0 ok, 1 usage, 2 validation/ambiguity/review-abort, 3 resolve miss, 4 node too old, 5 git missing/too old, 6 wiki corrupt, 7 NEEDS_TIER2 suspend-and-resume, 8 DEPS_MISSING runtime dependency missing)"
18
+ tags:
19
+ - cli
20
+ - commands
21
+ - reference
22
+ activation:
23
+ keyword_matches:
24
+ - cli
25
+ - command
26
+ - subcommand
27
+ - build
28
+ - extend
29
+ - rebuild
30
+ - fix
31
+ - join
32
+ - validate
33
+ - rollback
34
+ - migrate
35
+ - diff
36
+ - log
37
+ - show
38
+ - blame
39
+ - reflog
40
+ - history
41
+ - remote
42
+ - sync
43
+ - ingest
44
+ - shape-check
45
+ - index-rebuild
46
+ - draft-leaf
47
+ tag_matches:
48
+ - any-op
49
+ escalation_from:
50
+ - build
51
+ - extend
52
+ - validate
53
+ - rebuild
54
+ - fix
55
+ - join
56
+ source:
57
+ origin: file
58
+ path: cli.md
59
+ hash: "sha256:d26a2c5e19a7257aa7febd2f04f26db8df89debf44e7ea20a9be0db9136c7f7c"
60
+ ---
61
+
62
+
63
+ # CLI subcommand reference
64
+
65
+ All subcommands are invoked via `node scripts/cli.mjs <subcommand> [args]`. Never read the source of any `.mjs` file — everything you need is documented here.
66
+
67
+ The CLI exits with code **4** if invoked on Node.js < 18.0.0, code **5** if git is missing or older than 2.25, and code **6** if an existing wiki's private repo is corrupt (fsck failure). These are defence-in-depth runtime guards — always run the Bash preflight from SKILL.md first so the user sees the detailed, actionable message.
68
+
69
+ All git invocations run under the isolation env (see `guide/coexistence.md`): no hooks, no system config, no global config, no GPG signing, no askpass. Remote URLs in every echoed line and error message are redacted via `redactUrl`.
70
+
71
+ ## Top-level operations
72
+
73
+ Every top-level operation resolves its intent via `scripts/lib/intent.mjs` and may refuse with an `INT-NN` structured error if the invocation is ambiguous (see `guide/user-intent.md`). All accept the layout-mode / tiered-AI / UX flags documented at the bottom of this file.
74
+
75
+ ### `build <source> [--layout-mode <mode>] [--target <path>]`
76
+
77
+ Create a new wiki from a source corpus.
78
+
79
+ - **Default** — writes to a sibling `<source>.wiki/`. Initialises `.llmwiki/git/` on first use, takes a `pre-op/<op-id>` snapshot, runs ingest → draft-frontmatter → operator-convergence → index-generation → validation → commit-finalize, tags `op/<op-id>`.
80
+ - `--layout-mode in-place` — transforms `<source>/` itself; `pre-op/<op-id>` captures the original content byte-for-byte so the operation is reversible via `rollback`.
81
+ - `--layout-mode hosted --target <path>` — writes under a user-chosen path that has a `.llmwiki.layout.yaml` contract.
82
+ - **Exit codes:** 0 on success; 2 on intent ambiguity or validation failure; 6 on wiki-corrupt preflight.
83
+
84
+ ### `extend <wiki> <source> [flags]`
85
+
86
+ Add a new source corpus to an existing wiki. The wiki keeps its layout mode; `extend` appends commits under a new `op/<op-id>` tag.
87
+
88
+ ### `validate <wiki>`
89
+
90
+ Run all hard invariants against a wiki. Read-only. Prints one `[TAG] CODE target` line per finding plus a `N error(s), M warning(s)` summary.
91
+
92
+ - **Exit codes:** 0 if clean, 2 if any errors, 6 if the private git is corrupt.
93
+ - **Invariants:** see `guide/invariants.md`. `GIT-01` and `LOSS-01` are guarded on the presence of `.llmwiki/git/HEAD` and `.llmwiki/provenance.yaml` respectively.
94
+
95
+ ### `rebuild <wiki> [--review]`
96
+
97
+ Re-run operator convergence on an existing wiki to optimise for token-efficiency. Same phase pipeline as build.
98
+
99
+ - `--review` — between operator convergence and validation, print `git diff --stat pre-op/<id>..HEAD` and the per-iteration commit list; prompt the user for approve / abort / `drop:<sha>`. Drops become `git revert --no-edit` commits and the loop re-prompts so the user can drop multiple iterations before approving. Requires a TTY; non-interactive sessions fall through with `outcome: "non-interactive"` and no changes.
100
+ - **Abort** resets the working tree to `pre-op/<id>` and exits with code 2.
101
+
102
+ ### `fix <wiki>`
103
+
104
+ Repair methodology divergences detected by `validate` / `shape-check`. AUTO-class fixes are deterministic; AI-ASSIST fixes ask Claude at session-time to draft content; HUMAN-class divergences surface as structured prompts for the user to resolve. *(Currently a minimal build-forward stub; full fix pipeline — with a dedicated INT error code for HUMAN-class findings — is future work. Today, HUMAN findings are raised as plain validation errors and the user reruns fix after correcting the upstream cause.)*
105
+
106
+ ### `join <target> <wiki-a> <wiki-b> [<wiki-c> …]`
107
+
108
+ Merge two or more wikis into one unified wiki at `<target>`. Requires an explicit canonical designation (multi-source `join` without ordering raises `INT-07`). *(Currently a stub; full join pipeline is future work.)*
109
+
110
+ ### `rollback <wiki> --to <ref>`
111
+
112
+ Restore the wiki's working tree to a prior commit, destructively (`git reset --hard` + `git clean -fd`). Never touches the private git metadata.
113
+
114
+ - `<ref>` accepts: `<op-id>` (state after that op finished), `pre-<op-id>` (state before that op started — maps to the `pre-op/<op-id>` tag), `genesis` (the very first tracked state), or any git ref expression (`HEAD~2`, etc).
115
+ - Refs starting with `-` or containing control characters are refused at the boundary (security D2 guard).
116
+ - **Exit codes:** 0 on success; 2 if the ref cannot be parsed or does not exist.
117
+
118
+ ### `migrate <legacy-wiki>`
119
+
120
+ Convert a pre-Phase-2 `<source>.llmwiki.v<N>/` wiki to the new `<source>.wiki/` layout. Copies the directory's content into the new sibling, initialises `.llmwiki/git/`, commits as genesis, and tags `op/<opId>`. The legacy directory is left untouched; the user prunes it manually later. Always prompts before proceeding (`INT-04`).
121
+
122
+ ## Hidden-git plumbing
123
+
124
+ Read-only introspection subcommands that run `git` under the isolation env against the wiki's private repo. Claude uses these when the user asks "what changed", "when did this break", "why was this split".
125
+
126
+ ### `log <wiki> [--op <id>] [git-log-args…]`
127
+
128
+ `git log` passthrough. Default output is `--oneline --decorate --all`.
129
+
130
+ - `--op <id>` narrows the range to `pre-op/<id>..op/<id>` (or `pre-op/<id>..HEAD` for an in-flight operation), matching `diff --op` sugar.
131
+ - Additional git-log args pass through (`-p`, `-n`, `--format=%H`, etc.).
132
+ - **Exit codes:** 0 on success, 2 if `--op` names a non-existent pre-op tag.
133
+
134
+ ### `show <wiki> <ref> [-- <path>]`
135
+
136
+ `git show` passthrough. Display the contents of a commit, tree, blob, or tag.
137
+
138
+ ### `diff <wiki> [--op <id>] [git-diff-args…]`
139
+
140
+ `git diff` passthrough. The wrapper adds `--find-renames --find-copies` by default so rename/copy detection is on (this means the output is byte-identical to `git diff --find-renames --find-copies`, not to a plain `git diff`).
141
+
142
+ - `--op <id>` expands to `pre-op/<id>..op/<id>` (or `pre-op/<id>..HEAD`).
143
+ - Additional git-diff args pass through (`--stat`, `--name-status`, `--patch`, etc.).
144
+
145
+ ### `blame <wiki> <path> [git-blame-args…]`
146
+
147
+ `git blame` passthrough for line-level attribution.
148
+
149
+ ### `reflog <wiki> [git-reflog-args…]`
150
+
151
+ `git reflog` passthrough. Surfaces even aborted operations — crucial for debugging a Build that crashed mid-convergence.
152
+
153
+ ### `history <wiki> <entry-id>`
154
+
155
+ Higher-level wrapper: walks `<wiki>/.llmwiki/op-log.yaml` for op-level references to the entry, then runs `git log --oneline --follow` on any file matching `**/<entry-id>.md` to catch renames across operations. Produces a two-section report.
156
+
157
+ ## Remote mirroring
158
+
159
+ Optional: push the private git's tag history to a bare remote the user manages. The skill never auto-pushes; `sync` is always explicit.
160
+
161
+ ### `remote <wiki> add <name> <url>`
162
+
163
+ Configure a remote. The URL is redacted on both the success line and any error message (security B3).
164
+
165
+ ### `remote <wiki> list`
166
+
167
+ List configured remotes as `name\tfetch-url\tpush-url`. URLs redacted.
168
+
169
+ ### `remote <wiki> remove <name>`
170
+
171
+ Delete a configured remote.
172
+
173
+ ### `sync <wiki> [--remote <name>] [--push-branch <branch>] [--skip-fetch] [--skip-push]`
174
+
175
+ Fetch tags from the remote (read side), then push the private repo's `op/*` and `pre-op/*` tags (write side). Default push refspec is tag-only so the remote is a read-only history mirror rather than a competing branch HEAD.
176
+
177
+ - `--remote <name>` — which configured remote to talk to (default `origin`).
178
+ - `--push-branch <branch>` — additionally push `refs/heads/<branch>`. Validated against `^[A-Za-z0-9][A-Za-z0-9._/-]*$` to block refspec injection (security D7).
179
+ - `--skip-fetch` / `--skip-push` — one-sided sync.
180
+
181
+ ## Internal helpers
182
+
183
+ These are called by orchestrated phases; users rarely invoke them directly. Documented for completeness.
184
+
185
+ ### `ingest <source>`
186
+
187
+ Walks a source directory, computes content hashes, emits an array of entry candidates.
188
+
189
+ - **Output (stdout, JSON):** `{ "candidates": [ {id, source_path, absolute_path, ext, size, hash, kind, title, lead, headings}, … ] }`.
190
+ - **Determinism:** walk order is sorted by path; symlinks are dropped (directories and files only).
191
+
192
+ ### `draft-leaf <candidate-file>`
193
+
194
+ Script-first frontmatter draft for a single candidate.
195
+
196
+ - **Output (stdout, JSON):** `{ "data": <frontmatter-object>, "confidence": <0..1>, "needs_ai": <boolean> }`.
197
+
198
+ ### `draft-category <candidate-file>`
199
+
200
+ Deterministic category hint by directory prefix.
201
+
202
+ ### `index-rebuild <wiki>`
203
+
204
+ Regenerate every `index.md` in a wiki, bottom-up. Preserves authored frontmatter fields and authored body content; replaces derived fields and the auto-generated navigation zone.
205
+
206
+ ### `index-rebuild-one <dir> <wiki>`
207
+
208
+ Rebuild a single directory's `index.md`.
209
+
210
+ ### `shape-check <wiki>`
211
+
212
+ Detect operator candidates and write findings to `<wiki>/.shape/suggestions.md`. Never touches the private git (the hook-mode path has an explicit no-git contract).
213
+
214
+ ### Legacy `.llmwiki.vN` helpers
215
+
216
+ These subcommands survived the Phase 2 migration for backward compatibility with pre-Phase-2 wikis that still use the versioned-sibling naming. New wikis should not use them.
217
+
218
+ - `resolve-wiki <source>` — print current live wiki path for a legacy source. Exit 3 if none exists.
219
+ - `next-version <source>` — print the next version tag (e.g. `v3`).
220
+ - `list-versions <source>` — print `<tag>\t<absolute-path>` per existing version.
221
+ - `set-current <source> <version>` — update the current-pointer file.
222
+
223
+ ## Layout mode flags
224
+
225
+ All top-level operations accept:
226
+
227
+ - `--layout-mode sibling|in-place|hosted` — select layout mode. Default `sibling`. Unknown values raise `INT-10`.
228
+ - `--target <path>` — explicit destination. Required for `hosted` mode; raises `INT-09a` if combined with `in-place`, `INT-09b` if missing for `hosted`.
229
+ - `--accept-foreign-target` — deliberate override to write into a non-empty non-skill-managed directory (escape hatch for `INT-01b`).
230
+
231
+ ## Tiered-AI flags
232
+
233
+ - `--quality-mode tiered-fast|claude-first|tier0-only` — select the escalation policy. Default `tiered-fast` (TF-IDF → MiniLM embeddings → Claude). `tier0-only` never calls Claude, never loads Tier 1; mid-band pairs become "undecidable" markers the user resolves interactively. Unknown values raise `INT-13`.
234
+
235
+ ## UX flags
236
+
237
+ - `--no-prompt` / env `LLM_WIKI_NO_PROMPT=1` — fail loudly on any ambiguity instead of prompting; emits `INT-12` if the skill would otherwise ask a TTY question.
238
+ - `--json-errors` — emit `INT-NN` ambiguity errors as JSON on stderr instead of numbered-options text.
239
+ - `--accept-dirty` — operate on a source inside a dirty user git repo (escape hatch for `INT-08`).
240
+ - `--review` — enable the `rebuild` interactive review cycle. See `guide/operations/rebuild.md`.
241
+
242
+ ## `--version` / `--help`
243
+
244
+ Print the CLI version string or a condensed command list.
245
+
246
+ ## Exit code summary
247
+
248
+ - **0** — success
249
+ - **1** — usage error (missing/bad arguments, unknown subcommand)
250
+ - **2** — validation errors, intent ambiguity (`INT-NN`), review abort, or a malformed rollback ref
251
+ - **3** — legacy `resolve-wiki` could not find a wiki for the given source
252
+ - **4** — Node.js is present but below the required minimum (defence-in-depth runtime guard)
253
+ - **5** — `git` binary missing or older than 2.25 (preflight)
254
+ - **6** — existing wiki's private git is corrupt (`git fsck` failed during preflight)
255
+ - **7** — `NEEDS_TIER2` — the operator-convergence phase accumulated Tier 2 requests (cluster naming, mid-band merge decisions, …) that must be resolved by the wiki-runner sub-agent before the operation can continue. **Exit 7 is NOT a failure.** It is the suspend-and-resume signal of the Tier 2 exit-7 handshake. The CLI writes every pending batch to `<wiki>/.work/tier2/pending-<batch-id>.json` before exiting; the wiki-runner spawns one `Agent` sub-agent per request, writes responses to `<wiki>/.work/tier2/responses-<batch-id>.json` next to the pending file, and re-invokes the CLI with the same positional args. See `guide/tiered-ai.md` "The exit-7 handshake" for details.
256
+ - **8** — `DEPS_MISSING` — a required runtime dependency (`gray-matter` or `@xenova/transformers`) could not be resolved from the skill's `node_modules/` and the install attempt was either declined (interactive `[Y/n]` answered `n`) or failed (`npm install` non-zero exit, or the deps were still missing after a successful install). The dependency preflight runs at the start of every subcommand except `--version` and `--help`; in non-interactive sessions (`!process.stdin.isTTY` or `LLM_WIKI_NO_PROMPT=1`) it attempts `npm install --silent` automatically before giving up. See `guide/ux/preflight.md` Case E for the full user-facing message and recovery steps.
@@ -0,0 +1,45 @@
1
+ ---
2
+ id: correctness
3
+ type: index
4
+ depth_role: subcategory
5
+ depth: 1
6
+ focus: Hard invariants, validation, and the safety envelope around every mutation.
7
+ parents:
8
+ - "../index.md"
9
+ shared_covers: []
10
+ entries:
11
+ - id: invariants
12
+ file: invariants.md
13
+ type: primary
14
+ focus: hard validation invariants and soft shape signals for LLM wikis
15
+ tags:
16
+ - validation
17
+ - invariants
18
+ - shape-check
19
+ - id: safety
20
+ file: safety.md
21
+ type: primary
22
+ focus: safety envelope, phase-commit pipeline, and commit semantics for every operation
23
+ tags:
24
+ - safety
25
+ - pipeline
26
+ - commit
27
+ children: []
28
+ ---
29
+ <!-- BEGIN AUTO-GENERATED NAVIGATION -->
30
+
31
+ # Correctness
32
+
33
+ **Focus:** Hard invariants, validation, and the safety envelope around every mutation.
34
+
35
+ ## Children
36
+
37
+ | File | Type | Focus |
38
+ |------|------|-------|
39
+ | [invariants.md](invariants.md) | 📄 primary | hard validation invariants and soft shape signals for LLM wikis |
40
+ | [safety.md](safety.md) | 📄 primary | safety envelope, phase-commit pipeline, and commit semantics for every operation |
41
+
42
+ <!-- END AUTO-GENERATED NAVIGATION -->
43
+
44
+ <!-- BEGIN AUTHORED ORIENTATION -->
45
+ <!-- END AUTHORED ORIENTATION -->
@@ -0,0 +1,89 @@
1
+ ---
2
+ id: invariants
3
+ type: primary
4
+ depth_role: leaf
5
+ focus: hard validation invariants and soft shape signals for LLM wikis
6
+ parents:
7
+ - index.md
8
+ covers:
9
+ - "22 hard invariants checked by `cli.mjs validate` — including id/filename match, narrowing chain, DAG acyclicity, canonical-parent consistency, parent-file contract, size caps, GIT-01 private-git integrity, and LOSS-01 byte-range coverage"
10
+ - "soft shape signals reported by `cli.mjs shape-check` (DECOMPOSE, NEST, MERGE, LIFT, DESCEND candidates, coverage holes, golden-path regressions)"
11
+ - "hosted-mode layering: contract global_invariants add to the methodology defaults"
12
+ - "how to read the validate report (TAG, CODE, path, severity)"
13
+ - "exit codes: 0 clean, 2 errors, warnings do not change exit"
14
+ tags:
15
+ - validation
16
+ - invariants
17
+ - shape-check
18
+ activation:
19
+ keyword_matches:
20
+ - invariant
21
+ - validate
22
+ - validation
23
+ - errors
24
+ - check
25
+ - verify
26
+ tag_matches:
27
+ - validating
28
+ - fixing
29
+ escalation_from:
30
+ - build
31
+ - extend
32
+ - validate
33
+ - rebuild
34
+ - fix
35
+ - join
36
+ source:
37
+ origin: file
38
+ path: invariants.md
39
+ hash: "sha256:878f4f2bb2254330df2276c12c6dce8d263693d9f45865469db55508ed8b8373"
40
+ ---
41
+
42
+ # Validation invariants
43
+
44
+ ## Hard invariants (checked by `node scripts/cli.mjs validate`)
45
+
46
+ All of these are hard errors and block commit:
47
+
48
+ 1. Every entry has required frontmatter fields for its `type`.
49
+ 2. `id` matches filename (leaves) or directory name (indices).
50
+ 3. `depth_role` matches actual tree depth.
51
+ 4. Strict narrowing chain along canonical `parents[0]` up to the root.
52
+ 5. Every `entries[]` reference in an index resolves to an on-disk file.
53
+ 6. Every `overlay_targets` resolves to an existing primary id or alias.
54
+ 7. Every `links[].id` resolves to an existing id or alias.
55
+ 8. Non-root entries have non-empty `parents[]`.
56
+ 9. DAG acyclicity — `parents[]` never forms a cycle.
57
+ 10. Canonical-parent consistency — entry lives inside `parents[0]`'s directory.
58
+ 11. No duplicate ids; aliases don't collide with live ids.
59
+ 12. Size caps: primaries ≤ 500 lines, overlays ≤ 200 lines.
60
+ 13. Parent file contract — index body authored zone ≤ 2 KB, no leaf-content signatures.
61
+ 14. Every directory containing entries has a valid `index.md`.
62
+ 15. No entry at depth > 0 outside an indexed directory.
63
+ 16. Every relative markdown link in bodies resolves.
64
+ 17. Counts in human-facing summaries match actual entry counts.
65
+ 18. Stale-index detection — no leaf mtime newer than its containing index's mtime.
66
+ 19. Source integrity — if `source.hash` is set, current upstream hash must match.
67
+ 20. Cross-reference coherence — every soft-parent cross-reference resolves to a real canonical entry.
68
+ 21. **`GIT-01` — private-git integrity.** Guarded on `<wiki>/.llmwiki/git/HEAD`. Requires `git fsck --no-dangling --no-reflogs` to succeed under the isolation env; when the op-log has at least one entry, the most recent logged op's `pre-op/<op-id>` tag must exist and be reachable from HEAD.
69
+ 22. **`LOSS-01` — byte-range coverage.** Guarded on `<wiki>/.llmwiki/provenance.yaml`. For every source file in the manifest, the sum of `sources[].byte_range` lengths across every target plus `discarded_ranges[].byte_range` lengths must equal the manifest-recorded `source_size`, with no overlapping ranges. Source sizes come from the manifest (captured at ingest time) so the check runs without needing the original source tree.
70
+
71
+ Pre-Phase-2 wikis that never ran through git-backed history remain valid — both `GIT-01` and `LOSS-01` are guarded on the presence of their underlying artifacts and silently skip when those artifacts are absent. The root `generator: skill-llm-wiki/v1` check is enforced as part of `isWikiRoot` rather than as a numbered invariant (the validator refuses to run against a non-wiki target at all).
72
+
73
+ In hosted mode, add the contract's `global_invariants` to this list. See `guide/layout-contract.md`.
74
+
75
+ ## Soft shape signals (reported by `node scripts/cli.mjs shape-check`)
76
+
77
+ Non-blocking suggestions that feed the next Rebuild:
78
+
79
+ - **DECOMPOSE candidate**: `covers[]` clusters into disjoint groups, or exceeds 12 items.
80
+ - **NEST candidate**: ≥3 H2 sections each a strict narrowing, or `nests_into[]` is set.
81
+ - **MERGE candidate**: sibling pair with high focus similarity and >70% covers overlap.
82
+ - **LIFT candidate**: folder contains exactly one non-index entry.
83
+ - **DESCEND candidate**: index body authored zone exceeds budget or contains leaf signatures.
84
+ - **Coverage hole**: `shared_covers[]` empty or no overlap with children.
85
+ - **Golden-path regression**: a fixture's load set grew vs. the previous version.
86
+
87
+ ## Reading the validate report
88
+
89
+ The `validate` CLI prints one `[TAG] CODE path` line per finding, then a summary `N error(s), M warning(s)`. Exit 0 = clean, exit 2 = errors. Relay every finding to the user with the code and the affected path so they can locate the problem.
@@ -0,0 +1,96 @@
1
+ ---
2
+ id: safety
3
+ type: primary
4
+ depth_role: leaf
5
+ focus: safety envelope, phase-commit pipeline, and commit semantics for every operation
6
+ parents:
7
+ - index.md
8
+ covers:
9
+ - "source immutability in sibling/hosted modes; in-place mode anchored by pre-op snapshot"
10
+ - ".work/ staging convention: ephemeral phase scratch, deleted at commit-finalize"
11
+ - per-phase git commits as the durable audit trail on the private repo
12
+ - full validator must pass before commit-finalize; otherwise reset to pre-op and preserve prior state
13
+ - "atomic commit semantics across sibling / in-place / hosted modes via git tags"
14
+ - "rollback to any pre-op/<id> tag via `skill-llm-wiki rollback <wiki> --to pre-<id>`"
15
+ - "backup before structural mutation in hosted mode (backup_before_mutate default true)"
16
+ tags:
17
+ - safety
18
+ - pipeline
19
+ - commit
20
+ activation:
21
+ keyword_matches:
22
+ - safety
23
+ - envelope
24
+ - commit
25
+ - backup
26
+ - rollback
27
+ tag_matches:
28
+ - mutation
29
+ - any-op
30
+ escalation_from:
31
+ - build
32
+ - extend
33
+ - rebuild
34
+ - fix
35
+ - join
36
+ source:
37
+ origin: file
38
+ path: safety.md
39
+ hash: "sha256:9272b85ad1de923fe74d5a3a61a44eb2156f5cd2e56ded323b27cf45afd4f067"
40
+ ---
41
+
42
+ # Safety envelope and phased pipeline
43
+
44
+ Every operation honors these rules. Break any of them and you have broken the skill.
45
+
46
+ ## Hard rules
47
+
48
+ 1. **Sibling / hosted modes: source is immutable.** Never write inside the user's source folder. Ever.
49
+ 2. **In-place mode: the pre-op snapshot is the rollback anchor.** The user's original content is captured byte-for-byte by `pre-op/<op-id>` before the operation starts, so every change is reversible via `rollback`.
50
+ 3. **Hosted mode: contract defines the write surface.** Write only into directories the contract permits. Never create directories outside the contract. Never place entries in violation of its rules.
51
+ 4. **Every phase is a git commit.** The private repo at `<wiki>/.llmwiki/git/` takes a `pre-op/<op-id>` snapshot before the operation starts and commits after every subsequent phase. `git log pre-op/<id>..HEAD` is the complete per-phase audit trail for the operation.
52
+ 5. **Run the full validator before commit-finalize.** Any hard-invariant violation triggers `git reset --hard pre-op/<id>` + `git clean -fd`. The failed phase commits survive in the reflog for post-mortem; the working tree returns to the pre-op state exactly.
53
+ 6. **Atomic commit-finalize.** Tagging `op/<op-id>` and appending to the op-log are the last operations. Until the tag exists, the operation is still reversible in one command.
54
+ 7. **Backup before structural mutation in hosted mode.** If the contract has `backup_before_mutate: true`, snapshot the target tree to `<backup_dir>/<timestamp>/` before Rebuild/Fix/Join apply.
55
+
56
+ ## Phase-commit audit trail and rollback
57
+
58
+ Every long-running operation runs as a named sequence of phases. Each phase (and each operator-convergence iteration) is a git commit in the private repo at `<wiki>/.llmwiki/git/`, so the complete history of "what the skill did during this operation" is introspectable via `skill-llm-wiki log --op <id>`, `skill-llm-wiki diff --op <id>`, and `skill-llm-wiki reflog <wiki>`. An interrupted operation leaves partial phase commits behind; they survive in the git reflog, and the user can roll back to `pre-op/<id>` in one command to restore the pre-op state exactly.
59
+
60
+ The `.work/` directory is scratch space used by phases that need to stage intermediate artifacts (candidate JSON, partial plans). It is **not** the durable audit layer — the git commits are. `.work/` is created at the start of an operation and deleted at commit-finalize.
61
+
62
+ > **Future work.** A true mid-phase resume (`skill-llm-wiki resume <wiki>` that picks up from the last committed phase rather than restarting the whole operation) is scoped but not implemented. The current orchestrator treats a re-invocation after a crash as a fresh operation; the user rolls back to `pre-op/<id>` from the prior attempt, then re-runs.
63
+
64
+ ## Commit semantics by mode
65
+
66
+ **Sibling mode (default, Phase 2+):**
67
+
68
+ - Wiki lives at `<source>.wiki/` as a single directory — no version-numbered
69
+ folders. History is tracked by the private git repo at
70
+ `<source>.wiki/.llmwiki/git/`, and rollback is `skill-llm-wiki rollback
71
+ <source>.wiki --to pre-<op-id>` (byte-exact via `git reset --hard`).
72
+ - See [guide/layout-modes.md](layout-modes.md) for the full mode matrix and
73
+ [guide/in-place-mode.md](in-place-mode.md) for the in-place variant. Legacy
74
+ `<source>.llmwiki.v<N>/` wikis are detected via **INT-04** and must be
75
+ migrated explicitly with `skill-llm-wiki migrate <legacy-path>` before any
76
+ other operation will run.
77
+
78
+ **Legacy free mode (pre–Phase 2):**
79
+
80
+ - New version directory is created alongside the source (e.g. `<source>.llmwiki.v<N+1>/`).
81
+ - All staged content is moved atomically into place.
82
+ - The current-pointer file is updated (`echo v<N+1> > <source>.llmwiki.current`).
83
+ - Previous version remains on disk; rollback is just flipping the pointer back.
84
+
85
+ **Hosted mode, `versioning.style: in-place`:**
86
+
87
+ - Before any structural mutation (Rebuild, Fix, Join apply), snapshot the target to `<backup_dir>/<timestamp>/`.
88
+ - Apply staged content directly into the contract's directories.
89
+ - Rollback is restoring the backup snapshot.
90
+
91
+ **Hosted mode, `versioning.style: sibling-versioned`:**
92
+
93
+ - Same as free mode, but content inside each version honors the contract's layout rules.
94
+ - The sibling directory is named after the target (not the source), and the current-pointer lives next to it.
95
+
96
+ In every mode, if validation fails before commit, the `.work/` staging is preserved for the user to inspect but the live wiki is untouched.
@@ -0,0 +1,110 @@
1
+ ---
2
+ id: diff
3
+ type: primary
4
+ depth_role: leaf
5
+ focus: the diff subcommand — git-style file-level changes for any operation
6
+ parents:
7
+ - index.md
8
+ covers:
9
+ - "skill-llm-wiki diff <wiki> runs git diff --find-renames --find-copies under the isolation env"
10
+ - "--op <id> expands to pre-op/<id>..op/<id> so you can see exactly what an operation changed"
11
+ - without --op, shows unstaged working-tree changes since the last commit
12
+ - "all remaining args pass through to git diff unchanged (--stat, --name-status, -M, --patch, etc.)"
13
+ - "tag namespace: pre-op/<id> is the pre-op anchor, op/<id> is the finalised commit"
14
+ - rename detection is on by default — no need to pass -M explicitly
15
+ tags:
16
+ - history
17
+ - diff
18
+ activation:
19
+ keyword_matches:
20
+ - diff
21
+ - changes
22
+ - what changed
23
+ - renamed
24
+ - moved
25
+ - review
26
+ - "--stat"
27
+ - "--name-status"
28
+ tag_matches:
29
+ - history
30
+ escalation_from:
31
+ - log
32
+ - show
33
+ - rebuild
34
+ - rollback
35
+ source:
36
+ origin: file
37
+ path: diff.md
38
+ hash: "sha256:48b6d8002c7dc53ec81a57505d8efa15599d19c7010c7e67841a62a0406f4a82"
39
+ ---
40
+
41
+ # `skill-llm-wiki diff`
42
+
43
+ A thin wrapper around `git diff` in the wiki's private repo. The
44
+ wrapper adds two things:
45
+
46
+ 1. **Rename detection is on by default.** Every invocation passes
47
+ `--find-renames --find-copies`, so operator moves (NEST / LIFT /
48
+ MERGE) show up as rename edges in `--stat` and `--name-status`.
49
+ 2. **`--op <id>` expands to a commit range.** If you pass
50
+ `--op build-20260414-abc123`, the wrapper resolves that to
51
+ `pre-op/build-20260414-abc123..op/build-20260414-abc123` — exactly
52
+ the range that covers what the operation did. If the operation did
53
+ not complete (validation failure rolled back), the range is
54
+ `pre-op/<id>..HEAD` instead.
55
+
56
+ ## Common invocations
57
+
58
+ ```text
59
+ # What did the last operation do, file-by-file?
60
+ skill-llm-wiki diff <wiki> --op <last-op-id> --stat
61
+
62
+ # Name-status view with rename letters (R100 = 100% rename, M = modified):
63
+ skill-llm-wiki diff <wiki> --op <last-op-id> --name-status
64
+
65
+ # Full patch of a specific entry across an operation:
66
+ skill-llm-wiki diff <wiki> --op <last-op-id> -- <path/to/entry.md>
67
+
68
+ # Compare two operations directly:
69
+ skill-llm-wiki diff <wiki> op/<first-op-id>..op/<second-op-id> --stat
70
+
71
+ # What's dirty in the working tree right now?
72
+ skill-llm-wiki diff <wiki>
73
+ ```
74
+
75
+ ## Rename detection in practice
76
+
77
+ When a NEST operator extracts an H2 section into its own leaf, the
78
+ original file is rewritten and a new file appears. Git's rename
79
+ detector (`-M`, `-C`) will report this as a pair with similarity
80
+ percentage:
81
+
82
+ ```text
83
+ R087 old/entry.md → new/extracted-section.md
84
+ M old/entry.md
85
+ ```
86
+
87
+ A percentage ≥ 50 on `R` is git's default threshold for "this is a
88
+ rename". If the operator reshaped the content heavily, the percentage
89
+ drops and git shows it as `add` + `delete` instead — still informative,
90
+ just less condensed.
91
+
92
+ ## Scale note
93
+
94
+ On a multi-megabyte wiki, `diff --op <id>` remains cheap because git
95
+ diffs are computed at the object layer, not the working-tree layer.
96
+ Even when the operation touches thousands of files, `--stat` runs in
97
+ tens of milliseconds. For `--patch` output on a huge op, pipe through
98
+ a pager or narrow with a path argument.
99
+
100
+ ## What this does NOT do
101
+
102
+ - Run against the user's own git repo. `<wiki>` is always the skill's
103
+ private repo rooted at `<wiki>/.llmwiki/git/`.
104
+ - Show logical diffs (e.g. "this entry's covers[] grew by 3 items").
105
+ For that, parse the frontmatter yourself via `scripts/lib/frontmatter.mjs`
106
+ or walk the index.md tables via `scripts/lib/indices.mjs`.
107
+ - Replace `log` or `history`. Use `log` to see the commit sequence,
108
+ `history <entry-id>` to trace one entry's lineage across op-log
109
+ entries, and `diff` to see file-level changes within one op or
110
+ between two ops.