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

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.
@@ -1,6 +1,6 @@
1
1
  // src/i18n/locales/en.ts
2
2
  var enMessages = {
3
- "cli.main.description": "Fabric CLI - AI agent collaboration framework.\n\nThree-step mental model:\n Install (\u88C5) - fab install one-shot project setup\n Configure (\u914D) - fab config interactive configuration panel\n Run (\u8DD1) - fab serve launch the local MCP HTTP service\n fab doctor run target-state diagnostics\n\nExamples:\n fab install install Fabric in the current project\n fab config open the interactive configuration panel\n fab serve --port 7373 start the MCP HTTP service\n fab doctor --fix repair derived Fabric state\n fab uninstall --dry-run preview uninstall without removing files",
3
+ "cli.main.description": "Fabric CLI - AI agent collaboration framework.\n\nThree-step mental model:\n Install (\u88C5) - fabric install one-shot project setup\n Configure (\u914D) - fabric config interactive configuration panel\n Run (\u8DD1) - fabric serve launch the local MCP HTTP service\n fabric doctor run target-state diagnostics\n\nExamples:\n fabric install install Fabric in the current project\n fabric config open the interactive configuration panel\n fabric serve --port 7373 start the MCP HTTP service\n fabric doctor --fix repair derived Fabric state\n fabric uninstall --dry-run preview uninstall without removing files",
4
4
  "cli.shared.created": "Created",
5
5
  "cli.shared.skipped": "Skipped",
6
6
  "cli.shared.next": "Next",
@@ -38,7 +38,7 @@ var enMessages = {
38
38
  "cli.bootstrap.install.skipped-header": "Skipped {path}: Fabric Bootstrap header already present.",
39
39
  "cli.bootstrap.install.prepended": "Prepended {path}",
40
40
  "cli.bootstrap.errors.unknown-client": 'Unknown client "{client}". Use a comma-separated list such as claude,cursor,codex.',
41
- "cli.config.description": "Open the interactive Fabric configuration panel (language, knowledge layer, audit mode, hint windows, MCP client wiring, etc.).\n\nExamples:\n fab config open the interactive panel\n fab config --target /path edit configuration for a specific project",
41
+ "cli.config.description": "Open the interactive Fabric configuration panel (language, knowledge layer, audit mode, hint windows, MCP client wiring, etc.).\n\nExamples:\n fabric config open the interactive panel\n fabric config --target /path edit configuration for a specific project",
42
42
  "cli.config.args.target.description": "Target project directory (defaults to cwd).",
43
43
  "cli.config.clients.claude": "Claude Code CLI",
44
44
  "cli.config.install.description": "Install Fabric MCP server entries into detected client configs.",
@@ -50,14 +50,14 @@ var enMessages = {
50
50
  "cli.config.install.no-config-path": "Skipping {client}: no config path detected.",
51
51
  "cli.config.install.dry-run": "[dry-run] {client}: would write {path}",
52
52
  "cli.config.install.wrote": "{client}: wrote {path}",
53
- // rc.16 TASK-006 (F1-panel): clack-driven `fab config` interactive panel.
53
+ // rc.16 TASK-006 (F1-panel): clack-driven `fabric config` interactive panel.
54
54
  // Keys consumed by packages/cli/src/commands/config.ts (menu loop +
55
55
  // per-field prompts) and by getPanelFields() (label_i18n_key references).
56
56
  "cli.config.intro": "Fabric Configuration",
57
57
  "cli.config.outro": "Configuration saved.",
58
58
  "cli.config.outro-no-changes": "No changes made.",
59
59
  "cli.config.cancel": "Cancelled.",
60
- "cli.config.non-tty-notice": "fab config requires an interactive terminal. Run it from a TTY to edit configuration fields.",
60
+ "cli.config.non-tty-notice": "fabric config requires an interactive terminal. Run it from a TTY to edit configuration fields.",
61
61
  "cli.config.menu.field-select": "Select a field to edit:",
62
62
  "cli.config.menu.exit": "Exit",
63
63
  "cli.config.value.current": "current: {value}",
@@ -66,7 +66,7 @@ var enMessages = {
66
66
  "cli.config.prompt.text": "Enter a new value for {key} (current: {current}):",
67
67
  "cli.config.write.success": "Saved {key} = {value}",
68
68
  "cli.config.write.failure": "Failed to write fabric-config.json: {message}",
69
- "cli.config.errors.uninit-workspace.message": "Workspace not initialized. Run `fab install` first.",
69
+ "cli.config.errors.uninit-workspace.message": "Workspace not initialized. Run `fabric install` first.",
70
70
  "cli.config.errors.invalid-int": "Must be a positive integer.",
71
71
  "cli.config.errors.unknown-field": "Unknown field selection \u2014 skipping.",
72
72
  "cli.config.errors.no-enum-options": "No enum options available for this field \u2014 skipping.",
@@ -93,14 +93,14 @@ var enMessages = {
93
93
  "cli.config.fields.maintenance_hint_cooldown_days.description": "Cooldown (in days) before the maintenance hint can fire again.",
94
94
  "cli.config.fields.audit_mode.label": "Audit mode",
95
95
  "cli.config.fields.audit_mode.description": "Audit verbosity for human-lock + drift detection (strict / warn / off).",
96
- "cli.doctor.description": "Run Fabric target-state diagnostics (meta sync, knowledge index, bootstrap, events ledger, human-lock drift).\n\nExamples:\n fab doctor read-only diagnostics report\n fab doctor --fix repair derived state (meta + indexes)\n fab doctor --fix-knowledge apply lint mutations (demote / archive)\n fab doctor --json --strict machine-readable output, warnings as errors",
96
+ "cli.doctor.description": "Run Fabric target-state diagnostics (meta sync, knowledge index, bootstrap, events ledger, human-lock drift).\n\nExamples:\n fabric doctor read-only diagnostics report\n fabric doctor --fix repair derived state (meta + indexes)\n fabric doctor --fix-knowledge apply lint mutations (demote / archive)\n fabric doctor --json --strict machine-readable output, warnings as errors",
97
97
  "doctor.section.fixable": "Fixable errors:",
98
98
  "doctor.section.manual": "Manual errors:",
99
99
  "doctor.section.warnings": "Warnings:",
100
100
  "doctor.section.fix-knowledge-mutations": "Fix-knowledge mutations:",
101
101
  // v2.0.0-rc.29 REVIEW (codex LOW-2): F2's payload-limit defaults reach the JSON
102
102
  // envelope but never surfaced in the human renderer, so operators tuning
103
- // `mcpPayloadLimits` had no fast `fab doctor` confirmation that their config
103
+ // `mcpPayloadLimits` had no fast `fabric doctor` confirmation that their config
104
104
  // override took effect. Two strings: a section header + a one-liner row.
105
105
  "doctor.section.payload-limits": "MCP payload limits:",
106
106
  "doctor.payload-limits.line": "warn={warnKb} KB, hard={hardKb} KB (source: {source})",
@@ -137,7 +137,7 @@ var enMessages = {
137
137
  "cite-coverage.contract.cite_id_unresolved": "Unresolved cite IDs",
138
138
  "cite-coverage.contract.skip_count": "Skip bucket",
139
139
  "cite-coverage.contract.status.ok": "ok",
140
- "cite-coverage.contract.status.skipped_bootstrap_drift": "skipped (bootstrap drift \u2014 run `fab install`)",
140
+ "cite-coverage.contract.status.skipped_bootstrap_drift": "skipped (bootstrap drift \u2014 run `fabric install`)",
141
141
  "cite-coverage.contract.status.awaiting_marker": "awaiting first marker emit",
142
142
  // Plural knowledge-type labels (rc.29 BUG-C1: verbatim alignment with
143
143
  // canonical KnowledgeTypeSchema) plus the sixth "unresolved" bucket.
@@ -166,6 +166,9 @@ var enMessages = {
166
166
  "cli.doctor.args.strict.description": "Treat warnings as failures.",
167
167
  "cli.doctor.args.fix-knowledge.description": "Apply knowledge lint mutations: demote orphaned canonical entries, archive stale drafts, and bump drifted index counters. Default doctor run remains report-only.",
168
168
  "cli.doctor.args.yes.description": "Skip the --fix-knowledge safety confirm. Required for non-tty invocations unless FABRIC_NONINTERACTIVE=1 is set in the environment.",
169
+ // rc.35 TASK-12 (P0-11): --verbose unfolds maintainer-audience hints.
170
+ "cli.doctor.args.verbose.description": "Show all action hints including maintainer-audience ones (Fabric contributors editing the source tree). By default these are folded for npm end users.",
171
+ "doctor.maintainer-hint-folded": "(maintainer-only remediation \u2014 re-run with `fabric doctor --verbose` to see)",
169
172
  "cli.doctor.errors.fix-knowledge-fix-mutually-exclusive": "--fix-knowledge and --fix cannot be combined. --fix-knowledge mutates user knowledge state (demote/archive); --fix repairs derived state (meta/index). Run them separately.",
170
173
  // rc.20 TASK-05: --cite-coverage report flags. Read-only; mutually exclusive with --fix/--fix-knowledge.
171
174
  "cli.doctor.args.cite-coverage.description": "Generate cite policy adherence report (read-only; skips standard inspections)",
@@ -183,7 +186,7 @@ var enMessages = {
183
186
  "cli.doctor.args.auto.description": "With --enrich-descriptions: write deterministic stub values for missing fields. Without --auto, the run is read-only.",
184
187
  "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
188
  // 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.",
189
+ "cli.doctor.fix-dry-run-banner": "[dry-run] No mutations were applied. The fixable_errors list below shows what `fabric doctor --fix` would address; rerun without --dry-run to actually fix.",
187
190
  "cli.doctor.errors.enrich-descriptions-mutex": "--enrich-descriptions cannot be combined with --fix, --fix-knowledge, or --cite-coverage. Run them separately.",
188
191
  "doctor.enrich.allComplete": "All canonical knowledge entries already declare intent_clues / tech_stack / impact / must_read_if.",
189
192
  // rc.26 TASK-02a: doctor foundation-batch check messages.
@@ -191,21 +194,21 @@ var enMessages = {
191
194
  "doctor.check.bootstrap_marker_migration.ok": "No legacy fabric:knowledge-base markers detected in bootstrap target files.",
192
195
  "doctor.check.bootstrap_marker_migration.message.singular": "{count} file still carry the legacy fabric:knowledge-base bootstrap marker: {list}.",
193
196
  "doctor.check.bootstrap_marker_migration.message.plural": "{count} files still carry the legacy fabric:knowledge-base bootstrap marker: {list}.",
194
- "doctor.check.bootstrap_marker_migration.remediation": "Run `fab doctor --fix` to migrate to fabric:bootstrap marker",
197
+ "doctor.check.bootstrap_marker_migration.remediation": "Run `fabric doctor --fix` to migrate to fabric:bootstrap marker",
195
198
  "doctor.check.bootstrap_snapshot_drift.name": "Bootstrap snapshot drift",
196
199
  "doctor.check.bootstrap_snapshot_drift.message.drift": ".fabric/AGENTS.md content diverges byte-for-byte from BOOTSTRAP_CANONICAL.",
197
- "doctor.check.bootstrap_snapshot_drift.remediation.drift": "Run `fab doctor --fix` to restore canonical bootstrap snapshot",
200
+ "doctor.check.bootstrap_snapshot_drift.remediation.drift": "Run `fabric doctor --fix` to restore canonical bootstrap snapshot",
198
201
  "doctor.check.bootstrap_snapshot_drift.ok.ok": ".fabric/AGENTS.md byte-equals BOOTSTRAP_CANONICAL.",
199
202
  "doctor.check.bootstrap_snapshot_drift.ok.missing_delegated": ".fabric/AGENTS.md absent \u2014 delegated to bootstrap_anchor_missing.",
200
203
  "doctor.check.managed_block_drift.name": "Managed block drift",
201
204
  "doctor.check.managed_block_drift.message.singular": "{count} three-end managed block diverge from expected body (snapshot + optional project-rules concat): {list}.",
202
205
  "doctor.check.managed_block_drift.message.plural": "{count} three-end managed blocks diverge from expected body (snapshot + optional project-rules concat): {list}.",
203
- "doctor.check.managed_block_drift.remediation": "Run `fab doctor --fix` to restore three-end managed blocks from canonical",
206
+ "doctor.check.managed_block_drift.remediation": "Run `fabric doctor --fix` to restore three-end managed blocks from canonical",
204
207
  "doctor.check.managed_block_drift.ok.ok": "Three-end managed blocks byte-equal expectedBody.",
205
208
  "doctor.check.managed_block_drift.ok.no_managed_block": "No three-end managed blocks detected \u2014 propagation pending or legacy-marker state.",
206
209
  "doctor.check.bootstrap_anchor.name": "Bootstrap anchor",
207
210
  "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.",
208
- "doctor.check.bootstrap_anchor.remediation.missing": "Run `fab install` to generate the AGENTS.md / CLAUDE.md bootstrap anchor at the repo root.",
211
+ "doctor.check.bootstrap_anchor.remediation.missing": "Run `fabric install` to generate the AGENTS.md / CLAUDE.md bootstrap anchor at the repo root.",
209
212
  "doctor.check.bootstrap_anchor.ok": "Bootstrap anchor present at repo root: {present}.",
210
213
  "doctor.check.baseline_filename_format.name": "Baseline filename format",
211
214
  "doctor.check.baseline_filename_format.ok": "All baseline knowledge files use the canonical `${id}--${slug}.md` filename format.",
@@ -216,60 +219,63 @@ var enMessages = {
216
219
  "doctor.check.knowledge_dir_missing.name": "Knowledge layout",
217
220
  "doctor.check.knowledge_dir_missing.message.singular": "{count} required knowledge subdir is missing: {list}.",
218
221
  "doctor.check.knowledge_dir_missing.message.plural": "{count} required knowledge subdirs are missing: {list}.",
219
- "doctor.check.knowledge_dir_missing.remediation": "Run `fab doctor --fix` to create the missing .fabric/knowledge/* subdirectories.",
222
+ "doctor.check.knowledge_dir_missing.remediation": "Run `fabric doctor --fix` to create the missing .fabric/knowledge/* subdirectories.",
220
223
  "doctor.check.knowledge_dir_missing.ok": "All {count} required .fabric/knowledge/* subdirectories exist.",
221
224
  "doctor.check.forensic.name": "Scan evidence",
222
225
  "doctor.check.forensic.message.missing.singular": "{error} Live scan detects {frameworkKind} with {count} entry point.",
223
226
  "doctor.check.forensic.message.missing.plural": "{error} Live scan detects {frameworkKind} with {count} entry points.",
224
227
  "doctor.check.forensic.message.missing-default": ".fabric/forensic.json is missing.",
225
228
  "doctor.check.forensic.message.invalid-default": ".fabric/forensic.json is invalid.",
226
- "doctor.check.forensic.remediation": "Run `fab install` to regenerate .fabric/forensic.json.",
229
+ "doctor.check.forensic.remediation": "Run `fabric install` to regenerate .fabric/forensic.json.",
227
230
  "doctor.check.forensic.ok": ".fabric/forensic.json is valid for {frameworkKind}.",
228
231
  "doctor.check.agents_meta.name": "Agents metadata",
229
232
  "doctor.check.agents_meta.message.missing": ".fabric/agents.meta.json is missing.",
230
- "doctor.check.agents_meta.remediation.missing": "Run `fab doctor --fix` to rebuild agents.meta.json from .fabric/knowledge/.",
233
+ "doctor.check.agents_meta.remediation.missing": "Run `fabric doctor --fix` to rebuild agents.meta.json from .fabric/knowledge/.",
231
234
  "doctor.check.agents_meta.message.invalid-default": ".fabric/agents.meta.json is invalid.",
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).",
235
+ // rc.35 TASK-09 (P0-14): humanised parse-failure messages.
236
+ "doctor.check.agents_meta.message.invalid-zod": ".fabric/agents.meta.json fails schema validation \u2014 {issues}. The file was likely written by an incompatible fabric CLI version, or hand-edited.",
237
+ "doctor.check.agents_meta.message.invalid-from-old-cli": ".fabric/agents.meta.json fails schema validation because the GLOBAL `fabric` CLI on PATH ({version}) is older than the minimum-supported {minVersion}. The schema gained backward-compatible singular\u2192plural normalisation in rc.31; older CLIs cannot parse the result they themselves write back.",
238
+ "doctor.check.agents_meta.remediation.invalid": "Run `fabric 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).",
233
239
  "doctor.check.agents_meta.message.stale": ".fabric/agents.meta.json revision {revision} does not match .fabric/knowledge derived revision {computedRevision}.",
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.",
240
+ "doctor.check.agents_meta.remediation.stale": "Benign \u2014 engine auto-heals on next plan-context/get-sections call. Run `fabric doctor --fix` for explicit reconciliation.",
235
241
  "doctor.check.agents_meta.ok": ".fabric/agents.meta.json revision {revision} is aligned with .fabric/knowledge.",
236
242
  "doctor.check.rule_content_refs.name": "Rule content refs",
237
243
  "doctor.check.rule_content_refs.message.unavailable": "Cannot inspect content_ref entries until agents.meta.json is valid.",
238
- "doctor.check.rule_content_refs.remediation.unavailable": "Fix agents.meta.json first: run `fab doctor --fix`.",
244
+ "doctor.check.rule_content_refs.remediation.unavailable": "Fix agents.meta.json first: run `fabric doctor --fix`.",
239
245
  "doctor.check.rule_content_refs.message.outside.singular": "{count} content_ref entry is outside .fabric/knowledge.",
240
246
  "doctor.check.rule_content_refs.message.outside.plural": "{count} content_ref entries are outside .fabric/knowledge.",
241
247
  // 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.",
243
- "doctor.check.rule_content_refs.message.missing.singular": "{count} content_ref target is missing. Run `fab doctor --fix` to reconcile.",
244
- "doctor.check.rule_content_refs.message.missing.plural": "{count} content_ref targets are missing. Run `fab doctor --fix` to reconcile.",
245
- "doctor.check.rule_content_refs.remediation.missing": "Run `fab doctor --fix` to reconcile agents.meta.json with the files present in .fabric/knowledge/.",
248
+ "doctor.check.rule_content_refs.remediation.outside": "Run `fabric 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.",
249
+ "doctor.check.rule_content_refs.message.missing.singular": "{count} content_ref target is missing. Run `fabric doctor --fix` to reconcile.",
250
+ "doctor.check.rule_content_refs.message.missing.plural": "{count} content_ref targets are missing. Run `fabric doctor --fix` to reconcile.",
251
+ "doctor.check.rule_content_refs.remediation.missing": "Run `fabric doctor --fix` to reconcile agents.meta.json with the files present in .fabric/knowledge/.",
246
252
  "doctor.check.rule_content_refs.ok": "All content_ref entries resolve to .fabric/knowledge files.",
247
253
  "doctor.check.knowledge_test_index.name": "Knowledge-test index",
248
- "doctor.check.knowledge_test_index.remediation.missing": "Run `fab doctor --fix` to rebuild .fabric/.cache/knowledge-test.index.json.",
249
- "doctor.check.knowledge_test_index.remediation.invalid": "Delete .fabric/.cache/knowledge-test.index.json and run `fab doctor --fix` to regenerate it.",
254
+ "doctor.check.knowledge_test_index.remediation.missing": "Run `fabric doctor --fix` to rebuild .fabric/.cache/knowledge-test.index.json.",
255
+ "doctor.check.knowledge_test_index.remediation.invalid": "Delete .fabric/.cache/knowledge-test.index.json and run `fabric doctor --fix` to regenerate it.",
250
256
  "doctor.check.knowledge_test_index.message.stale": ".fabric/.cache/knowledge-test.index.json is stale.",
251
- "doctor.check.knowledge_test_index.remediation.stale": "Run `fab doctor --fix` to rebuild the knowledge-test index.",
257
+ "doctor.check.knowledge_test_index.remediation.stale": "Run `fabric doctor --fix` to rebuild the knowledge-test index.",
252
258
  "doctor.check.knowledge_test_index.ok.link_singular.orphan_singular": "{linkCount} link and {orphanCount} orphan annotation indexed.",
253
259
  "doctor.check.knowledge_test_index.ok.link_singular.orphan_plural": "{linkCount} link and {orphanCount} orphan annotations indexed.",
254
260
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_singular": "{linkCount} links and {orphanCount} orphan annotation indexed.",
255
261
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_plural": "{linkCount} links and {orphanCount} orphan annotations indexed.",
256
262
  "doctor.check.event_ledger.name": "Event ledger",
257
263
  "doctor.check.event_ledger.message.missing": ".fabric/events.jsonl is missing.",
258
- "doctor.check.event_ledger.remediation.missing": "Run `fab doctor --fix` to create .fabric/events.jsonl.",
264
+ "doctor.check.event_ledger.remediation.missing": "Run `fabric doctor --fix` to create .fabric/events.jsonl.",
259
265
  "doctor.check.event_ledger.message.not_writable-default": ".fabric/events.jsonl is not writable.",
260
266
  "doctor.check.event_ledger.remediation.not_writable": "Check file permissions on .fabric/events.jsonl and ensure no other process holds a write lock.",
261
267
  "doctor.check.event_ledger.message.invalid-default": ".fabric/events.jsonl is invalid.",
262
268
  // 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/.",
269
+ "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 `fabric doctor --fix` to create a new empty ledger. Historical events are preserved under events.archive/.",
264
270
  "doctor.check.event_ledger.ok": ".fabric/events.jsonl exists, is writable, and is parseable.",
265
271
  "doctor.check.mcp_config_in_wrong_file.name": "Claude MCP config location",
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.",
267
- "doctor.check.mcp_config_in_wrong_file.remediation": "Run `fab doctor --fix` to remove mcpServers.fabric from .claude/settings.json, then run `fab install` to write .mcp.json.",
272
+ "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 fabric install to write .mcp.json.",
273
+ "doctor.check.mcp_config_in_wrong_file.remediation": "Run `fabric doctor --fix` to remove mcpServers.fabric from .claude/settings.json, then run `fabric install` to write .mcp.json.",
268
274
  "doctor.check.mcp_config_in_wrong_file.ok": "mcpServers.fabric is not in .claude/settings.json.",
269
275
  "doctor.check.event_ledger_partial_write.name": "Event ledger partial write",
270
276
  "doctor.check.event_ledger_partial_write.ok.skipped": "No partial-write check needed (ledger missing or not writable).",
271
277
  "doctor.check.event_ledger_partial_write.message": "events.jsonl has a partial write at byte offset {byteOffset} ({byteLength} corrupted bytes). Run --fix to truncate and preserve corrupted bytes.",
272
- "doctor.check.event_ledger_partial_write.remediation": "Run `fab doctor --fix` to truncate the partial write and restore events.jsonl to a valid state.",
278
+ "doctor.check.event_ledger_partial_write.remediation": "Run `fabric doctor --fix` to truncate the partial write and restore events.jsonl to a valid state.",
273
279
  "doctor.check.event_ledger_partial_write.ok.clean": "events.jsonl has no partial trailing write.",
274
280
  // v2.0.0-rc.27 TASK-010 (audit §2.24): schema-compat forward-warn category.
275
281
  "doctor.check.event_ledger_schema_compat.name": "Event ledger schema compat",
@@ -278,30 +284,30 @@ var enMessages = {
278
284
  "doctor.check.event_ledger_schema_compat.message.schema_version": "events.jsonl has {count} row(s) with unsupported `schema_version` (samples: {samples}).",
279
285
  "doctor.check.event_ledger_schema_compat.message.event_type": "events.jsonl has {count} row(s) with unknown `event_type` (samples: {samples}).",
280
286
  // 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.",
287
+ "doctor.check.event_ledger_schema_compat.remediation": "Preferred: upgrade the fabric 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 `fabric doctor --fix` to create a new empty ledger. Historical events stay under events.archive/ for later manual migration.",
282
288
  // v2.0.0-rc.28 TASK-04 (audit §3.1): SKILL ref/ mirror parity check.
283
289
  "doctor.check.skill_ref_mirror.name": "Skill ref mirror parity",
284
290
  "doctor.check.skill_ref_mirror.ok": "All `.claude/skills/<slug>/ref/` and `.codex/skills/<slug>/ref/` files are byte-identical.",
285
291
  "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.",
286
- "doctor.check.skill_ref_mirror.remediation": "Run `fab install` to rewrite both client subtrees from the canonical templates and restore parity.",
292
+ "doctor.check.skill_ref_mirror.remediation": "Run `fabric install` to rewrite both client subtrees from the canonical templates and restore parity.",
287
293
  // 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
294
  "doctor.check.skill_token_budget.name": "Skill token budget",
289
295
  "doctor.check.skill_token_budget.ok": "All .claude/skills/<slug>/SKILL.md files are within token budget (warn 5K / error 10K).",
290
296
  "doctor.check.skill_token_budget.message.singular": "{count} SKILL.md exceeds the token budget: {list}. Sink detail into ref/ for progressive disclosure.",
291
297
  "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.",
298
+ "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 `fabric install` to sync both client subtrees.",
293
299
  // 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
300
  "doctor.check.skill_description.name": "Skill description quality",
295
301
  "doctor.check.skill_description.ok": "All SKILL.md description fields are well-structured (non-empty, <60 tokens, bilingual triggers).",
296
302
  "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
303
  "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).",
304
+ "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 `fabric install` to sync both client subtrees. For recall verification, run the W1 gemini delegate (see .workflow/.scratchpad/rc33-plan/W1-VERIFY-RESULT.md).",
299
305
  // 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
306
  "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
301
307
  "doctor.check.cite_goodhart.ok": "No cite-policy Goodhart patterns detected over the last 7 days.",
302
308
  "doctor.check.cite_goodhart.message.singular": "Detected {count} cite-policy Goodhart pattern: {list}.",
303
309
  "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`.",
310
+ "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 `fabric doctor --cite-coverage --since=7d`.",
305
311
  // 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
312
  "doctor.check.draft_backlog.name": "Knowledge draft backlog",
307
313
  "doctor.check.draft_backlog.ok": "draft-maturity entry ratio is healthy (< 50%, or workspace too small to compute).",
@@ -311,15 +317,15 @@ var enMessages = {
311
317
  "doctor.check.meta_manually_diverged.ok.unreadable": "agents.meta.json not readable; skipping divergence check.",
312
318
  "doctor.check.meta_manually_diverged.message.extra.singular": "agents.meta.json has {count} entry with no backing file on disk. Run --fix to reconcile.",
313
319
  "doctor.check.meta_manually_diverged.message.extra.plural": "agents.meta.json has {count} entries with no backing file on disk. Run --fix to reconcile.",
314
- "doctor.check.meta_manually_diverged.remediation.extra": "Run `fab doctor --fix` to reconcile agents.meta.json with the rule files currently on disk.",
320
+ "doctor.check.meta_manually_diverged.remediation.extra": "Run `fabric doctor --fix` to reconcile agents.meta.json with the rule files currently on disk.",
315
321
  "doctor.check.meta_manually_diverged.message.hash.singular": "agents.meta.json has {count} entry whose hash does not match the file on disk. Run --fix to reconcile.",
316
322
  "doctor.check.meta_manually_diverged.message.hash.plural": "agents.meta.json has {count} entries whose hash does not match the file on disk. Run --fix to reconcile.",
317
- "doctor.check.meta_manually_diverged.remediation.hash": "Run `fab doctor --fix` to reconcile agents.meta.json with the current rule file contents.",
323
+ "doctor.check.meta_manually_diverged.remediation.hash": "Run `fabric doctor --fix` to reconcile agents.meta.json with the current rule file contents.",
318
324
  "doctor.check.meta_manually_diverged.ok.consistent": "agents.meta.json is consistent with rule files on disk.",
319
325
  "doctor.check.knowledge_dir_unindexed.name": "Knowledge dir unindexed",
320
- "doctor.check.knowledge_dir_unindexed.message.singular": "{count} .md file in .fabric/knowledge/ not indexed in agents.meta.json. Run `fab doctor --fix` to index the missing knowledge files.",
321
- "doctor.check.knowledge_dir_unindexed.message.plural": "{count} .md files in .fabric/knowledge/ not indexed in agents.meta.json. Run `fab doctor --fix` to index the missing knowledge files.",
322
- "doctor.check.knowledge_dir_unindexed.remediation": "Run `fab doctor --fix` to index the missing knowledge files.",
326
+ "doctor.check.knowledge_dir_unindexed.message.singular": "{count} .md file in .fabric/knowledge/ not indexed in agents.meta.json. Run `fabric doctor --fix` to index the missing knowledge files.",
327
+ "doctor.check.knowledge_dir_unindexed.message.plural": "{count} .md files in .fabric/knowledge/ not indexed in agents.meta.json. Run `fabric doctor --fix` to index the missing knowledge files.",
328
+ "doctor.check.knowledge_dir_unindexed.remediation": "Run `fabric doctor --fix` to index the missing knowledge files.",
323
329
  "doctor.check.knowledge_dir_unindexed.ok": "All .fabric/knowledge/ .md files are indexed in agents.meta.json.",
324
330
  "doctor.check.stable_id_collision.name": "Stable ID collision",
325
331
  "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.',
@@ -328,9 +334,9 @@ var enMessages = {
328
334
  "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.",
329
335
  "doctor.check.stable_id_collision.ok": "No declared stable_id collisions found in .fabric/knowledge/.",
330
336
  "doctor.check.counter_desync.name": "Knowledge counter desync",
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.",
332
- "doctor.check.counter_desync.message.plural": "{count} knowledge counters desynced from observed stable_ids. {counterPath} = {current} but observed {observedId}. Run `fab doctor --fix` to bump counters.",
333
- "doctor.check.counter_desync.remediation": "Run `fab doctor --fix` to bump agents.meta.json counters to the maximum observed counter value.",
337
+ "doctor.check.counter_desync.message.singular": "{count} knowledge counter desynced from observed stable_ids. {counterPath} = {current} but observed {observedId}. Run `fabric doctor --fix` to bump counters.",
338
+ "doctor.check.counter_desync.message.plural": "{count} knowledge counters desynced from observed stable_ids. {counterPath} = {current} but observed {observedId}. Run `fabric doctor --fix` to bump counters.",
339
+ "doctor.check.counter_desync.remediation": "Run `fabric doctor --fix` to bump agents.meta.json counters to the maximum observed counter value.",
334
340
  "doctor.check.counter_desync.ok": "agents.meta.json counters envelope is consistent with observed stable_ids.",
335
341
  "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
336
342
  "doctor.check.preexisting_root_files.ok": "No CLAUDE.md or AGENTS.md detected at project root.",
@@ -345,12 +351,12 @@ var enMessages = {
345
351
  "doctor.check.orphan_demote.ok": "No canonical knowledge entries exceed their maturity-keyed inactivity threshold.",
346
352
  "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}.",
347
353
  "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}.",
348
- "doctor.check.orphan_demote.remediation": "Run `fab doctor --fix-knowledge` to demote orphan entries one maturity tier.",
354
+ "doctor.check.orphan_demote.remediation": "Run `fabric doctor --fix-knowledge` to demote orphan entries one maturity tier.",
349
355
  "doctor.check.stale_archive.name": "Knowledge stale archive",
350
356
  "doctor.check.stale_archive.ok": "No draft knowledge entries exceed the additional stale-archive quiet window.",
351
357
  "doctor.check.stale_archive.message.singular": "{count} draft knowledge entry is stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
352
358
  "doctor.check.stale_archive.message.plural": "{count} draft knowledge entries are stale beyond the demote+{additionalDays}d additional quiet window. First: {detail}.",
353
- "doctor.check.stale_archive.remediation": "Run `fab doctor --fix-knowledge` to move stale entries into `.fabric/.archive/<type>/`.",
359
+ "doctor.check.stale_archive.remediation": "Run `fabric doctor --fix-knowledge` to move stale entries into `.fabric/.archive/<type>/`.",
354
360
  "doctor.check.pending_overdue.name": "Knowledge pending overdue",
355
361
  "doctor.check.pending_overdue.ok": "No pending knowledge entries exceed the 14-day review threshold.",
356
362
  "doctor.check.pending_overdue.message.singular": "{count} pending knowledge entry has been awaiting review for more than {thresholdDays} days. First: {detail}.",
@@ -372,7 +378,7 @@ var enMessages = {
372
378
  "doctor.check.index_drift.ok": "agents.meta.json counters envelope is at or above the highest existing canonical counter for every (layer, type) pair.",
373
379
  "doctor.check.index_drift.message.singular": "{count} (layer, type) counter slot have drifted below the observed canonical maximum (next allocate would collide). First: {detail}.",
374
380
  "doctor.check.index_drift.message.plural": "{count} (layer, type) counter slots have drifted below the observed canonical maximum (next allocate would collide). First: {detail}.",
375
- "doctor.check.index_drift.remediation": "Run `fab doctor --fix-knowledge` to bump agents.meta.json counters to max_observed + 1.",
381
+ "doctor.check.index_drift.remediation": "Run `fabric doctor --fix-knowledge` to bump agents.meta.json counters to max_observed + 1.",
376
382
  "doctor.check.underseeded.name": "Knowledge underseeded",
377
383
  "doctor.check.underseeded.ok": "Knowledge corpus has {count} canonical entries (>= {threshold}).",
378
384
  "doctor.check.underseeded.message.singular": "Knowledge corpus has only {count} canonical entry (< {threshold} threshold). The plan_context retrieval surface is below its useful floor.",
@@ -406,7 +412,7 @@ var enMessages = {
406
412
  "doctor.check.session_hints_stale.ok": "No session-hints cache files older than {days} days under .fabric/.cache/.",
407
413
  "doctor.check.session_hints_stale.message.singular": "{count} session-hints cache file under .fabric/.cache/ is older than {days} days. First: {detail}.",
408
414
  "doctor.check.session_hints_stale.message.plural": "{count} session-hints cache files under .fabric/.cache/ are older than {days} days. First: {detail}.",
409
- "doctor.check.session_hints_stale.remediation": "Run `fab doctor --fix-knowledge` to delete stale session-hints cache files.",
415
+ "doctor.check.session_hints_stale.remediation": "Run `fabric doctor --fix-knowledge` to delete stale session-hints cache files.",
410
416
  "doctor.check.stale_serve_lock.name": "Serve lock",
411
417
  "doctor.check.stale_serve_lock.ok.no_lock": "No .fabric/.serve.lock present.",
412
418
  "doctor.check.stale_serve_lock.ok.live_pid": ".fabric/.serve.lock held by live PID {pid}.",
@@ -414,26 +420,39 @@ var enMessages = {
414
420
  "doctor.check.stale_serve_lock.age.day.plural": "{count} days ago",
415
421
  "doctor.check.stale_serve_lock.age.hour.singular": "{count} hour ago",
416
422
  "doctor.check.stale_serve_lock.age.hour.plural": "{count} hours ago",
417
- "doctor.check.stale_serve_lock.message.dead_pid": "[advisory] .fabric/.serve.lock holds dead PID {pid} (acquired {acquiredAgo}). Run `fab doctor --fix` to remove.",
418
- "doctor.check.stale_serve_lock.remediation.dead_pid": "Run `fab doctor --fix` to remove the stale .fabric/.serve.lock.",
423
+ "doctor.check.stale_serve_lock.message.dead_pid": "[advisory] .fabric/.serve.lock holds dead PID {pid} (acquired {acquiredAgo}). Run `fabric doctor --fix` to remove.",
424
+ "doctor.check.stale_serve_lock.remediation.dead_pid": "Run `fabric doctor --fix` to remove the stale .fabric/.serve.lock.",
419
425
  "doctor.check.relevance_fields_missing.name": "Knowledge relevance fields missing",
420
426
  "doctor.check.relevance_fields_missing.ok": "All pending entries declare both relevance_scope and relevance_paths.",
421
427
  "doctor.check.relevance_fields_missing.message.singular": "{count} pending entry is missing relevance_scope and/or relevance_paths in frontmatter. First: {detail}.",
422
428
  "doctor.check.relevance_fields_missing.message.plural": "{count} pending entries are missing relevance_scope and/or relevance_paths in frontmatter. First: {detail}.",
423
- "doctor.check.relevance_fields_missing.remediation": "Run `fab doctor --fix-knowledge` to back-fill the schema defaults (relevance_scope: broad, relevance_paths: []).",
429
+ "doctor.check.relevance_fields_missing.remediation": "Run `fabric doctor --fix-knowledge` to back-fill the schema defaults (relevance_scope: broad, relevance_paths: []).",
424
430
  // rc.31 BUG-M3/NEW-4: hooks_wired observability.
425
431
  "doctor.check.hooks_wired.name": "Claude Code hooks wired",
426
432
  "doctor.check.hooks_wired.ok.skipped": "Project does not use Claude Code (no .claude/ directory); hooks_wired check skipped.",
427
433
  "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.",
434
+ "doctor.check.hooks_wired.message.missing_settings": ".claude/ exists but .claude/settings.json is absent or unparseable; fabric install may have never run successfully, or the file was wiped externally.",
435
+ "doctor.check.hooks_wired.message.incomplete": ".claude/settings.json is missing fabric hook injections: {missing}. fabric install dry-run report does not match actual state (rc.30 audit BUG-M3 / NEW-4).",
436
+ "doctor.check.hooks_wired.remediation": "Run `fabric install` to re-inject hooks (idempotent; only fills missing slots). If hooks config was accidentally wiped, back up .claude/settings.json before running.",
431
437
  // rc.31 BUG-G2/G5: promote-ledger invariant check.
432
438
  "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
433
439
  "doctor.check.promote_ledger_invariant.ok": "knowledge_proposed={proposed} >= knowledge_promote_started={started} >= knowledge_promoted={promoted}; ledger invariant holds.",
434
440
  "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
441
  "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.",
442
+ "doctor.check.promote_ledger_invariant.remediation": "Starting in rc.31, review.approve synthesizes a knowledge_proposed event to keep the invariant; re-run fabric doctor after the next approve to settle. Historical imbalance is observability-only and does not affect KB function.",
443
+ // rc.35 TASK-04 (P0-9.b): global_cli_outdated.
444
+ "doctor.check.global_cli_outdated.name": "Global fabric CLI version",
445
+ "doctor.check.global_cli_outdated.ok": "Global `fabric` on PATH is {version}; compatible with the rc.31+ project schema.",
446
+ "doctor.check.global_cli_outdated.message.outdated": "Global `fabric` on PATH is {version}, older than the minimum-supported {minVersion}. rc.31 introduced an agents.meta.json schema fix; hooks installed by an outdated binary silently fail. Upgrade the global CLI to match the project.",
447
+ "doctor.check.global_cli_outdated.message.not_found": "No `fabric` binary on PATH. The CLI is required for `fabric install` / `fabric doctor`; install it globally.",
448
+ "doctor.check.global_cli_outdated.message.unparseable": "Could not parse `fabric -v` output ({detail}). Skipping outdated-version check.",
449
+ "doctor.check.global_cli_outdated.remediation": "Run `npm install -g @fenglimg/fabric-cli@latest`, then re-run `fabric install` in each fabric-managed project to resync hooks + SKILL.md.",
450
+ // rc.35 TASK-05 (P0-10.a): knowledge_summary_opaque.
451
+ "doctor.check.knowledge_summary_opaque.name": "Knowledge summary opacity",
452
+ "doctor.check.knowledge_summary_opaque.ok.skipped": "agents.meta.json is absent or invalid; summary-opacity check skipped.",
453
+ "doctor.check.knowledge_summary_opaque.ok": "{opaque}/{total} entries have summary == stable_id; opacity ratio is within the healthy band.",
454
+ "doctor.check.knowledge_summary_opaque.message.warn": "{opaque}/{total} entries ({pct}%) have description.summary equal to their stable_id, exceeding the {threshold}% threshold. Narrow-hint output renders as `<id> \xB7 <id>`, signaling nothing useful, and AI clients skip the fetch. First opaque: {sample}.",
455
+ "doctor.check.knowledge_summary_opaque.remediation": "Run the fabric-review skill to rewrite opaque summaries with one short human-readable phrase. The rc.35 hint renderer fallback (TASK-06) will also synthesize a temporary summary from the entry's `## Summary` section.",
437
456
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
438
457
  "doctor.check.skill_md_yaml_invalid.ok": "All .claude/.codex SKILL.md frontmatter values parse as strict YAML.",
439
458
  "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}.",
@@ -470,11 +489,17 @@ var enMessages = {
470
489
  "cli.human-lint.table.location": "Location",
471
490
  "cli.human-lint.table.expected": "Expected",
472
491
  "cli.human-lint.table.got": "Got",
473
- "cli.install.description": "Install Fabric in the target project (scaffold .fabric/, bootstrap templates, MCP client wiring, git hooks).\n\nExamples:\n fab install interactive install in the current project\n fab install --yes accept defaults, skip the TTY wizard\n fab install --dry-run preview the install plan without writing files",
492
+ "cli.install.description": "Install Fabric in the target project (scaffold .fabric/, bootstrap templates, MCP client wiring, git hooks).\n\nExamples:\n fabric install interactive install in the current project\n fabric install --yes accept defaults, skip the TTY wizard\n fabric install --dry-run preview the install plan without writing files",
474
493
  "cli.install.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
475
494
  "cli.install.args.debug.description": "Print target resolution details to stderr.",
476
495
  "cli.install.args.yes.description": "Accept the current install plan and run without the TTY wizard",
477
496
  "cli.install.args.dry-run.description": "Print the install plan without writing files or running follow-up stages",
497
+ // rc.35 TASK-08 (P0-5/6): --force-skills-only.
498
+ "cli.install.args.force-skills-only.description": "Skip bootstrap / MCP / hooks / settings; refresh ONLY the fabric Skill template copies (.claude/.codex/.cursor/skills/*).",
499
+ "cli.install.force-skills-only.banner": "Refreshing fabric Skill templates only",
500
+ "cli.install.force-skills-only.uninitialised.message": "fabric install --force-skills-only: project is not initialised (.fabric/agents.meta.json is missing).",
501
+ "cli.install.force-skills-only.uninitialised.hint": "Run `fabric install` (without --force-skills-only) first to lay down the base scaffold, then re-run with --force-skills-only for subsequent Skill refreshes.",
502
+ "cli.install.force-skills-only.summary": "Skills refresh complete \u2014 written: {written}, skipped: {skipped}, errors: {errors}",
478
503
  "cli.install.mcp.install.global": "Using globally-installed @fenglimg/fabric-server",
479
504
  "cli.install.mcp.install.local": "Installing @fenglimg/fabric-server to project devDependencies",
480
505
  "cli.install.mcp.local.installing": "Running {manager} add -D @fenglimg/fabric-server...",
@@ -549,7 +574,7 @@ var enMessages = {
549
574
  "cli.install.capabilities.follow-up.ready": "continue in client",
550
575
  "cli.install.capabilities.follow-up.install": "install client assets",
551
576
  "cli.install.capabilities.follow-up.manual": "manual step required",
552
- "cli.install.next-step.message": "run fab hooks install to add the Day 4 pre-commit pipeline.",
577
+ "cli.install.next-step.message": "run fabric hooks install to add the Day 4 pre-commit pipeline.",
553
578
  "cli.install.reason-message.installable-body": ".fabric/forensic.json is ready; some detected clients support Fabric follow-up but still need client assets installed.",
554
579
  "cli.install.reason-message.manual-body": ".fabric/forensic.json is ready; some detected clients still need manual follow-up because no Fabric skill is installed for them yet.",
555
580
  "cli.install.codex-hooks.created": "{label} {path} with Codex hooks config (requires features.codex_hooks = true).",
@@ -563,15 +588,15 @@ var enMessages = {
563
588
  "cli.install.claude-settings.invalid-json": "{label} {path}: invalid JSON ({reason}).",
564
589
  "cli.install.claude-settings.invalid-hooks": '{label} {path}: "hooks" must be a JSON object.',
565
590
  "cli.install.claude-settings.invalid-stop-array": '{label} {path}: "hooks.Stop" must be an array.',
566
- "cli.install.errors.abort-existing": "ABORT: {path} already exists. fab install is non-destructive.",
591
+ "cli.install.errors.abort-existing": "ABORT: {path} already exists. fabric install is non-destructive.",
567
592
  "cli.install.diff.canonical": "Workspace already canonical ({count} files verified).",
568
593
  "cli.install.diff.applying-missing": "Applying {count} missing pieces: {files}",
569
- "cli.install.diff.drift-abort": "Drift detected in {path}. Run `fab doctor` to inspect, or `fab uninstall && fab install` to reset.",
594
+ "cli.install.diff.drift-abort": "Drift detected in {path}. Run `fabric doctor` to inspect, or `fabric uninstall && fabric install` to reset.",
570
595
  "cli.install.diff.state.missing": "missing",
571
596
  "cli.install.diff.state.present-canonical": "canonical",
572
597
  "cli.install.diff.state.drifted": "drifted",
573
598
  "cli.install.diff.state.user-modified": "user-modified",
574
- "cli.uninstall.description": "Uninstall Fabric from the target project. .fabric/knowledge/ is always preserved; ~/.fabric/knowledge/ is never touched.\n\nExamples:\n fab uninstall interactive uninstall in the current project\n fab uninstall --yes accept defaults, skip the TTY wizard\n fab uninstall --dry-run preview the uninstall plan without removing files",
599
+ "cli.uninstall.description": "Uninstall Fabric from the target project. .fabric/knowledge/ is always preserved; ~/.fabric/knowledge/ is never touched.\n\nExamples:\n fabric uninstall interactive uninstall in the current project\n fabric uninstall --yes accept defaults, skip the TTY wizard\n fabric uninstall --dry-run preview the uninstall plan without removing files",
575
600
  "cli.uninstall.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
576
601
  "cli.uninstall.args.debug.description": "Print target resolution details to stderr.",
577
602
  "cli.uninstall.args.yes.description": "Accept the current uninstall plan and run without the TTY wizard.",
@@ -622,7 +647,7 @@ var enMessages = {
622
647
  "cli.scan.args.target.description": "Target absolute path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
623
648
  "cli.scan.args.debug.description": "Print detection evidence in formatted output.",
624
649
  "cli.scan.args.json.description": "Print the diagnostic report as JSON.",
625
- "cli.scan.error.missing-forensic": "forensic.json not found at {path}; run `fab install` first to produce the deterministic project snapshot.",
650
+ "cli.scan.error.missing-forensic": "forensic.json not found at {path}; run `fabric install` first to produce the deterministic project snapshot.",
626
651
  "cli.scan.summary.created": "Wrote {count} knowledge entries to .fabric/knowledge/.",
627
652
  "cli.scan.summary.skipped": "No changes detected; {count} entries already up-to-date.",
628
653
  "cli.scan.report.title": "Fabric scan report",
@@ -637,20 +662,20 @@ var enMessages = {
637
662
  "cli.scan.report.recommendations": "Recommendations:",
638
663
  "cli.scan.readme-quality.ok": "ok",
639
664
  "cli.scan.readme-quality.stub": "stub",
640
- "cli.scan.recommendation.init": "L0: Run fab install to scaffold `.fabric/AGENTS.md` with the canonical Fabric bootstrap content.",
665
+ "cli.scan.recommendation.init": "L0: Run fabric install to scaffold `.fabric/AGENTS.md` with the canonical Fabric bootstrap content.",
641
666
  "cli.scan.recommendation.readme": "L0: Expand README.md before promoting project facts into Fabric references.",
642
667
  "cli.scan.recommendation.contributing": "L0: Add CONTRIBUTING.md or leave a bootstrap TODO reference for contribution flow.",
643
668
  "cli.scan.recommendation.unknown-framework": "L1: Add tech-stack TODOs manually because no framework marker was detected.",
644
669
  "cli.scan.recommendation.framework-dirs": "L1: Review {framework} directories for future scoped Fabric rule files.",
645
- "cli.serve.description": "Start the local Fabric MCP HTTP service.\n\nExamples:\n fab serve bind 127.0.0.1:7373 (default)\n fab serve --port 8787 use a custom port\n FABRIC_AUTH_TOKEN=<token> fab serve --host 0.0.0.0 bind non-loopback with Bearer auth",
670
+ "cli.serve.description": "Start the local Fabric MCP HTTP service.\n\nExamples:\n fabric serve bind 127.0.0.1:7373 (default)\n fabric serve --port 8787 use a custom port\n FABRIC_AUTH_TOKEN=<token> fabric serve --host 0.0.0.0 bind non-loopback with Bearer auth",
646
671
  "cli.serve.args.port.description": "Listen port, default 7373.",
647
672
  "cli.serve.args.host.description": "Listen host, default 127.0.0.1. Non-loopback hosts (e.g. 0.0.0.0) require FABRIC_AUTH_TOKEN to enable Bearer auth, otherwise serve falls back to 127.0.0.1.",
648
673
  "cli.serve.args.target.description": "Target project path. Defaults to --target, then EXTERNAL_FIXTURE_PATH, then cwd.",
649
674
  "cli.serve.args.debug.description": "Print target resolution details to stderr.",
650
675
  "cli.serve.args.allow-loopback-no-auth.description": "Opt in to running the loopback HTTP server without Bearer auth (default-deny). Use only on a trusted single-user machine; any local process can then read your knowledge ledger.",
651
676
  "cli.serve.ready.title": "Fabric Dashboard",
652
- "cli.serve.lock-held.action-hint": "A `fab serve` instance (PID {pid}) is holding the workspace lock. Stop it (Ctrl-C in that terminal or `kill {pid}`) before running this command.",
653
- "cli.serve.warning.host-fallback": "--host {host} requires FABRIC_AUTH_TOKEN for non-loopback exposure; falling back to 127.0.0.1. To bind {host}, run: FABRIC_AUTH_TOKEN=<token> fab serve --host {host}",
677
+ "cli.serve.lock-held.action-hint": "A `fabric serve` instance (PID {pid}) is holding the workspace lock. Stop it (Ctrl-C in that terminal or `kill {pid}`) before running this command.",
678
+ "cli.serve.warning.host-fallback": "--host {host} requires FABRIC_AUTH_TOKEN for non-loopback exposure; falling back to 127.0.0.1. To bind {host}, run: FABRIC_AUTH_TOKEN=<token> fabric serve --host {host}",
654
679
  "cli.serve.warning.loopback-deny-default": "FABRIC_AUTH_TOKEN is not set: /api /events /mcp will return 401 by default (any local process could otherwise read .fabric/agents.meta.json + forensic.json + events.jsonl). Set FABRIC_AUTH_TOKEN=<secret> or pass --allow-loopback-no-auth to opt in.",
655
680
  "cli.serve.error.port-in-use": "Port {port} in use - try --port {nextPort}",
656
681
  // v2.0.0-rc.29 TASK-008 (BUG-L2): onboard-coverage i18n keys.
@@ -664,7 +689,7 @@ var enMessages = {
664
689
  "cli.sync-meta.description": "Sync Fabric metadata from internal rule files.",
665
690
  "cli.sync-meta.args.target.description": "Target project path, default is the current working directory.",
666
691
  "cli.sync-meta.args.check-only.description": "Exit with code 1 when .fabric/agents.meta.json is out of date.",
667
- "cli.sync-meta.drift-detected": "Fabric metadata drift detected. Run fab sync-meta to update.",
692
+ "cli.sync-meta.drift-detected": "Fabric metadata drift detected. Run fabric sync-meta to update.",
668
693
  "cli.sync-meta.updated": "{label} {path}",
669
694
  "dashboard.app.nav.aria-label": "Dashboard views",
670
695
  "dashboard.app.nav.readiness.label": "Readiness",
@@ -871,7 +896,7 @@ var enMessages = {
871
896
 
872
897
  // src/i18n/locales/zh-CN.ts
873
898
  var zhCNMessages = {
874
- "cli.main.description": "Fabric CLI - AI \u667A\u80FD\u4F53\u534F\u4F5C\u6846\u67B6\u3002\n\n\u4E09\u6B65\u5FC3\u667A\u6A21\u578B\uFF1A\n \u88C5 (install) - fab install \u4E00\u952E\u5B8C\u6210\u9879\u76EE\u521D\u59CB\u5316\n \u914D (config) - fab config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n \u8DD1 (run) - fab serve \u542F\u52A8\u672C\u5730 MCP HTTP \u670D\u52A1\n fab doctor \u8FD0\u884C\u76EE\u6807\u6001\u8BCA\u65AD\n\n\u793A\u4F8B\uFF1A\n fab install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\n fab config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n fab serve --port 7373 \u542F\u52A8 MCP HTTP \u670D\u52A1\n fab doctor --fix \u4FEE\u590D Fabric \u6D3E\u751F\u72B6\u6001\n fab uninstall --dry-run \u9884\u89C8\u5378\u8F7D\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
899
+ "cli.main.description": "Fabric CLI - AI \u667A\u80FD\u4F53\u534F\u4F5C\u6846\u67B6\u3002\n\n\u4E09\u6B65\u5FC3\u667A\u6A21\u578B\uFF1A\n \u88C5 (install) - fabric install \u4E00\u952E\u5B8C\u6210\u9879\u76EE\u521D\u59CB\u5316\n \u914D (config) - fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n \u8DD1 (run) - fabric serve \u542F\u52A8\u672C\u5730 MCP HTTP \u670D\u52A1\n fabric doctor \u8FD0\u884C\u76EE\u6807\u6001\u8BCA\u65AD\n\n\u793A\u4F8B\uFF1A\n fabric install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\n fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\n fabric serve --port 7373 \u542F\u52A8 MCP HTTP \u670D\u52A1\n fabric doctor --fix \u4FEE\u590D Fabric \u6D3E\u751F\u72B6\u6001\n fabric uninstall --dry-run \u9884\u89C8\u5378\u8F7D\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
875
900
  "cli.shared.created": "\u5DF2\u521B\u5EFA",
876
901
  "cli.shared.skipped": "\u5DF2\u8DF3\u8FC7",
877
902
  "cli.shared.next": "\u4E0B\u4E00\u6B65",
@@ -909,7 +934,7 @@ var zhCNMessages = {
909
934
  "cli.bootstrap.install.skipped-header": "\u5DF2\u8DF3\u8FC7 {path}\uFF1AFabric Bootstrap \u5934\u90E8\u5DF2\u5B58\u5728\u3002",
910
935
  "cli.bootstrap.install.prepended": "\u5DF2\u524D\u7F6E\u5199\u5165 {path}",
911
936
  "cli.bootstrap.errors.unknown-client": "\u672A\u77E5\u5BA2\u6237\u7AEF\u201C{client}\u201D\u3002\u8BF7\u4F7F\u7528\u9017\u53F7\u5206\u9694\u5217\u8868\uFF0C\u4F8B\u5982 claude,cursor,codex\u3002",
912
- "cli.config.description": "\u6253\u5F00 Fabric \u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\uFF08\u8BED\u8A00\u3001\u77E5\u8BC6\u5C42\u3001\u5BA1\u8BA1\u6A21\u5F0F\u3001\u63D0\u793A\u7A97\u53E3\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u7B49\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fab config \u6253\u5F00\u4EA4\u4E92\u5F0F\u9762\u677F\n fab config --target /path \u7F16\u8F91\u6307\u5B9A\u9879\u76EE\u7684\u914D\u7F6E",
937
+ "cli.config.description": "\u6253\u5F00 Fabric \u4EA4\u4E92\u5F0F\u914D\u7F6E\u9762\u677F\uFF08\u8BED\u8A00\u3001\u77E5\u8BC6\u5C42\u3001\u5BA1\u8BA1\u6A21\u5F0F\u3001\u63D0\u793A\u7A97\u53E3\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u7B49\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric config \u6253\u5F00\u4EA4\u4E92\u5F0F\u9762\u677F\n fabric config --target /path \u7F16\u8F91\u6307\u5B9A\u9879\u76EE\u7684\u914D\u7F6E",
913
938
  "cli.config.args.target.description": "\u76EE\u6807\u9879\u76EE\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09\u3002",
914
939
  "cli.config.clients.claude": "Claude Code CLI",
915
940
  "cli.config.install.description": "\u5C06 Fabric MCP \u670D\u52A1\u7AEF\u6761\u76EE\u5B89\u88C5\u5230\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\u914D\u7F6E\u4E2D\u3002",
@@ -921,14 +946,14 @@ var zhCNMessages = {
921
946
  "cli.config.install.no-config-path": "\u8DF3\u8FC7 {client}\uFF1A\u672A\u68C0\u6D4B\u5230\u914D\u7F6E\u8DEF\u5F84\u3002",
922
947
  "cli.config.install.dry-run": "[dry-run] {client}\uFF1A\u5C06\u5199\u5165 {path}",
923
948
  "cli.config.install.wrote": "{client}\uFF1A\u5DF2\u5199\u5165 {path}",
924
- // rc.16 TASK-006 (F1-panel): clack 驱动的 `fab config` 交互式面板。
949
+ // rc.16 TASK-006 (F1-panel): clack 驱动的 `fabric config` 交互式面板。
925
950
  // 由 packages/cli/src/commands/config.ts(菜单循环 + 字段编辑)以及
926
951
  // getPanelFields() 的 label_i18n_key 引用消费。
927
952
  "cli.config.intro": "Fabric \u914D\u7F6E",
928
953
  "cli.config.outro": "\u914D\u7F6E\u5DF2\u4FDD\u5B58\u3002",
929
954
  "cli.config.outro-no-changes": "\u672A\u505A\u4EFB\u4F55\u4FEE\u6539\u3002",
930
955
  "cli.config.cancel": "\u5DF2\u53D6\u6D88\u3002",
931
- "cli.config.non-tty-notice": "fab config \u9700\u8981\u5728\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u4E2D\u8FD0\u884C\u3002\u8BF7\u5728 TTY \u4E2D\u6267\u884C\u4EE5\u7F16\u8F91\u914D\u7F6E\u5B57\u6BB5\u3002",
956
+ "cli.config.non-tty-notice": "fabric config \u9700\u8981\u5728\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u4E2D\u8FD0\u884C\u3002\u8BF7\u5728 TTY \u4E2D\u6267\u884C\u4EE5\u7F16\u8F91\u914D\u7F6E\u5B57\u6BB5\u3002",
932
957
  "cli.config.menu.field-select": "\u9009\u62E9\u8981\u7F16\u8F91\u7684\u5B57\u6BB5\uFF1A",
933
958
  "cli.config.menu.exit": "\u9000\u51FA",
934
959
  "cli.config.value.current": "\u5F53\u524D\uFF1A{value}",
@@ -937,7 +962,7 @@ var zhCNMessages = {
937
962
  "cli.config.prompt.text": "\u4E3A {key} \u8F93\u5165\u65B0\u503C\uFF08\u5F53\u524D\uFF1A{current}\uFF09\uFF1A",
938
963
  "cli.config.write.success": "\u5DF2\u4FDD\u5B58 {key} = {value}",
939
964
  "cli.config.write.failure": "\u5199\u5165 fabric-config.json \u5931\u8D25\uFF1A{message}",
940
- "cli.config.errors.uninit-workspace.message": "\u5DE5\u4F5C\u533A\u5C1A\u672A\u521D\u59CB\u5316\u3002\u8BF7\u5148\u8FD0\u884C `fab install`\u3002",
965
+ "cli.config.errors.uninit-workspace.message": "\u5DE5\u4F5C\u533A\u5C1A\u672A\u521D\u59CB\u5316\u3002\u8BF7\u5148\u8FD0\u884C `fabric install`\u3002",
941
966
  "cli.config.errors.invalid-int": "\u5FC5\u987B\u662F\u6B63\u6574\u6570\u3002",
942
967
  "cli.config.errors.unknown-field": "\u672A\u77E5\u5B57\u6BB5\u9009\u62E9 \u2014 \u5DF2\u8DF3\u8FC7\u3002",
943
968
  "cli.config.errors.no-enum-options": "\u8BE5\u5B57\u6BB5\u6CA1\u6709\u53EF\u9009\u679A\u4E3E\u503C \u2014 \u5DF2\u8DF3\u8FC7\u3002",
@@ -964,13 +989,13 @@ var zhCNMessages = {
964
989
  "cli.config.fields.maintenance_hint_cooldown_days.description": "\u7EF4\u62A4\u63D0\u793A\u518D\u6B21\u89E6\u53D1\u524D\u7684\u51B7\u5374\u65F6\u95F4\uFF08\u5929\uFF09\u3002",
965
990
  "cli.config.fields.audit_mode.label": "\u5BA1\u8BA1\u6A21\u5F0F",
966
991
  "cli.config.fields.audit_mode.description": "human-lock \u4E0E\u6F02\u79FB\u68C0\u6D4B\u7684\u5BA1\u8BA1\u7C92\u5EA6\uFF08strict / warn / off\uFF09\u3002",
967
- "cli.doctor.description": "\u8FD0\u884C Fabric \u76EE\u6807\u6001\u8BCA\u65AD\uFF08meta \u540C\u6B65\u3001\u77E5\u8BC6\u7D22\u5F15\u3001bootstrap\u3001events ledger\u3001human-lock \u6F02\u79FB\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fab doctor \u53EA\u8BFB\u8BCA\u65AD\u62A5\u544A\n fab doctor --fix \u4FEE\u590D\u6D3E\u751F\u72B6\u6001\uFF08meta + \u7D22\u5F15\uFF09\n fab doctor --fix-knowledge \u5E94\u7528\u77E5\u8BC6\u5E93 lint \u53D8\u66F4\uFF08\u964D\u7EA7 / \u5F52\u6863\uFF09\n fab doctor --json --strict \u673A\u5668\u53EF\u8BFB\u8F93\u51FA\uFF0Cwarning \u89C6\u4E3A\u5931\u8D25",
992
+ "cli.doctor.description": "\u8FD0\u884C Fabric \u76EE\u6807\u6001\u8BCA\u65AD\uFF08meta \u540C\u6B65\u3001\u77E5\u8BC6\u7D22\u5F15\u3001bootstrap\u3001events ledger\u3001human-lock \u6F02\u79FB\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric doctor \u53EA\u8BFB\u8BCA\u65AD\u62A5\u544A\n fabric doctor --fix \u4FEE\u590D\u6D3E\u751F\u72B6\u6001\uFF08meta + \u7D22\u5F15\uFF09\n fabric doctor --fix-knowledge \u5E94\u7528\u77E5\u8BC6\u5E93 lint \u53D8\u66F4\uFF08\u964D\u7EA7 / \u5F52\u6863\uFF09\n fabric doctor --json --strict \u673A\u5668\u53EF\u8BFB\u8F93\u51FA\uFF0Cwarning \u89C6\u4E3A\u5931\u8D25",
968
993
  "doctor.section.fixable": "\u53EF\u4FEE\u590D\u9519\u8BEF\uFF1A",
969
994
  "doctor.section.manual": "\u9700\u624B\u52A8\u4FEE\u590D\uFF1A",
970
995
  "doctor.section.warnings": "\u8B66\u544A\uFF1A",
971
996
  "doctor.section.fix-knowledge-mutations": "Fix-knowledge \u53D8\u66F4\uFF1A",
972
997
  // v2.0.0-rc.29 REVIEW (codex LOW-2): F2 的 payload 阈值之前只出现在 JSON envelope,
973
- // 人类输出看不到,导致改了 mcpPayloadLimits 之后没法用 `fab doctor` 快速确认是否生效。
998
+ // 人类输出看不到,导致改了 mcpPayloadLimits 之后没法用 `fabric doctor` 快速确认是否生效。
974
999
  "doctor.section.payload-limits": "MCP payload \u9608\u503C\uFF1A",
975
1000
  "doctor.payload-limits.line": "warn={warnKb} KB, hard={hardKb} KB (\u6765\u6E90: {source})",
976
1001
  // rc.20 TASK-07: cite-coverage 人类可读格式化键。
@@ -1006,7 +1031,7 @@ var zhCNMessages = {
1006
1031
  "cite-coverage.contract.cite_id_unresolved": "\u5F15\u7528 ID \u4E0D\u5B58\u5728",
1007
1032
  "cite-coverage.contract.skip_count": "skip \u6876",
1008
1033
  "cite-coverage.contract.status.ok": "\u6B63\u5E38",
1009
- "cite-coverage.contract.status.skipped_bootstrap_drift": "\u5DF2\u8DF3\u8FC7\uFF08bootstrap drift \u2014 \u8BF7\u8FD0\u884C fab install\uFF09",
1034
+ "cite-coverage.contract.status.skipped_bootstrap_drift": "\u5DF2\u8DF3\u8FC7\uFF08bootstrap drift \u2014 \u8BF7\u8FD0\u884C fabric install\uFF09",
1010
1035
  "cite-coverage.contract.status.awaiting_marker": "\u7B49\u5F85\u9996\u6B21 marker emit",
1011
1036
  // 复数知识类型(rc.29 BUG-C1: 与统一后的 KnowledgeTypeSchema 枚举字面量逐字对齐)+ 第六桶 unresolved。
1012
1037
  "cite-coverage.contract.type.decisions": "decisions",
@@ -1033,6 +1058,9 @@ var zhCNMessages = {
1033
1058
  "cli.doctor.args.strict.description": "\u5C06 warning \u4E5F\u89C6\u4E3A\u5931\u8D25\u3002",
1034
1059
  "cli.doctor.args.fix-knowledge.description": "\u5E94\u7528\u77E5\u8BC6\u5E93 lint \u53D8\u66F4\uFF1A\u964D\u7EA7\u5B64\u7ACB\u7684\u89C4\u8303\u6761\u76EE\u3001\u5F52\u6863\u9648\u65E7 draft\u3001\u4FEE\u6B63\u6F02\u79FB\u7684\u7D22\u5F15\u8BA1\u6570\u5668\u3002\u9ED8\u8BA4 doctor \u8FD0\u884C\u4ECD\u7136\u53EA\u8BFB\u3002",
1035
1060
  "cli.doctor.args.yes.description": "\u8DF3\u8FC7 --fix-knowledge \u7684\u5B89\u5168\u786E\u8BA4\uFF1B\u975E tty \u8C03\u7528\u5FC5\u987B\u663E\u5F0F\u8BBE\u7F6E\u8BE5\u6807\u8BB0\uFF0C\u6216\u5728\u73AF\u5883\u53D8\u91CF\u4E2D\u8BBE\u7F6E FABRIC_NONINTERACTIVE=1\u3002",
1061
+ // rc.35 TASK-12 (P0-11): --verbose 展开 maintainer 受众的 remediation。
1062
+ "cli.doctor.args.verbose.description": "\u5C55\u5F00\u5168\u90E8 action hint,\u5305\u62EC maintainer \u53D7\u4F17\u7684(Fabric \u8D21\u732E\u8005\u4FEE\u6E90\u7801\u7528)\u3002\u9ED8\u8BA4 npm \u7EC8\u7AEF\u7528\u6237\u89C6\u56FE\u4F1A\u628A\u8FD9\u4E9B\u6298\u53E0\u3002",
1063
+ "doctor.maintainer-hint-folded": "(maintainer-only remediation \u2014 \u52A0 `fabric doctor --verbose` \u67E5\u770B)",
1036
1064
  "cli.doctor.errors.fix-knowledge-fix-mutually-exclusive": "--fix-knowledge \u4E0E --fix \u4E0D\u53EF\u540C\u65F6\u4F7F\u7528\u3002--fix-knowledge \u4FEE\u6539\u7528\u6237\u77E5\u8BC6\u72B6\u6001\uFF08\u964D\u7EA7/\u5F52\u6863\uFF09\uFF1B--fix \u4FEE\u590D\u6D3E\u751F\u72B6\u6001\uFF08meta/\u7D22\u5F15\uFF09\u3002\u8BF7\u5206\u522B\u8FD0\u884C\u3002",
1037
1065
  // rc.20 TASK-05: --cite-coverage 报告参数;只读,与 --fix/--fix-knowledge 互斥。
1038
1066
  "cli.doctor.args.cite-coverage.description": "Cite \u653F\u7B56\u5408\u89C4\u62A5\u544A(\u53EA\u8BFB;\u8DF3\u8FC7\u6807\u51C6\u68C0\u67E5)",
@@ -1049,7 +1077,7 @@ var zhCNMessages = {
1049
1077
  "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",
1050
1078
  "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
1079
  // 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",
1080
+ "cli.doctor.fix-dry-run-banner": "[dry-run] \u672A\u5E94\u7528\u4EFB\u4F55 mutation\u3002\u4E0B\u65B9 fixable_errors \u5217\u8868\u5C31\u662F `fabric doctor --fix` \u4F1A\u5904\u7406\u7684\u9879;\u53BB\u6389 --dry-run \u518D\u8DD1\u53EF\u5B9E\u9645\u4FEE\u590D\u3002",
1053
1081
  "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",
1054
1082
  "doctor.enrich.allComplete": "\u6240\u6709\u6B63\u5F0F\u77E5\u8BC6\u6761\u76EE\u5747\u5DF2\u5305\u542B intent_clues / tech_stack / impact / must_read_if\u3002",
1055
1083
  // rc.26 TASK-02a: doctor foundation-batch check messages.
@@ -1057,21 +1085,21 @@ var zhCNMessages = {
1057
1085
  "doctor.check.bootstrap_marker_migration.ok": "bootstrap \u76EE\u6807\u6587\u4EF6\u4E2D\u672A\u68C0\u6D4B\u5230\u65E7 fabric:knowledge-base marker\u3002",
1058
1086
  "doctor.check.bootstrap_marker_migration.message.singular": "{count} \u4E2A\u6587\u4EF6\u4ECD\u5E26\u6709\u65E7 fabric:knowledge-base bootstrap marker\uFF1A{list}\u3002",
1059
1087
  "doctor.check.bootstrap_marker_migration.message.plural": "{count} \u4E2A\u6587\u4EF6\u4ECD\u5E26\u6709\u65E7 fabric:knowledge-base bootstrap marker\uFF1A{list}\u3002",
1060
- "doctor.check.bootstrap_marker_migration.remediation": "\u8FD0\u884C `fab doctor --fix` \u8FC1\u79FB\u5230 fabric:bootstrap marker",
1088
+ "doctor.check.bootstrap_marker_migration.remediation": "\u8FD0\u884C `fabric doctor --fix` \u8FC1\u79FB\u5230 fabric:bootstrap marker",
1061
1089
  "doctor.check.bootstrap_snapshot_drift.name": "Bootstrap snapshot drift",
1062
1090
  "doctor.check.bootstrap_snapshot_drift.message.drift": ".fabric/AGENTS.md \u5185\u5BB9\u4E0E BOOTSTRAP_CANONICAL \u9010\u5B57\u8282\u4E0D\u4E00\u81F4\u3002",
1063
- "doctor.check.bootstrap_snapshot_drift.remediation.drift": "\u8FD0\u884C `fab doctor --fix` \u6062\u590D canonical bootstrap snapshot",
1091
+ "doctor.check.bootstrap_snapshot_drift.remediation.drift": "\u8FD0\u884C `fabric doctor --fix` \u6062\u590D canonical bootstrap snapshot",
1064
1092
  "doctor.check.bootstrap_snapshot_drift.ok.ok": ".fabric/AGENTS.md \u4E0E BOOTSTRAP_CANONICAL \u9010\u5B57\u8282\u4E00\u81F4\u3002",
1065
1093
  "doctor.check.bootstrap_snapshot_drift.ok.missing_delegated": ".fabric/AGENTS.md \u4E0D\u5B58\u5728\uFF0C\u5DF2\u4EA4\u7531 bootstrap_anchor_missing \u62A5\u544A\u3002",
1066
1094
  "doctor.check.managed_block_drift.name": "Managed block drift",
1067
1095
  "doctor.check.managed_block_drift.message.singular": "{count} \u4E2A three-end managed block \u4E0E\u671F\u671B\u5185\u5BB9\uFF08snapshot + \u53EF\u9009 project-rules concat\uFF09\u4E0D\u4E00\u81F4\uFF1A{list}\u3002",
1068
1096
  "doctor.check.managed_block_drift.message.plural": "{count} \u4E2A three-end managed block \u4E0E\u671F\u671B\u5185\u5BB9\uFF08snapshot + \u53EF\u9009 project-rules concat\uFF09\u4E0D\u4E00\u81F4\uFF1A{list}\u3002",
1069
- "doctor.check.managed_block_drift.remediation": "\u8FD0\u884C `fab doctor --fix` \u4ECE canonical \u6062\u590D three-end managed blocks",
1097
+ "doctor.check.managed_block_drift.remediation": "\u8FD0\u884C `fabric doctor --fix` \u4ECE canonical \u6062\u590D three-end managed blocks",
1070
1098
  "doctor.check.managed_block_drift.ok.ok": "Three-end managed blocks \u4E0E expectedBody \u9010\u5B57\u8282\u4E00\u81F4\u3002",
1071
1099
  "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",
1072
1100
  "doctor.check.bootstrap_anchor.name": "Bootstrap anchor",
1073
1101
  "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",
1074
- "doctor.check.bootstrap_anchor.remediation.missing": "\u8FD0\u884C `fab install` \u5728 repo root \u751F\u6210 AGENTS.md / CLAUDE.md bootstrap anchor\u3002",
1102
+ "doctor.check.bootstrap_anchor.remediation.missing": "\u8FD0\u884C `fabric install` \u5728 repo root \u751F\u6210 AGENTS.md / CLAUDE.md bootstrap anchor\u3002",
1075
1103
  "doctor.check.bootstrap_anchor.ok": "repo root \u4E0B\u5DF2\u5B58\u5728 Bootstrap anchor\uFF1A{present}\u3002",
1076
1104
  "doctor.check.baseline_filename_format.name": "Baseline \u6587\u4EF6\u540D\u683C\u5F0F",
1077
1105
  "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",
@@ -1082,60 +1110,63 @@ var zhCNMessages = {
1082
1110
  "doctor.check.knowledge_dir_missing.name": "Knowledge layout",
1083
1111
  "doctor.check.knowledge_dir_missing.message.singular": "{count} \u4E2A\u5FC5\u9700 knowledge subdir \u7F3A\u5931\uFF1A{list}\u3002",
1084
1112
  "doctor.check.knowledge_dir_missing.message.plural": "{count} \u4E2A\u5FC5\u9700 knowledge subdir \u7F3A\u5931\uFF1A{list}\u3002",
1085
- "doctor.check.knowledge_dir_missing.remediation": "\u8FD0\u884C `fab doctor --fix` \u521B\u5EFA\u7F3A\u5931\u7684 .fabric/knowledge/* subdirectories\u3002",
1113
+ "doctor.check.knowledge_dir_missing.remediation": "\u8FD0\u884C `fabric doctor --fix` \u521B\u5EFA\u7F3A\u5931\u7684 .fabric/knowledge/* subdirectories\u3002",
1086
1114
  "doctor.check.knowledge_dir_missing.ok": "\u5168\u90E8 {count} \u4E2A\u5FC5\u9700 .fabric/knowledge/* subdirectories \u5747\u5DF2\u5B58\u5728\u3002",
1087
1115
  "doctor.check.forensic.name": "Scan evidence",
1088
1116
  "doctor.check.forensic.message.missing.singular": "{error} \u5B9E\u65F6\u626B\u63CF\u68C0\u6D4B\u5230 {frameworkKind}\uFF0C\u5171\u6709 {count} \u4E2A\u5165\u53E3\u70B9\u3002",
1089
1117
  "doctor.check.forensic.message.missing.plural": "{error} \u5B9E\u65F6\u626B\u63CF\u68C0\u6D4B\u5230 {frameworkKind}\uFF0C\u5171\u6709 {count} \u4E2A\u5165\u53E3\u70B9\u3002",
1090
1118
  "doctor.check.forensic.message.missing-default": ".fabric/forensic.json \u7F3A\u5931\u3002",
1091
1119
  "doctor.check.forensic.message.invalid-default": ".fabric/forensic.json \u65E0\u6548\u3002",
1092
- "doctor.check.forensic.remediation": "\u8FD0\u884C `fab install` \u91CD\u65B0\u751F\u6210 .fabric/forensic.json\u3002",
1120
+ "doctor.check.forensic.remediation": "\u8FD0\u884C `fabric install` \u91CD\u65B0\u751F\u6210 .fabric/forensic.json\u3002",
1093
1121
  "doctor.check.forensic.ok": ".fabric/forensic.json \u5BF9 {frameworkKind} \u6709\u6548\u3002",
1094
1122
  "doctor.check.agents_meta.name": "Agents metadata",
1095
1123
  "doctor.check.agents_meta.message.missing": ".fabric/agents.meta.json \u7F3A\u5931\u3002",
1096
- "doctor.check.agents_meta.remediation.missing": "\u8FD0\u884C `fab doctor --fix` \u4ECE .fabric/knowledge/ \u91CD\u5EFA agents.meta.json\u3002",
1124
+ "doctor.check.agents_meta.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u4ECE .fabric/knowledge/ \u91CD\u5EFA agents.meta.json\u3002",
1097
1125
  "doctor.check.agents_meta.message.invalid-default": ".fabric/agents.meta.json \u65E0\u6548\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",
1126
+ // rc.35 TASK-09 (P0-14): 人话化的 schema 解析失败消息。
1127
+ "doctor.check.agents_meta.message.invalid-zod": ".fabric/agents.meta.json schema \u6821\u9A8C\u5931\u8D25 \u2014 {issues}\u3002\u8BE5\u6587\u4EF6\u5F88\u53EF\u80FD\u7531\u4E0D\u517C\u5BB9\u7248\u672C\u7684 fabric CLI \u5199\u5165,\u6216\u88AB\u624B\u5DE5\u7F16\u8F91\u3002",
1128
+ "doctor.check.agents_meta.message.invalid-from-old-cli": ".fabric/agents.meta.json schema \u6821\u9A8C\u5931\u8D25,\u56E0\u4E3A PATH \u4E0A\u7684\u5168\u5C40 `fabric` CLI ({version}) \u4F4E\u4E8E\u6700\u4F4E\u652F\u6301\u7248\u672C {minVersion}\u3002rc.31 \u5F15\u5165\u4E86\u5411\u540E\u517C\u5BB9\u7684 singular\u2192plural \u5F52\u4E00\u5316,\u65E7\u7248 CLI \u5199\u51FA\u7684\u6587\u4EF6\u81EA\u5DF1\u4E5F\u65E0\u6CD5\u89E3\u6790\u3002",
1129
+ "doctor.check.agents_meta.remediation.invalid": "\u8FD0\u884C `fabric 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",
1099
1130
  "doctor.check.agents_meta.message.stale": ".fabric/agents.meta.json revision {revision} \u4E0E .fabric/knowledge \u6D3E\u751F revision {computedRevision} \u4E0D\u4E00\u81F4\u3002",
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",
1131
+ "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 `fabric doctor --fix`\u3002",
1101
1132
  "doctor.check.agents_meta.ok": ".fabric/agents.meta.json revision {revision} \u5DF2\u4E0E .fabric/knowledge \u5BF9\u9F50\u3002",
1102
1133
  "doctor.check.rule_content_refs.name": "Rule content refs",
1103
1134
  "doctor.check.rule_content_refs.message.unavailable": "agents.meta.json \u6709\u6548\u524D\uFF0C\u65E0\u6CD5\u68C0\u67E5 content_ref entries\u3002",
1104
- "doctor.check.rule_content_refs.remediation.unavailable": "\u5148\u4FEE\u590D agents.meta.json\uFF1A\u8FD0\u884C `fab doctor --fix`\u3002",
1135
+ "doctor.check.rule_content_refs.remediation.unavailable": "\u5148\u4FEE\u590D agents.meta.json\uFF1A\u8FD0\u884C `fabric doctor --fix`\u3002",
1105
1136
  "doctor.check.rule_content_refs.message.outside.singular": "{count} \u4E2A content_ref entry \u4F4D\u4E8E .fabric/knowledge \u5916\u90E8\u3002",
1106
1137
  "doctor.check.rule_content_refs.message.outside.plural": "{count} \u4E2A content_ref entries \u4F4D\u4E8E .fabric/knowledge \u5916\u90E8\u3002",
1107
1138
  // 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",
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",
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",
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",
1139
+ "doctor.check.rule_content_refs.remediation.outside": "\u8FD0\u884C `fabric 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",
1140
+ "doctor.check.rule_content_refs.message.missing.singular": "{count} \u4E2A content_ref target \u7F3A\u5931\u3002\u8FD0\u884C `fabric doctor --fix` \u6267\u884C reconcile\u3002",
1141
+ "doctor.check.rule_content_refs.message.missing.plural": "{count} \u4E2A content_ref targets \u7F3A\u5931\u3002\u8FD0\u884C `fabric doctor --fix` \u6267\u884C reconcile\u3002",
1142
+ "doctor.check.rule_content_refs.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u8BA9 agents.meta.json \u4E0E .fabric/knowledge/ \u4E2D\u7684\u73B0\u6709\u6587\u4EF6 reconcile\u3002",
1112
1143
  "doctor.check.rule_content_refs.ok": "\u6240\u6709 content_ref entries \u90FD\u80FD\u89E3\u6790\u5230 .fabric/knowledge files\u3002",
1113
1144
  "doctor.check.knowledge_test_index.name": "Knowledge-test index",
1114
- "doctor.check.knowledge_test_index.remediation.missing": "\u8FD0\u884C `fab doctor --fix` \u91CD\u5EFA .fabric/.cache/knowledge-test.index.json\u3002",
1115
- "doctor.check.knowledge_test_index.remediation.invalid": "\u5220\u9664 .fabric/.cache/knowledge-test.index.json \u5E76\u8FD0\u884C `fab doctor --fix` \u91CD\u65B0\u751F\u6210\u3002",
1145
+ "doctor.check.knowledge_test_index.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u91CD\u5EFA .fabric/.cache/knowledge-test.index.json\u3002",
1146
+ "doctor.check.knowledge_test_index.remediation.invalid": "\u5220\u9664 .fabric/.cache/knowledge-test.index.json \u5E76\u8FD0\u884C `fabric doctor --fix` \u91CD\u65B0\u751F\u6210\u3002",
1116
1147
  "doctor.check.knowledge_test_index.message.stale": ".fabric/.cache/knowledge-test.index.json \u5DF2\u8FC7\u671F\u3002",
1117
- "doctor.check.knowledge_test_index.remediation.stale": "\u8FD0\u884C `fab doctor --fix` \u91CD\u5EFA knowledge-test index\u3002",
1148
+ "doctor.check.knowledge_test_index.remediation.stale": "\u8FD0\u884C `fabric doctor --fix` \u91CD\u5EFA knowledge-test index\u3002",
1118
1149
  "doctor.check.knowledge_test_index.ok.link_singular.orphan_singular": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1119
1150
  "doctor.check.knowledge_test_index.ok.link_singular.orphan_plural": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1120
1151
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_singular": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1121
1152
  "doctor.check.knowledge_test_index.ok.link_plural.orphan_plural": "\u5DF2\u7D22\u5F15 {linkCount} \u4E2A link \u548C {orphanCount} \u4E2A orphan annotation\u3002",
1122
1153
  "doctor.check.event_ledger.name": "Event ledger",
1123
1154
  "doctor.check.event_ledger.message.missing": ".fabric/events.jsonl \u7F3A\u5931\u3002",
1124
- "doctor.check.event_ledger.remediation.missing": "\u8FD0\u884C `fab doctor --fix` \u521B\u5EFA .fabric/events.jsonl\u3002",
1155
+ "doctor.check.event_ledger.remediation.missing": "\u8FD0\u884C `fabric doctor --fix` \u521B\u5EFA .fabric/events.jsonl\u3002",
1125
1156
  "doctor.check.event_ledger.message.not_writable-default": ".fabric/events.jsonl \u4E0D\u53EF\u5199\u3002",
1126
1157
  "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",
1127
1158
  "doctor.check.event_ledger.message.invalid-default": ".fabric/events.jsonl \u65E0\u6548\u3002",
1128
1159
  // 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",
1160
+ "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 `fabric doctor --fix` \u521B\u5EFA\u65B0\u7A7A ledger\u3002\u5386\u53F2\u4E8B\u4EF6\u4FDD\u7559\u5728 events.archive/ \u4E0D\u4E22\u3002",
1130
1161
  "doctor.check.event_ledger.ok": ".fabric/events.jsonl \u5DF2\u5B58\u5728\uFF0C\u53EF\u5199\uFF0C\u4E14\u53EF\u89E3\u6790\u3002",
1131
1162
  "doctor.check.mcp_config_in_wrong_file.name": "Claude MCP config \u4F4D\u7F6E",
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",
1133
- "doctor.check.mcp_config_in_wrong_file.remediation": "\u8FD0\u884C `fab doctor --fix` \u4ECE .claude/settings.json \u4E2D\u79FB\u9664 mcpServers.fabric\uFF0C\u7136\u540E\u8FD0\u884C `fab install` \u5199\u5165 .mcp.json\u3002",
1163
+ "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 fabric install \u5199\u5165 .mcp.json\u3002",
1164
+ "doctor.check.mcp_config_in_wrong_file.remediation": "\u8FD0\u884C `fabric doctor --fix` \u4ECE .claude/settings.json \u4E2D\u79FB\u9664 mcpServers.fabric\uFF0C\u7136\u540E\u8FD0\u884C `fabric install` \u5199\u5165 .mcp.json\u3002",
1134
1165
  "doctor.check.mcp_config_in_wrong_file.ok": "mcpServers.fabric \u4E0D\u5728 .claude/settings.json \u4E2D\u3002",
1135
1166
  "doctor.check.event_ledger_partial_write.name": "Event ledger partial write",
1136
1167
  "doctor.check.event_ledger_partial_write.ok.skipped": "\u65E0\u9700\u6267\u884C partial-write \u68C0\u67E5\uFF08ledger \u7F3A\u5931\u6216\u4E0D\u53EF\u5199\uFF09\u3002",
1137
1168
  "doctor.check.event_ledger_partial_write.message": "events.jsonl \u5728 byte offset {byteOffset} \u5904\u5B58\u5728 partial write\uFF08{byteLength} \u4E2A corrupted bytes\uFF09\u3002\u8FD0\u884C --fix \u622A\u65AD\u5E76\u4FDD\u7559 corrupted bytes\u3002",
1138
- "doctor.check.event_ledger_partial_write.remediation": "\u8FD0\u884C `fab doctor --fix` \u622A\u65AD partial write \u5E76\u5C06 events.jsonl \u6062\u590D\u5230\u6709\u6548\u72B6\u6001\u3002",
1169
+ "doctor.check.event_ledger_partial_write.remediation": "\u8FD0\u884C `fabric doctor --fix` \u622A\u65AD partial write \u5E76\u5C06 events.jsonl \u6062\u590D\u5230\u6709\u6548\u72B6\u6001\u3002",
1139
1170
  "doctor.check.event_ledger_partial_write.ok.clean": "events.jsonl \u6CA1\u6709 partial trailing write\u3002",
1140
1171
  // v2.0.0-rc.27 TASK-010 (audit §2.24): schema-compat 向前兼容警告类别。
1141
1172
  "doctor.check.event_ledger_schema_compat.name": "Event ledger schema \u517C\u5BB9\u6027",
@@ -1144,30 +1175,30 @@ var zhCNMessages = {
1144
1175
  "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",
1145
1176
  "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",
1146
1177
  // 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",
1178
+ "doctor.check.event_ledger_schema_compat.remediation": "\u5347\u7EA7 fabric 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 `fabric 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",
1148
1179
  // v2.0.0-rc.28 TASK-04 (audit §3.1): SKILL ref/ 镜像一致性检查。
1149
1180
  "doctor.check.skill_ref_mirror.name": "Skill ref \u955C\u50CF\u4E00\u81F4\u6027",
1150
1181
  "doctor.check.skill_ref_mirror.ok": "`.claude/skills/<slug>/ref/` \u4E0E `.codex/skills/<slug>/ref/` \u5B57\u8282\u4E00\u81F4\u3002",
1151
1182
  "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",
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",
1183
+ "doctor.check.skill_ref_mirror.remediation": "\u8DD1 `fabric install` \u4ECE canonical templates \u91CD\u5199\u4E24\u7AEF ref \u5B50\u6811\u4EE5\u6062\u590D\u4E00\u81F4\u3002",
1153
1184
  // 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
1185
  "doctor.check.skill_token_budget.name": "Skill token budget",
1155
1186
  "doctor.check.skill_token_budget.ok": "\u6240\u6709 .claude/skills/<slug>/SKILL.md \u5728 token budget \u5185 (warn 5K / error 10K)\u3002",
1156
1187
  "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
1188
  "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",
1189
+ "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 `fabric install` \u540C\u6B65\u4E24\u7AEF\u3002",
1159
1190
  // 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
1191
  "doctor.check.skill_description.name": "Skill description quality",
1161
1192
  "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
1193
  "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
1194
  "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",
1195
+ "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 `fabric 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
1196
  // 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
1197
  "doctor.check.cite_goodhart.name": "Cite-policy Goodhart",
1167
1198
  "doctor.check.cite_goodhart.ok": "\u8FC7\u53BB 7d \u672A\u68C0\u6D4B\u5230 cite-policy Goodhart \u53CD\u6A21\u5F0F\u3002",
1168
1199
  "doctor.check.cite_goodhart.message.singular": "\u68C0\u6D4B\u5230 {count} \u4E2A cite-policy Goodhart \u6A21\u5F0F: {list}\u3002",
1169
1200
  "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",
1201
+ "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 `fabric doctor --cite-coverage --since=7d`\u3002",
1171
1202
  // 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
1203
  "doctor.check.draft_backlog.name": "Knowledge draft backlog",
1173
1204
  "doctor.check.draft_backlog.ok": "canonical knowledge entries \u4E2D draft \u5360\u6BD4\u6B63\u5E38 (< 50%, \u6216 workspace \u592A\u5C0F\u4E0D\u8BC4)\u3002",
@@ -1177,15 +1208,15 @@ var zhCNMessages = {
1177
1208
  "doctor.check.meta_manually_diverged.ok.unreadable": "agents.meta.json \u4E0D\u53EF\u8BFB\uFF0C\u8DF3\u8FC7 divergence \u68C0\u67E5\u3002",
1178
1209
  "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",
1179
1210
  "doctor.check.meta_manually_diverged.message.extra.plural": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entries \u5728\u78C1\u76D8\u4E0A\u6CA1\u6709\u5BF9\u5E94\u6587\u4EF6\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
1180
- "doctor.check.meta_manually_diverged.remediation.extra": "\u8FD0\u884C `fab doctor --fix` \u8BA9 agents.meta.json \u4E0E\u78C1\u76D8\u4E0A\u5F53\u524D\u7684 rule files reconcile\u3002",
1211
+ "doctor.check.meta_manually_diverged.remediation.extra": "\u8FD0\u884C `fabric doctor --fix` \u8BA9 agents.meta.json \u4E0E\u78C1\u76D8\u4E0A\u5F53\u524D\u7684 rule files reconcile\u3002",
1181
1212
  "doctor.check.meta_manually_diverged.message.hash.singular": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entry \u7684 hash \u4E0E\u78C1\u76D8\u6587\u4EF6\u4E0D\u5339\u914D\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
1182
1213
  "doctor.check.meta_manually_diverged.message.hash.plural": "agents.meta.json \u4E2D\u6709 {count} \u4E2A entries \u7684 hash \u4E0E\u78C1\u76D8\u6587\u4EF6\u4E0D\u5339\u914D\u3002\u8FD0\u884C --fix \u6267\u884C reconcile\u3002",
1183
- "doctor.check.meta_manually_diverged.remediation.hash": "\u8FD0\u884C `fab doctor --fix` \u8BA9 agents.meta.json \u4E0E\u5F53\u524D rule file \u5185\u5BB9 reconcile\u3002",
1214
+ "doctor.check.meta_manually_diverged.remediation.hash": "\u8FD0\u884C `fabric doctor --fix` \u8BA9 agents.meta.json \u4E0E\u5F53\u524D rule file \u5185\u5BB9 reconcile\u3002",
1184
1215
  "doctor.check.meta_manually_diverged.ok.consistent": "agents.meta.json \u4E0E\u78C1\u76D8\u4E0A\u7684 rule files \u4E00\u81F4\u3002",
1185
1216
  "doctor.check.knowledge_dir_unindexed.name": "Knowledge dir unindexed",
1186
- "doctor.check.knowledge_dir_unindexed.message.singular": ".fabric/knowledge/ \u4E2D\u6709 {count} \u4E2A .md file \u672A\u7D22\u5F15\u5230 agents.meta.json\u3002\u8FD0\u884C `fab doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1187
- "doctor.check.knowledge_dir_unindexed.message.plural": ".fabric/knowledge/ \u4E2D\u6709 {count} \u4E2A .md files \u672A\u7D22\u5F15\u5230 agents.meta.json\u3002\u8FD0\u884C `fab doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1188
- "doctor.check.knowledge_dir_unindexed.remediation": "\u8FD0\u884C `fab doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1217
+ "doctor.check.knowledge_dir_unindexed.message.singular": ".fabric/knowledge/ \u4E2D\u6709 {count} \u4E2A .md file \u672A\u7D22\u5F15\u5230 agents.meta.json\u3002\u8FD0\u884C `fabric doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1218
+ "doctor.check.knowledge_dir_unindexed.message.plural": ".fabric/knowledge/ \u4E2D\u6709 {count} \u4E2A .md files \u672A\u7D22\u5F15\u5230 agents.meta.json\u3002\u8FD0\u884C `fabric doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1219
+ "doctor.check.knowledge_dir_unindexed.remediation": "\u8FD0\u884C `fabric doctor --fix` \u7D22\u5F15\u7F3A\u5931\u7684 knowledge files\u3002",
1189
1220
  "doctor.check.knowledge_dir_unindexed.ok": "\u6240\u6709 .fabric/knowledge/ .md files \u90FD\u5DF2\u7D22\u5F15\u5230 agents.meta.json\u3002",
1190
1221
  "doctor.check.stable_id_collision.name": "Stable ID collision",
1191
1222
  "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',
@@ -1194,9 +1225,9 @@ var zhCNMessages = {
1194
1225
  "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",
1195
1226
  "doctor.check.stable_id_collision.ok": ".fabric/knowledge/ \u4E2D\u672A\u53D1\u73B0\u5DF2\u58F0\u660E\u7684 stable_id collisions\u3002",
1196
1227
  "doctor.check.counter_desync.name": "Knowledge counter desync",
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",
1198
- "doctor.check.counter_desync.message.plural": "{count} \u4E2A knowledge counters \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",
1199
- "doctor.check.counter_desync.remediation": "\u8FD0\u884C `fab doctor --fix` \u5C06 agents.meta.json counters \u63D0\u5347\u5230\u89C2\u6D4B\u5230\u7684\u6700\u5927 counter \u503C\u3002",
1228
+ "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 `fabric doctor --fix` bump counters\u3002",
1229
+ "doctor.check.counter_desync.message.plural": "{count} \u4E2A knowledge counters \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E0D\u540C\u6B65\u3002{counterPath} = {current}\uFF0C\u4F46\u68C0\u6D4B\u5230 {observedId}\u3002\u8FD0\u884C `fabric doctor --fix` bump counters\u3002",
1230
+ "doctor.check.counter_desync.remediation": "\u8FD0\u884C `fabric doctor --fix` \u5C06 agents.meta.json counters \u63D0\u5347\u5230\u89C2\u6D4B\u5230\u7684\u6700\u5927 counter \u503C\u3002",
1200
1231
  "doctor.check.counter_desync.ok": "agents.meta.json counters envelope \u4E0E\u89C2\u6D4B\u5230\u7684 stable_ids \u4E00\u81F4\u3002",
1201
1232
  "doctor.check.preexisting_root_files.name": "Preexisting root markdown",
1202
1233
  "doctor.check.preexisting_root_files.ok": "project root \u672A\u68C0\u6D4B\u5230 CLAUDE.md \u6216 AGENTS.md\u3002",
@@ -1211,12 +1242,12 @@ var zhCNMessages = {
1211
1242
  "doctor.check.orphan_demote.ok": "\u6CA1\u6709 canonical knowledge entries \u8D85\u8FC7\u6309 maturity \u8BBE\u5B9A\u7684 inactivity threshold\u3002",
1212
1243
  "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",
1213
1244
  "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",
1214
- "doctor.check.orphan_demote.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 orphan entries \u964D\u7EA7\u4E00\u4E2A maturity tier\u3002",
1245
+ "doctor.check.orphan_demote.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge`\u5C06 orphan entries \u964D\u7EA7\u4E00\u4E2A maturity tier\u3002",
1215
1246
  "doctor.check.stale_archive.name": "Knowledge stale archive",
1216
1247
  "doctor.check.stale_archive.ok": "\u6CA1\u6709 draft knowledge entries \u8D85\u8FC7\u989D\u5916\u7684 stale-archive quiet window\u3002",
1217
1248
  "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",
1218
1249
  "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",
1219
- "doctor.check.stale_archive.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 stale entries \u79FB\u52A8\u5230 `.fabric/.archive/<type>/`\u3002",
1250
+ "doctor.check.stale_archive.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge`\u5C06 stale entries \u79FB\u52A8\u5230 `.fabric/.archive/<type>/`\u3002",
1220
1251
  "doctor.check.pending_overdue.name": "Knowledge pending overdue",
1221
1252
  "doctor.check.pending_overdue.ok": "\u6CA1\u6709 pending knowledge entries \u8D85\u8FC7 14-day review threshold\u3002",
1222
1253
  "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",
@@ -1238,7 +1269,7 @@ var zhCNMessages = {
1238
1269
  "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",
1239
1270
  "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",
1240
1271
  "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",
1241
- "doctor.check.index_drift.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge`\u5C06 agents.meta.json counters \u63D0\u5347\u5230 max_observed + 1\u3002",
1272
+ "doctor.check.index_drift.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge`\u5C06 agents.meta.json counters \u63D0\u5347\u5230 max_observed + 1\u3002",
1242
1273
  "doctor.check.underseeded.name": "Knowledge underseeded",
1243
1274
  "doctor.check.underseeded.ok": "\u77E5\u8BC6\u5E93\u5DF2\u6709 {count} \u4E2A canonical entries\uFF08>= {threshold}\uFF09\u3002",
1244
1275
  "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",
@@ -1272,7 +1303,7 @@ var zhCNMessages = {
1272
1303
  "doctor.check.session_hints_stale.ok": ".fabric/.cache/ \u4E0B\u6CA1\u6709\u8D85\u8FC7 {days} \u5929\u7684 session-hints cache files\u3002",
1273
1304
  "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",
1274
1305
  "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",
1275
- "doctor.check.session_hints_stale.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge` \u5220\u9664\u8FC7\u671F\u7684 session-hints cache files\u3002",
1306
+ "doctor.check.session_hints_stale.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge` \u5220\u9664\u8FC7\u671F\u7684 session-hints cache files\u3002",
1276
1307
  "doctor.check.stale_serve_lock.name": "Serve lock",
1277
1308
  "doctor.check.stale_serve_lock.ok.no_lock": "\u672A\u53D1\u73B0 .fabric/.serve.lock\u3002",
1278
1309
  "doctor.check.stale_serve_lock.ok.live_pid": ".fabric/.serve.lock \u7531 live PID {pid} \u6301\u6709\u3002",
@@ -1280,26 +1311,39 @@ var zhCNMessages = {
1280
1311
  "doctor.check.stale_serve_lock.age.day.plural": "{count} \u5929\u524D",
1281
1312
  "doctor.check.stale_serve_lock.age.hour.singular": "{count} \u5C0F\u65F6\u524D",
1282
1313
  "doctor.check.stale_serve_lock.age.hour.plural": "{count} \u5C0F\u65F6\u524D",
1283
- "doctor.check.stale_serve_lock.message.dead_pid": "[advisory] .fabric/.serve.lock \u6301\u6709 dead PID {pid}\uFF08acquired {acquiredAgo}\uFF09\u3002\u8FD0\u884C `fab doctor --fix` \u79FB\u9664\u3002",
1284
- "doctor.check.stale_serve_lock.remediation.dead_pid": "\u8FD0\u884C `fab doctor --fix` \u79FB\u9664\u8FC7\u671F\u7684 .fabric/.serve.lock\u3002",
1314
+ "doctor.check.stale_serve_lock.message.dead_pid": "[advisory] .fabric/.serve.lock \u6301\u6709 dead PID {pid}\uFF08acquired {acquiredAgo}\uFF09\u3002\u8FD0\u884C `fabric doctor --fix` \u79FB\u9664\u3002",
1315
+ "doctor.check.stale_serve_lock.remediation.dead_pid": "\u8FD0\u884C `fabric doctor --fix` \u79FB\u9664\u8FC7\u671F\u7684 .fabric/.serve.lock\u3002",
1285
1316
  "doctor.check.relevance_fields_missing.name": "Knowledge relevance fields missing",
1286
1317
  "doctor.check.relevance_fields_missing.ok": "\u6240\u6709 pending entries \u90FD\u58F0\u660E\u4E86 relevance_scope \u548C relevance_paths\u3002",
1287
1318
  "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",
1288
1319
  "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",
1289
- "doctor.check.relevance_fields_missing.remediation": "\u8FD0\u884C `fab doctor --fix-knowledge` \u56DE\u586B schema defaults\uFF08relevance_scope: broad\uFF0Crelevance_paths: []\uFF09\u3002",
1320
+ "doctor.check.relevance_fields_missing.remediation": "\u8FD0\u884C `fabric doctor --fix-knowledge` \u56DE\u586B schema defaults\uFF08relevance_scope: broad\uFF0Crelevance_paths: []\uFF09\u3002",
1290
1321
  // rc.31 BUG-M3/NEW-4: hooks_wired observability.
1291
1322
  "doctor.check.hooks_wired.name": "Claude Code hooks wired",
1292
1323
  "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
1324
  "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",
1325
+ "doctor.check.hooks_wired.message.missing_settings": ".claude/ \u76EE\u5F55\u5B58\u5728\u4F46 .claude/settings.json \u7F3A\u5931\u6216\u65E0\u6CD5\u89E3\u6790\uFF1Bfabric install \u53EF\u80FD\u4ECE\u672A\u8DD1\u6210\u529F\uFF0C\u6216\u6587\u4EF6\u88AB\u5916\u90E8\u6E05\u7A7A\u3002",
1326
+ "doctor.check.hooks_wired.message.incomplete": ".claude/settings.json \u7F3A\u5C11 fabric hook \u6CE8\u5165\uFF1A{missing}\u3002fabric install \u7684 dry-run \u62A5\u544A\u4E0E\u5B9E\u9645\u72B6\u6001\u4E0D\u4E00\u81F4\uFF08rc.30 audit BUG-M3 / NEW-4\uFF09\u3002",
1327
+ "doctor.check.hooks_wired.remediation": "\u8FD0\u884C `fabric 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
1328
  // rc.31 BUG-G2/G5: promote-ledger invariant check.
1298
1329
  "doctor.check.promote_ledger_invariant.name": "Promote ledger invariant",
1299
1330
  "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
1331
  "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
1332
  "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",
1333
+ "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 fabric 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",
1334
+ // rc.35 TASK-04 (P0-9.b): global_cli_outdated.
1335
+ "doctor.check.global_cli_outdated.name": "\u5168\u5C40 fabric CLI \u7248\u672C",
1336
+ "doctor.check.global_cli_outdated.ok": "PATH \u4E0A\u7684 `fabric` \u662F {version}\uFF0C\u4E0E rc.31+ \u9879\u76EE schema \u517C\u5BB9\u3002",
1337
+ "doctor.check.global_cli_outdated.message.outdated": "PATH \u4E0A\u7684 `fabric` \u662F {version}\uFF0C\u4F4E\u4E8E\u6700\u4F4E\u652F\u6301\u7248\u672C {minVersion}\u3002rc.31 \u4FEE\u590D\u4E86 agents.meta.json schema\uFF0C\u65E7\u7248 CLI \u5B89\u88C5\u7684 hook \u4F1A\u9759\u9ED8\u5931\u6548\uFF0C\u5FC5\u987B\u5347\u7EA7\u3002",
1338
+ "doctor.check.global_cli_outdated.message.not_found": "PATH \u4E0A\u627E\u4E0D\u5230 `fabric` \u4E8C\u8FDB\u5236\u3002`fabric install` / `fabric doctor` \u90FD\u4F9D\u8D56\u5B83\uFF0C\u8BF7\u5148\u5168\u5C40\u5B89\u88C5\u3002",
1339
+ "doctor.check.global_cli_outdated.message.unparseable": "\u65E0\u6CD5\u89E3\u6790 `fabric -v` \u8F93\u51FA\uFF08{detail}\uFF09\uFF0C\u8DF3\u8FC7\u7248\u672C\u68C0\u67E5\u3002",
1340
+ "doctor.check.global_cli_outdated.remediation": "\u8FD0\u884C `npm install -g @fenglimg/fabric-cli@latest`\uFF0C\u7136\u540E\u5230\u6BCF\u4E2A fabric-managed \u9879\u76EE\u4E0B\u91CD\u8DD1 `fabric install` \u540C\u6B65 hook + SKILL.md\u3002",
1341
+ // rc.35 TASK-05 (P0-10.a): knowledge_summary_opaque.
1342
+ "doctor.check.knowledge_summary_opaque.name": "\u77E5\u8BC6 summary \u900F\u660E\u5EA6",
1343
+ "doctor.check.knowledge_summary_opaque.ok.skipped": "agents.meta.json \u7F3A\u5931\u6216\u65E0\u6548\uFF0C\u8DF3\u8FC7 summary \u900F\u660E\u5EA6\u68C0\u67E5\u3002",
1344
+ "doctor.check.knowledge_summary_opaque.ok": "{opaque}/{total} \u4E2A entry \u7684 summary == stable_id\uFF0C\u6BD4\u4F8B\u5728\u5065\u5EB7\u8303\u56F4\u5185\u3002",
1345
+ "doctor.check.knowledge_summary_opaque.message.warn": "{opaque}/{total} \u4E2A entry ({pct}%) \u7684 description.summary \u7B49\u4E8E stable_id\uFF0C\u8D85\u8FC7 {threshold}% \u9608\u503C\u3002narrow hint \u8F93\u51FA\u4F1A\u53D8\u6210 `<id> \xB7 <id>` \u800C\u975E\u771F\u5B9E\u6982\u8981\uFF0CAI \u770B\u4E0D\u5230\u4FE1\u606F\u4F1A\u4E3B\u52A8\u8DF3\u8FC7 fetch\u3002\u9996\u6279\u4E0D\u900F\u660E: {sample}\u3002",
1346
+ "doctor.check.knowledge_summary_opaque.remediation": "\u8C03 fabric-review skill \u91CD\u5199\u4E0D\u900F\u660E summary \u4E3A\u4E00\u53E5\u4EBA\u7C7B\u53EF\u8BFB\u7684\u6982\u8981\u3002rc.35 hint renderer fallback (TASK-06) \u4E5F\u4F1A\u4ECE entry \u7684 `## Summary` \u6BB5\u81EA\u52A8\u5408\u6210\u4E34\u65F6 summary\u3002",
1303
1347
  "doctor.check.skill_md_yaml_invalid.name": "Skill markdown YAML",
1304
1348
  "doctor.check.skill_md_yaml_invalid.ok": "\u6240\u6709 .claude/.codex SKILL.md frontmatter values \u90FD\u80FD\u6309 strict YAML \u89E3\u6790\u3002",
1305
1349
  "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",
@@ -1334,11 +1378,17 @@ var zhCNMessages = {
1334
1378
  "cli.human-lint.table.location": "\u4F4D\u7F6E",
1335
1379
  "cli.human-lint.table.expected": "\u9884\u671F",
1336
1380
  "cli.human-lint.table.got": "\u5B9E\u9645",
1337
- "cli.install.description": "\u5728\u76EE\u6807\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\uFF08\u811A\u624B\u67B6 .fabric/\u3001bootstrap \u6A21\u677F\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u3001git hooks\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fab install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5B89\u88C5\n fab install --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fab install --dry-run \u4EC5\u9884\u89C8\u5B89\u88C5\u8BA1\u5212\uFF0C\u4E0D\u5199\u5165\u6587\u4EF6",
1381
+ "cli.install.description": "\u5728\u76EE\u6807\u9879\u76EE\u4E2D\u5B89\u88C5 Fabric\uFF08\u811A\u624B\u67B6 .fabric/\u3001bootstrap \u6A21\u677F\u3001MCP \u5BA2\u6237\u7AEF\u914D\u7F6E\u3001git hooks\uFF09\u3002\n\n\u793A\u4F8B\uFF1A\n fabric install \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5B89\u88C5\n fabric install --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fabric install --dry-run \u4EC5\u9884\u89C8\u5B89\u88C5\u8BA1\u5212\uFF0C\u4E0D\u5199\u5165\u6587\u4EF6",
1338
1382
  "cli.install.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1339
1383
  "cli.install.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1340
1384
  "cli.install.args.yes.description": "\u63A5\u53D7\u5F53\u524D\u5B89\u88C5\u8BA1\u5212\u5E76\u8DF3\u8FC7 TTY \u5411\u5BFC\u76F4\u63A5\u6267\u884C",
1341
1385
  "cli.install.args.dry-run.description": "\u4EC5\u8F93\u51FA\u5B89\u88C5\u8BA1\u5212\uFF0C\u4E0D\u5199\u6587\u4EF6\u4E5F\u4E0D\u6267\u884C\u540E\u7EED\u9636\u6BB5",
1386
+ // rc.35 TASK-08 (P0-5/6): --force-skills-only。
1387
+ "cli.install.args.force-skills-only.description": "\u8DF3\u8FC7 bootstrap / MCP / hooks / settings,\u53EA\u91CD\u65B0\u5237\u65B0 fabric Skill \u6A21\u677F (.claude/.codex/.cursor/skills/*)\u3002",
1388
+ "cli.install.force-skills-only.banner": "\u53EA\u5237\u65B0 fabric Skill \u6A21\u677F",
1389
+ "cli.install.force-skills-only.uninitialised.message": "fabric install --force-skills-only: \u9879\u76EE\u672A\u521D\u59CB\u5316(\u627E\u4E0D\u5230 .fabric/agents.meta.json)\u3002",
1390
+ "cli.install.force-skills-only.uninitialised.hint": "\u8BF7\u5148\u8FD0\u884C `fabric install`(\u4E0D\u5E26 --force-skills-only)\u94FA\u8BBE\u57FA\u7840 scaffold;\u4E4B\u540E\u518D\u7528 --force-skills-only \u505A\u540E\u7EED Skill \u5237\u65B0\u3002",
1391
+ "cli.install.force-skills-only.summary": "Skill \u5237\u65B0\u5B8C\u6210 \u2014 \u5199\u5165: {written}, \u8DF3\u8FC7: {skipped}, \u9519\u8BEF: {errors}",
1342
1392
  "cli.install.mcp.install.global": "\u4F7F\u7528\u5168\u5C40\u5B89\u88C5\u7684 @fenglimg/fabric-server",
1343
1393
  "cli.install.mcp.install.local": "\u5C06 @fenglimg/fabric-server \u5B89\u88C5\u5230\u9879\u76EE devDependencies",
1344
1394
  "cli.install.mcp.local.installing": "\u6B63\u5728\u8FD0\u884C {manager} add -D @fenglimg/fabric-server...",
@@ -1413,7 +1463,7 @@ var zhCNMessages = {
1413
1463
  "cli.install.capabilities.follow-up.ready": "\u53EF\u5728\u5BA2\u6237\u7AEF\u7EE7\u7EED",
1414
1464
  "cli.install.capabilities.follow-up.install": "\u5B89\u88C5\u5BA2\u6237\u7AEF\u8D44\u4EA7",
1415
1465
  "cli.install.capabilities.follow-up.manual": "\u9700\u8981\u624B\u52A8\u540E\u7EED\u5904\u7406",
1416
- "cli.install.next-step.message": "\u8FD0\u884C fab hooks install \u4EE5\u6DFB\u52A0\u7B2C 4 \u5929\u7684 pre-commit \u6D41\u6C34\u7EBF\u3002",
1466
+ "cli.install.next-step.message": "\u8FD0\u884C fabric hooks install \u4EE5\u6DFB\u52A0\u7B2C 4 \u5929\u7684 pre-commit \u6D41\u6C34\u7EBF\u3002",
1417
1467
  "cli.install.reason-message.installable-body": ".fabric/forensic.json \u5DF2\u5C31\u7EEA\uFF1B\u90E8\u5206\u5DF2\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\u5DF2\u652F\u6301 Fabric \u540E\u7EED\u63A5\u529B\uFF0C\u4F46\u4ECD\u9700\u5B89\u88C5\u5BA2\u6237\u7AEF\u8D44\u4EA7\u3002",
1418
1468
  "cli.install.reason-message.manual-body": ".fabric/forensic.json \u5DF2\u5C31\u7EEA\uFF1B\u90E8\u5206\u5DF2\u68C0\u6D4B\u5230\u7684\u5BA2\u6237\u7AEF\u5C1A\u672A\u5B89\u88C5 Fabric skill\uFF0C\u9700\u8981\u624B\u52A8\u5B8C\u6210\u540E\u7EED\u5B89\u88C5\u3002",
1419
1469
  "cli.install.codex-hooks.created": "{label} {path}\uFF0C\u5E76\u5199\u5165 Codex hooks \u914D\u7F6E\uFF08\u9700\u542F\u7528 features.codex_hooks = true\uFF09\u3002",
@@ -1427,15 +1477,15 @@ var zhCNMessages = {
1427
1477
  "cli.install.claude-settings.invalid-json": "{label} {path}\uFF1AJSON \u65E0\u6548\uFF08{reason}\uFF09\u3002",
1428
1478
  "cli.install.claude-settings.invalid-hooks": '{label} {path}\uFF1A"hooks" \u5FC5\u987B\u662F JSON \u5BF9\u8C61\u3002',
1429
1479
  "cli.install.claude-settings.invalid-stop-array": '{label} {path}\uFF1A"hooks.Stop" \u5FC5\u987B\u662F\u6570\u7EC4\u3002',
1430
- "cli.install.errors.abort-existing": "\u4E2D\u6B62\uFF1A{path} \u5DF2\u5B58\u5728\u3002fab install \u662F\u975E\u7834\u574F\u6027\u7684\u3002",
1480
+ "cli.install.errors.abort-existing": "\u4E2D\u6B62\uFF1A{path} \u5DF2\u5B58\u5728\u3002fabric install \u662F\u975E\u7834\u574F\u6027\u7684\u3002",
1431
1481
  "cli.install.diff.canonical": "\u5DE5\u4F5C\u533A\u5DF2\u662F\u89C4\u8303\u72B6\u6001\uFF08\u5DF2\u6821\u9A8C {count} \u4E2A\u6587\u4EF6\uFF09\u3002",
1432
1482
  "cli.install.diff.applying-missing": "\u6B63\u5728\u8865\u9F50 {count} \u4E2A\u7F3A\u5931\u9879\uFF1A{files}",
1433
- "cli.install.diff.drift-abort": "\u68C0\u6D4B\u5230 {path} \u5DF2\u88AB\u4FEE\u6539\u3002\u8FD0\u884C `fab doctor` \u8FDB\u884C\u68C0\u67E5\uFF0C\u6216 `fab uninstall && fab install` \u8FDB\u884C\u91CD\u7F6E\u3002",
1483
+ "cli.install.diff.drift-abort": "\u68C0\u6D4B\u5230 {path} \u5DF2\u88AB\u4FEE\u6539\u3002\u8FD0\u884C `fabric doctor` \u8FDB\u884C\u68C0\u67E5\uFF0C\u6216 `fabric uninstall && fabric install` \u8FDB\u884C\u91CD\u7F6E\u3002",
1434
1484
  "cli.install.diff.state.missing": "\u7F3A\u5931",
1435
1485
  "cli.install.diff.state.present-canonical": "\u89C4\u8303",
1436
1486
  "cli.install.diff.state.drifted": "\u6F02\u79FB",
1437
1487
  "cli.install.diff.state.user-modified": "\u7528\u6237\u4FEE\u6539",
1438
- "cli.uninstall.description": "\u4ECE\u76EE\u6807\u9879\u76EE\u4E2D\u5378\u8F7D Fabric\u3002.fabric/knowledge/ \u59CB\u7EC8\u4FDD\u7559\uFF1B~/.fabric/knowledge/ \u6C38\u4E0D\u53D7\u5F71\u54CD\u3002\n\n\u793A\u4F8B\uFF1A\n fab uninstall \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5378\u8F7D\n fab uninstall --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fab uninstall --dry-run \u4EC5\u9884\u89C8\u5378\u8F7D\u8BA1\u5212\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
1488
+ "cli.uninstall.description": "\u4ECE\u76EE\u6807\u9879\u76EE\u4E2D\u5378\u8F7D Fabric\u3002.fabric/knowledge/ \u59CB\u7EC8\u4FDD\u7559\uFF1B~/.fabric/knowledge/ \u6C38\u4E0D\u53D7\u5F71\u54CD\u3002\n\n\u793A\u4F8B\uFF1A\n fabric uninstall \u5728\u5F53\u524D\u9879\u76EE\u4E2D\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u5378\u8F7D\n fabric uninstall --yes \u63A5\u53D7\u9ED8\u8BA4\u503C\uFF0C\u8DF3\u8FC7 TTY \u5411\u5BFC\n fabric uninstall --dry-run \u4EC5\u9884\u89C8\u5378\u8F7D\u8BA1\u5212\uFF0C\u4E0D\u5220\u9664\u6587\u4EF6",
1439
1489
  "cli.uninstall.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1440
1490
  "cli.uninstall.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1441
1491
  "cli.uninstall.args.yes.description": "\u63A5\u53D7\u5F53\u524D\u5378\u8F7D\u8BA1\u5212\u5E76\u8DF3\u8FC7 TTY \u5411\u5BFC\u76F4\u63A5\u6267\u884C\u3002",
@@ -1486,7 +1536,7 @@ var zhCNMessages = {
1486
1536
  "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",
1487
1537
  "cli.scan.args.debug.description": "\u4EE5\u683C\u5F0F\u5316\u8F93\u51FA\u6253\u5370\u68C0\u6D4B\u8BC1\u636E\u3002",
1488
1538
  "cli.scan.args.json.description": "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u8BCA\u65AD\u62A5\u544A\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",
1539
+ "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",
1490
1540
  "cli.scan.summary.created": "\u5DF2\u5199\u5165 {count} \u6761\u77E5\u8BC6\u6761\u76EE\u81F3 .fabric/knowledge/\u3002",
1491
1541
  "cli.scan.summary.skipped": "\u65E0\u5DEE\u5F02\uFF1B{count} \u6761\u5DF2\u5B58\u5728\u7684\u6761\u76EE\u4FDD\u6301\u4E0D\u53D8\u3002",
1492
1542
  "cli.scan.report.title": "Fabric \u626B\u63CF\u62A5\u544A",
@@ -1501,20 +1551,20 @@ var zhCNMessages = {
1501
1551
  "cli.scan.report.recommendations": "\u5EFA\u8BAE\uFF1A",
1502
1552
  "cli.scan.readme-quality.ok": "\u826F\u597D",
1503
1553
  "cli.scan.readme-quality.stub": "\u8349\u7A3F",
1504
- "cli.scan.recommendation.init": "L0\uFF1A\u8FD0\u884C fab install\uFF0C\u5728 .fabric/AGENTS.md \u751F\u6210 Fabric \u5F15\u5BFC\u89C4\u8303\u5185\u5BB9\u3002",
1554
+ "cli.scan.recommendation.init": "L0\uFF1A\u8FD0\u884C fabric install\uFF0C\u5728 .fabric/AGENTS.md \u751F\u6210 Fabric \u5F15\u5BFC\u89C4\u8303\u5185\u5BB9\u3002",
1505
1555
  "cli.scan.recommendation.readme": "L0\uFF1A\u5148\u8865\u5145 README.md\uFF0C\u518D\u628A\u9879\u76EE\u4E8B\u5B9E\u6574\u7406\u5230 Fabric \u53C2\u8003\u6587\u4EF6\u4E2D\u3002",
1506
1556
  "cli.scan.recommendation.contributing": "L0\uFF1A\u6DFB\u52A0 CONTRIBUTING.md\uFF0C\u6216\u5728 bootstrap \u4E2D\u7559\u4E0B\u8D21\u732E\u6D41\u7A0B\u7684 TODO \u8BF4\u660E\u3002",
1507
1557
  "cli.scan.recommendation.unknown-framework": "L1\uFF1A\u5F53\u524D\u672A\u68C0\u6D4B\u5230\u6846\u67B6\u6807\u8BB0\uFF0C\u9700\u8981\u624B\u52A8\u8865\u5145\u6280\u672F\u6808\u8BF4\u660E\u3002",
1508
1558
  "cli.scan.recommendation.framework-dirs": "L1\uFF1A\u68C0\u67E5 {framework} \u76EE\u5F55\uFF0C\u540E\u7EED\u4E3A\u5176\u8865\u5145\u5BF9\u5E94\u4F5C\u7528\u57DF\u7684 Fabric \u89C4\u5219\u6587\u4EF6\u3002",
1509
- "cli.serve.description": "\u542F\u52A8\u672C\u5730 Fabric MCP HTTP \u670D\u52A1\u3002\n\n\u793A\u4F8B\uFF1A\n fab serve \u7ED1\u5B9A 127.0.0.1:7373\uFF08\u9ED8\u8BA4\uFF09\n fab serve --port 8787 \u4F7F\u7528\u81EA\u5B9A\u4E49\u7AEF\u53E3\n FABRIC_AUTH_TOKEN=<token> fab serve --host 0.0.0.0 \u7ED1\u5B9A\u975E loopback \u5E76\u542F\u7528 Bearer \u9274\u6743",
1559
+ "cli.serve.description": "\u542F\u52A8\u672C\u5730 Fabric MCP HTTP \u670D\u52A1\u3002\n\n\u793A\u4F8B\uFF1A\n fabric serve \u7ED1\u5B9A 127.0.0.1:7373\uFF08\u9ED8\u8BA4\uFF09\n fabric serve --port 8787 \u4F7F\u7528\u81EA\u5B9A\u4E49\u7AEF\u53E3\n FABRIC_AUTH_TOKEN=<token> fabric serve --host 0.0.0.0 \u7ED1\u5B9A\u975E loopback \u5E76\u542F\u7528 Bearer \u9274\u6743",
1510
1560
  "cli.serve.args.port.description": "\u76D1\u542C\u7AEF\u53E3\uFF0C\u9ED8\u8BA4 7373\u3002",
1511
1561
  "cli.serve.args.host.description": "\u76D1\u542C\u4E3B\u673A\uFF0C\u9ED8\u8BA4 127.0.0.1\u3002\u7ED1\u5B9A\u975E loopback \u4E3B\u673A\uFF08\u5982 0.0.0.0\uFF09\u5FC5\u987B\u8BBE\u7F6E FABRIC_AUTH_TOKEN \u542F\u7528 Bearer \u9274\u6743\uFF0C\u5426\u5219\u5C06\u81EA\u52A8\u56DE\u9000\u5230 127.0.0.1\u3002",
1512
1562
  "cli.serve.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\u3002\u9ED8\u8BA4\u4F9D\u6B21\u4F7F\u7528 --target\u3001EXTERNAL_FIXTURE_PATH\u3001\u5F53\u524D\u76EE\u5F55\u3002",
1513
1563
  "cli.serve.args.debug.description": "\u5C06\u76EE\u6807\u89E3\u6790\u7EC6\u8282\u8F93\u51FA\u5230 stderr\u3002",
1514
1564
  "cli.serve.args.allow-loopback-no-auth.description": "\u663E\u5F0F\u5141\u8BB8\u5728 loopback \u4E0A\u4EE5\u65E0\u9274\u6743\u65B9\u5F0F\u8FD0\u884C\uFF08\u9ED8\u8BA4 default-deny\uFF09\u3002\u4EC5\u5728\u53EF\u4FE1\u5355\u7528\u6237\u673A\u5668\u4E0A\u4F7F\u7528\u2014\u2014\u5426\u5219\u4EFB\u4F55\u672C\u673A\u8FDB\u7A0B\u90FD\u80FD\u8BFB\u53D6\u4F60\u7684\u77E5\u8BC6\u5E93\u8D26\u672C\u3002",
1515
1565
  "cli.serve.ready.title": "Fabric \u4EEA\u8868\u76D8",
1516
- "cli.serve.lock-held.action-hint": "\u53E6\u4E00\u4E2A `fab serve` \u8FDB\u7A0B (PID {pid}) \u6B63\u5360\u7528\u5DE5\u4F5C\u533A\u9501\u3002\u8BF7\u5148\u505C\u6B62\u5B83 (\u5728\u8BE5\u7EC8\u7AEF\u6309 Ctrl-C \u6216\u8FD0\u884C `kill {pid}`) \u518D\u6267\u884C\u6B64\u547D\u4EE4\u3002",
1517
- "cli.serve.warning.host-fallback": "--host {host} \u9700\u8981\u8BBE\u7F6E FABRIC_AUTH_TOKEN \u624D\u80FD\u5BF9\u5916\u66B4\u9732\uFF1B\u5DF2\u56DE\u9000\u5230 127.0.0.1\u3002\u5982\u9700\u7ED1\u5B9A {host}\uFF0C\u8BF7\u8FD0\u884C\uFF1AFABRIC_AUTH_TOKEN=<token> fab serve --host {host}",
1566
+ "cli.serve.lock-held.action-hint": "\u53E6\u4E00\u4E2A `fabric serve` \u8FDB\u7A0B (PID {pid}) \u6B63\u5360\u7528\u5DE5\u4F5C\u533A\u9501\u3002\u8BF7\u5148\u505C\u6B62\u5B83 (\u5728\u8BE5\u7EC8\u7AEF\u6309 Ctrl-C \u6216\u8FD0\u884C `kill {pid}`) \u518D\u6267\u884C\u6B64\u547D\u4EE4\u3002",
1567
+ "cli.serve.warning.host-fallback": "--host {host} \u9700\u8981\u8BBE\u7F6E FABRIC_AUTH_TOKEN \u624D\u80FD\u5BF9\u5916\u66B4\u9732\uFF1B\u5DF2\u56DE\u9000\u5230 127.0.0.1\u3002\u5982\u9700\u7ED1\u5B9A {host}\uFF0C\u8BF7\u8FD0\u884C\uFF1AFABRIC_AUTH_TOKEN=<token> fabric serve --host {host}",
1518
1568
  "cli.serve.warning.loopback-deny-default": "\u672A\u8BBE\u7F6E FABRIC_AUTH_TOKEN\uFF1A/api /events /mcp \u9ED8\u8BA4\u8FD4\u56DE 401\uFF08\u5426\u5219\u4EFB\u4F55\u672C\u673A\u8FDB\u7A0B\u90FD\u80FD\u8BFB\u53D6 .fabric/agents.meta.json + forensic.json + events.jsonl\uFF09\u3002\u8BF7\u8BBE\u7F6E FABRIC_AUTH_TOKEN=<secret>\uFF0C\u6216\u4F20\u5165 --allow-loopback-no-auth \u663E\u5F0F\u653E\u884C\u3002",
1519
1569
  "cli.serve.error.port-in-use": "\u7AEF\u53E3 {port} \u5DF2\u88AB\u5360\u7528\uFF0C\u53EF\u5C1D\u8BD5 --port {nextPort}",
1520
1570
  // v2.0.0-rc.29 TASK-008 (BUG-L2): onboard-coverage 国际化键。
@@ -1528,7 +1578,7 @@ var zhCNMessages = {
1528
1578
  "cli.sync-meta.description": "\u4ECE\u5185\u90E8\u89C4\u5219\u6587\u4EF6\u540C\u6B65 Fabric \u5143\u6570\u636E\u3002",
1529
1579
  "cli.sync-meta.args.target.description": "\u76EE\u6807\u9879\u76EE\u8DEF\u5F84\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u3002",
1530
1580
  "cli.sync-meta.args.check-only.description": "\u5982\u679C .fabric/agents.meta.json \u5DF2\u8FC7\u671F\uFF0C\u5219\u4EE5\u4EE3\u7801 1 \u9000\u51FA\u3002",
1531
- "cli.sync-meta.drift-detected": "\u68C0\u6D4B\u5230 Fabric \u5143\u6570\u636E\u6F02\u79FB\u3002\u8BF7\u8FD0\u884C fab sync-meta \u8FDB\u884C\u66F4\u65B0\u3002",
1581
+ "cli.sync-meta.drift-detected": "\u68C0\u6D4B\u5230 Fabric \u5143\u6570\u636E\u6F02\u79FB\u3002\u8BF7\u8FD0\u884C fabric sync-meta \u8FDB\u884C\u66F4\u65B0\u3002",
1532
1582
  "cli.sync-meta.updated": "{label} {path}",
1533
1583
  "dashboard.app.nav.aria-label": "\u4EEA\u8868\u76D8\u89C6\u56FE\u5BFC\u822A",
1534
1584
  "dashboard.app.nav.readiness.label": "\u51C6\u5907\u60C5\u51B5",
@@ -1806,7 +1856,7 @@ function resolveFabricLocale(projectRoot) {
1806
1856
  }
1807
1857
  if (fabricLanguage === "match-existing" || fabricLanguage === "zh-CN-hybrid") {
1808
1858
  console.warn(
1809
- `[fabric] fabric_language="${fabricLanguage}" is a pre-init placeholder that should have been resolved during 'fab init' (KT-DEC-9004). Falling back to FAB_LANG / LANG environment detection.`
1859
+ `[fabric] fabric_language="${fabricLanguage}" is a pre-init placeholder that should have been resolved during 'fabric init' (KT-DEC-9004). Falling back to FAB_LANG / LANG environment detection.`
1810
1860
  );
1811
1861
  return detectNodeLocale();
1812
1862
  }