@fenglimg/fabric-cli 2.2.0-rc.1 → 2.2.0-rc.11

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 (83) hide show
  1. package/README.md +8 -5
  2. package/dist/chunk-27HK6H5Y.js +69 -0
  3. package/dist/{chunk-AOE6AYI7.js → chunk-2KBCTMID.js} +31 -8
  4. package/dist/chunk-3D7B2UAZ.js +149 -0
  5. package/dist/{chunk-XC5RUHLK.js → chunk-3IOLS5EK.js} +23 -38
  6. package/dist/{plan-context-hint-FC6P3WFE.js → chunk-722JU5BP.js} +52 -12
  7. package/dist/{chunk-2R55HNVD.js → chunk-7ZDXBOOU.js} +234 -206
  8. package/dist/{doctor-YONYXDX6.js → chunk-E7HJUU34.js} +215 -52
  9. package/dist/chunk-EOT63RDH.js +36 -0
  10. package/dist/chunk-FNHDQTPC.js +16 -0
  11. package/dist/{chunk-2CY4BMTH.js → chunk-HORSMSZL.js} +9 -5
  12. package/dist/{chunk-BO4XIZWZ.js → chunk-NLNH64A3.js} +5 -18
  13. package/dist/{chunk-WU6GAPKH.js → chunk-PTGQAZEW.js} +12 -4
  14. package/dist/chunk-QFIVFZRH.js +13 -0
  15. package/dist/chunk-QPAW6IYT.js +387 -0
  16. package/dist/{chunk-COI5VDFU.js → chunk-WA3DYGSY.js} +1 -2
  17. package/dist/{config-XYRBZJDU.js → config-A3LTECAY.js} +4 -3
  18. package/dist/context-UJCGYOT6.js +117 -0
  19. package/dist/doctor-MDTZWKBK.js +24 -0
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +133 -22
  22. package/dist/info-7FKBTMVO.js +139 -0
  23. package/dist/install-v2-WLEJ5XHT.js +3279 -0
  24. package/dist/{metrics-RER6NLFC.js → metrics-HMFH4YHK.js} +1 -1
  25. package/dist/{onboard-coverage-JWQWDZW7.js → onboard-coverage-XSG77LL3.js} +48 -27
  26. package/dist/plan-context-hint-5TNGH3R4.js +12 -0
  27. package/dist/{scope-explain-CDIZESP5.js → scope-explain-HLJZ2M33.js} +17 -6
  28. package/dist/status-4R3TM4FJ.js +37 -0
  29. package/dist/store-HOCORVL3.js +563 -0
  30. package/dist/{sync-UJ4BBCZJ.js → sync-DT5UJMMR.js} +197 -30
  31. package/dist/{uninstall-C3QXKOO6.js → uninstall-IFN2KYBK.js} +97 -140
  32. package/dist/whoami-ITGEFWH4.js +49 -0
  33. package/package.json +7 -5
  34. package/templates/hooks/cite-policy-evict.cjs +412 -160
  35. package/templates/hooks/configs/README.md +14 -27
  36. package/templates/hooks/configs/claude-code.json +17 -2
  37. package/templates/hooks/configs/codex-hooks.json +15 -3
  38. package/templates/hooks/fabric-hint.cjs +742 -259
  39. package/templates/hooks/knowledge-hint-broad.cjs +577 -274
  40. package/templates/hooks/knowledge-hint-narrow.cjs +113 -73
  41. package/templates/hooks/lib/banner-i18n.cjs +50 -1
  42. package/templates/hooks/lib/bindings-snapshot-reader.cjs +118 -7
  43. package/templates/hooks/lib/cite-line-parser.cjs +12 -20
  44. package/templates/hooks/lib/client-adapter.cjs +66 -7
  45. package/templates/hooks/lib/nudge-policy.cjs +117 -0
  46. package/templates/hooks/lib/state-store.cjs +60 -0
  47. package/templates/hooks/post-tooluse-mutation.cjs +386 -0
  48. package/templates/hooks/session-end-marker.cjs +140 -0
  49. package/templates/skills/fabric/SKILL.md +100 -0
  50. package/templates/skills/fabric-archive/SKILL.md +47 -24
  51. package/templates/skills/fabric-archive/ref/dry-run-scope.md +1 -1
  52. package/templates/skills/fabric-archive/ref/i18n-policy.md +2 -3
  53. package/templates/skills/fabric-archive/ref/phase-1-5-onboard.md +2 -3
  54. package/templates/skills/fabric-archive/ref/phase-1-cross-session.md +1 -1
  55. package/templates/skills/fabric-archive/ref/phase-2-5-viability.md +1 -1
  56. package/templates/skills/fabric-archive/ref/phase-3-6-related-edges.md +18 -0
  57. package/templates/skills/fabric-archive/ref/phase-3-7-semantic-scope.md +47 -0
  58. package/templates/skills/fabric-audit/SKILL.md +13 -3
  59. package/templates/skills/fabric-connect/SKILL.md +3 -3
  60. package/templates/skills/fabric-import/SKILL.md +7 -7
  61. package/templates/skills/fabric-import/ref/i18n-policy.md +2 -3
  62. package/templates/skills/fabric-import/ref/state-recovery.md +1 -2
  63. package/templates/skills/fabric-review/SKILL.md +14 -5
  64. package/templates/skills/fabric-review/ref/cite-contract.md +1 -1
  65. package/templates/skills/fabric-review/ref/i18n-policy.md +2 -3
  66. package/templates/skills/fabric-review/ref/output-contract.md +1 -1
  67. package/templates/skills/fabric-review/ref/per-mode-flows.md +2 -2
  68. package/templates/skills/fabric-review/ref/worked-examples.md +1 -1
  69. package/templates/skills/fabric-store/SKILL.md +1 -1
  70. package/templates/skills/fabric-sync/SKILL.md +1 -1
  71. package/templates/skills/lib/shared-policy.md +2 -2
  72. package/dist/chunk-4R2CYEA4.js +0 -116
  73. package/dist/chunk-L4Q55UC4.js +0 -52
  74. package/dist/chunk-LFIKMVY7.js +0 -27
  75. package/dist/chunk-RYAFBNES.js +0 -33
  76. package/dist/chunk-T5RPGCCM.js +0 -40
  77. package/dist/install-74ANPCCP.js +0 -2737
  78. package/dist/status-GLQWLWH6.js +0 -23
  79. package/dist/store-XB3ADT65.js +0 -144
  80. package/dist/whoami-2MLO4Y37.js +0 -36
  81. package/templates/hooks/configs/cursor-hooks.json +0 -18
  82. package/templates/hooks/lib/cite-contract-reminder.cjs +0 -179
  83. package/templates/hooks/lib/summary-fallback.cjs +0 -210
