@fenglimg/fabric-cli 2.2.0-rc.3 → 2.2.0-rc.8

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/README.md +8 -5
  2. package/dist/{chunk-5LQIHYFC.js → chunk-27HK6H5Y.js} +10 -5
  3. package/dist/{chunk-F6ITRM7T.js → chunk-2KBCTMID.js} +29 -6
  4. package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
  5. package/dist/{chunk-XHHCRDIR.js → chunk-CMDW3PYK.js} +105 -220
  6. package/dist/chunk-FEOPLBGA.js +150 -0
  7. package/dist/{chunk-XCBVSGCS.js → chunk-FNHDQTPC.js} +1 -10
  8. package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
  9. package/dist/{doctor-J4O3X54I.js → chunk-JTHWLUD3.js} +103 -51
  10. package/dist/{chunk-BO4XIZWZ.js → chunk-NLNH64A3.js} +5 -18
  11. package/dist/{chunk-H3FE6VIK.js → chunk-PTGQAZEW.js} +13 -3
  12. package/dist/chunk-QFIVFZRH.js +13 -0
  13. package/dist/chunk-QPAW6IYT.js +387 -0
  14. package/dist/{chunk-COI5VDFU.js → chunk-WA3DYGSY.js} +1 -2
  15. package/dist/{plan-context-hint-CHVZGOZ5.js → chunk-YM4XATJF.js} +29 -4
  16. package/dist/{config-VJMXCLXW.js → config-A3LTECAY.js} +4 -3
  17. package/dist/context-7NUKXDB6.js +117 -0
  18. package/dist/doctor-REZDNH4A.js +24 -0
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +131 -21
  21. package/dist/info-7FKBTMVO.js +139 -0
  22. package/dist/install-v2-2COC3DO3.js +3277 -0
  23. package/dist/{metrics-RER6NLFC.js → metrics-HMFH4YHK.js} +1 -1
  24. package/dist/{onboard-coverage-JWQWDZW7.js → onboard-coverage-XSG77LL3.js} +48 -27
  25. package/dist/plan-context-hint-G75R4P4J.js +12 -0
  26. package/dist/{scope-explain-BWRWBCCP.js → scope-explain-HLJZ2M33.js} +3 -2
  27. package/dist/{status-PANEGKU2.js → status-4R3TM4FJ.js} +8 -5
  28. package/dist/store-HOCORVL3.js +563 -0
  29. package/dist/{sync-EA5HZMXM.js → sync-DT5UJMMR.js} +36 -13
  30. package/dist/{uninstall-F75MPKQC.js → uninstall-62F4LNKI.js} +62 -140
  31. package/dist/{whoami-66YKY5DZ.js → whoami-ITGEFWH4.js} +9 -7
  32. package/package.json +7 -5
  33. package/templates/hooks/cite-policy-evict.cjs +5 -5
  34. package/templates/hooks/configs/README.md +14 -27
  35. package/templates/hooks/configs/claude-code.json +1 -1
  36. package/templates/hooks/configs/codex-hooks.json +3 -3
  37. package/templates/hooks/fabric-hint.cjs +301 -161
  38. package/templates/hooks/knowledge-hint-broad.cjs +426 -207
  39. package/templates/hooks/knowledge-hint-narrow.cjs +56 -56
  40. package/templates/hooks/lib/banner-i18n.cjs +31 -0
  41. package/templates/hooks/lib/bindings-snapshot-reader.cjs +117 -7
  42. package/templates/hooks/lib/cite-line-parser.cjs +12 -20
  43. package/templates/hooks/lib/client-adapter.cjs +66 -7
  44. package/templates/hooks/lib/nudge-policy.cjs +117 -0
  45. package/templates/hooks/lib/state-store.cjs +60 -0
  46. package/templates/hooks/lib/summary-fallback.cjs +82 -19
  47. package/templates/hooks/post-tooluse-mutation.cjs +112 -11
  48. package/templates/skills/fabric/SKILL.md +94 -0
  49. package/templates/skills/fabric-archive/SKILL.md +29 -26
  50. package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
  51. package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
  52. package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
  53. package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
  54. package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
  55. package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
  56. package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
  57. package/templates/skills/fabric-audit/SKILL.md +13 -3
  58. package/templates/skills/fabric-connect/SKILL.md +3 -3
  59. package/templates/skills/fabric-import/SKILL.md +7 -7
  60. package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
  61. package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
  62. package/templates/skills/fabric-review/SKILL.md +5 -5
  63. package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
  64. package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
  65. package/templates/skills/fabric-review/ref/output-contract.md +1 -1
  66. package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
  67. package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
  68. package/templates/skills/fabric-store/SKILL.md +1 -1
  69. package/templates/skills/fabric-sync/SKILL.md +1 -1
  70. package/templates/skills/lib/shared-policy.md +2 -2
  71. package/dist/chunk-5ZUMLCD5.js +0 -248
  72. package/dist/install-BULNDUIM.js +0 -2816
  73. package/dist/store-66NK2FTQ.js +0 -443
  74. package/templates/hooks/configs/cursor-hooks.json +0 -30
  75. package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fabric-archive
3
- description: 归档对话洞察到 .fabric/knowledge/pending (NOT code review). Triggers 以后/always/never/下次/记一下;wrong-turn-revert;decision-confirm;dismissal-reason;/fabric-archive.
3
+ description: 归档对话洞察到 active write store 的 pending knowledge (NOT code review). Triggers 以后/always/never/下次/记一下;wrong-turn-revert;decision-confirm;dismissal-reason;/fabric-archive.
4
4
  allowed-tools: Read, Glob, Grep, Bash, mcp__fabric__fab_extract_knowledge
5
5
  ---
6
6
 
@@ -25,19 +25,19 @@ This skill runs automatically — it does not interview the user for preferences
25
25
 
26
26
  ## 执行流程 (1 User Review Round)
27
27
 
28
- v2.0.0-rc.37 NEW-9 collapsed the flow to **3 macro-phases**; the legacy fine-grained phases survive as labelled sub-steps (back-compat for `ref/` navigation + existing traces):
28
+ rc.37 NEW-9 collapsed the flow to **3 macro-phases**; the legacy fine-grained phases survive as labelled sub-steps:
29
29
 
30
- - **GATHER** = Phase 0 (range) → 0.5 (config) → 1 (ledger scan via `fab_archive_scan`) → [1.5 onboard] → 2 (candidates). Resolve scope, load config, deterministically scan the ledger for in-scope sessions, collect candidate observations.
31
- - **REVIEW** = Phase 2.5 (viability gate — abort guard) → 3 (classify / layer / slug + batch review) → 3.5 (scope + relevance_paths). The single user review round lives here.
30
+ - **GATHER** = Phase 0 (range) → 0.5 (config) → 1 (ledger scan via `fab_archive_scan`) → [1.5 onboard] → 2 (candidates).
31
+ - **REVIEW** = Phase 2.5 (viability gate) → 3 (classify / layer / slug + batch review) → 3.5 (relevance scope + relevance_paths) → 3.7 (semantic scope / audience axis). The single user review round lives here.
32
32
  - **PERSIST** = Phase 4 (`fab_extract_knowledge`, one call per candidate) → 4.5 (archive-attempt ledger).
33
33
 
34
- Sub-step chain: `0 → 0.5 → 1 → [1.5] → 2 → 2.5 → 3 → 3.5 → 4 → 4.5`. Each below is a navigator stub — full procedure, decision tables, and worked examples live in `ref/`.
34
+ Sub-step chain: `0 → 0.5 → 1 → [1.5] → 2 → 2.5 → 3 → 3.5 → 3.7 → 4 → 4.5`. Each below is a navigator stub — full procedure, decision tables, and worked examples live in `ref/`.
35
35
 
36
36
  ### Phase 0 — Range Resolution
37
37
 
38
38
  Parse user's prompt for time-window (`今日` / `last week`), topic keyword (`rc.20`), or literal `session_id` reference; emit `session_id[]` OR `"all"` sentinel that constrains Phase 1 collection. LLM-as-parser contract — no parser code.
39
39
 
