@fenglimg/fabric-shared 2.0.0-rc.30 → 2.0.0-rc.33

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.
@@ -181,7 +181,9 @@ var enMessages = {
181
181
  // four description-grade frontmatter fields on canonical knowledge entries.
182
182
  "cli.doctor.args.enrich-descriptions.description": "Back-fill missing intent_clues / tech_stack / impact / must_read_if on canonical knowledge entries (read-only by default; pair with --auto to write stubs).",
183
183
  "cli.doctor.args.auto.description": "With --enrich-descriptions: write deterministic stub values for missing fields. Without --auto, the run is read-only.",
184
- "cli.doctor.args.dry-run.description": "With --enrich-descriptions --auto: preview the would-be changes without writing to disk.",
184
+ "cli.doctor.args.dry-run.description": "With --enrich-descriptions --auto or --fix: preview the planned changes without writing to disk. The fix-dry-run output mirrors --fix's fixable_errors list but executes no mutations.",
185
+ // v2.0.0-rc.33 W4-B1 (T6 P2): --fix --dry-run banner — printed before the standard report so users see no mutations were applied.
186
+ "cli.doctor.fix-dry-run-banner": "[dry-run] No mutations were applied. The fixable_errors list below shows what `fab doctor --fix` would address; rerun without --dry-run to actually fix.",
185
187
  "cli.doctor.errors.enrich-descriptions-mutex": "--enrich-descriptions cannot be combined with --fix, --fix-knowledge, or --cite-coverage. Run them separately.",
186
188
  "doctor.enrich.allComplete": "All canonical knowledge entries already declare intent_clues / tech_stack / impact / must_read_if.",
187
189
  // rc.26 TASK-02a: doctor foundation-batch check messages.
@@ -203,13 +205,14 @@ var enMessages = {
203
205
  "doctor.check.managed_block_drift.ok.no_managed_block": "No three-end managed blocks detected \u2014 propagation pending or legacy-marker state.",
204
206
  "doctor.check.bootstrap_anchor.name": "Bootstrap anchor",
205
207
  "doctor.check.bootstrap_anchor.message.missing": "Neither AGENTS.md nor CLAUDE.md exists at the repo root. Fabric requires a bootstrap anchor file at the project root.",
206
- "doctor.check.bootstrap_anchor.remediation.missing": "Run `fabric install` to generate the AGENTS.md / CLAUDE.md bootstrap anchor at the repo root.",
208
+ "doctor.check.bootstrap_anchor.remediation.missing": "Run `fab install` to generate the AGENTS.md / CLAUDE.md bootstrap anchor at the repo root.",
207
209
  "doctor.check.bootstrap_anchor.ok": "Bootstrap anchor present at repo root: {present}.",
208
210
  "doctor.check.baseline_filename_format.name": "Baseline filename format",
209
211
  "doctor.check.baseline_filename_format.ok": "All baseline knowledge files use the canonical `${id}--${slug}.md` filename format.",
210
212
  "doctor.check.baseline_filename_format.message.singular": "{count} baseline knowledge file uses the deprecated bare-slug filename format and must be migrated to `${id}--${slug}.md`. First: {detail}.",
211
213
  "doctor.check.baseline_filename_format.message.plural": "{count} baseline knowledge files use the deprecated bare-slug filename format and must be migrated to `${id}--${slug}.md`. First: {detail}.",
212
- "doctor.check.baseline_filename_format.remediation": "Delete the legacy bare-slug baseline file(s) manually \u2014 the baseline pipeline was removed in rc.23 and is no longer an auto-fix path.",
214
+ // v2.0.0-rc.33 W3-2 (T6 #5): reference the file names from the message so users can copy-paste rm targets rather than grep for them.
215
+ "doctor.check.baseline_filename_format.remediation": "Manually rm the bare-slug baseline file(s) listed in the message (e.g. `rm <file from message>`). The baseline pipeline was removed in rc.23 and is no longer an auto-fix path.",
213
216
  "doctor.check.knowledge_dir_missing.name": "Knowledge layout",
214
217
  "doctor.check.knowledge_dir_missing.message.singular": "{count} required knowledge subdir is missing: {list}.",
215
218
  "doctor.check.knowledge_dir_missing.message.plural": "{count} required knowledge subdirs are missing: {list}.",
@@ -226,7 +229,7 @@ var enMessages = {
226
229
  "doctor.check.agents_meta.message.missing": ".fabric/agents.meta.json is missing.",
227
230
  "doctor.check.agents_meta.remediation.missing": "Run `fab doctor --fix` to rebuild agents.meta.json from .fabric/knowledge/.",
228
231
  "doctor.check.agents_meta.message.invalid-default": ".fabric/agents.meta.json is invalid.",
229
- "doctor.check.agents_meta.remediation.invalid": "Delete .fabric/agents.meta.json and run `fab doctor --fix` to regenerate it.",
232
+ "doctor.check.agents_meta.remediation.invalid": "Run `fab doctor --fix` to let reconcile rebuild agents.meta.json from the .fabric/knowledge/ disk ground-truth (rc.31+ auto-migrates legacy singular knowledge_type values to canonical plural; do NOT manually delete agents.meta.json \u2014 you would lose counters envelope and promote-ledger associations).",
230
233
  "doctor.check.agents_meta.message.stale": ".fabric/agents.meta.json revision {revision} does not match .fabric/knowledge derived revision {computedRevision}.",
231
234
  "doctor.check.agents_meta.remediation.stale": "Benign \u2014 engine auto-heals on next plan-context/get-sections call. Run `fab doctor --fix` for explicit reconciliation.",
232
235
  "doctor.check.agents_meta.ok": ".fabric/agents.meta.json revision {revision} is aligned with .fabric/knowledge.",
@@ -235,7 +238,8 @@ var enMessages = {
235
238
  "doctor.check.rule_content_refs.remediation.unavailable": "Fix agents.meta.json first: run `fab doctor --fix`.",
236
239
  "doctor.check.rule_content_refs.message.outside.singular": "{count} content_ref entry is outside .fabric/knowledge.",
237
240
  "doctor.check.rule_content_refs.message.outside.plural": "{count} content_ref entries are outside .fabric/knowledge.",
238
- "doctor.check.rule_content_refs.remediation.outside": "Edit agents.meta.json to ensure all content_ref values point inside .fabric/knowledge/{type}/ (team) or ~/.fabric/knowledge/{type}/ (personal).",
241
+ // v2.0.0-rc.33 W3-2 (T6 #12): project rules forbid hand-editing agents.meta.json (see .fabric/AGENTS.md). Direct users through doctor --fix reconcile path instead.
242
+ "doctor.check.rule_content_refs.remediation.outside": "Run `fab doctor --fix` to let reconcile auto-prune external content_refs (rc.31+ compatible). Do NOT hand-edit agents.meta.json \u2014 the engine reconciles automatically.",
239
243
  "doctor.check.rule_content_refs.message.missing.singular": "{count} content_ref target is missing. Run `fab doctor --fix` to reconcile.",
240
244
  "doctor.check.rule_content_refs.message.missing.plural": "{count} content_ref targets are missing. Run `fab doctor --fix` to reconcile.",
241
245
  "doctor.check.rule_content_refs.remediation.missing": "Run `fab doctor --fix` to reconcile agents.meta.json with the files present in .fabric/knowledge/.",
@@ -255,7 +259,8 @@ var enMessages = {
255
259
  "doctor.check.event_ledger.message.not_writable-default": ".fabric/events.jsonl is not writable.",
256
260
  "doctor.check.event_ledger.remediation.not_writable": "Check file permissions on .fabric/events.jsonl and ensure no other process holds a write lock.",
257
261
  "doctor.check.event_ledger.message.invalid-default": ".fabric/events.jsonl is invalid.",
258
- "doctor.check.event_ledger.remediation.invalid": "Delete .fabric/events.jsonl and run `fab doctor --fix` to recreate it.",
262
+ // v2.0.0-rc.33 W3-1 (P0-6): archive-history mode — direct users to mv the broken ledger into events.archive/ before recreating, preserving history rather than rm'ing it. Mirrors rotateEventLedgerIfNeeded's events-rotated-YYYY-MM-DD.jsonl naming convention (events-corrupted-YYYY-MM-DD.jsonl distinguishes this archive cause from sliding-window rotation).
263
+ "doctor.check.event_ledger.remediation.invalid": "Archive history first (`mkdir -p .fabric/events.archive && mv .fabric/events.jsonl .fabric/events.archive/events-corrupted-$(date +%Y-%m-%d).jsonl`), then run `fab doctor --fix` to create a new empty ledger. Historical events are preserved under events.archive/.",
259
264
  "doctor.check.event_ledger.ok": ".fabric/events.jsonl exists, is writable, and is parseable.",
260
265
  "doctor.check.mcp_config_in_wrong_file.name": "Claude MCP config location",
261
266
  "doctor.check.mcp_config_in_wrong_file.message": ".claude/settings.json contains mcpServers.fabric \u2014 this file is for hooks/permissions only. Run --fix to remove it, then re-run fab install to write .mcp.json.",
@@ -272,12 +277,36 @@ var enMessages = {
272
277
  "doctor.check.event_ledger_schema_compat.ok.clean": "events.jsonl rows all parse against the current schema.",
273
278
  "doctor.check.event_ledger_schema_compat.message.schema_version": "events.jsonl has {count} row(s) with unsupported `schema_version` (samples: {samples}).",
274
279
  "doctor.check.event_ledger_schema_compat.message.event_type": "events.jsonl has {count} row(s) with unknown `event_type` (samples: {samples}).",
275
- "doctor.check.event_ledger_schema_compat.remediation": "Either upgrade the fab CLI to a server-compatible version, or archive `.fabric/events.jsonl` and run `fab doctor --fix` to recreate a fresh ledger.",
280
+ // v2.0.0-rc.33 W3-1 (P0-6): archive-history mode same as event_ledger.invalid above. Explicit "archive" wording (rather than "back up") makes it clear the old ledger is preserved under events.archive/, not discarded.
281
+ "doctor.check.event_ledger_schema_compat.remediation": "Preferred: upgrade the fab CLI to a server-compatible version. Otherwise archive history first (`mkdir -p .fabric/events.archive && mv .fabric/events.jsonl .fabric/events.archive/events-schema-mismatch-$(date +%Y-%m-%d).jsonl`), then run `fab doctor --fix` to create a new empty ledger. Historical events stay under events.archive/ for later manual migration.",
276
282
  // v2.0.0-rc.28 TASK-04 (audit §3.1): SKILL ref/ mirror parity check.
277
283
  "doctor.check.skill_ref_mirror.name": "Skill ref mirror parity",
278
284
  "doctor.check.skill_ref_mirror.ok": "All `.claude/skills/<slug>/ref/` and `.codex/skills/<slug>/ref/` files are byte-identical.",
279
285
  "doctor.check.skill_ref_mirror.message": "{count} skill ref file(s) differ between `.claude/skills/` and `.codex/skills/` (paths: {list}). One client was hand-edited or partially installed.",
280
286
  "doctor.check.skill_ref_mirror.remediation": "Run `fab install` to rewrite both client subtrees from the canonical templates and restore parity.",
287
+ // v2.0.0-rc.33 W3-6 (P1-13): SKILL.md token budget lint. warn > 5K / error > 10K tokens (chars/3 estimate). Anthropic recommends SKILL.md hot path stay ~3K; over 5K hurts progressive disclosure; over 10K is blocking (wasted model context + load latency).
288
+ "doctor.check.skill_token_budget.name": "Skill token budget",
289
+ "doctor.check.skill_token_budget.ok": "All .claude/skills/<slug>/SKILL.md files are within token budget (warn 5K / error 10K).",
290
+ "doctor.check.skill_token_budget.message.singular": "{count} SKILL.md exceeds the token budget: {list}. Sink detail into ref/ for progressive disclosure.",
291
+ "doctor.check.skill_token_budget.message.plural": "{count} SKILL.md files exceed the token budget: {list}. Sink detail into ref/ for progressive disclosure.",
292
+ "doctor.check.skill_token_budget.remediation": "Move detailed phase / worked-examples / decision tables out of the SKILL.md hot path into `templates/skills/<slug>/ref/*.md`. Keep SKILL.md focused on trigger-gate + key-phase summaries; see W1 progressive disclosure split. Re-run `fab install` to sync both client subtrees.",
293
+ // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description structural lint. Proxy for trigger-recall (a live-LLM recall test requires a model — W1 ran gemini for that). This lint catches regression: missing description / >60 tokens / no Chinese trigger / no English trigger.
294
+ "doctor.check.skill_description.name": "Skill description quality",
295
+ "doctor.check.skill_description.ok": "All SKILL.md description fields are well-structured (non-empty, <60 tokens, bilingual triggers).",
296
+ "doctor.check.skill_description.message.singular": "{count} SKILL.md description structural issue: {list}. The description field is the host's primary auto-invoke matching signal.",
297
+ "doctor.check.skill_description.message.plural": "{count} SKILL.md description structural issues: {list}. The description field is the host's primary auto-invoke matching signal.",
298
+ "doctor.check.skill_description.remediation": "Edit the `description:` field in `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter: (1) non-empty; (2) <60 tokens (chars/3 estimate, ~180 chars); (3) at least one Chinese trigger phrase; (4) at least one English trigger phrase. See W1 description rewrite style. Re-run `fab install` to sync both client subtrees. For recall verification, run the W1 gemini delegate (see .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md).",
299
+ // v2.0.0-rc.33 W3-3 (P1-3): cite-policy Goodhart pattern detection. Scans 7d of assistant_turn_observed events for 4 anti-patterns (G1 ritual / G2 dismissal abuse / G3 chained-from misuse / G5 placeholder cite). Warning severity — heuristics can false-positive; advisory only.
300
+ "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
301
+ "doctor.check.cite_goodhart.ok": "No cite-policy Goodhart patterns detected over the last 7 days.",
302
+ "doctor.check.cite_goodhart.message.singular": "Detected {count} cite-policy Goodhart pattern: {list}.",
303
+ "doctor.check.cite_goodhart.message.plural": "Detected {count} cite-policy Goodhart patterns: {list}.",
304
+ "doctor.check.cite_goodhart.remediation": "Review the fired patterns: G1 ritual \u2192 the same id repeated as [recalled] suggests the KB should land into a contract instead; G2 dismissal abuse \u2192 > 60% of recalled cites used skip: bypasses contract enforcement, audit skip-reason validity; G3 chained-from misuse \u2192 chained-from tag with no commitment (operators=[] + skip_reason=null), add operators or use a different tag; G5 placeholder cite \u2192 too many bare 'KB: none' / [unspecified], prefer specific sentinels like [no-relevant] / [not-applicable]. For raw data, run `fab doctor --cite-coverage --since=7d`.",
305
+ // v2.0.0-rc.33 W4-A4 (T5 P2): draft-backlog lint. rc.32 baseline showed 92% of entries stuck at draft, signaling a broken promote loop. Warns when > 50% draft (workspace must have >= 10 entries to compute the ratio — small corpora are noisy).
306
+ "doctor.check.draft_backlog.name": "Knowledge draft backlog",
307
+ "doctor.check.draft_backlog.ok": "draft-maturity entry ratio is healthy (< 50%, or workspace too small to compute).",
308
+ "doctor.check.draft_backlog.message": "{draftCount}/{totalCount} ({pct}%) canonical knowledge entries are stuck at draft maturity \u2014 promote loop is broken (rc.32 baseline was 92%).",
309
+ "doctor.check.draft_backlog.remediation": "Run `/fabric-review` to triage drafts: approve to promote to verified/proven, reject to drop, modify to fix. A long-standing draft backlog usually means archive produces drafts faster than review can promote them.",
281
310
  "doctor.check.meta_manually_diverged.name": "Meta manual divergence",
282
311
  "doctor.check.meta_manually_diverged.ok.unreadable": "agents.meta.json not readable; skipping divergence check.",
283
312
  "doctor.check.meta_manually_diverged.message.extra.singular": "agents.meta.json has {count} entry with no backing file on disk. Run --fix to reconcile.",
@@ -295,7 +324,8 @@ var enMessages = {
295
324
  "doctor.check.stable_id_collision.name": "Stable ID collision",
296
325
  "doctor.check.stable_id_collision.message.singular": 'stable_id "{stableId}" is declared in {fileCount} files: {files}. Edit one of the knowledge files to use a unique stable_id.',
297
326
  "doctor.check.stable_id_collision.message.plural": '{count} stable_id collisions detected. First: "{stableId}" in {files}. Edit one of the knowledge files to use a unique stable_id.',
298
- "doctor.check.stable_id_collision.remediation": "Edit one of the colliding knowledge files to declare a different `id: K[PT]-XXX-NNNN` frontmatter value.",
327
+ // v2.0.0-rc.33 W3-2 (T6 #27): route through fabric-review modify so the canonical id allocator picks a fresh id (avoids hand-counter math).
328
+ "doctor.check.stable_id_collision.remediation": "Run `/fabric-review modify <one of the colliding ids from the message>` to let the canonical id allocator reassign it (updates frontmatter + counters + historical cross-refs atomically). Do NOT hand-edit id frontmatter \u2014 it will desync counters.",
299
329
  "doctor.check.stable_id_collision.ok": "No declared stable_id collisions found in .fabric/knowledge/.",
300
330
  "doctor.check.counter_desync.name": "Knowledge counter desync",
301
331
  "doctor.check.counter_desync.message.singular": "{count} knowledge counter desynced from observed stable_ids. {counterPath} = {current} but observed {observedId}. Run `fab doctor --fix` to bump counters.",
@@ -315,12 +345,12 @@ var enMessages = {
315
345
  "doctor.check.orphan_demote.ok": "No canonical knowledge entries exceed their maturity-keyed inactivity threshold.",
316
346
  "doctor.check.orphan_demote.message.singular": "{count} canonical knowledge entry exceeds their maturity-keyed inactivity threshold (stable={stableDays}d / endorsed={endorsedDays}d / draft={draftDays}d). First: {detail}.",
317
347
  "doctor.check.orphan_demote.message.plural": "{count} canonical knowledge entries exceed their maturity-keyed inactivity threshold (stable={stableDays}d / endorsed={endorsedDays}d / draft={draftDays}d). First: {detail}.",
318
- "doctor.check.orphan_demote.remediation": "Run `fab doctor --apply-lint` (rc.4 TASK-003) to demote orphan entries one maturity tier.",
348
+ "doctor.check.orphan_demote.remediation": "Run `fab doctor --fix-knowledge` to demote orphan entries one maturity tier.",
319
349
  "doctor.check.stale_archive.name": "Knowledge stale archive",
320
350
  "doctor.check.stale_archive.ok": "No draft knowledge entries exceed the additional stale-archive quiet window.",
321
351
  "doctor.check.stale_archive.message.singular": "{count} draft knowledge entry is stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
322
352
  "doctor.check.stale_archive.message.plural": "{count} draft knowledge entries are stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
323
- "doctor.check.stale_archive.remediation": "Run `fab doctor --apply-lint` (rc.4 TASK-003) to move stale entries into `.fabric/.archive/<type>/`.",
353
+ "doctor.check.stale_archive.remediation": "Run `fab doctor --fix-knowledge` to move stale entries into `.fabric/.archive/<type>/`.",
324
354
  "doctor.check.pending_overdue.name": "Knowledge pending overdue",
325
355
  "doctor.check.pending_overdue.ok": "No pending knowledge entries exceed the 14-day review threshold.",
326
356
  "doctor.check.pending_overdue.message.singular": "{count} pending knowledge entry has been awaiting review for more than {thresholdDays} days. First: {detail}.",
@@ -330,17 +360,19 @@ var enMessages = {
330
360
  "doctor.check.stable_id_duplicate.ok": "No canonical knowledge files share a stable_id across team / personal trees.",
331
361
  "doctor.check.stable_id_duplicate.message.singular": "{count} stable_id duplicated across canonical knowledge files (path-decoupled identity invariant). First: {detail}.",
332
362
  "doctor.check.stable_id_duplicate.message.plural": "{count} stable_ids duplicated across canonical knowledge files (path-decoupled identity invariant). First: {detail}.",
333
- "doctor.check.stable_id_duplicate.remediation": "Manually rename one of the colliding files to a fresh `<prefix>-<type>-<counter>--<slug>.md` allocated via the canonical id allocator; do not edit by hand.",
363
+ // v2.0.0-rc.33 W3-2 (T6 #34): same as stable_id_collision route through fabric-review modify so allocator handles the new id.
364
+ "doctor.check.stable_id_duplicate.remediation": "Run `/fabric-review modify <one of the duplicate ids from the message>` to let the canonical id allocator assign a fresh `<prefix>-<type>-<counter>--<slug>.md` (renames the file + updates frontmatter + corrects counters in one shot).",
334
365
  "doctor.check.layer_mismatch.name": "Knowledge layer mismatch",
335
366
  "doctor.check.layer_mismatch.ok": "All canonical knowledge files are physically located under the layer their stable_id prefix declares.",
336
367
  "doctor.check.layer_mismatch.message.singular": "{count} canonical knowledge file are physically misaligned with their stable_id layer prefix (KT-* must live under team/, KP-* under personal/). First: {detail}.",
337
368
  "doctor.check.layer_mismatch.message.plural": "{count} canonical knowledge files are physically misaligned with their stable_id layer prefix (KT-* must live under team/, KP-* under personal/). First: {detail}.",
338
- "doctor.check.layer_mismatch.remediation": "Move the file to the correct layer root, or use the fabric-review modify flow to flip its layer (which renames the stable_id prefix accordingly).",
369
+ // v2.0.0-rc.33 W3-2 (T6 #35): make the skill entry point explicit so users know how to invoke fabric-review.
370
+ "doctor.check.layer_mismatch.remediation": "Move the file to the correct layer root (KT-* \u2192 .fabric/knowledge/team/, KP-* \u2192 ~/.fabric/knowledge/personal/), or run `/fabric-review modify <id from the message>` to flip its layer (which renames the stable_id prefix accordingly).",
339
371
  "doctor.check.index_drift.name": "Knowledge index drift",
340
372
  "doctor.check.index_drift.ok": "agents.meta.json counters envelope is at or above the highest existing canonical counter for every (layer, type) pair.",
341
373
  "doctor.check.index_drift.message.singular": "{count} (layer, type) counter slot have drifted below the observed canonical maximum (next allocate would collide). First: {detail}.",
342
374
  "doctor.check.index_drift.message.plural": "{count} (layer, type) counter slots have drifted below the observed canonical maximum (next allocate would collide). First: {detail}.",
343
- "doctor.check.index_drift.remediation": "Run `fab doctor --apply-lint` (rc.4 TASK-003) to bump agents.meta.json counters to max_observed + 1.",
375
+ "doctor.check.index_drift.remediation": "Run `fab doctor --fix-knowledge` to bump agents.meta.json counters to max_observed + 1.",
344
376
  "doctor.check.underseeded.name": "Knowledge underseeded",
345
377
  "doctor.check.underseeded.ok": "Knowledge corpus has {count} canonical entries (>= {threshold}).",
346
378
  "doctor.check.underseeded.message.singular": "Knowledge corpus has only {count} canonical entry (< {threshold} threshold). The plan_context retrieval surface is below its useful floor.",
@@ -374,7 +406,7 @@ var enMessages = {
374
406
  "doctor.check.session_hints_stale.ok": "No session-hints cache files older than {days} days under .fabric/.cache/.",
375
407
  "doctor.check.session_hints_stale.message.singular": "{count} session-hints cache file under .fabric/.cache/ is older than {days} days. First: {detail}.",
376
408
  "doctor.check.session_hints_stale.message.plural": "{count} session-hints cache files under .fabric/.cache/ are older than {days} days. First: {detail}.",
377
- "doctor.check.session_hints_stale.remediation": "Run `fab doctor --apply-lint` to delete stale session-hints cache files.",
409
+ "doctor.check.session_hints_stale.remediation": "Run `fab doctor --fix-knowledge` to delete stale session-hints cache files.",
378
410
  "doctor.check.stale_serve_lock.name": "Serve lock",
379
411
  "doctor.check.stale_serve_lock.ok.no_lock": "No .fabric/.serve.lock present.",
380
412
  "doctor.check.stale_serve_lock.ok.live_pid": ".fabric/.serve.lock held by live PID {pid}.",
@@ -388,7 +420,20 @@ var enMessages = {
388
420
  "doctor.check.relevance_fields_missing.ok": "All pending entries declare both relevance_scope and relevance_paths.",
389
421
  "doctor.check.relevance_fields_missing.message.singular": "{count} pending entry is missing relevance_scope and/or relevance_paths in frontmatter. First: {detail}.",
390
422
  "doctor.check.relevance_fields_missing.message.plural": "{count} pending entries are missing relevance_scope and/or relevance_paths in frontmatter. First: {detail}.",
391
- "doctor.check.relevance_fields_missing.remediation": "Run `fab doctor --apply-lint` to back-fill the schema defaults (relevance_scope: broad, relevance_paths: []).",
423
+ "doctor.check.relevance_fields_missing.remediation": "Run `fab doctor --fix-knowledge` to back-fill the schema defaults (relevance_scope: broad, relevance_paths: []).",
424
+ // rc.31 BUG-M3/NEW-4: hooks_wired observability.
425
+ "doctor.check.hooks_wired.name": "Claude Code hooks wired",
426
+ "doctor.check.hooks_wired.ok.skipped": "Project does not use Claude Code (no .claude/ directory); hooks_wired check skipped.",
427
+ "doctor.check.hooks_wired.ok.wired": ".claude/settings.json has the three fabric hooks wired: Stop:fabric-hint / SessionStart:knowledge-hint-broad / PreToolUse:knowledge-hint-narrow.",
428
+ "doctor.check.hooks_wired.message.missing_settings": ".claude/ exists but .claude/settings.json is absent or unparseable; fab install may have never run successfully, or the file was wiped externally.",
429
+ "doctor.check.hooks_wired.message.incomplete": ".claude/settings.json is missing fabric hook injections: {missing}. fab install dry-run report does not match actual state (rc.30 audit BUG-M3 / NEW-4).",
430
+ "doctor.check.hooks_wired.remediation": "Run `fab install` to re-inject hooks (idempotent; only fills missing slots). If hooks config was accidentally wiped, back up .claude/settings.json before running.",
431
+ // rc.31 BUG-G2/G5: promote-ledger invariant check.
432
+ "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
433
+ "doctor.check.promote_ledger_invariant.ok": "knowledge_proposed={proposed} >= knowledge_promote_started={started} >= knowledge_promoted={promoted}; ledger invariant holds.",
434
+ "doctor.check.promote_ledger_invariant.message.proposed-lt-started": "knowledge_proposed={proposed} is less than knowledge_promote_started={started} (ledger invariant violated; some pending entries were approved without going through fab_extract_knowledge, so no propose event was emitted for them).",
435
+ "doctor.check.promote_ledger_invariant.message.started-lt-promoted": "knowledge_promote_started={started} is less than knowledge_promoted={promoted} (ledger invariant violated; unpaired promoted events exist, possibly from doctor filesystem-edit fallback or external writers).",
436
+ "doctor.check.promote_ledger_invariant.remediation": "Starting in rc.31, review.approve synthesizes a knowledge_proposed event to keep the invariant; re-run fab doctor after the next approve to settle. Historical imbalance is observability-only and does not affect KB function.",
392
437
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
393
438
  "doctor.check.skill_md_yaml_invalid.ok": "All .claude/.codex SKILL.md frontmatter values parse as strict YAML.",
394
439
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} SKILL.md frontmatter value contains an unquoted ': ' that strict YAML parsers reject (Claude Code tolerates it; Codex CLI drops the skill at load). First: {detail}.",
@@ -577,7 +622,7 @@ var enMessages = {
577
622
  "cli.scan.args.target.description": "Target absolute path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
578
623
  "cli.scan.args.debug.description": "Print detection evidence in formatted output.",
579
624
  "cli.scan.args.json.description": "Print the diagnostic report as JSON.",
580
- "cli.scan.error.missing-forensic": "forensic.json not found at {path}; run `fabric install` first to produce the deterministic project snapshot.",
625
+ "cli.scan.error.missing-forensic": "forensic.json not found at {path}; run `fab install` first to produce the deterministic project snapshot.",
581
626
  "cli.scan.summary.created": "Wrote {count} knowledge entries to .fabric/knowledge/.",
582
627
  "cli.scan.summary.skipped": "No changes detected; {count} entries already up-to-date.",
583
628
  "cli.scan.report.title": "Fabric scan report",
@@ -1002,7 +1047,9 @@ var zhCNMessages = {
1002
1047
  // rc.23 TASK-007 (a-C2): --enrich-descriptions 回填四个 description 字段。
1003
1048
  "cli.doctor.args.enrich-descriptions.description": "\u56DE\u586B\u6B63\u5F0F\u77E5\u8BC6\u6761\u76EE\u7F3A\u5931\u7684 intent_clues / tech_stack / impact / must_read_if \u5B57\u6BB5\uFF08\u9ED8\u8BA4\u53EA\u8BFB;\u642D\u914D --auto \u5199\u5165 stub\uFF09\u3002",
1004
1049
  "cli.doctor.args.auto.description": "\u4E0E --enrich-descriptions \u642D\u914D\uFF1A\u4E3A\u7F3A\u5931\u5B57\u6BB5\u5199\u5165\u786E\u5B9A\u6027 stub \u503C\u3002\u4E0D\u52A0 --auto \u4EC5\u505A\u53EA\u8BFB\u626B\u63CF\u3002",
1005
- "cli.doctor.args.dry-run.description": "\u4E0E --enrich-descriptions --auto \u642D\u914D\uFF1A\u4EC5\u9884\u89C8\u6539\u52A8\u8BA1\u5212,\u4E0D\u5199\u5165\u78C1\u76D8\u3002",
1050
+ "cli.doctor.args.dry-run.description": "\u4E0E --enrich-descriptions --auto \u6216 --fix \u642D\u914D:\u4EC5\u9884\u89C8\u6539\u52A8\u8BA1\u5212,\u4E0D\u5199\u5165\u78C1\u76D8\u3002fix-dry-run \u8F93\u51FA\u4E0E --fix \u76F8\u540C\u7684 fixable_errors \u5217\u8868,\u4F46\u4E0D\u6267\u884C\u4EFB\u4F55 mutation\u3002",
1051
+ // v2.0.0-rc.33 W4-B1 (T6 P2): --fix --dry-run banner — 出现在 report 之前, 让用户明确没有发生 mutation。
1052
+ "cli.doctor.fix-dry-run-banner": "[dry-run] \u672A\u5E94\u7528\u4EFB\u4F55 mutation\u3002\u4E0B\u65B9 fixable_errors \u5217\u8868\u5C31\u662F `fab doctor --fix` \u4F1A\u5904\u7406\u7684\u9879;\u53BB\u6389 --dry-run \u518D\u8DD1\u53EF\u5B9E\u9645\u4FEE\u590D\u3002",
1006
1053
  "cli.doctor.errors.enrich-descriptions-mutex": "--enrich-descriptions \u4E0D\u80FD\u4E0E --fix / --fix-knowledge / --cite-coverage \u540C\u65F6\u4F7F\u7528,\u8BF7\u5206\u522B\u8FD0\u884C\u3002",
1007
1054
  "doctor.enrich.allComplete": "\u6240\u6709\u6B63\u5F0F\u77E5\u8BC6\u6761\u76EE\u5747\u5DF2\u5305\u542B intent_clues / tech_stack / impact / must_read_if\u3002",
1008
1055
  // rc.26 TASK-02a: doctor foundation-batch check messages.
@@ -1024,13 +1071,14 @@ var zhCNMessages = {
1024
1071
  "doctor.check.managed_block_drift.ok.no_managed_block": "\u672A\u68C0\u6D4B\u5230 three-end managed blocks\uFF1B\u53EF\u80FD\u5C1A\u672A\u4F20\u64AD\uFF0C\u6216\u4ECD\u5904\u4E8E legacy-marker \u72B6\u6001\u3002",
1025
1072
  "doctor.check.bootstrap_anchor.name": "Bootstrap anchor",
1026
1073
  "doctor.check.bootstrap_anchor.message.missing": "repo root \u4E0B AGENTS.md \u4E0E CLAUDE.md \u90FD\u4E0D\u5B58\u5728\u3002Fabric \u9700\u8981\u5728\u9879\u76EE\u6839\u76EE\u5F55\u5B58\u5728 bootstrap anchor \u6587\u4EF6\u3002",
1027
- "doctor.check.bootstrap_anchor.remediation.missing": "\u8FD0\u884C `fabric install` \u5728 repo root \u751F\u6210 AGENTS.md / CLAUDE.md bootstrap anchor\u3002",
1074
+ "doctor.check.bootstrap_anchor.remediation.missing": "\u8FD0\u884C `fab install` \u5728 repo root \u751F\u6210 AGENTS.md / CLAUDE.md bootstrap anchor\u3002",
1028
1075
  "doctor.check.bootstrap_anchor.ok": "repo root \u4E0B\u5DF2\u5B58\u5728 Bootstrap anchor\uFF1A{present}\u3002",
1029
1076
  "doctor.check.baseline_filename_format.name": "Baseline \u6587\u4EF6\u540D\u683C\u5F0F",
1030
1077
  "doctor.check.baseline_filename_format.ok": "\u6240\u6709 baseline knowledge \u6587\u4EF6\u90FD\u4F7F\u7528 canonical `${id}--${slug}.md` \u6587\u4EF6\u540D\u683C\u5F0F\u3002",
1031
1078
  "doctor.check.baseline_filename_format.message.singular": "{count} \u4E2A baseline knowledge \u6587\u4EF6\u4ECD\u4F7F\u7528\u5DF2\u5E9F\u5F03\u7684 bare-slug \u6587\u4EF6\u540D\u683C\u5F0F\uFF0C\u5FC5\u987B\u8FC1\u79FB\u4E3A `${id}--${slug}.md`\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1032
1079
  "doctor.check.baseline_filename_format.message.plural": "{count} \u4E2A baseline knowledge \u6587\u4EF6\u4ECD\u4F7F\u7528\u5DF2\u5E9F\u5F03\u7684 bare-slug \u6587\u4EF6\u540D\u683C\u5F0F\uFF0C\u5FC5\u987B\u8FC1\u79FB\u4E3A `${id}--${slug}.md`\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1033
- "doctor.check.baseline_filename_format.remediation": "\u624B\u52A8\u5220\u9664\u65E7 bare-slug baseline file(s)\uFF1Bbaseline pipeline \u5DF2\u5728 rc.23 \u79FB\u9664\uFF0C\u4E0D\u518D\u63D0\u4F9B auto-fix \u8DEF\u5F84\u3002",
1080
+ // v2.0.0-rc.33 W3-2 (T6 #5): 文案显式引用 message 内已列出的 detail (file), 让用户直接 rm 而非自己去 grep 找。baseline pipeline rc.23 移除, 没有 auto-fix
1081
+ "doctor.check.baseline_filename_format.remediation": "\u624B\u52A8\u5220\u9664\u4E0A\u9762 message \u4E2D\u5217\u51FA\u7684 bare-slug baseline file(s) (\u4F8B\u5982 `rm <message \u5217\u51FA\u7684 file>`);baseline pipeline \u5DF2\u5728 rc.23 \u79FB\u9664, \u4E0D\u518D\u63D0\u4F9B auto-fix \u8DEF\u5F84\u3002",
1034
1082
  "doctor.check.knowledge_dir_missing.name": "Knowledge layout",
1035
1083
  "doctor.check.knowledge_dir_missing.message.singular": "{count} \u4E2A\u5FC5\u9700 knowledge subdir \u7F3A\u5931\uFF1A{list}\u3002",
1036
1084
  "doctor.check.knowledge_dir_missing.message.plural": "{count} \u4E2A\u5FC5\u9700 knowledge subdir \u7F3A\u5931\uFF1A{list}\u3002",
@@ -1047,7 +1095,7 @@ var zhCNMessages = {
1047
1095
  "doctor.check.agents_meta.message.missing": ".fabric/agents.meta.json \u7F3A\u5931\u3002",
1048
1096
  "doctor.check.agents_meta.remediation.missing": "\u8FD0\u884C `fab doctor --fix` \u4ECE .fabric/knowledge/ \u91CD\u5EFA agents.meta.json\u3002",
1049
1097
  "doctor.check.agents_meta.message.invalid-default": ".fabric/agents.meta.json \u65E0\u6548\u3002",
1050
- "doctor.check.agents_meta.remediation.invalid": "\u5220\u9664 .fabric/agents.meta.json \u5E76\u8FD0\u884C `fab doctor --fix` \u91CD\u65B0\u751F\u6210\u3002",
1098
+ "doctor.check.agents_meta.remediation.invalid": "\u8FD0\u884C `fab doctor --fix` \u8BA9 reconcile \u4ECE .fabric/knowledge/ \u78C1\u76D8 ground-truth \u91CD\u5EFA agents.meta.json\uFF08rc.31 \u8D77\u517C\u5BB9\u5386\u53F2 schema \u7684 singular knowledge_type \u81EA\u52A8\u8FC1\u79FB\u5230 plural\uFF1B\u4E0D\u8981\u624B\u52A8\u5220\u9664 agents.meta.json\uFF0C\u4F1A\u4E22 counters envelope \u4E0E promote ledger \u5173\u8054\uFF09\u3002",
1051
1099
  "doctor.check.agents_meta.message.stale": ".fabric/agents.meta.json revision {revision} \u4E0E .fabric/knowledge \u6D3E\u751F revision {computedRevision} \u4E0D\u4E00\u81F4\u3002",
1052
1100
  "doctor.check.agents_meta.remediation.stale": "\u53EF\u5FFD\u7565\uFF1Bengine \u4F1A\u5728\u4E0B\u4E00\u6B21 plan-context/get-sections \u8C03\u7528\u65F6\u81EA\u52A8\u4FEE\u590D\u3002\u9700\u8981\u663E\u5F0F reconcile \u65F6\u8FD0\u884C `fab doctor --fix`\u3002",
1053
1101
  "doctor.check.agents_meta.ok": ".fabric/agents.meta.json revision {revision} \u5DF2\u4E0E .fabric/knowledge \u5BF9\u9F50\u3002",
@@ -1056,7 +1104,8 @@ var zhCNMessages = {
1056
1104
  "doctor.check.rule_content_refs.remediation.unavailable": "\u5148\u4FEE\u590D agents.meta.json\uFF1A\u8FD0\u884C `fab doctor --fix`\u3002",
1057
1105
  "doctor.check.rule_content_refs.message.outside.singular": "{count} \u4E2A content_ref entry \u4F4D\u4E8E .fabric/knowledge \u5916\u90E8\u3002",
1058
1106
  "doctor.check.rule_content_refs.message.outside.plural": "{count} \u4E2A content_ref entries \u4F4D\u4E8E .fabric/knowledge \u5916\u90E8\u3002",
1059
- "doctor.check.rule_content_refs.remediation.outside": "\u7F16\u8F91 agents.meta.json\uFF0C\u786E\u4FDD\u6240\u6709 content_ref \u503C\u90FD\u6307\u5411 .fabric/knowledge/{type}/\uFF08team\uFF09\u6216 ~/.fabric/knowledge/{type}/\uFF08personal\uFF09\u5185\u90E8\u3002",
1107
+ // v2.0.0-rc.33 W3-2 (T6 #12): 项目规则禁止手动编辑 agents.meta.json (见 .fabric/AGENTS.md); 改引导用户跑 doctor --fix 走 reconcile 路径 (rc.31+ 兼容自动剔除外部 refs)。
1108
+ "doctor.check.rule_content_refs.remediation.outside": "\u8FD0\u884C `fab doctor --fix` \u8BA9 reconcile \u81EA\u52A8\u5254\u9664\u5916\u90E8 content_ref (rc.31+ \u517C\u5BB9)\u3002\u4E25\u7981\u624B\u52A8\u7F16\u8F91 agents.meta.json \u2014 engine \u4F1A\u81EA\u52A8 reconcile\u3002",
1060
1109
  "doctor.check.rule_content_refs.message.missing.singular": "{count} \u4E2A content_ref target \u7F3A\u5931\u3002\u8FD0\u884C `fab doctor --fix` \u6267\u884C reconcile\u3002",
1061
1110
  "doctor.check.rule_content_refs.message.missing.plural": "{count} \u4E2A content_ref targets \u7F3A\u5931\u3002\u8FD0\u884C `fab doctor --fix` \u6267\u884C reconcile\u3002",
1062
1111
  "doctor.check.rule_content_refs.remediation.missing": "\u8FD0\u884C `fab doctor --fix` \u8BA9 agents.meta.json \u4E0E .fabric/knowledge/ \u4E2D\u7684\u73B0\u6709\u6587\u4EF6 reconcile\u3002",
@@ -1076,7 +1125,8 @@ var zhCNMessages = {
1076
1125
  "doctor.check.event_ledger.message.not_writable-default": ".fabric/events.jsonl \u4E0D\u53EF\u5199\u3002",
1077
1126
  "doctor.check.event_ledger.remediation.not_writable": "\u68C0\u67E5 .fabric/events.jsonl \u7684\u6587\u4EF6\u6743\u9650\uFF0C\u5E76\u786E\u8BA4\u6CA1\u6709\u5176\u4ED6\u8FDB\u7A0B\u6301\u6709\u5199\u9501\u3002",
1078
1127
  "doctor.check.event_ledger.message.invalid-default": ".fabric/events.jsonl \u65E0\u6548\u3002",
1079
- "doctor.check.event_ledger.remediation.invalid": "\u5220\u9664 .fabric/events.jsonl \u5E76\u8FD0\u884C `fab doctor --fix` \u91CD\u65B0\u521B\u5EFA\u3002",
1128
+ // v2.0.0-rc.33 W3-1 (P0-6): archive-history 模式 — 引导用户先 mv 备份到 events.archive/ 保留历史, 再跑 --fix 重建空 ledger。与 rotateEventLedgerIfNeeded 的命名约定一致 (events-rotated-YYYY-MM-DD.jsonl 是滑窗 rotation; events-corrupted-YYYY-MM-DD.jsonl 是 invalid-fix 归档)。
1129
+ "doctor.check.event_ledger.remediation.invalid": "\u5148\u5F52\u6863\u5386\u53F2 (`mkdir -p .fabric/events.archive && mv .fabric/events.jsonl .fabric/events.archive/events-corrupted-$(date +%Y-%m-%d).jsonl`), \u518D\u8FD0\u884C `fab doctor --fix` \u521B\u5EFA\u65B0\u7A7A ledger\u3002\u5386\u53F2\u4E8B\u4EF6\u4FDD\u7559\u5728 events.archive/ \u4E0D\u4E22\u3002",
1080
1130
  "doctor.check.event_ledger.ok": ".fabric/events.jsonl \u5DF2\u5B58\u5728\uFF0C\u53EF\u5199\uFF0C\u4E14\u53EF\u89E3\u6790\u3002",
1081
1131
  "doctor.check.mcp_config_in_wrong_file.name": "Claude MCP config \u4F4D\u7F6E",
1082
1132
  "doctor.check.mcp_config_in_wrong_file.message": ".claude/settings.json \u5305\u542B mcpServers.fabric\uFF1B\u6B64\u6587\u4EF6\u4EC5\u7528\u4E8E hooks/permissions\u3002\u8FD0\u884C --fix \u79FB\u9664\u5B83\uFF0C\u7136\u540E\u91CD\u65B0\u8FD0\u884C fab install \u5199\u5165 .mcp.json\u3002",
@@ -1093,12 +1143,36 @@ var zhCNMessages = {
1093
1143
  "doctor.check.event_ledger_schema_compat.ok.clean": "events.jsonl \u6240\u6709\u884C\u90FD\u80FD\u89E3\u6790\u4E3A\u5F53\u524D schema\u3002",
1094
1144
  "doctor.check.event_ledger_schema_compat.message.schema_version": "events.jsonl \u542B {count} \u884C `schema_version` \u4E0D\u88AB\u5F53\u524D CLI \u8BC6\u522B\uFF08\u6837\u672C: {samples}\uFF09\u3002",
1095
1145
  "doctor.check.event_ledger_schema_compat.message.event_type": "events.jsonl \u542B {count} \u884C `event_type` \u4E0D\u5728\u5F53\u524D schema \u4E2D\uFF08\u6837\u672C: {samples}\uFF09\u3002",
1096
- "doctor.check.event_ledger_schema_compat.remediation": "\u5347\u7EA7 fab CLI \u5230\u4E0E server \u517C\u5BB9\u7684\u7248\u672C\uFF0C\u6216\u5907\u4EFD `.fabric/events.jsonl` \u540E\u8DD1 `fab doctor --fix` \u91CD\u5EFA\u7A7A ledger\u3002",
1146
+ // v2.0.0-rc.33 W3-1 (P0-6): archive-history 模式 event_ledger.invalid, 文案显式说"归档备份"而非"备份后重建",避免用户误以为旧 ledger 被丢弃。
1147
+ "doctor.check.event_ledger_schema_compat.remediation": "\u5347\u7EA7 fab CLI \u5230\u4E0E server \u517C\u5BB9\u7684\u7248\u672C (\u9996\u9009);\u6216\u5148\u5F52\u6863\u5386\u53F2 (`mkdir -p .fabric/events.archive && mv .fabric/events.jsonl .fabric/events.archive/events-schema-mismatch-$(date +%Y-%m-%d).jsonl`),\u518D\u8DD1 `fab doctor --fix` \u521B\u5EFA\u65B0\u7A7A ledger\u3002\u5386\u53F2\u4E8B\u4EF6\u4FDD\u7559\u5728 events.archive/ \u4E0D\u4E22,\u53EF\u540E\u7EED\u624B\u52A8\u8FC1\u79FB\u3002",
1097
1148
  // v2.0.0-rc.28 TASK-04 (audit §3.1): SKILL ref/ 镜像一致性检查。
1098
1149
  "doctor.check.skill_ref_mirror.name": "Skill ref \u955C\u50CF\u4E00\u81F4\u6027",
1099
1150
  "doctor.check.skill_ref_mirror.ok": "`.claude/skills/<slug>/ref/` \u4E0E `.codex/skills/<slug>/ref/` \u5B57\u8282\u4E00\u81F4\u3002",
1100
1151
  "doctor.check.skill_ref_mirror.message": "\u6709 {count} \u4E2A ref \u6587\u4EF6\u5728 `.claude/skills/` \u4E0E `.codex/skills/` \u4E4B\u95F4\u4E0D\u4E00\u81F4\uFF08\u8DEF\u5F84: {list}\uFF09\u3002\u53EF\u80FD\u67D0\u7AEF\u88AB\u624B\u52A8\u7F16\u8F91\u6216 install \u5199\u5165\u5931\u8D25\u3002",
1101
1152
  "doctor.check.skill_ref_mirror.remediation": "\u8DD1 `fab install` \u4ECE canonical templates \u91CD\u5199\u4E24\u7AEF ref \u5B50\u6811\u4EE5\u6062\u590D\u4E00\u81F4\u3002",
1153
+ // v2.0.0-rc.33 W3-6 (P1-13): SKILL.md token budget lint。warn > 5K / error > 10K token (chars/3 估算)。基于 Anthropic 推荐 SKILL.md 热路径 ~3K, 超过 5K 已影响 progressive disclosure;超过 10K 是阻断级 (model context 浪费 + 加载延迟)。
1154
+ "doctor.check.skill_token_budget.name": "Skill token budget",
1155
+ "doctor.check.skill_token_budget.ok": "\u6240\u6709 .claude/skills/<slug>/SKILL.md \u5728 token budget \u5185 (warn 5K / error 10K)\u3002",
1156
+ "doctor.check.skill_token_budget.message.singular": "{count} \u4E2A SKILL.md \u8D85\u51FA token budget: {list}\u3002\u5EFA\u8BAE\u628A\u8BE6\u7EC6\u5185\u5BB9\u4E0B\u6C89\u5230 ref/ progressive disclosure\u3002",
1157
+ "doctor.check.skill_token_budget.message.plural": "{count} \u4E2A SKILL.md \u8D85\u51FA token budget: {list}\u3002\u5EFA\u8BAE\u628A\u8BE6\u7EC6\u5185\u5BB9\u4E0B\u6C89\u5230 ref/ progressive disclosure\u3002",
1158
+ "doctor.check.skill_token_budget.remediation": "\u5C06\u8D85\u6807 SKILL.md \u4E2D\u7684\u8BE6\u7EC6 phase / worked-examples / decision \u8868\u79FB\u5230 `templates/skills/<slug>/ref/*.md`,SKILL.md \u70ED\u8DEF\u5F84\u53EA\u7559 trigger gate + \u5173\u952E phase \u6982\u8981;\u53C2\u8003 W1 progressive disclosure \u62C6\u5206\u6A21\u5F0F\u3002\u91CD\u65B0\u8DD1 `fab install` \u540C\u6B65\u4E24\u7AEF\u3002",
1159
+ // v2.0.0-rc.33 W3-7 (P1-14): SKILL.md description 结构 lint。代理 trigger-recall (真 LLM 测要 live model, W1 已用 gemini 跑过);本 lint 抓回归: description 缺失 / 超 60 token / 缺中文 trigger / 缺英文 trigger。
1160
+ "doctor.check.skill_description.name": "Skill description quality",
1161
+ "doctor.check.skill_description.ok": "\u6240\u6709 SKILL.md description \u5B57\u6BB5\u7ED3\u6784\u826F\u597D (\u975E\u7A7A / <60 token / \u4E2D\u82F1\u53CC\u8BED trigger)\u3002",
1162
+ "doctor.check.skill_description.message.singular": "{count} \u4E2A SKILL.md description \u7ED3\u6784\u95EE\u9898: {list}\u3002description \u662F host \u7AEF auto-invoke \u7684\u4E3B\u8981\u5339\u914D\u4FE1\u53F7\u3002",
1163
+ "doctor.check.skill_description.message.plural": "{count} \u4E2A SKILL.md description \u7ED3\u6784\u95EE\u9898: {list}\u3002description \u662F host \u7AEF auto-invoke \u7684\u4E3B\u8981\u5339\u914D\u4FE1\u53F7\u3002",
1164
+ "doctor.check.skill_description.remediation": "\u7F16\u8F91 `packages/cli/templates/skills/<slug>/SKILL.md` frontmatter `description:` \u5B57\u6BB5: (1) \u975E\u7A7A; (2) <60 token (chars/3 \u4F30\u7B97, \u7EA6 180 \u5B57\u7B26); (3) \u81F3\u5C11 1 \u4E2A\u4E2D\u6587 trigger \u77ED\u8BED; (4) \u81F3\u5C11 1 \u4E2A\u82F1\u6587 trigger \u77ED\u8BED\u3002\u53C2\u8003 W1 description rewrite \u98CE\u683C\u3002\u91CD\u65B0\u8DD1 `fab install` \u540C\u6B65\u4E24\u7AEF\u3002\u5982\u9700\u9A8C\u8BC1 recall, \u8DD1 W1 \u7684 gemini delegate (\u89C1 .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md)\u3002",
1165
+ // v2.0.0-rc.33 W3-3 (P1-3): cite-policy Goodhart 模式检测。扫 7d 内 assistant_turn_observed 事件, 4 个 anti-pattern (G1 仪式化 / G2 抄底引用 / G3 chained-from 滥用 / G5 placeholder cite)。warning 级 (启发式有 false-positive, 不阻断)。
1166
+ "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
1167
+ "doctor.check.cite_goodhart.ok": "\u8FC7\u53BB 7d \u672A\u68C0\u6D4B\u5230 cite-policy Goodhart \u53CD\u6A21\u5F0F\u3002",
1168
+ "doctor.check.cite_goodhart.message.singular": "\u68C0\u6D4B\u5230 {count} \u4E2A cite-policy Goodhart \u6A21\u5F0F: {list}\u3002",
1169
+ "doctor.check.cite_goodhart.message.plural": "\u68C0\u6D4B\u5230 {count} \u4E2A cite-policy Goodhart \u6A21\u5F0F: {list}\u3002",
1170
+ "doctor.check.cite_goodhart.remediation": "\u5BA1\u9605\u89E6\u53D1\u7684 pattern: G1 \u4EEA\u5F0F\u5316 \u2192 \u540C\u4E00 [recalled] cite \u91CD\u590D\u7528,\u8BE5\u628A KB \u771F\u6B63\u843D\u5230 contract; G2 \u6284\u5E95\u5F15\u7528 \u2192 > 60% recalled \u7528 skip: \u662F\u7ED5\u8FC7 contract, review skip reason \u771F\u5B9E\u6027; G3 chained-from \u6EE5\u7528 \u2192 chained-from \u6807\u4E86\u4F46\u6CA1 commitment, \u8981\u8865 operators \u6216\u6539\u7528\u5176\u4ED6 tag; G5 placeholder cite \u2192 'KB: none' / [unspecified] \u592A\u591A, \u8BE5\u7528\u5177\u4F53 sentinel \u5982 [no-relevant] / [not-applicable]\u3002\u8BE6\u7EC6\u6570\u636E\u8DD1 `fab doctor --cite-coverage --since=7d`\u3002",
1171
+ // v2.0.0-rc.33 W4-A4 (T5 P2): draft-backlog lint。rc.32 baseline 92% entry 卡在 draft, 揭示 promote 断流。> 50% draft 触发 warning (workspace 必须 >= 10 entries 才计算比率, 避免小语料噪音)。
1172
+ "doctor.check.draft_backlog.name": "Knowledge draft backlog",
1173
+ "doctor.check.draft_backlog.ok": "canonical knowledge entries \u4E2D draft \u5360\u6BD4\u6B63\u5E38 (< 50%, \u6216 workspace \u592A\u5C0F\u4E0D\u8BC4)\u3002",
1174
+ "doctor.check.draft_backlog.message": "{draftCount}/{totalCount} ({pct}%) canonical knowledge entries \u5361\u5728 draft maturity \u2014 promote \u65AD\u6D41 (rc.32 baseline 92%)\u3002",
1175
+ "doctor.check.draft_backlog.remediation": "\u8C03 `/fabric-review` \u6279\u91CF\u5BA1 draft entries: approve \u5347 verified/proven, reject \u4E22, modify \u4FEE\u3002draft \u957F\u671F\u5806\u79EF\u901A\u5E38\u610F\u5473\u7740 archive skill \u4EA7 draft \u592A\u5FEB\u6216 review skill \u6CA1\u8DDF\u4E0A\u3002",
1102
1176
  "doctor.check.meta_manually_diverged.name": "Meta manual divergence",
1103
1177
  "doctor.check.meta_manually_diverged.ok.unreadable": "agents.meta.json \u4E0D\u53EF\u8BFB\uFF0C\u8DF3\u8FC7 divergence \u68C0\u67E5\u3002",
1104
1178
  "doctor.check.meta_manually_diverged.message.extra.singular": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entry \u5728\u78C1\u76D8\u4E0A\u6CA1\u6709\u5BF9\u5E94\u6587\u4EF6\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
@@ -1116,7 +1190,8 @@ var zhCNMessages = {
1116
1190
  "doctor.check.stable_id_collision.name": "Stable ID collision",
1117
1191
  "doctor.check.stable_id_collision.message.singular": 'stable_id "{stableId}" \u88AB\u58F0\u660E\u5728 {fileCount} \u4E2A\u6587\u4EF6\u4E2D\uFF1A{files}\u3002\u8BF7\u7F16\u8F91\u5176\u4E2D\u4E00\u4E2A knowledge file\uFF0C\u6539\u7528\u552F\u4E00 stable_id\u3002',
1118
1192
  "doctor.check.stable_id_collision.message.plural": '\u68C0\u6D4B\u5230 {count} \u4E2A stable_id collisions\u3002\u9996\u4E2A\uFF1A"{stableId}" \u4F4D\u4E8E {files}\u3002\u8BF7\u7F16\u8F91\u5176\u4E2D\u4E00\u4E2A knowledge file\uFF0C\u6539\u7528\u552F\u4E00 stable_id\u3002',
1119
- "doctor.check.stable_id_collision.remediation": "\u7F16\u8F91\u5176\u4E2D\u4E00\u4E2A colliding knowledge file\uFF0C\u6539\u7528\u4E0D\u540C\u7684 `id: K[PT]-XXX-NNNN` frontmatter \u503C\u3002",
1193
+ // v2.0.0-rc.33 W3-2 (T6 #27): fabric-review modify 流程让 canonical id allocator 重新分配, 而非让用户自己选 id (易撞 counter, 难手算)。
1194
+ "doctor.check.stable_id_collision.remediation": "\u8C03 `/fabric-review modify <message \u4E2D\u5217\u51FA\u7684 colliding id \u4E4B\u4E00>`, \u8BA9 canonical id allocator \u81EA\u52A8\u91CD\u5206\u914D id (\u4F1A\u540C\u6B65\u66F4\u65B0 frontmatter + counters + \u5386\u53F2 cross-ref)\u3002\u4E25\u7981\u624B\u5DE5\u7F16\u8F91 id frontmatter \u2014 \u4F1A\u649E counter\u3002",
1120
1195
  "doctor.check.stable_id_collision.ok": ".fabric/knowledge/ \u4E2D\u672A\u53D1\u73B0\u5DF2\u58F0\u660E\u7684 stable_id collisions\u3002",
1121
1196
  "doctor.check.counter_desync.name": "Knowledge counter desync",
1122
1197
  "doctor.check.counter_desync.message.singular": "{count} \u4E2A knowledge counter \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E0D\u540C\u6B65\u3002{counterPath} = {current}\uFF0C\u4F46\u68C0\u6D4B\u5230 {observedId}\u3002\u8FD0\u884C `fab doctor --fix` bump counters\u3002",
@@ -1136,12 +1211,12 @@ var zhCNMessages = {
1136
1211
  "doctor.check.orphan_demote.ok": "\u6CA1\u6709 canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\u3002",
1137
1212
  "doctor.check.orphan_demote.message.singular": "{count} \u4E2A canonical knowledge entry \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\uFF08stable={stableDays}d / endorsed={endorsedDays}d / draft={draftDays}d\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1138
1213
  "doctor.check.orphan_demote.message.plural": "{count} \u4E2A canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\uFF08stable={stableDays}d / endorsed={endorsedDays}d / draft={draftDays}d\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1139
- "doctor.check.orphan_demote.remediation": "\u8FD0\u884C `fab doctor --apply-lint`\uFF08rc.4 TASK-003\uFF09\u5C06 orphan entries \u964D\u7EA7\u4E00\u4E2A maturity tier\u3002",
1214
+ "doctor.check.orphan_demote.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 orphan entries \u964D\u7EA7\u4E00\u4E2A maturity tier\u3002",
1140
1215
  "doctor.check.stale_archive.name": "Knowledge stale archive",
1141
1216
  "doctor.check.stale_archive.ok": "\u6CA1\u6709 draft knowledge entries \u8D85\u8FC7\u989D\u5916\u7684 stale-archive quiet window\u3002",
1142
1217
  "doctor.check.stale_archive.message.singular": "{count} \u4E2A draft knowledge entry \u5DF2\u8D85\u8FC7 demote+{additionalDays}d \u989D\u5916 quiet window\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1143
1218
  "doctor.check.stale_archive.message.plural": "{count} \u4E2A draft knowledge entries \u5DF2\u8D85\u8FC7 demote+{additionalDays}d \u989D\u5916 quiet window\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1144
- "doctor.check.stale_archive.remediation": "\u8FD0\u884C `fab doctor --apply-lint`\uFF08rc.4 TASK-003\uFF09\u5C06 stale entries \u79FB\u52A8\u5230 `.fabric/.archive/<type>/`\u3002",
1219
+ "doctor.check.stale_archive.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 stale entries \u79FB\u52A8\u5230 `.fabric/.archive/<type>/`\u3002",
1145
1220
  "doctor.check.pending_overdue.name": "Knowledge pending overdue",
1146
1221
  "doctor.check.pending_overdue.ok": "\u6CA1\u6709 pending knowledge entries \u8D85\u8FC7 14-day review threshold\u3002",
1147
1222
  "doctor.check.pending_overdue.message.singular": "{count} \u4E2A pending knowledge entry \u5DF2\u7B49\u5F85 review \u8D85\u8FC7 {thresholdDays} \u5929\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
@@ -1151,17 +1226,19 @@ var zhCNMessages = {
1151
1226
  "doctor.check.stable_id_duplicate.ok": "team / personal trees \u4E2D\u6CA1\u6709 canonical knowledge files \u5171\u4EAB stable_id\u3002",
1152
1227
  "doctor.check.stable_id_duplicate.message.singular": "{count} \u4E2A stable_id \u5728 canonical knowledge files \u4E2D\u91CD\u590D\uFF08path-decoupled identity invariant\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1153
1228
  "doctor.check.stable_id_duplicate.message.plural": "{count} \u4E2A stable_ids \u5728 canonical knowledge files \u4E2D\u91CD\u590D\uFF08path-decoupled identity invariant\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1154
- "doctor.check.stable_id_duplicate.remediation": "\u624B\u52A8\u5C06\u5176\u4E2D\u4E00\u4E2A colliding file \u91CD\u547D\u540D\u4E3A\u901A\u8FC7 canonical id allocator \u5206\u914D\u7684\u65B0 `<prefix>-<type>-<counter>--<slug>.md`\uFF1B\u4E0D\u8981\u624B\u5DE5\u7F16\u8F91\u3002",
1229
+ // v2.0.0-rc.33 W3-2 (T6 #34): stable_id_collision fabric-review modify allocator 分配新 id, 不让用户手算。
1230
+ "doctor.check.stable_id_duplicate.remediation": "\u8C03 `/fabric-review modify <message \u4E2D\u5217\u51FA\u7684 duplicate id \u4E4B\u4E00>`, \u7531 canonical id allocator \u5206\u914D\u65B0\u7684 `<prefix>-<type>-<counter>--<slug>.md` (\u4F1A\u540C\u6B65\u91CD\u547D\u540D\u6587\u4EF6 + \u66F4\u65B0 frontmatter + \u4FEE\u6B63 counters)\u3002",
1155
1231
  "doctor.check.layer_mismatch.name": "Knowledge layer mismatch",
1156
1232
  "doctor.check.layer_mismatch.ok": "\u6240\u6709 canonical knowledge files \u90FD\u4F4D\u4E8E stable_id prefix \u58F0\u660E\u7684 layer \u4E0B\u3002",
1157
1233
  "doctor.check.layer_mismatch.message.singular": "{count} \u4E2A canonical knowledge file \u4E0E\u5176 stable_id layer prefix \u7684\u7269\u7406\u4F4D\u7F6E\u4E0D\u4E00\u81F4\uFF08KT-* must live under team/, KP-* under personal/\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1158
1234
  "doctor.check.layer_mismatch.message.plural": "{count} \u4E2A canonical knowledge files \u4E0E\u5176 stable_id layer prefix \u7684\u7269\u7406\u4F4D\u7F6E\u4E0D\u4E00\u81F4\uFF08KT-* must live under team/, KP-* under personal/\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1159
- "doctor.check.layer_mismatch.remediation": "\u5C06\u6587\u4EF6\u79FB\u52A8\u5230\u6B63\u786E\u7684 layer root\uFF0C\u6216\u901A\u8FC7 fabric-review modify \u6D41\u7A0B\u5207\u6362\u5176 layer\uFF08\u4F1A\u76F8\u5E94\u91CD\u547D\u540D stable_id prefix\uFF09\u3002",
1235
+ // v2.0.0-rc.33 W3-2 (T6 #35): skill 入口 (`/fabric-review modify <id>`) 让用户知道怎么 invoke。
1236
+ "doctor.check.layer_mismatch.remediation": "\u5C06\u6587\u4EF6\u79FB\u52A8\u5230\u6B63\u786E\u7684 layer root (KT-* \u2192 .fabric/knowledge/team/, KP-* \u2192 ~/.fabric/knowledge/personal/), \u6216\u8C03 `/fabric-review modify <message \u4E2D\u5217\u51FA\u7684 id>` \u5207\u6362\u5176 layer (\u4F1A\u76F8\u5E94\u91CD\u547D\u540D stable_id prefix)\u3002",
1160
1237
  "doctor.check.index_drift.name": "Knowledge index drift",
1161
1238
  "doctor.check.index_drift.ok": "agents.meta.json counters envelope \u5BF9\u6BCF\u4E2A (layer, type) pair \u90FD\u5927\u4E8E\u6216\u7B49\u4E8E\u73B0\u6709 canonical counter \u6700\u5927\u503C\u3002",
1162
1239
  "doctor.check.index_drift.message.singular": "{count} \u4E2A (layer, type) counter slot \u5DF2\u4F4E\u4E8E\u89C2\u6D4B\u5230\u7684 canonical maximum\uFF08next allocate would collide\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1163
1240
  "doctor.check.index_drift.message.plural": "{count} \u4E2A (layer, type) counter slots \u5DF2\u4F4E\u4E8E\u89C2\u6D4B\u5230\u7684 canonical maximum\uFF08next allocate would collide\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1164
- "doctor.check.index_drift.remediation": "\u8FD0\u884C `fab doctor --apply-lint`\uFF08rc.4 TASK-003\uFF09\u5C06 agents.meta.json counters \u63D0\u5347\u5230 max_observed + 1\u3002",
1241
+ "doctor.check.index_drift.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 agents.meta.json counters \u63D0\u5347\u5230 max_observed + 1\u3002",
1165
1242
  "doctor.check.underseeded.name": "Knowledge underseeded",
1166
1243
  "doctor.check.underseeded.ok": "\u77E5\u8BC6\u5E93\u5DF2\u6709 {count} \u4E2A canonical entries\uFF08>= {threshold}\uFF09\u3002",
1167
1244
  "doctor.check.underseeded.message.singular": "\u77E5\u8BC6\u5E93\u4EC5\u6709 {count} \u4E2A canonical entry\uFF08< {threshold} threshold\uFF09\u3002plan_context \u68C0\u7D22\u9762\u4F4E\u4E8E\u53EF\u7528\u4E0B\u9650\u3002",
@@ -1195,7 +1272,7 @@ var zhCNMessages = {
1195
1272
  "doctor.check.session_hints_stale.ok": ".fabric/.cache/ \u4E0B\u6CA1\u6709\u8D85\u8FC7 {days} \u5929\u7684 session-hints cache files\u3002",
1196
1273
  "doctor.check.session_hints_stale.message.singular": ".fabric/.cache/ \u4E0B\u6709 {count} \u4E2A session-hints cache file \u8D85\u8FC7 {days} \u5929\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1197
1274
  "doctor.check.session_hints_stale.message.plural": ".fabric/.cache/ \u4E0B\u6709 {count} \u4E2A session-hints cache files \u8D85\u8FC7 {days} \u5929\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1198
- "doctor.check.session_hints_stale.remediation": "\u8FD0\u884C `fab doctor --apply-lint` \u5220\u9664\u8FC7\u671F\u7684 session-hints cache files\u3002",
1275
+ "doctor.check.session_hints_stale.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge` \u5220\u9664\u8FC7\u671F\u7684 session-hints cache files\u3002",
1199
1276
  "doctor.check.stale_serve_lock.name": "Serve lock",
1200
1277
  "doctor.check.stale_serve_lock.ok.no_lock": "\u672A\u53D1\u73B0 .fabric/.serve.lock\u3002",
1201
1278
  "doctor.check.stale_serve_lock.ok.live_pid": ".fabric/.serve.lock \u7531 live PID {pid} \u6301\u6709\u3002",
@@ -1209,7 +1286,20 @@ var zhCNMessages = {
1209
1286
  "doctor.check.relevance_fields_missing.ok": "\u6240\u6709 pending entries \u90FD\u58F0\u660E\u4E86 relevance_scope \u548C relevance_paths\u3002",
1210
1287
  "doctor.check.relevance_fields_missing.message.singular": "{count} \u4E2A pending entry \u7684 frontmatter \u7F3A\u5C11 relevance_scope \u548C/\u6216 relevance_paths\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1211
1288
  "doctor.check.relevance_fields_missing.message.plural": "{count} \u4E2A pending entries \u7684 frontmatter \u7F3A\u5C11 relevance_scope \u548C/\u6216 relevance_paths\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
1212
- "doctor.check.relevance_fields_missing.remediation": "\u8FD0\u884C `fab doctor --apply-lint` \u56DE\u586B schema defaults\uFF08relevance_scope: broad\uFF0Crelevance_paths: []\uFF09\u3002",
1289
+ "doctor.check.relevance_fields_missing.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge` \u56DE\u586B schema defaults\uFF08relevance_scope: broad\uFF0Crelevance_paths: []\uFF09\u3002",
1290
+ // rc.31 BUG-M3/NEW-4: hooks_wired observability.
1291
+ "doctor.check.hooks_wired.name": "Claude Code hooks wired",
1292
+ "doctor.check.hooks_wired.ok.skipped": "\u9879\u76EE\u672A\u542F\u7528 Claude Code\uFF08\u65E0 .claude/ \u76EE\u5F55\uFF09\uFF1B\u8DF3\u8FC7 hooks_wired \u68C0\u67E5\u3002",
1293
+ "doctor.check.hooks_wired.ok.wired": ".claude/settings.json \u5DF2\u6CE8\u5165 Stop:fabric-hint / SessionStart:knowledge-hint-broad / PreToolUse:knowledge-hint-narrow \u4E09\u4E2A fabric hook\u3002",
1294
+ "doctor.check.hooks_wired.message.missing_settings": ".claude/ \u76EE\u5F55\u5B58\u5728\u4F46 .claude/settings.json \u7F3A\u5931\u6216\u65E0\u6CD5\u89E3\u6790\uFF1Bfab install \u53EF\u80FD\u4ECE\u672A\u8DD1\u6210\u529F\uFF0C\u6216\u6587\u4EF6\u88AB\u5916\u90E8\u6E05\u7A7A\u3002",
1295
+ "doctor.check.hooks_wired.message.incomplete": ".claude/settings.json \u7F3A\u5C11 fabric hook \u6CE8\u5165\uFF1A{missing}\u3002fab install \u7684 dry-run \u62A5\u544A\u4E0E\u5B9E\u9645\u72B6\u6001\u4E0D\u4E00\u81F4\uFF08rc.30 audit BUG-M3 / NEW-4\uFF09\u3002",
1296
+ "doctor.check.hooks_wired.remediation": "\u8FD0\u884C `fab install` \u91CD\u65B0\u6CE8\u5165 hooks\uFF08\u5E42\u7B49\uFF1B\u53EA\u8865\u7F3A\u5931\u9879\uFF09\u3002\u82E5\u610F\u5916\u8986\u76D6\u4E86 hooks \u914D\u7F6E\uFF0C\u5148\u5907\u4EFD .claude/settings.json \u518D\u8DD1\u3002",
1297
+ // rc.31 BUG-G2/G5: promote-ledger invariant check.
1298
+ "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
1299
+ "doctor.check.promote_ledger_invariant.ok": "knowledge_proposed={proposed} \u2265 knowledge_promote_started={started} \u2265 knowledge_promoted={promoted}\uFF0Cledger \u4E0D\u53D8\u91CF\u6301\u6709\u3002",
1300
+ "doctor.check.promote_ledger_invariant.message.proposed-lt-started": "knowledge_proposed={proposed} \u5C0F\u4E8E knowledge_promote_started={started}\uFF08ledger \u4E0D\u53D8\u91CF\u88AB\u7834\u574F\uFF1B\u90E8\u5206 pending \u5728 approve \u65F6\u672A\u7ECF\u8FC7 fab_extract_knowledge \u2192 \u7F3A\u5C11 propose \u4E8B\u4EF6\uFF09\u3002",
1301
+ "doctor.check.promote_ledger_invariant.message.started-lt-promoted": "knowledge_promote_started={started} \u5C0F\u4E8E knowledge_promoted={promoted}\uFF08ledger \u4E0D\u53D8\u91CF\u88AB\u7834\u574F\uFF1B\u5B58\u5728\u672A\u914D\u5BF9\u7684 promoted \u4E8B\u4EF6\uFF0C\u53EF\u80FD\u6765\u81EA doctor filesystem-edit fallback \u6216\u5916\u90E8\u5199\u5165\uFF09\u3002",
1302
+ "doctor.check.promote_ledger_invariant.remediation": "rc.31 \u8D77 review.approve \u4F1A\u8865\u53D1 knowledge_proposed \u4E8B\u4EF6\u4EE5\u7EF4\u62A4\u4E0D\u53D8\u91CF\uFF1B\u65B0 approve \u540E\u518D\u8DD1\u4E00\u6B21 fab doctor \u5373\u53EF\u6062\u590D\u3002\u5386\u53F2\u5931\u8861\u4EC5\u662F\u53EF\u89C2\u6D4B\u6027\u6307\u793A\uFF0C\u4E0D\u5F71\u54CD KB \u529F\u80FD\u3002",
1213
1303
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
1214
1304
  "doctor.check.skill_md_yaml_invalid.ok": "\u6240\u6709 .claude/.codex SKILL.md frontmatter values \u90FD\u80FD\u6309 strict YAML \u89E3\u6790\u3002",
1215
1305
  "doctor.check.skill_md_yaml_invalid.message.singular": "{count} \u4E2A SKILL.md frontmatter value \u5305\u542B\u672A\u52A0\u5F15\u53F7\u7684 ': '\uFF0Cstrict YAML parsers \u4F1A\u62D2\u7EDD\uFF08Claude Code tolerates it\uFF1BCodex CLI drops the skill at load\uFF09\u3002\u9996\u4E2A\uFF1A{detail}\u3002",
@@ -1396,7 +1486,7 @@ var zhCNMessages = {
1396
1486
  "cli.scan.args.target.description": "\u76EE\u6807\u7EDD\u5BF9\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1397
1487
  "cli.scan.args.debug.description": "\u4EE5\u683C\u5F0F\u5316\u8F93\u51FA\u6253\u5370\u68C0\u6D4B\u8BC1\u636E\u3002",
1398
1488
  "cli.scan.args.json.description": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\u3002",
1399
- "cli.scan.error.missing-forensic": "\u672A\u627E\u5230 forensic.json\uFF08\u8DEF\u5F84 {path}\uFF09\uFF1B\u8BF7\u5148\u8FD0\u884C `fabric install` \u751F\u6210\u9879\u76EE\u5FEB\u7167\u3002",
1489
+ "cli.scan.error.missing-forensic": "\u672A\u627E\u5230 forensic.json\uFF08\u8DEF\u5F84 {path}\uFF09\uFF1B\u8BF7\u5148\u8FD0\u884C `fab install` \u751F\u6210\u9879\u76EE\u5FEB\u7167\u3002",
1400
1490
  "cli.scan.summary.created": "\u5DF2\u5199\u5165 {count} \u6761\u77E5\u8BC6\u6761\u76EE\u81F3 .fabric/knowledge/\u3002",
1401
1491
  "cli.scan.summary.skipped": "\u65E0\u5DEE\u5F02\uFF1B{count} \u6761\u5DF2\u5B58\u5728\u7684\u6761\u76EE\u4FDD\u6301\u4E0D\u53D8\u3002",
1402
1492
  "cli.scan.report.title": "Fabric \u626B\u63CF\u62A5\u544A",
@@ -7,7 +7,7 @@ import {
7
7
  normalizeLocale,
8
8
  resolveFabricLocale,
9
9
  zhCNMessages
10
- } from "../chunk-225L7D4T.js";
10
+ } from "../chunk-Z7UPW75I.js";
11
11
  export {
12
12
  PROTECTED_TOKENS,
13
13
  createTranslator,
@@ -178,6 +178,16 @@ declare const fabricConfigSchema: z.ZodObject<{
178
178
  review_stale_pending_days: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
179
179
  fabric_event_retention_days: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<7>, z.ZodLiteral<30>, z.ZodLiteral<90>]>>;
180
180
  onboard_slots_opted_out: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
181
+ hint_broad_top_k: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
182
+ hint_narrow_top_k: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
183
+ hint_narrow_dedup_window_turns: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
184
+ hint_broad_cooldown_hours: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
185
+ hint_narrow_cooldown_hours: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
186
+ orphan_demote_stable_days: z.ZodOptional<z.ZodNumber>;
187
+ orphan_demote_endorsed_days: z.ZodOptional<z.ZodNumber>;
188
+ orphan_demote_draft_days: z.ZodOptional<z.ZodNumber>;
189
+ hint_summary_max_len: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
190
+ hint_reminder_to_context: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
181
191
  selection_token_ttl_ms: z.ZodOptional<z.ZodNumber>;
182
192
  }, "strip", z.ZodTypeAny, {
183
193
  fabric_language: "match-existing" | "zh-CN" | "en" | "zh-CN-hybrid";
@@ -201,6 +211,13 @@ declare const fabricConfigSchema: z.ZodObject<{
201
211
  review_topic_result_cap: number;
202
212
  review_stale_pending_days: number;
203
213
  onboard_slots_opted_out: string[];
214
+ hint_broad_top_k: number;
215
+ hint_narrow_top_k: number;
216
+ hint_narrow_dedup_window_turns: number;
217
+ hint_broad_cooldown_hours: number;
218
+ hint_narrow_cooldown_hours: number;
219
+ hint_summary_max_len: number;
220
+ hint_reminder_to_context: boolean;
204
221
  clientPaths?: {
205
222
  claudeCodeCLI?: string | undefined;
206
223
  claudeCodeDesktop?: string | undefined;
@@ -214,6 +231,9 @@ declare const fabricConfigSchema: z.ZodObject<{
214
231
  hardBytes?: number | undefined;
215
232
  } | undefined;
216
233
  fabric_event_retention_days?: 7 | 30 | 90 | undefined;
234
+ orphan_demote_stable_days?: number | undefined;
235
+ orphan_demote_endorsed_days?: number | undefined;
236
+ orphan_demote_draft_days?: number | undefined;
217
237
  selection_token_ttl_ms?: number | undefined;
218
238
  }, {
219
239
  clientPaths?: {
@@ -250,6 +270,16 @@ declare const fabricConfigSchema: z.ZodObject<{
250
270
  review_stale_pending_days?: number | undefined;
251
271
  fabric_event_retention_days?: 7 | 30 | 90 | undefined;
252
272
  onboard_slots_opted_out?: string[] | undefined;
273
+ hint_broad_top_k?: number | undefined;
274
+ hint_narrow_top_k?: number | undefined;
275
+ hint_narrow_dedup_window_turns?: number | undefined;
276
+ hint_broad_cooldown_hours?: number | undefined;
277
+ hint_narrow_cooldown_hours?: number | undefined;
278
+ orphan_demote_stable_days?: number | undefined;
279
+ orphan_demote_endorsed_days?: number | undefined;
280
+ orphan_demote_draft_days?: number | undefined;
281
+ hint_summary_max_len?: number | undefined;
282
+ hint_reminder_to_context?: boolean | undefined;
253
283
  selection_token_ttl_ms?: number | undefined;
254
284
  }>;
255
285
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentsMetaNode, a as AgentsIdentitySource, b as AgentsLayer, c as AgentsTopologyType, H as HumanLockEntry, f as fabricConfigSchema, d as AgentsMeta, L as LedgerEntry } from './index-DkXJGQCD.js';
2
- export { e as AgentsActivationTier, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, i as AgentsMetaNodeActivation, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem, o as auditModeSchema, p as clientPathsSchema, q as defaultLayerFilterSchema, r as fabricLanguageSchema, s as mcpPayloadLimitsSchema, t as selectionTokenTtlMsSchema } from './index-DkXJGQCD.js';
1
+ import { A as AgentsMetaNode, a as AgentsIdentitySource, b as AgentsLayer, c as AgentsTopologyType, H as HumanLockEntry, f as fabricConfigSchema, d as AgentsMeta, L as LedgerEntry } from './index-Crx0-0-9.js';
2
+ export { e as AgentsActivationTier, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, i as AgentsMetaNodeActivation, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem, o as auditModeSchema, p as clientPathsSchema, q as defaultLayerFilterSchema, r as fabricLanguageSchema, s as mcpPayloadLimitsSchema, t as selectionTokenTtlMsSchema } from './index-Crx0-0-9.js';
3
3
  export { Locale, Messages, PROTECTED_TOKENS, ProtectedToken, TranslationKey, Translator, createTranslator, defaultMessages, detectNodeLocale, enMessages, normalizeLocale, resolveFabricLocale, zhCNMessages } from './i18n/index.js';
4
4
  import { z } from 'zod';
5
5
  import { Layer, KnowledgeType, StableId } from './schemas/api-contracts.js';
@@ -26,7 +26,7 @@ declare const ruleDescriptionSchema: z.ZodObject<{
26
26
  must_read_if: z.ZodString;
27
27
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
28
28
  id: z.ZodOptional<z.ZodString>;
29
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
29
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
30
30
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
31
31
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
32
32
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -60,7 +60,7 @@ declare const ruleDescriptionSchema: z.ZodObject<{
60
60
  relevance_paths?: string[] | undefined;
61
61
  entities?: string[] | undefined;
62
62
  id?: string | undefined;
63
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
63
+ knowledge_type?: unknown;
64
64
  maturity?: "draft" | "verified" | "proven" | undefined;
65
65
  knowledge_layer?: "personal" | "team" | undefined;
66
66
  layer_reason?: string | undefined;
@@ -80,7 +80,7 @@ declare const ruleDescriptionIndexItemSchema: z.ZodObject<{
80
80
  must_read_if: z.ZodString;
81
81
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
82
82
  id: z.ZodOptional<z.ZodString>;
83
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
83
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
84
84
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
85
85
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
86
86
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -114,7 +114,7 @@ declare const ruleDescriptionIndexItemSchema: z.ZodObject<{
114
114
  relevance_paths?: string[] | undefined;
115
115
  entities?: string[] | undefined;
116
116
  id?: string | undefined;
117
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
117
+ knowledge_type?: unknown;
118
118
  maturity?: "draft" | "verified" | "proven" | undefined;
119
119
  knowledge_layer?: "personal" | "team" | undefined;
120
120
  layer_reason?: string | undefined;
@@ -154,7 +154,7 @@ declare const ruleDescriptionIndexItemSchema: z.ZodObject<{
154
154
  relevance_paths?: string[] | undefined;
155
155
  entities?: string[] | undefined;
156
156
  id?: string | undefined;
157
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
157
+ knowledge_type?: unknown;
158
158
  maturity?: "draft" | "verified" | "proven" | undefined;
159
159
  knowledge_layer?: "personal" | "team" | undefined;
160
160
  layer_reason?: string | undefined;
@@ -191,7 +191,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
191
191
  must_read_if: z.ZodString;
192
192
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
193
193
  id: z.ZodOptional<z.ZodString>;
194
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
194
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
195
195
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
196
196
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
197
197
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -225,7 +225,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
225
225
  relevance_paths?: string[] | undefined;
226
226
  entities?: string[] | undefined;
227
227
  id?: string | undefined;
228
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
228
+ knowledge_type?: unknown;
229
229
  maturity?: "draft" | "verified" | "proven" | undefined;
230
230
  knowledge_layer?: "personal" | "team" | undefined;
231
231
  layer_reason?: string | undefined;
@@ -258,7 +258,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
258
258
  must_read_if: z.ZodString;
259
259
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
260
260
  id: z.ZodOptional<z.ZodString>;
261
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
261
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
262
262
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
263
263
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
264
264
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -292,7 +292,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
292
292
  relevance_paths?: string[] | undefined;
293
293
  entities?: string[] | undefined;
294
294
  id?: string | undefined;
295
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
295
+ knowledge_type?: unknown;
296
296
  maturity?: "draft" | "verified" | "proven" | undefined;
297
297
  knowledge_layer?: "personal" | "team" | undefined;
298
298
  layer_reason?: string | undefined;
@@ -325,7 +325,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
325
325
  must_read_if: z.ZodString;
326
326
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
327
327
  id: z.ZodOptional<z.ZodString>;
328
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
328
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
329
329
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
330
330
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
331
331
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -359,7 +359,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
359
359
  relevance_paths?: string[] | undefined;
360
360
  entities?: string[] | undefined;
361
361
  id?: string | undefined;
362
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
362
+ knowledge_type?: unknown;
363
363
  maturity?: "draft" | "verified" | "proven" | undefined;
364
364
  knowledge_layer?: "personal" | "team" | undefined;
365
365
  layer_reason?: string | undefined;
@@ -392,7 +392,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
392
392
  must_read_if: z.ZodString;
393
393
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
394
394
  id: z.ZodOptional<z.ZodString>;
395
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
395
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
396
396
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
397
397
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
398
398
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -426,7 +426,7 @@ declare const agentsMetaNodeSchema: z.ZodEffects<z.ZodObject<{
426
426
  relevance_paths?: string[] | undefined;
427
427
  entities?: string[] | undefined;
428
428
  id?: string | undefined;
429
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
429
+ knowledge_type?: unknown;
430
430
  maturity?: "draft" | "verified" | "proven" | undefined;
431
431
  knowledge_layer?: "personal" | "team" | undefined;
432
432
  layer_reason?: string | undefined;
@@ -533,7 +533,7 @@ declare const agentsMetaSchema: z.ZodObject<{
533
533
  must_read_if: z.ZodString;
534
534
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
535
535
  id: z.ZodOptional<z.ZodString>;
536
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
536
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
537
537
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
538
538
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
539
539
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -567,7 +567,7 @@ declare const agentsMetaSchema: z.ZodObject<{
567
567
  relevance_paths?: string[] | undefined;
568
568
  entities?: string[] | undefined;
569
569
  id?: string | undefined;
570
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
570
+ knowledge_type?: unknown;
571
571
  maturity?: "draft" | "verified" | "proven" | undefined;
572
572
  knowledge_layer?: "personal" | "team" | undefined;
573
573
  layer_reason?: string | undefined;
@@ -600,7 +600,7 @@ declare const agentsMetaSchema: z.ZodObject<{
600
600
  must_read_if: z.ZodString;
601
601
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
602
602
  id: z.ZodOptional<z.ZodString>;
603
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
603
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
604
604
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
605
605
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
606
606
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -634,7 +634,7 @@ declare const agentsMetaSchema: z.ZodObject<{
634
634
  relevance_paths?: string[] | undefined;
635
635
  entities?: string[] | undefined;
636
636
  id?: string | undefined;
637
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
637
+ knowledge_type?: unknown;
638
638
  maturity?: "draft" | "verified" | "proven" | undefined;
639
639
  knowledge_layer?: "personal" | "team" | undefined;
640
640
  layer_reason?: string | undefined;
@@ -667,7 +667,7 @@ declare const agentsMetaSchema: z.ZodObject<{
667
667
  must_read_if: z.ZodString;
668
668
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
669
669
  id: z.ZodOptional<z.ZodString>;
670
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
670
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
671
671
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
672
672
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
673
673
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -701,7 +701,7 @@ declare const agentsMetaSchema: z.ZodObject<{
701
701
  relevance_paths?: string[] | undefined;
702
702
  entities?: string[] | undefined;
703
703
  id?: string | undefined;
704
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
704
+ knowledge_type?: unknown;
705
705
  maturity?: "draft" | "verified" | "proven" | undefined;
706
706
  knowledge_layer?: "personal" | "team" | undefined;
707
707
  layer_reason?: string | undefined;
@@ -734,7 +734,7 @@ declare const agentsMetaSchema: z.ZodObject<{
734
734
  must_read_if: z.ZodString;
735
735
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
736
736
  id: z.ZodOptional<z.ZodString>;
737
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
737
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
738
738
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
739
739
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
740
740
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -768,7 +768,7 @@ declare const agentsMetaSchema: z.ZodObject<{
768
768
  relevance_paths?: string[] | undefined;
769
769
  entities?: string[] | undefined;
770
770
  id?: string | undefined;
771
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
771
+ knowledge_type?: unknown;
772
772
  maturity?: "draft" | "verified" | "proven" | undefined;
773
773
  knowledge_layer?: "personal" | "team" | undefined;
774
774
  layer_reason?: string | undefined;
@@ -874,7 +874,7 @@ declare const agentsMetaSchema: z.ZodObject<{
874
874
  must_read_if: z.ZodString;
875
875
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
876
876
  id: z.ZodOptional<z.ZodString>;
877
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
877
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
878
878
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
879
879
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
880
880
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -908,7 +908,7 @@ declare const agentsMetaSchema: z.ZodObject<{
908
908
  relevance_paths?: string[] | undefined;
909
909
  entities?: string[] | undefined;
910
910
  id?: string | undefined;
911
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
911
+ knowledge_type?: unknown;
912
912
  maturity?: "draft" | "verified" | "proven" | undefined;
913
913
  knowledge_layer?: "personal" | "team" | undefined;
914
914
  layer_reason?: string | undefined;
@@ -2320,7 +2320,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2320
2320
  must_read_if: z.ZodString;
2321
2321
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2322
2322
  id: z.ZodOptional<z.ZodString>;
2323
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2323
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2324
2324
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2325
2325
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2326
2326
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2354,7 +2354,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2354
2354
  relevance_paths?: string[] | undefined;
2355
2355
  entities?: string[] | undefined;
2356
2356
  id?: string | undefined;
2357
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2357
+ knowledge_type?: unknown;
2358
2358
  maturity?: "draft" | "verified" | "proven" | undefined;
2359
2359
  knowledge_layer?: "personal" | "team" | undefined;
2360
2360
  layer_reason?: string | undefined;
@@ -2387,7 +2387,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2387
2387
  must_read_if: z.ZodString;
2388
2388
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2389
2389
  id: z.ZodOptional<z.ZodString>;
2390
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2390
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2391
2391
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2392
2392
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2393
2393
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2421,7 +2421,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2421
2421
  relevance_paths?: string[] | undefined;
2422
2422
  entities?: string[] | undefined;
2423
2423
  id?: string | undefined;
2424
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2424
+ knowledge_type?: unknown;
2425
2425
  maturity?: "draft" | "verified" | "proven" | undefined;
2426
2426
  knowledge_layer?: "personal" | "team" | undefined;
2427
2427
  layer_reason?: string | undefined;
@@ -2454,7 +2454,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2454
2454
  must_read_if: z.ZodString;
2455
2455
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2456
2456
  id: z.ZodOptional<z.ZodString>;
2457
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2457
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2458
2458
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2459
2459
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2460
2460
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2488,7 +2488,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2488
2488
  relevance_paths?: string[] | undefined;
2489
2489
  entities?: string[] | undefined;
2490
2490
  id?: string | undefined;
2491
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2491
+ knowledge_type?: unknown;
2492
2492
  maturity?: "draft" | "verified" | "proven" | undefined;
2493
2493
  knowledge_layer?: "personal" | "team" | undefined;
2494
2494
  layer_reason?: string | undefined;
@@ -2521,7 +2521,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2521
2521
  must_read_if: z.ZodString;
2522
2522
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2523
2523
  id: z.ZodOptional<z.ZodString>;
2524
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2524
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2525
2525
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2526
2526
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2527
2527
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2555,7 +2555,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2555
2555
  relevance_paths?: string[] | undefined;
2556
2556
  entities?: string[] | undefined;
2557
2557
  id?: string | undefined;
2558
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2558
+ knowledge_type?: unknown;
2559
2559
  maturity?: "draft" | "verified" | "proven" | undefined;
2560
2560
  knowledge_layer?: "personal" | "team" | undefined;
2561
2561
  layer_reason?: string | undefined;
@@ -2661,7 +2661,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2661
2661
  must_read_if: z.ZodString;
2662
2662
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2663
2663
  id: z.ZodOptional<z.ZodString>;
2664
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2664
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2665
2665
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2666
2666
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2667
2667
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2695,7 +2695,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2695
2695
  relevance_paths?: string[] | undefined;
2696
2696
  entities?: string[] | undefined;
2697
2697
  id?: string | undefined;
2698
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2698
+ knowledge_type?: unknown;
2699
2699
  maturity?: "draft" | "verified" | "proven" | undefined;
2700
2700
  knowledge_layer?: "personal" | "team" | undefined;
2701
2701
  layer_reason?: string | undefined;
@@ -2769,7 +2769,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2769
2769
  must_read_if: z.ZodString;
2770
2770
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
2771
2771
  id: z.ZodOptional<z.ZodString>;
2772
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
2772
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
2773
2773
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
2774
2774
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
2775
2775
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -2803,7 +2803,7 @@ declare const metaUpdatedEventSchema: z.ZodObject<{
2803
2803
  relevance_paths?: string[] | undefined;
2804
2804
  entities?: string[] | undefined;
2805
2805
  id?: string | undefined;
2806
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
2806
+ knowledge_type?: unknown;
2807
2807
  maturity?: "draft" | "verified" | "proven" | undefined;
2808
2808
  knowledge_layer?: "personal" | "team" | undefined;
2809
2809
  layer_reason?: string | undefined;
@@ -3598,7 +3598,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3598
3598
  must_read_if: z.ZodString;
3599
3599
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3600
3600
  id: z.ZodOptional<z.ZodString>;
3601
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
3601
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
3602
3602
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
3603
3603
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
3604
3604
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -3632,7 +3632,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3632
3632
  relevance_paths?: string[] | undefined;
3633
3633
  entities?: string[] | undefined;
3634
3634
  id?: string | undefined;
3635
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
3635
+ knowledge_type?: unknown;
3636
3636
  maturity?: "draft" | "verified" | "proven" | undefined;
3637
3637
  knowledge_layer?: "personal" | "team" | undefined;
3638
3638
  layer_reason?: string | undefined;
@@ -3665,7 +3665,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3665
3665
  must_read_if: z.ZodString;
3666
3666
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3667
3667
  id: z.ZodOptional<z.ZodString>;
3668
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
3668
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
3669
3669
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
3670
3670
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
3671
3671
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -3699,7 +3699,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3699
3699
  relevance_paths?: string[] | undefined;
3700
3700
  entities?: string[] | undefined;
3701
3701
  id?: string | undefined;
3702
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
3702
+ knowledge_type?: unknown;
3703
3703
  maturity?: "draft" | "verified" | "proven" | undefined;
3704
3704
  knowledge_layer?: "personal" | "team" | undefined;
3705
3705
  layer_reason?: string | undefined;
@@ -3732,7 +3732,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3732
3732
  must_read_if: z.ZodString;
3733
3733
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3734
3734
  id: z.ZodOptional<z.ZodString>;
3735
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
3735
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
3736
3736
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
3737
3737
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
3738
3738
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -3766,7 +3766,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3766
3766
  relevance_paths?: string[] | undefined;
3767
3767
  entities?: string[] | undefined;
3768
3768
  id?: string | undefined;
3769
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
3769
+ knowledge_type?: unknown;
3770
3770
  maturity?: "draft" | "verified" | "proven" | undefined;
3771
3771
  knowledge_layer?: "personal" | "team" | undefined;
3772
3772
  layer_reason?: string | undefined;
@@ -3799,7 +3799,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3799
3799
  must_read_if: z.ZodString;
3800
3800
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3801
3801
  id: z.ZodOptional<z.ZodString>;
3802
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
3802
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
3803
3803
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
3804
3804
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
3805
3805
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -3833,7 +3833,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3833
3833
  relevance_paths?: string[] | undefined;
3834
3834
  entities?: string[] | undefined;
3835
3835
  id?: string | undefined;
3836
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
3836
+ knowledge_type?: unknown;
3837
3837
  maturity?: "draft" | "verified" | "proven" | undefined;
3838
3838
  knowledge_layer?: "personal" | "team" | undefined;
3839
3839
  layer_reason?: string | undefined;
@@ -3939,7 +3939,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3939
3939
  must_read_if: z.ZodString;
3940
3940
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
3941
3941
  id: z.ZodOptional<z.ZodString>;
3942
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
3942
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
3943
3943
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
3944
3944
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
3945
3945
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -3973,7 +3973,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3973
3973
  relevance_paths?: string[] | undefined;
3974
3974
  entities?: string[] | undefined;
3975
3975
  id?: string | undefined;
3976
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
3976
+ knowledge_type?: unknown;
3977
3977
  maturity?: "draft" | "verified" | "proven" | undefined;
3978
3978
  knowledge_layer?: "personal" | "team" | undefined;
3979
3979
  layer_reason?: string | undefined;
@@ -4047,7 +4047,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
4047
4047
  must_read_if: z.ZodString;
4048
4048
  entities: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
4049
4049
  id: z.ZodOptional<z.ZodString>;
4050
- knowledge_type: z.ZodOptional<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>>;
4050
+ knowledge_type: z.ZodOptional<z.ZodEffects<z.ZodEnum<["models", "decisions", "guidelines", "pitfalls", "processes"]>, "models" | "decisions" | "guidelines" | "pitfalls" | "processes", unknown>>;
4051
4051
  maturity: z.ZodOptional<z.ZodEnum<["draft", "verified", "proven"]>>;
4052
4052
  knowledge_layer: z.ZodOptional<z.ZodEnum<["personal", "team"]>>;
4053
4053
  layer_reason: z.ZodOptional<z.ZodString>;
@@ -4081,7 +4081,7 @@ declare const fabricEventSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
4081
4081
  relevance_paths?: string[] | undefined;
4082
4082
  entities?: string[] | undefined;
4083
4083
  id?: string | undefined;
4084
- knowledge_type?: "models" | "decisions" | "guidelines" | "pitfalls" | "processes" | undefined;
4084
+ knowledge_type?: unknown;
4085
4085
  maturity?: "draft" | "verified" | "proven" | undefined;
4086
4086
  knowledge_layer?: "personal" | "team" | undefined;
4087
4087
  layer_reason?: string | undefined;
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  normalizeLocale,
17
17
  resolveFabricLocale,
18
18
  zhCNMessages
19
- } from "./chunk-225L7D4T.js";
19
+ } from "./chunk-Z7UPW75I.js";
20
20
  import {
21
21
  FabExtractKnowledgeInputSchema,
22
22
  FabExtractKnowledgeInputShape,
@@ -64,6 +64,13 @@ import "./chunk-LXNCAKJZ.js";
64
64
  // src/schemas/agents-meta.ts
65
65
  import { z } from "zod";
66
66
  var FABRIC_AGENTS_PREFIX = ".fabric/agents/";
67
+ var KNOWLEDGE_TYPE_SINGULAR_TO_PLURAL = {
68
+ model: "models",
69
+ decision: "decisions",
70
+ guideline: "guidelines",
71
+ pitfall: "pitfalls",
72
+ process: "processes"
73
+ };
67
74
  var AGENTS_META_LAYERS = ["L0", "L1", "L2"];
68
75
  var AGENTS_META_TOPOLOGY_TYPES = ["mirror", "cross-cutting", "domain", "local", "global"];
69
76
  var AGENTS_META_IDENTITY_SOURCES = ["declared", "derived"];
@@ -79,7 +86,15 @@ var ruleDescriptionSchema = z.object({
79
86
  entities: z.array(z.string()).optional(),
80
87
  // v2.0 knowledge entry fields (TASK-002 schemas). All optional for backward compat.
81
88
  id: z.string().optional(),
82
- knowledge_type: z.enum(["models", "decisions", "guidelines", "pitfalls", "processes"]).optional(),
89
+ // rc.31 NEW-1: forward-compat for legacy on-disk agents.meta.json carrying
90
+ // singular knowledge_type values (model/decision/guideline/pitfall/process).
91
+ // Normalize to canonical plural form before enum validation so doctor and
92
+ // plan-context-hint can load pre-rc.28 meta files without aborting. Disk
93
+ // gets rewritten to plural on next reconcile (via knowledge-meta-builder).
94
+ knowledge_type: z.preprocess(
95
+ (value) => typeof value === "string" && value in KNOWLEDGE_TYPE_SINGULAR_TO_PLURAL ? KNOWLEDGE_TYPE_SINGULAR_TO_PLURAL[value] : value,
96
+ z.enum(["models", "decisions", "guidelines", "pitfalls", "processes"])
97
+ ).optional(),
83
98
  maturity: z.enum(["draft", "verified", "proven"]).optional(),
84
99
  knowledge_layer: z.enum(["personal", "team"]).optional(),
85
100
  layer_reason: z.string().optional(),
@@ -485,6 +500,76 @@ var fabricConfigSchema = z5.object({
485
500
  // Default `[]` keeps the field optional on existing configs — fresh
486
501
  // installs land with no opt-outs.
487
502
  onboard_slots_opted_out: z5.array(z5.string()).optional().default([]),
503
+ // v2.0.0-rc.33 W2-1 (P0-9): TopK upper bound for the broad SessionStart hint
504
+ // banner emitted by knowledge-hint-broad.cjs. After plan-context-hint returns
505
+ // its full broad-scoped index, the hook slices the entries to this many
506
+ // before grouping/truncation rendering — keeps the banner from scrolling off
507
+ // screen on well-seeded repos (Werewolf-class projects routinely surface 40+
508
+ // broad entries which buried the actually-relevant top hits). Default 8 is
509
+ // calibrated against the rc.32 eval baseline (cite-coverage 3.1%): the
510
+ // banner needs to fit in ~1 screenful so the agent actually reads it.
511
+ // Range 1..50; values above 20 effectively disable the cap because the
512
+ // TRUNCATION_THRESHOLD=12 grouped-render kicks in. Mirrors the rc.7 T7 +
513
+ // archive_max_* pattern of externalizing previously-hardcoded thresholds.
514
+ hint_broad_top_k: z5.number().int().min(1).max(50).optional().default(8),
515
+ // v2.0.0-rc.33 W2-1 (P0-9): TopK upper bound for the narrow PreToolUse hint
516
+ // emitted by knowledge-hint-narrow.cjs. After filtering to entries whose
517
+ // `relevance_scope === "narrow"` (rc.27 TASK-005 audit §2.5 fix), the hook
518
+ // slices to this many before the E3 emit-gate / renderSummary pipeline.
519
+ // Default 5 keeps each per-Edit hint terse — five lines max so the agent's
520
+ // working memory is not displaced by an unwieldy banner. Range 1..20.
521
+ hint_narrow_top_k: z5.number().int().min(1).max(20).optional().default(5),
522
+ // v2.0.0-rc.33 W2-1 (P0-9): per-file dedup window (in PreToolUse turns) for
523
+ // the narrow hint. Same (file_path, stable_id) tuple stays silent for this
524
+ // many turns even when the E3 cross-session cache would otherwise re-emit.
525
+ // Closes the rc.32 eval finding that a single hot file (e.g. werewolf
526
+ // GameRoom.tsx edited 30 times in a row) re-fired the same narrow hint
527
+ // each time, training the agent to ignore it. Default 5; range 1..50.
528
+ // Storage: .fabric/.cache/narrow-dedup-window.json — distinct from session-
529
+ // hints cache so a window-only suppression does not poison cross-session
530
+ // dedupe semantics.
531
+ hint_narrow_dedup_window_turns: z5.number().int().min(1).max(50).optional().default(5),
532
+ // v2.0.0-rc.33 W2-5 (P1-8): cooldown between broad SessionStart hint emits,
533
+ // in hours. Distinct from the archive_hint_cooldown_hours that gates the
534
+ // fabric-hint Stop hook — knowledge-hint-broad re-fires on every
535
+ // SessionStart by default (compact / clear / new-window), which on long
536
+ // sessions becomes redundant noise. Setting to 1 means "emit the broad
537
+ // menu at most once per hour"; 0 means "no cooldown, current behavior."
538
+ // Range 0..168 (one week). Stored alongside fabric-hint's cooldown cache
539
+ // under a distinct knowledge-hint-broad key.
540
+ hint_broad_cooldown_hours: z5.number().int().min(0).max(168).optional().default(0),
541
+ // v2.0.0-rc.33 W2-5 (P1-8): cooldown for the narrow PreToolUse hint.
542
+ // Same shape as hint_broad_cooldown_hours but applies to per-Edit hint
543
+ // re-emission across the cooldown window — independent of E3 session-
544
+ // hints dedupe. Default 0 preserves rc.32 behavior; set to e.g. 1 to
545
+ // throttle hint frequency during rapid-fire editing sprints. Range
546
+ // 0..168 (one week).
547
+ hint_narrow_cooldown_hours: z5.number().int().min(0).max(168).optional().default(0),
548
+ // v2.0.0-rc.33 W4-B3 (T5 P2): per-maturity inactivity thresholds (days)
549
+ // driving orphan_demote. Hardcoded at stable=90/endorsed=30/draft=14 in
550
+ // rc.32; chatty workspaces want them tighter, slow ones want them looser.
551
+ // Each field optional; absent → defaults inside doctor.ts apply. Ranges
552
+ // chosen so a typo can't accidentally disable the lint (min 1).
553
+ orphan_demote_stable_days: z5.number().int().min(1).max(3650).optional(),
554
+ orphan_demote_endorsed_days: z5.number().int().min(1).max(3650).optional(),
555
+ orphan_demote_draft_days: z5.number().int().min(1).max(3650).optional(),
556
+ // v2.0.0-rc.33 W4-A3 (T4 P2): per-entry summary truncation length used by
557
+ // knowledge-hint-{broad,narrow}.cjs. Hard-coded at 80 chars in rc.32 — too
558
+ // short for entries with parameterized summaries (e.g. "Use bcrypt with
559
+ // cost=12 for password hashing"), too long for terse pitfalls. Range 40..240;
560
+ // default 80 preserves rc.32 behavior. Both hooks read the same key so the
561
+ // banner styling stays consistent across SessionStart + PreToolUse.
562
+ hint_summary_max_len: z5.number().int().min(40).max(240).optional().default(80),
563
+ // v2.0.0-rc.33 W2-6 (P0-7 + P0-8): when true, knowledge-hint hooks emit
564
+ // their banners as `hookSpecificOutput.additionalContext` JSON on stdout
565
+ // (per Claude Code PreToolUse hook contract — see
566
+ // https://docs.claude.com/en/docs/claude-code/hooks#preToolUse), so the
567
+ // agent receives them in-context instead of as stderr breadcrumbs the
568
+ // user may not surface to the model. Default true reflects the rc.33 cite-
569
+ // coverage focus (rc.32 baseline 3.1% → primary cause: reminders never
570
+ // entered model context). Set false to revert to legacy stderr-only mode
571
+ // for hosts that don't honor the JSON contract.
572
+ hint_reminder_to_context: z5.boolean().optional().default(true),
488
573
  // v2.0.0-rc.29 TASK-008 (BUG-F3): selection-token TTL override. The
489
574
  // `fab_plan_context` MCP tool hands clients a `selection_token` whose default
490
575
  // 5-minute lifetime (`SELECTION_TOKEN_TTL_MS` at
@@ -1,2 +1,2 @@
1
- export { e as AgentsActivationTier, a as AgentsIdentitySource, b as AgentsLayer, d as AgentsMeta, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, i as AgentsMetaNodeActivation, c as AgentsTopologyType, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem } from '../index-DkXJGQCD.js';
1
+ export { e as AgentsActivationTier, a as AgentsIdentitySource, b as AgentsLayer, d as AgentsMeta, g as AgentsMetaCountersEnvelope, h as AgentsMetaKnowledgeTypeCounters, A as AgentsMetaNode, i as AgentsMetaNodeActivation, c as AgentsTopologyType, j as AiLedgerEntry, k as AuditMode, C as ClientPaths, D as DefaultLayerFilter, F as FabricConfig, l as FabricLanguage, m as HumanLedgerEntry, H as HumanLockEntry, L as LedgerEntry, M as McpPayloadLimits, R as RuleDescription, n as RuleDescriptionIndexItem } from '../index-Crx0-0-9.js';
2
2
  import 'zod';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fenglimg/fabric-shared",
3
- "version": "2.0.0-rc.30",
3
+ "version": "2.0.0-rc.33",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",