@@ -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,19 @@ 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
+ **Coverage transparency (crack 3 cheap recall backstop).** BEFORE collecting candidates, surface the scan's watermark + drops to the user so a human can act as the recall detector and manually override (`--range <session_id>` to force a dropped session back in). This is the affordable substitute for the (deferred) periodic cold-eval miss-rate audit show, don't hide, what the deterministic filter skipped:
69
+
70
+ ```
71
+ 📋 归档覆盖到 <covered_through_ts 转人类可读时间>。
72
+ 纳入会话: <session_ids.length> 个。
73
+ 跳过 <dropped.length> 个: <每个 {session_id 短码} (reason)>
74
+ reason 含义: user_dismissed=用户曾拒绝 / cooldown=12h 防抖内 / no_new_signal=自上次归档无新高价值活
75
+ 若某个被跳过的会话其实有该归档的内容,显式 `fabric-archive --range <session_id>` 强制纳入。
76
+ ```
77
+
78
+ Render `dropped` only when non-empty; render the watermark line always. en variant mirrors the same fields. Keep it ONE compact block — this is a backstop affordance, not a report.
79
+
80
+ `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
81
 
70
82
  Graceful degradation: missing digest cache → single-session fallback. Missing `session_archive_attempted` events (pre-rc.25) → legacy "scan everything since anchor" behaviour.
71
83
 
@@ -81,22 +93,20 @@ Gather raw evidence: tail `.fabric/events.jsonl` since last `knowledge_proposed`
81
93
 
82
94
  ### Phase 2.5 — Viability Gate (Anti-Archive Guard)
83
95
 
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):
96
+ 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
97
 
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.
98
+ 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
99
 
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.
100
+ **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
101
 
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.
102
+ `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
103
 