40
- `Read ref/phase-0-range-resolution.md` for the HIGH/MEDIUM/LOW/PARSE-MISS confidence decision rule (rc.33), Step 1 inspection table, bilingual time-window patterns (zh-CN + en), topic-keyword extraction, session_id resolution pseudocode, AskUserQuestion fallback (E2/E4 only), and 3 worked examples.
40
+ `Read ref/phase-0-range-resolution.md` for the confidence decision rule, bilingual time-window patterns, session_id resolution, AskUserQuestion fallback, and worked examples.
41
41
 
42
42
  ### Phase 0.5 — Config Load
43
43
 
@@ -45,7 +45,7 @@ Read `.fabric/fabric-config.json`; resolve `archive_max_candidates_per_batch` (d
45
45
 
46
46
  ### Phase 0.6 — Store routing (v2.1 multi-store)
47
47
 
48
- Archives land in the **active write store** for the entry's scope — NEVER pick a store yourself. Run `fabric scope-explain team` (or the relevant scope) to get the resolved `writeTarget` (alias + UUID); that is where `fab_extract_knowledge` persists. Single-store / no global config → the lone store (back-compat). After persisting, **echo the target store alias** to the user (`归档到 store '<alias>'`). Personal-scope entries route to the personal store (never the shared team store, R5#3). Do NOT read `~/.fabric` store trees directly — go through `scope-explain` / the MCP write path.
48
+ Archives land in the **active write store** for the entry's scope — NEVER pick a store yourself. Run `fabric scope-explain team` (or the relevant scope) to get the resolved `writeTarget`; that is where `fab_extract_knowledge` persists. Single-store → the lone store (back-compat). After persisting, **echo the target store alias** (`归档到 store '<alias>'`). Personal-scope entries route to the personal store (never the shared team store, R5#3). Do NOT read `~/.fabric` store trees directly — go through `scope-explain` / the MCP write path.
49
49
 
50
50
  ### UX i18n Policy
51
51
 
@@ -65,7 +65,7 @@ The deterministic ledger scan now runs **server-side** — call `fab_archive_sca
65
65
 
66
66
  Then (LLM side, Boundary B): for each returned `session_id`, load `.fabric/.cache/session-digests/<session_id>.md`, concatenate into a `### Cross-session digest` block, and populate `source_sessions[]` + `session_context` for Phase 4. Cap at `archive_digest_max_sessions`. Missing digest files degrade silently.
67
67
 
68
- `Read ref/phase-1-cross-session.md` for the (now server-side) filter state machine rules + the digest-stitch + graceful-degradation notes. The hand-rolled `tail -n 200` events.jsonl scan is retired — `fab_archive_scan` is the source of truth for which sessions to load.
68
+ `Read ref/phase-1-cross-session.md` for the filter state machine + digest-stitch + graceful-degradation notes. The hand-rolled `tail -n 200` scan is retired — `fab_archive_scan` is the source of truth.
69
69
 
70
70
  Graceful degradation: missing digest cache → single-session fallback. Missing `session_archive_attempted` events (pre-rc.25) → legacy "scan everything since anchor" behaviour.
71
71
 
@@ -81,17 +81,13 @@ Gather raw evidence: tail `.fabric/events.jsonl` since last `knowledge_proposed`
81
81
 
82
82
  ### Phase 2.5 — Viability Gate (Anti-Archive Guard)
83
83
 
84
- Coarse viability check. **PASS conditions**: user_explicit_invoke OR ≥1 archive signal hit. v2.0.0-rc.37 NEW-4 simplifies the legacy 8-signal list into **3 major categories** (each maps to multiple legacy signals for back-compat scoring):
84
+ Coarse viability check. **PASS**: user_explicit_invoke OR ≥1 archive signal hit. rc.37 NEW-4 folds the legacy 8 signals into **3 categories**: (1) **User-driven knowledge expression** (normative language `always`/`never`/`以后`/`记一下`/`永远不要`, OR decision-with-rationale, OR dismissal-with-reason); (2) **Reflective discovery** (wrong-turn-and-revert, OR long diagnostic loop, OR a named reusable pattern); (3) **Concrete artifact change** (new dependency diff, OR a formalized multi-step procedure).
85
85
 
86
- 1. **User-driven knowledge expression** user message contains normative language (`always`/`never`/`from now on`/`下次注意`/`记一下`/`以后`/`永远不要`), OR user weighed ≥2 alternatives and gave rationale (decision confirmation), OR user explicitly dismissed an approach AND stated why (dismissal-with-reason). Legacy signals #1 + #6 + #7.
87
- 2. **Reflective discovery** — AI tried path X, reflected, then took path Y (wrong-turn-and-revert); OR a long diagnostic loop (>15 min / >10 turns) surfaced a non-obvious cause; OR a reusable pattern was named in the session ("the X phase", "the Y pattern"). Legacy signals #2 + #3 + #5.
88
- 3. **Concrete artifact change** — a new dependency was added (package.json/pyproject.toml/Cargo.toml diff), OR a load-bearing multi-step procedure was formalized in a specific order. Legacy signals #4 + #8.
86
+ Pre-PASS HARD gate (rc.37 NEW-4): per candidate, run `fab_review action="search"` against the mounted read-set; duplicate canonical drop the candidate (anti-signal #4). Silently writing a near-duplicate is the highest-noise failure mode.
89
87
 
90
- Pre-PASS MUST step (rc.37 NEW-4): for each candidate, run a quick `Glob` over `.fabric/knowledge/**/*.md` keyed on slug-stem to check for duplicate canonical entry. If duplicate found → drop candidate (treat as anti-signal #4 'duplicate of existing canonical'). This is a HARD gate, not advisory — silently writing a near-duplicate is the highest-noise failure mode.
88
+ **FAIL branch**: E1/E3/E5 silent-skip (`outcome='skipped_no_signal'`); E2/E4 render gate-FAIL (`outcome='viability_failed'`) and MUST include the force-archive escape hatch (zh-CN: `如需强制归档,请显式调用 fabric-archive` / en: `To force-archive, explicitly invoke fabric-archive`).
91
89
 
92
- **FAIL → branch by entry_point**: E1/E3/E5 silent-skip (emit Phase 4.5 event `outcome='skipped_no_signal'`); E2/E4 render gate-FAIL message (emit `outcome='viability_failed'`). Gate-FAIL message for E2/E4 MUST include the "to force-archive, explicitly invoke fabric-archive" remediation pointer so the user has an unambiguous escape hatch when the gate misclassifies (zh-CN: `如需强制归档,请显式调用 fabric-archive` / en: `To force-archive, explicitly invoke fabric-archive`).
93
-
94
- `Read ref/phase-2-5-viability.md` for verbose signal definitions, zh-CN/en gate-FAIL message bodies, anti-archive signals (typo / refactor / rename / duplicate), and the events.jsonl 4KB POSIX atomicity constraint.
90
+ `Read ref/phase-2-5-viability.md` for verbose signal definitions, full gate-FAIL bodies, anti-archive signals, and the events.jsonl 4KB POSIX atomicity constraint.
95
91
 
96
92
  ### Phase 3 — Classify, Layer, Slug, Review
97
93
 
@@ -105,27 +101,33 @@ For each candidate, propose **type** ∈ {model, decision, guideline, pitfall, p
105
101
 
106
102
  Resolution: 强 team first; assign personal only if 强 personal dominates AND no 强 team applies; else default team.
107
103
 
108
- `Read ref/phase-3-classify.md` for per-type worth-archive vs skip signals with positive/negative examples, slug pass/fail samples, decision tree, en + zh-CN batch review templates. User MAY inline-edit `type` / `layer` / `slug` / `relevance_scope` / `relevance_paths` before confirming; scope edits trigger Phase 3.5 re-derivation.
104
+ `Read ref/phase-3-classify.md` for per-type worth-archive vs skip signals, slug samples, decision tree, and en + zh-CN batch review templates. User MAY inline-edit `type` / `layer` / `slug` / `relevance_scope` / `relevance_paths` / `semantic_scope` before confirming; scope edits trigger Phase 3.5 re-derivation.
109
105
 
110
106
  ### Phase 3.5 — Scope Decision + relevance_paths Derivation
111
107
 
112
108
  Assign `relevance_scope` ∈ {narrow, broad} + derive `relevance_paths` BEFORE batch review. **narrow** = candidate tied to specific module/file with single-module evidence in edit_paths; **broad** = cross-cutting/methodological/general (default on uncertainty). **Personal layer ALWAYS forces broad + `relevance_paths=[]`** (cross-project, paths don't generalize).
113
109
 
114
- `Read ref/phase-3-5-scope.md` for the 6-step relevance_paths derivation pseudocode (COLLECT → DEDUPE → BLACKLIST → PUBLIC-PREFIX GENERALIZE → SCOPE GATE → ATTACH READ-ONLY EVIDENCE), worked example (5 sample paths → glob + literal output), and narrow↔broad inline-edit re-derivation rules.
110
+ `Read ref/phase-3-5-scope.md` for the 6-step relevance_paths derivation pseudocode, the worked example, and narrow↔broad inline-edit re-derivation rules.
115
111
 
116
112
  ### Phase 3.6 — Related-edge Extraction (§7 graph generation)
117
113
 
118
- For each candidate, identify the **`related`** graph edges to other KB entries — the store-qualified `stable_id`s this entry semantically links to (the decision it supersedes, the pitfall it explains, the model it instantiates). You discovered these ids during the session via `fab_recall` / plan-context, so cite the ones you actually saw, NEVER invent stable_ids. Because `fab_extract_knowledge` has no dedicated `related` input, record the candidate edges as one line inside `session_context` (e.g. `related: team:KT-DEC-0007, team:KT-PIT-0011`) so they survive to approve-time frontmatter authoring (`fabric-review` writes the canonical `related: [...]` frontmatter).
114
+ For each candidate, record the `related` graph edges (store-qualified `stable_id`s this entry links to) as one line inside `session_context` (e.g. `related: team:KT-DEC-0007`) so they survive to approve-time frontmatter authoring. Cite only ids you actually saw via `fab_recall` NEVER invent. **§4 privacy iron law: `KT→KP` is FORBIDDEN** (a team entry MUST NOT point at a personal id); when unsure a target is personal, OMIT the edge.
115
+
116
+ `Read ref/phase-3-6-related-edges.md` for the allowed/forbidden edge matrix and worked examples.
117
+
118
+ ### Phase 3.7 — Semantic scope (audience axis, multi-project)
119
+
120
+ Sets the entry's **audience** `semantic_scope` (orthogonal to `layer`=store and `relevance_scope`=display). ONLY when `layer=team` AND `.fabric/fabric-config.json` has a non-empty `active_project`; else SKIP — the engine derives it. Default = OMIT → `project:<active_project>` (this-project-only). Escape hatch: pass explicit `semantic_scope: team` to keep a cross-project team-wide entry from being narrowed to this project. Phase 3 picks the STORE; this picks the AUDIENCE within the team store.
119
121
 
120
- **§4 privacy iron law — KT→KP is FORBIDDEN.** A **team** (`KT-*`) entry's `related` MUST NOT point at a **personal** (`KP-*`) id: that would write a personal-knowledge topology pointer into the project's shared physical ledger (`./.fabric/agents.meta.json`). Allowed: `KT→KT`, `KP→KP`, `KP→KT`. Forbidden: `KT→KP` only. When unsure whether a target is personal, OMIT the edge. (The meta-builder also strips any KT→KP edge that slips through, but do not rely on that — author clean edges.)
122
+ `Read ref/phase-3-7-semantic-scope.md` for the three-axis model, the this-project-only vs team-wide decision tree, and worked examples.
121
123
 
122
124
  ### Phase 4 — Persist via MCP
123
125
 
124
- For each user-confirmed candidate, call `fab_extract_knowledge` ONCE (NEVER batch). Required: `source_sessions[]`, `recent_paths[]` (cap 20), `user_messages_summary`, `type` (plural form: decisions/pitfalls/guidelines/models/processes), `slug`, `layer`, `relevance_scope`, `relevance_paths[]`, `proposed_reason` (enum), `session_context` (3-5 line narrative). Four OPTIONAL rc.23 triage fields (`intent_clues`, `tech_stack`, `impact`, `must_read_if`) — populate when clean, **omit rather than guess**.
126
+ For each user-confirmed candidate, call `fab_extract_knowledge` ONCE (NEVER batch). Required: `source_sessions[]`, `recent_paths[]` (cap 20), `user_messages_summary`, `type` (plural form: decisions/pitfalls/guidelines/models/processes), `slug`, `layer`, `relevance_scope`, `relevance_paths[]`, `proposed_reason` (enum), `session_context` (3-5 line narrative). One OPTIONAL audience field: `semantic_scope` — pass `team` ONLY when Phase 3.7 classified a team candidate as team-wide (cross-project); OMIT otherwise so the engine auto-derives `project:<active_project>` (or `team` when the repo has no `active_project`). Four OPTIONAL rc.23 triage fields (`intent_clues`, `tech_stack`, `impact`, `must_read_if`) — populate when clean, **omit rather than guess**.
125
127
 
126
128
  Server returns `{ pending_path, idempotency_key }`. Display `pending_path` for the user. `idempotency_key = sha256({source_session, type, slug})` — repeated calls SAFE (server merges evidence).
127
129
 
128
- `Read ref/phase-4-mcp-persist.md` for full TypeScript call shape, C1 triage-field inference table, Phase 2.5 signal → `proposed_reason` mapping, `session_context` format, T5 array-form idempotency notes.
130
+ `Read ref/phase-4-mcp-persist.md` for the full call shape, C1 triage-field inference table, signal → `proposed_reason` mapping, and idempotency notes.
129
131
 
130
132
  ### Phase 4.5 — Persist Archive Attempt
131
133
 
@@ -133,7 +135,7 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
133
135
 
134
136
  **Dry-run override**: SKIPS the `session_archive_attempted` emit entirely; read-side runs normally so user previews what WOULD have been written. See unified `## Dry-run Scope` pointer below.
135
137
 
136
- `Read ref/phase-4-5-emit.md` for the full event jsonc shape, 4-state outcome decision matrix (outcome × candidates_proposed × knowledge_proposed_ids), `covered_through_ts` watermark spec, multi-session emission rule, bash echo append pattern, and E5-cron silent-skip worked trace.
138
+ `Read ref/phase-4-5-emit.md` for the full event shape, 4-state outcome decision matrix, `covered_through_ts` watermark spec, multi-session emission rule, and E5-cron silent-skip trace.
137
139
 
138
140
  ## Hard Rules (DO NOT TRANSLATE) — DISPLAY / WRITE Split
139
141
 
@@ -144,16 +146,17 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
144
146
  - MUST present every candidate with explicit `[type=...]`, `[layer=...]`, `[relevance_scope=...]`, and `slug=...` fields plus a `relevance_paths` line.
145
147
  - MUST include a one-line `Layer reasoning:` for each candidate citing which 强 team / 强 personal signal applied (or default team).
146
148
  - MUST include a one-line `Scope reasoning:` for each candidate citing why narrow or broad was chosen (or that personal forced broad).
149
+ - WHEN `active_project` is set AND `layer=team`, MUST present `[semantic_scope=...]` (`team` for team-wide, or `project:<active_project>` for this-project-only) plus a one-line `Audience reasoning:` citing this-project-only vs team-wide (Phase 3.7).
147
150
  - MUST classify against the canonical singular nouns: model / decision / guideline / pitfall / process. NEVER invent new types.
148
151
  - MUST cap the batch at `archive_max_candidates_per_batch` candidates (config-resolved, default 8); drop weaker ones over the cap.
149
152
  - MUST display the resolved `pending_path` returned by `fab_extract_knowledge` so the user can verify.
150
- - MUST treat user inline edits to type/layer/slug/relevance_scope/relevance_paths as authoritative replacements before Phase 2.
153
+ - MUST treat user inline edits to type/layer/slug/relevance_scope/relevance_paths/semantic_scope as authoritative replacements before Phase 2.
151
154
  - MUST skip rather than guess when an observation does not fit any of the 5 types.
152
155
 
153
156
  ### WRITE Rules
154
157
 
155
158
  - NEVER write a knowledge entry directly to the filesystem; the only legal write path is `mcp__fabric__fab_extract_knowledge`.
156
- - NEVER write outside `.fabric/knowledge/pending/` — promotion to `.fabric/knowledge/<type>/` is rc.3 fab_review concern, NOT this skill.
159
+ - NEVER infer or glob a project-local pending directory persist through `fab_extract_knowledge` and use the returned store-resolved `pending_path`; promotion to canonical knowledge is fab_review concern, NOT this skill.
157
160
  - NEVER include an `id` field anywhere — pending entries have no id (late-bind on approve).
158
161
  - NEVER classify a candidate as `personal` when a 强 team signal applies. Default to team on ambiguity.
159
162
  - NEVER emit a non-empty `relevance_paths` when `relevance_scope=broad` — broad MUST always carry `relevance_paths=[]`.
@@ -161,7 +164,7 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
161
164
  - v2.0.0-rc.37 NEW-7 widened Phase 3.5: `edit_paths` ∪ `user_mentioned_paths` drives `relevance_paths`; `read_paths` flows separately to `evidence_paths` (structured frontmatter, not body markdown). NEVER lift body regex / symbol extraction into `relevance_paths` — those remain reserved for v2.1+.
162
165
  - NEVER batch multiple candidates into a single fab_extract_knowledge call; one call per candidate.
163
166
  - NEVER paraphrase the verbatim layer heuristic block above — the Chinese text is contract-locked.
164
- - MUST preserve protected tokens exactly: `stable_id`, `knowledge_proposed`, `knowledge_archive_aborted`, `knowledge_scope_degraded`, `.fabric/knowledge/pending/`, `fab_extract_knowledge`, `relevance_paths`, `relevance_scope`, `narrow`, `broad`, `edit_paths`, `source_sessions`, `proposed_reason`, `session_context`, `intent_clues`, `tech_stack`, `impact`, `must_read_if`, `pending_path`, `layer`, `team`, `personal`, `MUST`, `NEVER`, `强 team`, `强 personal`, `默认 team`, `related`, `KT→KP`.
167
+ - MUST preserve protected tokens exactly: `stable_id`, `knowledge_proposed`, `knowledge_archive_aborted`, `knowledge_scope_degraded`, `fab_extract_knowledge`, `relevance_paths`, `relevance_scope`, `narrow`, `broad`, `edit_paths`, `source_sessions`, `proposed_reason`, `session_context`, `intent_clues`, `tech_stack`, `impact`, `must_read_if`, `pending_path`, `layer`, `semantic_scope`, `active_project`, `team`, `personal`, `MUST`, `NEVER`, `强 team`, `强 personal`, `默认 team`, `related`, `KT→KP`.
165
168
 
166
169
  ## Worked Examples / E5 Cron / Dry-run (ref-only)
167
170
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Write operation | Normal mode | Dry-run mode |
6
6
  |---|---|---|
7
- | `fab_extract_knowledge` MCP call (Phase 4) | One call per confirmed candidate, writes to `.fabric/knowledge/pending/<slug>.md` | SKIPPED. Phase 4 renders "would write N pending entries" preview table instead. |
7
+ | `fab_extract_knowledge` MCP call (Phase 4) | One call per confirmed candidate, writes to the active write store and returns `pending_path` | SKIPPED. Phase 4 renders "would write N pending entries" preview table instead. |
8
8
  | `session_archive_attempted` event (Phase 4.5) | Appended to `.fabric/events.jsonl` for every session in scope | SKIPPED entirely. No ledger entry. |
9
9
  | `fab_review reject` (Phase 3 user-dismissed branch) | Invoked when user types `撤销` / `reject` after self-archive proposal | SKIPPED. The dismissal is rendered to console but no MCP write occurs. |
10
10
  | `fabric onboard-coverage` slot writes (Phase 1.5 fill-all / dismiss-all) | Each `Bash("fabric config dismiss-slot <slot>")` invocation runs | SKIPPED. Slot decisions are shown as "would dismiss/propose" preview. |
@@ -40,14 +40,14 @@ Rendering rule:
40
40
 
41
41
  - `fabric_language === "zh-CN"` → emit the zh-CN variant; pure monolingual, no language mixing inside a single user-facing block.
42
42
  - `fabric_language === "en"` → emit the en variant; pure monolingual, no language mixing inside a single user-facing block.
43
- - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_get_knowledge_sections`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
43
+ - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_recall`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
44
44
  - `fabric_language === "match-existing"` or any other value → emit the en variant; pure monolingual.
45
45
 
46
46
  Protected tokens (`fab_extract_knowledge`, `relevance_scope`,
47
47
  `relevance_paths`, `narrow`, `broad`, `source_sessions`, `proposed_reason`,
48
48
  `session_context`, `intent_clues`, `tech_stack`, `impact`, `must_read_if`,
49
49
  `pending_path`, `layer`, `team`, `personal`,
50
- `knowledge_scope_degraded`, `MUST`, `NEVER`, `.fabric/knowledge/`, the verbatim
50
+ `knowledge_scope_degraded`, `MUST`, `NEVER`, `knowledge/pending`, the verbatim
51
51
  `强 team` / `强 personal` / `默认 team` heuristic block, etc.) are NEVER
52
52
  translated — they appear verbatim in both language variants. The
53
53
  bilingualization scope is prose ONLY.
@@ -83,4 +83,3 @@ dual-string match (e.g. `if (choice === "team" || choice === "团队")`),
83
83
  which doubles the surface area for protected-token regressions and breaks
84
84
  the option-list invariants that downstream tooling depends on. Keeping
85
85
  `options[]` English-only is contract-locked across all three skills.
86
-
@@ -21,7 +21,7 @@ is the canonical taxonomy for this gate.
21
21
 
22
22
  | Entry | Symbol | Detection rule (LLM-native, evaluated at skill entry) |
23
23
  |-------|--------|-------------------------------------------------------|
24
- | **E1** | `hook_passive` | stdout JSON `{decision:'block', ...}` from `archive-hint.cjs` detected at skill entry (the Stop-hook reminder path). |
24
+ | **E1** | `hook_passive` | stdout JSON `{decision:'block', ...}` from `fabric-hint.cjs` detected at skill entry (the Stop-hook reminder path). |
25
25
  | **E2** | `explicit_user_invoke` | User prompt is a direct invocation: `fabric archive` / `/fabric-archive` / `archive what we just did` / `归档一下` / similar imperative. |
26
26
  | **E3** | `ai_self_trigger` | AI internal marker `self-archive policy triggered by signal: <X>` present (substring match on the verbatim prefix `self-archive policy triggered by signal` per AGENTS.md self-archive policy section; `<X>` is the signal name. v2.0.0-rc.37 NEW-2 simplified the AGENTS.md taxonomy to 2 categories: `User-driven normative` / `Wrong-turn-and-revert`. Back-compat: legacy 4-state names (`Normative` / `Decision confirmation` / `Explicit dismissal`) still route correctly because the substring gate only matches the verbatim prefix and treats any text after `signal:` as the signal label.) |
27
27
  | **E4** | `user_range_rollback` | Prompt contains a **range hint** (parsed in Phase 0 — e.g. `今日` / `上周` / `rc.20`) AND the user is invoking. Sub-mode of E2. |
@@ -83,7 +83,7 @@ $ /fabric-archive
83
83
  ---
84
84
 
85
85
  After F8a removed the auto-`fabric scan` baseline pipeline, a freshly installed
86
- Fabric workspace ships with an EMPTY `.fabric/knowledge/` tree. Five fixed
86
+ Fabric workspace ships with an EMPTY mounted store `knowledge/` tree. Five fixed
87
87
  **S5 onboard slots** capture the "project tone" baseline that the AI needs
88
88
  for high-quality plan_context retrieval from day one:
89
89
 
@@ -215,4 +215,3 @@ mcp__fabric__fab_extract_knowledge({
215
215
  the locked S5 strings (tech-stack-decision / architecture-pattern /
216
216
  code-style-tone / build-system-idiom / domain-vocabulary). The
217
217
  fab_extract_knowledge schema enum will reject anything else.
218
-
@@ -33,7 +33,7 @@ Before Step 5 builds the cross-session context, drop sessions that the outcome l
33
33
 
34
34
  No high-value signal → drop (no new content worth re-scanning, even though the cooldown has expired). Has signal → keep for re-scan.
35
35
  - **(e) Never attempted (no `session_archive_attempted` event found for this `session_id`) → keep.** First-time scan; nothing to filter against.
36
- - **(f) Cross-session pending dedupe** (operates on candidate observations, not on `session_id` filter): gather all `knowledge_proposed_ids` from `session_archive_attempted` events with `outcome === "proposed"` across ALL sessions in the recent window (NOT just the current candidate session). This builds a global set of idempotency keys already proposed by prior archive runs but not yet reviewed by the user (`.fabric/knowledge/pending/` may still contain them). When classifying new observations in Phase 3, drop any candidate whose computed `idempotency_key` matches an id already in this set — it was already proposed by an earlier archive run, the user just hasn't reviewed it yet, so re-proposing would duplicate pending entries and inflate `candidates_proposed` counts. Per Phase 4.5 dedupe consumer of `knowledge_proposed_ids`.
36
+ - **(f) Cross-session pending dedupe** (operates on candidate observations, not on `session_id` filter): gather all `knowledge_proposed_ids` from `session_archive_attempted` events with `outcome === "proposed"` across ALL sessions in the recent window (NOT just the current candidate session). This builds a global set of idempotency keys already proposed by prior archive runs but not yet reviewed by the user (the active write store may still contain matching pending entries). When classifying new observations in Phase 3, drop any candidate whose computed `idempotency_key` matches an id already in this set — it was already proposed by an earlier archive run, the user just hasn't reviewed it yet, so re-proposing would duplicate pending entries and inflate `candidates_proposed` counts. Per Phase 4.5 dedupe consumer of `knowledge_proposed_ids`.
37
37
 
38
38
  The resulting filtered `session_id[]` proceeds into Step 5's digest concatenation. Sessions filtered out in this step do NOT contribute to `### Cross-session digest`, are NOT included in `source_sessions` on any fab_extract_knowledge call, and are NOT referenced in `session_context` bodies.
39
39
 
@@ -36,7 +36,7 @@ These force the gate to FAIL **unless** an archive signal also fires (i.e. anti-
36
36
  1. **Typo-only edits** — the entire session is whitespace / spelling / formatting changes. No semantic content to archive.
37
37
  2. **Pure refactor** — rename / move / extract with no behavior change AND no naming convention being established.
38
38
  3. **Narrow rename request** — user asked to rename one symbol / file with no rationale. Zero generalization potential.
39
- 4. **Duplicate of existing canonical** — v2.0.0-rc.37 NEW-4: this check is now **mandatory** (was "do a quick Glob before deciding"). Pre-PASS MUST step: for each candidate, `Glob('.fabric/knowledge/**/*.md')` keyed on slug-stem. If duplicate found → drop candidate. Silently writing a near-duplicate is the highest-noise failure mode and dwarfs the cost of one extra glob per candidate.
39
+ 4. **Duplicate of existing canonical** — v2.0.0-rc.37 NEW-4: this check is now **mandatory** (was "do a quick Glob before deciding"). Pre-PASS MUST step: for each candidate, call `fab_review action="search"` scoped by type/slug keywords so the MCP read path searches mounted stores. If duplicate found → drop candidate. Silently writing a near-duplicate is the highest-noise failure mode.
40
40
 
41
41
  ## Gate-FAIL user messages (E2 / E4 only)
42
42
 
@@ -0,0 +1,18 @@
1
+ # Phase 3.6 — Related-edge Extraction (§7 graph generation)
2
+
3
+ For each candidate, identify the **`related`** graph edges to other KB entries — the store-qualified `stable_id`s this entry semantically links to (the decision it supersedes, the pitfall it explains, the model it instantiates). You discovered these ids during the session via `fab_recall` / plan-context, so cite the ones you actually saw, NEVER invent stable_ids.
4
+
5
+ Because `fab_extract_knowledge` has no dedicated `related` input, record the candidate edges as one line inside `session_context` (e.g. `related: team:KT-DEC-0007, team:KT-PIT-0011`) so they survive to approve-time frontmatter authoring (`fabric-review` writes the canonical `related: [...]` frontmatter).
6
+
7
+ ## §4 privacy iron law — KT→KP is FORBIDDEN
8
+
9
+ A **team** (`KT-*`) entry's `related` MUST NOT point at a **personal** (`KP-*`) id: that would write a personal-knowledge topology pointer into a shared store.
10
+
11
+ | Edge | Allowed? |
12
+ | --- | --- |
13
+ | `KT→KT` | ✅ |
14
+ | `KP→KP` | ✅ |
15
+ | `KP→KT` | ✅ |
16
+ | `KT→KP` | ❌ FORBIDDEN |
17
+
18
+ When unsure whether a target is personal, OMIT the edge.
@@ -0,0 +1,47 @@
1
+ # Phase 3.7 — Semantic scope (audience axis, multi-project) (ref)
2
+
3
+ > **Loaded on demand.** SKILL.md hot path retains the trigger condition (`layer=team` AND `active_project` set), the default-vs-escape rule, and the `semantic_scope: team` escape hatch. This file holds the store-vs-audience distinction, the this-project-only vs team-wide decision tree, and worked examples.
4
+
5
+ ## The three orthogonal axes (KT-MOD-0001)
6
+
7
+ A knowledge entry is positioned on three independent axes — do NOT collapse them:
8
+
9
+ | Axis | Field | Values | Decided by |
10
+ | --- | --- | --- | --- |
11
+ | **Store** (physical repo, privacy boundary) | `visibility_store` | `team` shared store / `personal` store | Phase 3 `强 team` / `强 personal` heuristic |
12
+ | **Audience** (logical resolution coordinate) | `semantic_scope` | `team` / `project:<id>` / `personal` / `org:<…>` | **this phase** |
13
+ | **Display** (how broadly it surfaces) | `relevance_scope` | `narrow` / `broad` | Phase 3.5 |
14
+
15
+ Phase 3 picks the STORE (team vs personal). This phase picks the AUDIENCE *within* the shared team store: is the entry for the whole team across all projects (`team`), or only for the current project (`project:<active_project>`)?
16
+
17
+ ## When this phase runs
18
+
19
+ - **Runs** only when `layer=team` AND `.fabric/fabric-config.json` has a non-empty `active_project`.
20
+ - **Skips** otherwise — the engine auto-derives `semantic_scope` at the write path (`resolveWriteScopeMeta`): `layer=personal` → `personal`; `layer=team` with no `active_project` → `team`. An explicit input always wins over auto-derivation (`semanticScope ?? defaultWriteScope(...)`).
21
+
22
+ ## Decision tree (per team candidate, when active_project is set)
23
+
24
+ ```
25
+ Is the knowledge tied to THIS project's code / business domain / workspace paths?
26
+ ├─ YES (this-project-only) → OMIT semantic_scope
27
+ │ → engine derives `project:<active_project>` ← DEFAULT, most candidates
28
+ └─ NO (team-wide, cross-project: methodology, team convention, tooling
29
+ not bound to this repo) → pass explicit `semantic_scope: team`
30
+ → entry stays visible across every project
31
+ ```
32
+
33
+ **Why the explicit escape hatch matters.** Without this step, *every* team archive in a project-bound repo is silently narrowed to `project:<active_project>`. Genuinely cross-project team knowledge (a naming convention, a review checklist, a tooling decision) would be trapped inside one project and invisible elsewhere. `semantic_scope: team` is the only way to opt out of the project narrowing.
34
+
35
+ ## Worked examples (active_project = `fabric-v2`)
36
+
37
+ | Candidate | layer | semantic_scope | Result |
38
+ | --- | --- | --- | --- |
39
+ | "The resolver's two-axis tie-break lives in `cross-store-write.ts`" | team | OMIT | `project:fabric-v2` — binds this repo's code |
40
+ | "We always write commit messages in Chinese, type: prefix" | team | `team` | `team` — team convention, spans every project |
41
+ | "Black-edge sprite root cause = inverted `premultiplyAlpha`" (a different game repo's domain) | team | `team` | `team` — not about fabric-v2 |
42
+ | "VoiceRoom 组件被本 app 多个玩法复用"(同一 app 内跨功能,**不**跨项目) | team | OMIT | `project:<active>` — 跨玩法复用 ≠ 跨项目;app 内共享组件仍绑本项目,**不是** team |
43
+ | First-person editor preference | personal | (n/a) | `personal` — store=personal, phase skipped |
44
+
45
+ ## Inline-edit support during batch review
46
+
47
+ The user MAY inline-edit `[semantic_scope=...]` in the batch review. Treat it as authoritative: a switch to `team` drops the project narrowing; a switch to `project:<active_project>` (or OMIT) restores the default. Personal-layer candidates have no `semantic_scope` choice — they are always `personal`.
@@ -19,7 +19,7 @@ description: 知识库语义淘汰门面 — 审计 KB 健康并以 deprecate-ov
19
19
  ## When NOT to use
20
20
 
21
21
  - 写 / 提议新知识条目 → `fabric-archive`。
22
- - 批量审 `.fabric/knowledge/pending/` draft → `fabric-review`。
22
+ - 批量审 pending draft → `fabric-review`(内部走 `fab_review action="list"` / `pending_path`)。
23
23
  - store 运维 / 同步 → `fabric-store` / `fabric-sync`。
24
24
 
25
25
  ## 两条红线
@@ -45,9 +45,19 @@ description: 知识库语义淘汰门面 — 审计 KB 健康并以 deprecate-ov
45
45
  4. never-valid → rescue-before-delete:独特知识?有则 merge + `related`,无则删空壳。
46
46
  5. 处置经 `fabric-review` skill 落盘(本 skill 给决策,review 做写入),保持单一写路径。
47
47
 
48
+ ## Scope re-assignment(迁移 / backfill 后纠偏)
49
+
50
+ `fabric store backfill-scope` 给老条目补 `semantic_scope`,**默认把所有 team-layer 条目标成 `semantic_scope: team`** —— over-broad 的保守默认,会让项目专属知识错误地暴露给所有项目。审计时按下面的测试纠偏:
51
+
52
+ - **team-scope 判定测试**:「换一个**没有本 app 代码**的不同 repo,这条知识还成立吗?」—— 成立才是 `team`。
53
+ - app **内部**跨功能 / 跨玩法复用的共享组件(同一 app 多处用)**≠ team** —— 它仍绑这个项目,应是 `project:<id>`。**跨玩法复用 ≠ 跨项目复用**(如语音房 VoiceRoom 被多个玩法共用,仍是 `project:<id>`)。
54
+ - **纠偏动作**:把被默认成 team 的项目专属条目降级 ——
55
+ `fabric store re-scope <store> --to project:<id> --id <id>`
56
+ - 完整判定树 / worked examples 见单一真源:`fabric-archive/ref/phase-3-7-semantic-scope.md`(本 skill 不重述,避免镜像漂移)。
57
+
48
58
  ## Constraints
49
59
 
50
- - 本 skill **只读 + 给处置建议**;实际写入(降级 / 标记 / 删)经 `fabric-review` 的写路径,不自行改 `.fabric/knowledge/`。
60
+ - 本 skill **只读 + 给处置建议**;实际写入(降级 / 标记 / 删)经 `fabric-review` 的写路径,不自行改 store `knowledge/`。
51
61
  - NEVER 绕过 rescue 检查直接删;删前 MUST 先跑抢救检查。删是最后手段,默认是 deprecate。
52
- - `agents.meta.json` 派生态严禁手改;退役动作改的是 `.fabric/knowledge/<type>/` 下 markdown 的 frontmatter(maturity / deprecated / superseded-by),再 `fabric doctor --fix` reconcile。
62
+ - store counters 派生态严禁手改;退役动作改的是 store `knowledge/<type>/` 下 markdown 的 frontmatter(maturity / deprecated / superseded-by),再 `fabric doctor --fix` reconcile。
53
63
  - health / orphan / stale 一律取自 `fabric doctor` 的 JSON 输出,不在 skill 内重算(单一真源)。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fabric-connect
3
- description: 知识图谱关联门面 — 发现 KB 条目间隐藏关联并回写 H2 `related` 图边。读 fab_recall/fab_plan_context 看候选, 按语义/共路径/共引提议 related 边, 经 fabric-review 写路径落盘。Triggers 连接知识/找关联条目/建知识图谱/link related entries/补 related 边/知识库连通性.
3
+ description: 知识图谱关联门面 — 发现 KB 条目间隐藏关联并回写 H2 `related` 图边。读 fab_recall 看候选, 按语义/共路径/共引提议 related 边, 经 fabric-review 写路径落盘。Triggers 连接知识/找关联条目/建知识图谱/link related entries/补 related 边/知识库连通性.
4
4
  ---
5
5
 
6
6
  # fabric-connect — 知识图谱关联
@@ -33,7 +33,7 @@ description: 知识图谱关联门面 — 发现 KB 条目间隐藏关联并回
33
33
 
34
34
  ## 流程
35
35
 
36
- 1. `fab_recall(paths=[...])` 或 `fab_plan_context` 拿候选 + 现有 `related`(读 description.related 看已连状态)。
36
+ 1. `fab_recall(paths=[...])` 拿候选 + 现有 `related`(读 description.related 看已连状态)。
37
37
  2. 对候选两两/成簇判隐藏关联(用上表判据);只提议**高置信**边,不为「话题相邻」乱连(噪声边稀释图价值)。
38
38
  3. 每条提议 = `(源 id, 目标 id, 类型, 一句理由)`;按需提议反向边。
39
39
  4. 落盘经 `fabric-review` 写路径:在源条目 frontmatter 的 `related` inline 数组追加目标 stable_id;`fabric doctor --fix` reconcile 进 agents.meta。
@@ -41,7 +41,7 @@ description: 知识图谱关联门面 — 发现 KB 条目间隐藏关联并回
41
41
 
42
42
  ## Constraints
43
43
 
44
- - 本 skill **只提议 + 经 review 写路径落盘**;不自行改 `.fabric/knowledge/`,不手改 `agents.meta.json`(派生态)。
44
+ - 本 skill **只提议 + 经 review 写路径落盘**;不自行改 store `knowledge/`,不手改 store counters(派生态)。
45
45
  - `related` MUST 只填**真实存在的 stable_id**(先 `fab_recall` 验证目标在库);NEVER 编造 / 指向 pending。
46
46
  - **稀疏优于稠密**:宁缺毋滥。只连高置信关联;低置信「相邻」不连(图的信噪比比覆盖率重要)。
47
47
  - 反向边按需补,不强制双向(有向语义:A 该带出 B ≠ B 该带出 A)。
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fabric-import
3
- description: 冷启动从 git log + docs/*.md 回灌 .fabric/knowledge/pending (NOT code/data import). Triggers 导入历史/bootstrap fabric/mine changelog/挖掘 commit.
3
+ description: 冷启动从 git log + docs/*.md 回灌 active write store pending knowledge (NOT code/data import). Triggers 导入历史/bootstrap fabric/mine changelog/挖掘 commit.
4
4
  allowed-tools: Read, Glob, Grep, Bash, mcp__fabric__fab_extract_knowledge, mcp__fabric__fab_review
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ allowed-tools: Read, Glob, Grep, Bash, mcp__fabric__fab_extract_knowledge, mcp__
8
8
 
9
9
  ## Purpose
10
10
 
11
- One-time per-project cold-start: lift git commits + `docs/*.md` into `.fabric/knowledge/pending/` as `team`-layer entries. Bridges `fabric install`'s 4-7 baseline → accumulated corpus. Run once on adoption or after major refactor.
11
+ One-time per-project cold-start: lift git commits + `docs/*.md` into the active write store as `team`-layer pending entries. Bridges `fabric install`'s 4-7 baseline → accumulated corpus. Run once on adoption or after major refactor.
12
12
 
13
13
  ## Precondition
14
14
 
@@ -18,7 +18,7 @@ Else stop: `没有触发 import 信号;如需手动 import 请显式调用 fab
18
18
 
19
19
  SKIP when: `.fabric/` missing (→ `fabric install`); canonical > `import_skip_canonical_threshold` (default 50); state file `phase=complete` + `last_checkpoint_at <24h`.
20
20
 
21
- Required: `.fabric/` exists, `agents.meta.json` present, MCP `fab_extract_knowledge` + `fab_review` registered, working tree reasonably clean.
21
+ Required: `.fabric/` exists, target store resolved, MCP `fab_extract_knowledge` + `fab_review` registered, working tree reasonably clean.
22
22
 
23
23
  ## Phase 0 — Init
24
24
 
@@ -56,9 +56,9 @@ Strict P1→P2→P3 order. State write after every sub-step. Infer-not-Ask.
56
56
 
57
57
  `fabric install` produced baseline. Phase 1 REFERENCES, does NOT redo.
58
58
 
59
- 1. Read `agents.meta.json` confirm baseline counters.
60
- 2. Glob `.fabric/knowledge/team/**/*.md` titles for P2 negative filter.
61
- 3. If meta missing OR team/ empty: STOP. Tell user `请先运行 fabric install 完成基线扫描` / `Please run fabric install first` and exit.
59
+ 1. Run `fabric onboard-coverage --json` and `fab_review action="search"` as needed to understand existing canonical titles in the mounted store read-set.
60
+ 2. If no write store is resolved: STOP. Tell user `请先绑定并选择写入 store` / `Please bind and select a write store first` and exit.
61
+ 3. Use the returned canonical titles for the P2 negative filter.
62
62
  4. State: `phase=P1-done`, `p1_baseline_titles=[...]`, `last_checkpoint_at=<ISO>`.
63
63
 
64
64
  No MCP calls.
@@ -134,7 +134,7 @@ Protected tokens (verbatim, no translate): `stable_id`, `pending_path`, `layer`,
134
134
 
135
135
  ## Output Contract
136
136
 
137
- Roll-up sections (per `fabric_language`): `Phase 2 — Mining` | `Phase 3 — Dedup` | `State` | `Next Steps`. Plus one-line `git status .fabric/knowledge/`. Bilingual templates → `Read .../ref/output-contract.md`.
137
+ Roll-up sections (per `fabric_language`): `Phase 2 — Mining` | `Phase 3 — Dedup` | `State` | `Next Steps`. Include the target store alias for proposed entries. Bilingual templates → `Read .../ref/output-contract.md`.
138
138
 
139
139
  ## Worked Examples
140
140
 
@@ -35,14 +35,14 @@ Rendering rule:
35
35
 
36
36
  - `fabric_language === "zh-CN"` → emit the zh-CN variant; pure monolingual, no language mixing inside a single user-facing block.
37
37
  - `fabric_language === "en"` → emit the en variant; pure monolingual, no language mixing inside a single user-facing block.
38
- - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_get_knowledge_sections`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
38
+ - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_recall`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
39
39
  - `fabric_language === "match-existing"` or any other value → emit the en variant; pure monolingual.
40
40
 
41
41
  Protected tokens (`fab_extract_knowledge`, `fab_review`, `relevance_scope`,
42
42
  `relevance_paths`, `broad`, `narrow`, `source_sessions`, `proposed_reason`,
43
43
  `session_context`, `intent_clues`, `tech_stack`, `impact`, `must_read_if`,
44
44
  `pending_path`, `layer`, `team`, `personal`,
45
- `knowledge_scope_degraded`, `MUST`, `NEVER`, `.fabric/knowledge/`, etc.)
45
+ `knowledge_scope_degraded`, `MUST`, `NEVER`, `knowledge/pending`, etc.)
46
46
  are NEVER translated — they appear verbatim in both language variants.
47
47
  The bilingualization scope is prose ONLY.
48
48
 
@@ -76,4 +76,3 @@ dual-string match (e.g. `if (choice === "approve" || choice === "通过")`),
76
76
  which doubles the surface area for protected-token regressions and breaks
77
77
  the option-list invariants that downstream tooling depends on. Keeping
78
78
  `options[]` English-only is contract-locked across all three skills.
79
-
@@ -46,7 +46,7 @@ On corruption (any condition above):
46
46
  1. `Bash: mv .fabric/.import-state.json .fabric/.import-state.json.corrupt-<ISO8601>`
47
47
  (preserve the corrupt file for postmortem; do NOT silently overwrite).
48
48
  2. Phase 1 restarts from scratch (Phase 1 produces no MCP calls, so re-run
49
- is safe — re-globbing `.fabric/knowledge/team/**/*.md` is cheap and
49
+ is safe — re-querying mounted store canonical titles via `fab_review search`
50
50
  idempotent; the `p1_baseline_titles` array is regenerated).
51
51
  3. DO NOT attempt automatic partial recovery; corrupt state is a signal
52
52
  that something serious happened (disk-full, kill -9 mid-write, fs
@@ -54,4 +54,3 @@ On corruption (any condition above):
54
54
 
55
55
  ENOENT (state file absent) is NOT corruption — it is the normal
56
56
  first-run state. Proceed to Phase 0.5.
57
-
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: fabric-review
3
- description: 审 .fabric/knowledge pending+canonical (NOT PR review):approve/reject/modify/revisit/defer。Triggers 审批/驳回/复审/重审/approve/reject/review pending.
3
+ description: 审 store-backed pending+canonical knowledge (NOT PR review):approve/reject/modify/revisit/defer。Triggers 审批/驳回/复审/重审/approve/reject/review pending.
4
4
  allowed-tools: Read, Glob, Grep, Bash, Edit, mcp__fabric__fab_review
5
5
  ---
6
6
 
@@ -25,7 +25,7 @@ This skill is `Infer-not-Ask` for mode and `Ask-when-genuine` for per-item actio
25
25
  - Per-item action (approve / reject / modify / defer) IS surfaced via AskUserQuestion — the user must judge
26
26
  - Layer-flip target (team vs personal) IS surfaced via AskUserQuestion when modify includes layer change
27
27
 
28
- Required preconditions before any `fab_review` call: `.fabric/` exists (or `~/.fabric/` for personal layer); `mcp__fabric__fab_review` MCP tool registered; `.fabric/agents.meta.json` present (id allocator reads it on approve); `.fabric/events.jsonl` exists (tolerate ENOENT — empty ledger normal first-run).
28
+ Required preconditions before any `fab_review` call: `.fabric/` exists; `mcp__fabric__fab_review` MCP tool registered; a write store is resolved for mutations; `.fabric/events.jsonl` exists (tolerate ENOENT — empty ledger normal first-run).
29
29
 
30
30
  ### Config Load
31
31
 
@@ -59,7 +59,7 @@ Read `fabric_language` (`zh-CN` / `en` / `zh-CN-hybrid` / `match-existing`); emi
59
59
 
60
60
  The skill MUST infer one of **2 modes** BEFORE any user-facing output (v2.0.0-rc.37 NEW-12 simplified 4 → 2):
61
61
 
62
- - **`pending`** — triage the write-side backlog (`.fabric/knowledge/pending/`): approve / reject / modify / defer per item. The dominant entry point.
62
+ - **`pending`** — triage the write-side backlog returned by `fab_review action="list"` (`pending_path` identifies each store-backed entry): approve / reject / modify / defer per item. The dominant entry point.
63
63
  - **`maintain`** — sustain the EXISTING canonical KB: browse by topic (search), survey staleness/health, or revisit a specific entry. Merges the legacy `topic` + `health` + `revisit` modes — they are all "operate on already-canonical knowledge", distinct from triaging new drafts.
64
64
 
65
65
  ### 2-Step Inference Algorithm
@@ -73,7 +73,7 @@ The skill MUST infer one of **2 modes** BEFORE any user-facing output (v2.0.0-rc
73
73
 
74
74
  A `maintain`-row match → lock `maintain`. A `pending`-row match (or 0/ambiguous) → fall to Step 2.
75
75
 
76
- **Step 2 — Backlog default.** Glob `.fabric/knowledge/pending/**/*.md`:
76
+ **Step 2 — Backlog default.** Call `fab_review action="list"` and inspect returned `items[].pending_path`:
77
77
 
78
78
  - Count ≥ `review_hint_pending_count` (default 10) OR oldest mtime > `review_hint_pending_age_days` (default 7) → `pending` (overflow, same threshold as Stop-hook).
79
79
  - Otherwise → default `pending` (most common review entry point).
@@ -179,7 +179,7 @@ Pending entry presented for review
179
179
 
180
180
  ## Output Contract & events.jsonl Constraint (ref-only)
181
181
 
182
- After each invocation, produce a bilingual `# Review Summary` (en) / `# Review 汇总` (zh-CN) roll-up: listed/approved/rejected/modified/deferred/skipped counts + new stable_ids + tail of `.fabric/events.jsonl` events (`knowledge_promote_started`, `knowledge_promoted`, `knowledge_layer_changed`, `knowledge_rejected`, `knowledge_deferred`). Also surface `git status` of `.fabric/knowledge/` so file moves are visible.
182
+ After each invocation, produce a bilingual `# Review Summary` (en) / `# Review 汇总` (zh-CN) roll-up: listed/approved/rejected/modified/deferred/skipped counts + new stable_ids + tail of `.fabric/events.jsonl` events (`knowledge_promote_started`, `knowledge_promoted`, `knowledge_layer_changed`, `knowledge_rejected`, `knowledge_deferred`). Also surface the target store alias/UUID for any mutation so file moves are attributable to the right store repo.
183
183
 
184
184
  events.jsonl appends MUST stay single-line + ≤4KB (POSIX `PIPE_BUF` atomicity).
185
185
 
@@ -11,7 +11,7 @@ KB: <id> (<≤8字 用法>) [applied|dismissed:<reason>]
11
11
  KB: none [<reason>]
12
12
  ```
13
13
 
14
- - `[applied]` 前必须先 `fab_recall`( `fab_plan_context` → `fab_get_knowledge_sections`)实际抓 KB body —— 防编造 id。验证不通过 = 不能 cite。
14
+ - `[applied]` 前必须先 `fab_recall`(并按需对其正文路径做原生 Read)实际抓 KB body —— 防编造 id。验证不通过 = 不能 cite。
15
15
  - **store 前缀** (多 store):read-set 含多 store 且同一 local id 跨 store shadow 时,cite 必须 store-qualified:`KB: <store-alias>:<id> ...`(如 `KB: team:KT-DEC-0001 (auth) [applied]`)。单 store / 无歧义时裸 `KB: <id>` 仍 valid。personal-only 条目 cite 进团队产物 = 强 warning(防泄漏 R5#3)。
16
16
 
17
17
  ## 2. Contract 语法 (decisions/pitfalls 类 `[applied]`)
@@ -39,13 +39,13 @@ Rendering rule:
39
39
 
40
40
  - `fabric_language === "zh-CN"` → emit the zh-CN variant; pure monolingual, no language mixing inside a single user-facing block.
41
41
  - `fabric_language === "en"` → emit the en variant; pure monolingual, no language mixing inside a single user-facing block.
42
- - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_get_knowledge_sections`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
42
+ - `fabric_language === "zh-CN-hybrid"` → emit Chinese narrative prose with English technical terms preserved. Protected tokens (always EN): MCP tool names (e.g. `fab_recall`), CLI command names (e.g. `fabric install`), file paths, technical concepts (`Skill`, `SessionStart`, `hook`, `MCP`, `revision_hash`, `pending`, `proven`, `verified`, `draft`).
43
43
  - `fabric_language === "match-existing"` or any other value → emit the en variant; pure monolingual.
44
44
 
45
45
  Protected tokens (`fab_review`, `relevance_scope`, `relevance_paths`,
46
46
  `narrow`, `broad`, `source_sessions`, `proposed_reason`, `session_context`,
47
47
  `pending_path`, `layer`, `team`, `personal`, `knowledge_scope_degraded`,
48
- `MUST`, `NEVER`, `.fabric/knowledge/`, etc.) are NEVER translated — they
48
+ `MUST`, `NEVER`, `knowledge/pending`, etc.) are NEVER translated — they
49
49
  appear verbatim in both language variants. The bilingualization scope is
50
50
  prose ONLY.
51
51
 
@@ -108,4 +108,3 @@ the option-list invariants that downstream tooling (the Skill's own
108
108
  `switch` statements over `choice`, plus any future MCP-level audit lint
109
109
  that scans for these specific string literals) depends on. Keeping
110
110
  `options[]` English-only is contract-locked across all three skills.
111
-
@@ -44,7 +44,7 @@ After each invocation, the skill MUST produce a brief roll-up to the user. UX i1
44
44
  - knowledge_deferred ×D
45
45
  ```
46
46
 
47
- Also surface a one-line `git status` of `.fabric/knowledge/` so the user sees the file moves caused by approve / layer-flip.
47
+ Also surface the target store alias/UUID for every mutation so the user can inspect that store repo's `git status` when needed.
48
48
 
49
49
  ## events.jsonl Constraint Note
50
50
 
@@ -75,7 +75,7 @@ Full bilingual rendering blocks + step-by-step procedures for the four modes ref
75
75
 
76
76
  1. Extract the topic keyword(s) from the user's message (e.g. "find about deepMerge" → query="deepMerge").
77
77
  2. Call `fab_review action="search"` with `query` and any obvious filters (if user said "team-only" → `filters.layer="team"`).
78
- 3. Server returns `items[]` ranked by relevance — these are entries already in `.fabric/knowledge/{layer}/{type}/` (NOT pending), unless `filters` says otherwise.
78
+ 3. Server returns `items[]` ranked by relevance — these are entries already in mounted store `knowledge/<type>/` (NOT pending), unless `filters` says otherwise.
79
79
  4. Render top-N (cap at `review_topic_result_cap`, config-resolved, default 8) results with title / summary / pending_path.
80
80
  5. If the user follow-up indicates intent to act ("approve all", "modify the second one"), pivot into the corresponding pending mode action — the search result already gives the `pending_path` needed for the action.
81
81
  6. NEVER surface a per-item AskUserQuestion just for browsing — only when the user signals an action verb.
@@ -134,7 +134,7 @@ Full bilingual rendering blocks + step-by-step procedures for the four modes ref
134
134
  ## Mode: revisit — Specific Entry Deep Dive
135
135
 
136
136
  1. The user referenced a specific entry (by id `KT-D-7` or by slug `single-cjs-hook`).
137
- 2. Call `fab_review action="list"` with `filters` narrowed by best-guess fields; if the entry is canonical (has stable_id), `Read` the file directly at `.fabric/knowledge/{layer}/{type}/<id>--<slug>.md`.
137
+ 2. Call `fab_review action="list"` with `filters` narrowed by best-guess fields; if the entry is canonical (has stable_id), use the path returned by `fab_review` instead of inventing a store path.
138
138
  3. Display the full body (frontmatter + content). Tail the events.jsonl for any history events tagged with this stable_id.
139
139
  4. Surface AskUserQuestion `{options: ["approve", "modify", "reject", "skip"]}` only if the entry is still pending; for canonical entries the only mutation path is `modify` (incl. layer flip).
140
140
 
@@ -36,7 +36,7 @@ Inferred mode: `revisit` (Step 1 keyword "look at <id>").
36
36
 
37
37
  Skill flow:
38
38
 
39
- 1. Read `.fabric/knowledge/team/guidelines/KT-G-0003--indent-style.md`. Display body to user.
39
+ 1. Read the canonical path returned by `fab_review search` for `KT-G-0003`. Display body to user.
40
40
  2. AskUserQuestion `{options: ["approve", "modify", "reject", "skip"]}` — user picks `modify`.
41
41
  3. Skill detects user-stated intent "actually personal not team" — surface AskUserQuestion `{options: ["team", "personal"]}` with current layer=team noted; user confirms `personal`.
42
42
  4. Call:
@@ -39,6 +39,6 @@ description: 知识 store 运维门面 — 创建 / 挂载 / 绑定 / 列出 /
39
39
 
40
40
  - `store remove` 是 *detach ≠ delete*:从 registry 卸载但 MUST 保留磁盘 git 树。
41
41
  - `store add` MUST 拒绝磁盘无 store 树的 uuid (无「幽灵挂载」) —— 先 clone (`fabric install --global --url <remote>`) 或 `store create`。
42
- - 知识条目写在各 store 的 `.fabric/knowledge/` 下;本 skill 只管 store 生命周期,不写条目。
42
+ - 知识条目写在各 store 的 `knowledge/` 下;本 skill 只管 store 生命周期,不写条目。
43
43
  - Personal-scope 写永远落在隐式 personal store,与 active write store 无关。
44
44
  - Hook/skill NEVER 直接解析 store 或执行 store 内文件 (S65 RCE 防线:store 是数据-only);所有 store 状态 MUST 经 CLI JSON 输出获取。