96
104
  ### Phase 3 — Classify, Layer, Slug, Review
97
105
 
98
106
  For each candidate, propose **type** ∈ {model, decision, guideline, pitfall, process}, **layer** ∈ {team, personal} via the verbatim heuristic below, **slug** (kebab-case 2-5 words, 20-40 chars, unique within type+layer bucket), **summary** (1-2 sentences).
99
107
 
108
+ > **Self-sufficiency standard — guideline / model summaries (KT-GLD-0001/0006).** These two types land in the SessionStart **ALWAYS-ACTIVE** sink as a single INDEX line with NO body injected — so the summary IS the operative rule the agent acts on. Author it as a self-contained imperative that states the thesis (the *what* + the operative *so-what*), e.g. `改源码前先读 bootstrap+compiler config;scripts 为 init 主执行边界`. A topic label that only points at the body (`Code style guidelines`, `Scope model`) is NOT acceptable here — the reader can't act on it without a fetch, breaking the always-active contract. decision/pitfall/process summaries are exempt (they surface as `must_read_if` triggers, deliberately pointers). Do NOT self-judge sufficiency in this phase (curse-of-knowledge rubber-stamps — KT-GLD-0006); authoring to the standard is the write-time floor, the zero-context cold-eval at review time is the real gate.
109
+
100
110
  #### Layer Classification Heuristic (verbatim, contract-locked)
101
111
 
102
112
  > - **强 team**: 引用本项目代码、团队共识用语("we decided")、fabric-import 路径产物、业务领域、绑定本项目代码的 pitfall
@@ -105,21 +115,33 @@ For each candidate, propose **type** ∈ {model, decision, guideline, pitfall, p
105
115
 
106
116
  Resolution: 强 team first; assign personal only if 强 personal dominates AND no 强 team applies; else default team.
107
117
 
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.
118
+ `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
119
 
110
120
  ### Phase 3.5 — Scope Decision + relevance_paths Derivation
111
121
 
112
122
  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
123
 
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.
124
+ `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.
125
+
126
+ ### Phase 3.6 — Related-edge Extraction (§7 graph generation)
127
+
128
+ 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.
129
+
130
+ `Read ref/phase-3-6-related-edges.md` for the allowed/forbidden edge matrix and worked examples.
131
+
132
+ ### Phase 3.7 — Semantic scope (audience axis, multi-project)
133
+
134
+ 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.
135
+
136
+ `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.
115
137
 
116
138
  ### Phase 4 — Persist via MCP
117
139
 
118
- 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**.
140
+ 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**.
119
141
 
120
142
  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).
121
143
 
122
- `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.
144
+ `Read ref/phase-4-mcp-persist.md` for the full call shape, C1 triage-field inference table, signal → `proposed_reason` mapping, and idempotency notes.
123
145
 
124
146
  ### Phase 4.5 — Persist Archive Attempt
125
147
 
@@ -127,7 +149,7 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
127
149
 
128
150
  **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.
129
151
 
130
- `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.
152
+ `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.
131
153
 
132
154
  ## Hard Rules (DO NOT TRANSLATE) — DISPLAY / WRITE Split
133
155
 
@@ -138,16 +160,17 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
138
160
  - MUST present every candidate with explicit `[type=...]`, `[layer=...]`, `[relevance_scope=...]`, and `slug=...` fields plus a `relevance_paths` line.
139
161
  - MUST include a one-line `Layer reasoning:` for each candidate citing which 强 team / 强 personal signal applied (or default team).
140
162
  - MUST include a one-line `Scope reasoning:` for each candidate citing why narrow or broad was chosen (or that personal forced broad).
163
+ - 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).
141
164
  - MUST classify against the canonical singular nouns: model / decision / guideline / pitfall / process. NEVER invent new types.
142
165
  - MUST cap the batch at `archive_max_candidates_per_batch` candidates (config-resolved, default 8); drop weaker ones over the cap.
143
166
  - MUST display the resolved `pending_path` returned by `fab_extract_knowledge` so the user can verify.
144
- - MUST treat user inline edits to type/layer/slug/relevance_scope/relevance_paths as authoritative replacements before Phase 2.
167
+ - MUST treat user inline edits to type/layer/slug/relevance_scope/relevance_paths/semantic_scope as authoritative replacements before Phase 2.
145
168
  - MUST skip rather than guess when an observation does not fit any of the 5 types.
146
169
 
147
170
  ### WRITE Rules
148
171
 
149
172
  - NEVER write a knowledge entry directly to the filesystem; the only legal write path is `mcp__fabric__fab_extract_knowledge`.
150
- - NEVER write outside `.fabric/knowledge/pending/` — promotion to `.fabric/knowledge/<type>/` is rc.3 fab_review concern, NOT this skill.
173
+ - 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.
151
174
  - NEVER include an `id` field anywhere — pending entries have no id (late-bind on approve).
152
175
  - NEVER classify a candidate as `personal` when a 强 team signal applies. Default to team on ambiguity.
153
176
  - NEVER emit a non-empty `relevance_paths` when `relevance_scope=broad` — broad MUST always carry `relevance_paths=[]`.
@@ -155,7 +178,7 @@ MANDATORY closing step on EVERY invocation (Phase 4 success path + every early-e
155
178
  - 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+.
156
179
  - NEVER batch multiple candidates into a single fab_extract_knowledge call; one call per candidate.
157
180
  - NEVER paraphrase the verbatim layer heuristic block above — the Chinese text is contract-locked.
158
- - 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`.
181
+ - 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`.
159
182
 
160
183
  ## Worked Examples / E5 Cron / Dry-run (ref-only)
161
184
 
@@ -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).
@@ -119,6 +119,15 @@ DO NOT AskUserQuestion "is this a duplicate?" — LLM already judged. User only
119
119
 
120
120
  `Read ref/semantic-check.md` for full procedure + 三类判断的细化定义.
121
121
 
122
+ ## Summary Self-Sufficiency Gate (guideline / model only — KT-GLD-0006)
123
+
124
+ Guideline/model entries surface in the SessionStart **ALWAYS-ACTIVE** sink as a body-less INDEX line, so an opaque summary (`Code style guidelines`) leaks in as an unactionable "rule". Before approving/promoting a **guideline or model** (only these two types — decision/pitfall/process surface as `must_read_if` triggers and are exempt), run the summary through the **zero-context cold-eval judge**, never your own judgment:
125
+
126
+ - The reviewing agent self-judging sufficiency is curse-of-knowledge — it back-fills from context it already has and rubber-stamps pointers (KT-GLD-0006). The withheld-body cold eval is the whole point.
127
+ - Build the batch with `summary-cold-eval.ts#buildColdEvalBatch` (rubric = `COLD_EVAL_RUBRIC`, candidates = the guideline/model summaries) and hand it to an **offline** judge via `maestro delegate` (zero-context, batched — NOT on the hot path). The judge returns `ColdEvalVerdict[]`.
128
+ - For each `self_sufficient=false` verdict: surface `⚠ Summary not act-on-able (cold-eval); suggested: <suggested_summary>` and route to `modify-content` (summary rewrite, stable_id preserved) — do NOT approve as-is. `self_sufficient=true` → no action.
129
+ - This is a nudge, not a hard block (KT-DEC-0007): the user may still approve over a failed verdict, but the flag must be shown.
130
+
122
131
  ## Narrowing Imported Entries & Modify Sub-Flow
123
132
 
124
133
  `modify` is the only action that mutates frontmatter or stable_id. Two paths:
@@ -179,7 +188,7 @@ Pending entry presented for review
179
188
 
180
189
  ## Output Contract & events.jsonl Constraint (ref-only)
181
190
 
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.
191
+ 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
192
 
184
193
  events.jsonl appends MUST stay single-line + ≤4KB (POSIX `PIPE_BUF` atomicity).
185
194
 
@@ -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