@fenglimg/fabric-shared 2.0.1 → 2.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,4 @@
1
- import {
2
- BOOTSTRAP_CANONICAL,
3
- BOOTSTRAP_MARKER_BEGIN,
4
- BOOTSTRAP_MARKER_END,
5
- BOOTSTRAP_REGEX,
6
- LEGACY_KB_MARKER_BEGIN,
7
- LEGACY_KB_MARKER_END,
8
- LEGACY_KB_REGEX
9
- } from "./chunk-LTDB2UDN.js";
1
+ import "./chunk-LXNCAKJZ.js";
10
2
  import {
11
3
  PROTECTED_TOKENS,
12
4
  createTranslator,
@@ -16,7 +8,7 @@ import {
16
8
  normalizeLocale,
17
9
  resolveFabricLocale,
18
10
  zhCNMessages
19
- } from "./chunk-7CX32MYL.js";
11
+ } from "./chunk-7TZ2PMVH.js";
20
12
  import {
21
13
  FabExtractKnowledgeInputSchema,
22
14
  FabExtractKnowledgeInputShape,
@@ -64,8 +56,16 @@ import {
64
56
  recallInputSchema,
65
57
  recallOutputSchema,
66
58
  structuredWarningSchema
67
- } from "./chunk-WVPDH4BF.js";
68
- import "./chunk-LXNCAKJZ.js";
59
+ } from "./chunk-JEXTOQVV.js";
60
+ import {
61
+ BOOTSTRAP_CANONICAL,
62
+ BOOTSTRAP_MARKER_BEGIN,
63
+ BOOTSTRAP_MARKER_END,
64
+ BOOTSTRAP_REGEX,
65
+ LEGACY_KB_MARKER_BEGIN,
66
+ LEGACY_KB_MARKER_END,
67
+ LEGACY_KB_REGEX
68
+ } from "./chunk-TX2XZ7AW.js";
69
69
 
70
70
  // src/schemas/agents-meta.ts
71
71
  import { z } from "zod";
@@ -112,7 +112,15 @@ var ruleDescriptionSchema = z.object({
112
112
  // relevance_scope → 'broad' (always-surface, safe default)
113
113
  // relevance_paths → [] (no path anchors)
114
114
  relevance_scope: z.enum(["narrow", "broad"]).default("broad"),
115
- relevance_paths: z.array(z.string()).default([])
115
+ relevance_paths: z.array(z.string()).default([]),
116
+ // v2.2 H2-related (W1-T7): explicit graph edges to related KB entries by
117
+ // stable_id. Authored in frontmatter (`related: [KT-DEC-0001, KT-PIT-0002]`)
118
+ // or written by the fabric-connect skill (SK2); read by fab_recall's
119
+ // include_related packaging (MC1). Optional + default [] so the field is a
120
+ // pure additive — every pre-v2.2 entry parses unchanged. The schema is
121
+ // .strict(), so this MUST be declared or `related:` frontmatter would be
122
+ // rejected at parse time.
123
+ related: z.array(z.string()).default([]).optional()
116
124
  }).strict();
117
125
  var ruleDescriptionIndexItemSchema = z.object({
118
126
  stable_id: z.string(),
@@ -327,28 +335,126 @@ var humanLockFileSchema = z4.object({
327
335
  });
328
336
 
329
337
  // src/schemas/fabric-config.ts
338
+ import { z as z6 } from "zod";
339
+
340
+ // src/schemas/store.ts
330
341
  import { z as z5 } from "zod";
331
- var auditModeSchema = z5.enum(["strict", "warn", "off"]);
332
- var clientPathsSchema = z5.object({
333
- claudeCodeCLI: z5.string().optional(),
334
- claudeCodeDesktop: z5.string().optional(),
335
- cursor: z5.string().optional(),
336
- codexCLI: z5.string().optional()
342
+ var STORE_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
343
+ var storeUuidSchema = z5.string().regex(STORE_UUID_PATTERN, "store_uuid must be a canonical lowercase UUID");
344
+ var PERSONAL_STORE_SENTINEL = "$personal";
345
+ var storeIdentitySchema = z5.object({
346
+ // Intrinsic, immutable once minted. Read from store.json, never recomputed.
347
+ store_uuid: storeUuidSchema,
348
+ // ISO-8601. When the store was first initialized.
349
+ created_at: z5.string(),
350
+ // Optional human-facing canonical alias baked into the store (e.g. the
351
+ // team picks "platform-kb"). Local per-machine aliases are resolved by the
352
+ // StoreResolver from config and may differ; this is the suggested default.
353
+ canonical_alias: z5.string().optional(),
354
+ // Optional one-line description surfaced in `store list` / onboarding.
355
+ description: z5.string().optional(),
356
+ // The semantic scopes this store is *allowed* to hold. A shared (team)
357
+ // store MUST NOT list "personal" (R5#3 privacy boundary, enforced at write
358
+ // time in P2). Open coordinate strings — see schemas/scope.ts.
359
+ allowed_scopes: z5.array(z5.string()).optional()
360
+ }).strict();
361
+ var requiredStoreEntrySchema = z5.object({
362
+ id: z5.string().min(1),
363
+ suggested_remote: z5.union([z5.string().min(1), z5.literal(PERSONAL_STORE_SENTINEL)]).optional()
364
+ }).strict();
365
+ var STORE_KNOWLEDGE_TYPE_DIRS = [
366
+ "models",
367
+ "decisions",
368
+ "guidelines",
369
+ "pitfalls",
370
+ "processes"
371
+ ];
372
+ var STORE_LAYOUT = {
373
+ identityFile: "store.json",
374
+ knowledgeDir: "knowledge",
375
+ bindingsDir: "bindings",
376
+ stateDir: "state"
377
+ };
378
+ var STORES_ROOT_DIR = "stores";
379
+ var GLOBAL_STATE_DIR = "state";
380
+ var GLOBAL_BINDINGS_DIR = "bindings";
381
+ function storeKnowledgeTypeDir(type) {
382
+ return `${STORE_LAYOUT.knowledgeDir}/${type}`;
383
+ }
384
+ function storeRelativePath(storeUuid) {
385
+ return `${STORES_ROOT_DIR}/${storeUuid}`;
386
+ }
387
+ var mountedStoreSchema = z5.object({
388
+ // Intrinsic identity of the mounted store (matches its store.json).
389
+ store_uuid: storeUuidSchema,
390
+ // Local per-machine alias the user references this store by (resolver maps
391
+ // alias → uuid). May differ from the store's canonical_alias.
392
+ alias: z5.string().min(1),
393
+ // Git remote locator for this clone, if any. Absent = local-only store
394
+ // (valid; doctor nudges to add a remote for backup — R5#5, P6).
395
+ remote: z5.string().min(1).optional(),
396
+ // v2.1.0-rc.1 P3: marks the implicit personal store (the one minted by
397
+ // `install --global`). Exactly one mounted store carries personal=true; it
398
+ // is the write target for personal-scope entries (R5#3) and always in the
399
+ // read-set (S11). Optional (no default) so the output type stays a plain
400
+ // optional — consumers coalesce `?? false` when building resolver input.
401
+ personal: z5.boolean().optional(),
402
+ // Whether writes are accepted into this store from this machine. Optional;
403
+ // consumers coalesce `?? true`. Shared stores cloned read-only set false.
404
+ writable: z5.boolean().optional()
337
405
  }).strict();
338
- var mcpPayloadLimitsSchema = z5.object({
339
- warnBytes: z5.number().int().positive().optional(),
340
- hardBytes: z5.number().int().positive().optional()
406
+ var globalConfigSchema = z5.object({
407
+ // Machine/account identity. Personal-knowledge id namespace (S33/S27).
408
+ uid: z5.string().min(1),
409
+ // All stores mounted on this machine. The implicit personal store is
410
+ // included here once initialized. Default empty so a fresh global config
411
+ // (before `install --global`) parses cleanly.
412
+ stores: z5.array(mountedStoreSchema).optional().default([])
413
+ }).passthrough();
414
+
415
+ // src/schemas/fabric-config.ts
416
+ var auditModeSchema = z6.enum(["strict", "warn", "off"]);
417
+ var clientPathsSchema = z6.object({
418
+ claudeCodeCLI: z6.string().optional(),
419
+ claudeCodeDesktop: z6.string().optional(),
420
+ cursor: z6.string().optional(),
421
+ codexCLI: z6.string().optional()
422
+ }).strict();
423
+ var mcpPayloadLimitsSchema = z6.object({
424
+ warnBytes: z6.number().int().positive().optional(),
425
+ hardBytes: z6.number().int().positive().optional()
341
426
  }).optional();
342
- var selectionTokenTtlMsSchema = z5.number().int().min(3e4).max(36e5);
343
- var fabricLanguageSchema = z5.enum([
427
+ var selectionTokenTtlMsSchema = z6.number().int().min(3e4).max(36e5);
428
+ var planContextTopKSchema = z6.number().int().min(1).max(200);
429
+ var fabricLanguageSchema = z6.enum([
344
430
  "match-existing",
345
431
  "zh-CN",
346
432
  "en",
347
433
  "zh-CN-hybrid"
348
434
  ]);
349
- var defaultLayerFilterSchema = z5.enum(["team", "personal", "both"]);
350
- var fabricConfigSchema = z5.object({
435
+ var defaultLayerFilterSchema = z6.enum(["team", "personal", "both"]);
436
+ var fabricConfigSchema = z6.object({
351
437
  clientPaths: clientPathsSchema.optional(),
438
+ // v2.1.0-rc.1 P0 (S13-projectid): the project's stable identity. A UUID
439
+ // bound at `fabric install` time; a remote-derived hash is only a SUGGESTED
440
+ // default, never authoritative (so re-homing the git remote does not change
441
+ // project identity). Optional under the zero-user clean-slate — pre-v2.1
442
+ // fabric-config.json files simply lack it and the ProjectRootResolver mints
443
+ // one on next install. `.fabric/fabric-config.json` carrying this field is
444
+ // also the upward marker the ProjectRootResolver searches for (S15/S32).
445
+ project_id: z6.string().optional(),
446
+ // v2.1.0-rc.1 P0 (S59/B3): the stores this repo expects mounted. Each entry
447
+ // names a store by alias/UUID with an optional suggested_remote (or the
448
+ // `$personal` sentinel). Drives the read-set (required_stores ∪ implicit
449
+ // personal, S11/S54) and `clone`'s missing-store onboarding (S51). Optional
450
+ // + absent → read-set is just the implicit personal store.
451
+ required_stores: z6.array(requiredStoreEntrySchema).optional(),
452
+ // v2.1.0-rc.1 P3 (S60 / `store switch-write`): alias of the store that
453
+ // non-personal-scope writes land in for this project. Set by
454
+ // `fabric store switch-write <alias>`; consumed as the resolver's
455
+ // activeWriteAlias. Absent → no active write store yet. Personal-scope
456
+ // writes always target the implicit personal store regardless (R5#3).
457
+ active_write_store: z6.string().optional(),
352
458
  // rc.17 (R-cut): the dev/test fixture-path config field was removed
353
459
  // end-to-end. The `EXTERNAL_FIXTURE_PATH` env var is now the sole source
354
460
  // consumed by `resolveDevMode()`. No z.preprocess alias — pre-rc.17
@@ -356,7 +462,7 @@ var fabricConfigSchema = z5.object({
356
462
  // the lenient root parser (no .strict() at root). Pre-user clean-slate per
357
463
  // memory/feedback_clean_slate.md; mirrors the rc.12 hard-rename precedent
358
464
  // documented above.
359
- scanIgnores: z5.array(z5.string()).optional(),
465
+ scanIgnores: z6.array(z6.string()).optional(),
360
466
  audit_mode: auditModeSchema.optional(),
361
467
  mcpPayloadLimits: mcpPayloadLimitsSchema,
362
468
  // Backward-compat: both fields are optional with defaults so existing
@@ -371,7 +477,7 @@ var fabricConfigSchema = z5.object({
371
477
  // day if the user keeps ignoring it." Set to 24 to align with the archive
372
478
  // trigger threshold. The legacy `archive_hint_` key is retained for backward
373
479
  // compat with existing user fabric-config.json files.
374
- archive_hint_cooldown_hours: z5.number().int().positive().optional().default(12),
480
+ archive_hint_cooldown_hours: z6.number().int().positive().optional().default(12),
375
481
  // Underseed-node threshold for the fabric-hint Stop hook's import signal
376
482
  // (rc.5 TASK-010). When the canonical knowledge node count is strictly less
377
483
  // than this value AND a successful `init_scan_completed` event happened at
@@ -380,7 +486,7 @@ var fabricConfigSchema = z5.object({
380
486
  // the rule-of-thumb that a workspace with fewer than ten knowledge entries
381
487
  // is below the floor for plan_context retrieval to be meaningful. Also
382
488
  // consumed by `doctor` lint #22 (knowledge_underseeded).
383
- underseed_node_threshold: z5.number().int().positive().optional().default(10),
489
+ underseed_node_threshold: z6.number().int().positive().optional().default(10),
384
490
  // Edit-count threshold for the fabric-hint Stop hook's Signal A
385
491
  // (rc.6 TASK-022 / E5). Signal A fires when EITHER (a) >=24h have elapsed
386
492
  // since the last `knowledge_proposed` event, OR (b) >=archive_edit_threshold
@@ -391,102 +497,102 @@ var fabricConfigSchema = z5.object({
391
497
  // there is probably something worth archiving"; lowered values nag more
392
498
  // aggressively, higher values rely on the 24h fallback. Missing or absent
393
499
  // edit-counter file degrades safely to the 24h-only path.
394
- archive_edit_threshold: z5.number().int().positive().optional().default(20),
500
+ archive_edit_threshold: z6.number().int().positive().optional().default(20),
395
501
  // rc.7 T7: hours-since-last-knowledge_proposed cutoff for Signal A's
396
502
  // time branch. Was hardcoded as 24 in fabric-hint.cjs's THRESHOLD_HOURS;
397
503
  // externalized so chatty workspaces can lower the bar and quiet ones can
398
504
  // raise it. Default 24 preserves rc.6 behavior. See docs/configuration.md.
399
- archive_hint_hours: z5.number().int().positive().optional().default(24),
505
+ archive_hint_hours: z6.number().int().positive().optional().default(24),
400
506
  // rc.7 T7: pending-count cutoff for Signal B (review skill). Was
401
507
  // hardcoded as 10 in fabric-hint.cjs's THRESHOLD_PENDING_COUNT.
402
508
  // Default 10 preserves rc.6 behavior. See docs/configuration.md for
403
509
  // small/medium/large repo recommendations.
404
- review_hint_pending_count: z5.number().int().positive().optional().default(10),
510
+ review_hint_pending_count: z6.number().int().positive().optional().default(10),
405
511
  // rc.7 T7: pending-age cutoff (in days) for Signal B (review skill).
406
512
  // Was hardcoded as 7 in fabric-hint.cjs's THRESHOLD_PENDING_AGE_DAYS.
407
513
  // Default 7 preserves rc.6 behavior. See docs/configuration.md.
408
- review_hint_pending_age_days: z5.number().int().positive().optional().default(7),
514
+ review_hint_pending_age_days: z6.number().int().positive().optional().default(7),
409
515
  // rc.7 T7 + T10 pre-wiring: days-since-last-doctor cutoff for the future
410
516
  // Signal D (maintenance hint). T10 will consume this to decide when the
411
517
  // fabric-hint Stop hook surfaces a "run `fabric doctor`" reminder.
412
518
  // Default 14 reflects a fortnightly cadence — long enough to avoid nag,
413
519
  // short enough to catch index drift before it compounds.
414
- maintenance_hint_days: z5.number().int().positive().optional().default(14),
520
+ maintenance_hint_days: z6.number().int().positive().optional().default(14),
415
521
  // rc.7 T7 + T10 pre-wiring: cooldown between Signal D reminders, in
416
522
  // days. Once Signal D fires, it stays silent for this many days even if
417
523
  // the user doesn't run doctor. Default 7 keeps the reminder weekly at
418
524
  // worst — pairing 14d trigger + 7d cooldown means at most ~2 reminders
419
525
  // per month for a workspace that ignores them.
420
- maintenance_hint_cooldown_days: z5.number().int().positive().optional().default(7),
526
+ maintenance_hint_cooldown_days: z6.number().int().positive().optional().default(7),
421
527
  // rc.9+ (skill-contract-fix B1): first-run import window in months. The
422
528
  // `fabric-import` skill scans this many months of git history on the very
423
529
  // first invocation (when no prior `import_run_completed` event exists).
424
530
  // Default 60 (~5 years) captures the bulk of a mature repo's signal in
425
531
  // one pass; small / fresh repos can lower to 12-24 with no loss.
426
- import_window_first_run_months: z5.number().int().min(1).optional().default(60),
532
+ import_window_first_run_months: z6.number().int().min(1).optional().default(60),
427
533
  // rc.9+ (skill-contract-fix B1): rerun import window in months. After
428
534
  // the first successful import, subsequent runs only scan this many
429
535
  // recent months — assumed everything older has already been crystallized
430
536
  // into pending or canonical knowledge. Default 2 keeps incremental cost
431
537
  // low; raise to 6 if the workspace pauses fabric-import for long stretches.
432
- import_window_rerun_months: z5.number().int().min(1).optional().default(2),
538
+ import_window_rerun_months: z6.number().int().min(1).optional().default(2),
433
539
  // rc.9+ (skill-contract-fix B1): hard cap on pending entries produced
434
540
  // per fabric-import invocation. Prevents one run from dumping hundreds
435
541
  // of proposals when a backfill window is wide open. Default 10 matches
436
542
  // the rule-of-thumb "human can triage ~10 pending entries in one
437
543
  // review pass." Range 1-50.
438
- import_max_pending_per_run: z5.number().int().min(1).max(50).optional().default(10),
544
+ import_max_pending_per_run: z6.number().int().min(1).max(50).optional().default(10),
439
545
  // rc.9+ (skill-contract-fix B1): hard cap on commits scanned per
440
546
  // fabric-import invocation. Bounds runtime on monorepos with high
441
547
  // commit velocity. Default 500 covers ~2 months of typical churn;
442
548
  // range 50-2000. Hitting the cap mid-window is logged but non-fatal.
443
- import_max_commits_scan: z5.number().int().min(50).max(2e3).optional().default(500),
549
+ import_max_commits_scan: z6.number().int().min(50).max(2e3).optional().default(500),
444
550
  // rc.9+ (skill-contract-fix B1): canonical-node count above which
445
551
  // fabric-import's pre-flight should warn / suggest review instead of
446
552
  // proceeding. A workspace with 50+ canonical entries usually benefits
447
553
  // more from `fabric-review` to consolidate than from importing more.
448
554
  // Default 50; raise to 100+ for large polyglot repos.
449
- import_skip_canonical_threshold: z5.number().int().positive().optional().default(50),
555
+ import_skip_canonical_threshold: z6.number().int().positive().optional().default(50),
450
556
  // rc.9+ (skill-contract-fix B1): max candidate entries surfaced per
451
557
  // fabric-archive batch (one invocation of the skill). Pagination knob
452
558
  // for the archive UI flow. Default 8 keeps each batch reviewable in
453
559
  // one sitting; raise for large repos with high archive throughput.
454
- archive_max_candidates_per_batch: z5.number().int().positive().optional().default(8),
560
+ archive_max_candidates_per_batch: z6.number().int().positive().optional().default(8),
455
561
  // rc.9+ (skill-contract-fix B1): max recently-touched paths included
456
562
  // in fabric-archive's "relevant context" lookup. Limits the size of
457
563
  // the path-relevance digest the skill emits when ranking candidates.
458
564
  // Default 20; large repos with deep directory fan-out can raise to
459
565
  // 50+ if archive candidates feel under-contextualized.
460
- archive_max_recent_paths: z5.number().int().positive().optional().default(20),
566
+ archive_max_recent_paths: z6.number().int().positive().optional().default(20),
461
567
  // rc.9+ (skill-contract-fix B1): max prior fabric-archive sessions
462
568
  // summarised in the digest the skill loads on start. Prevents the
463
569
  // digest from ballooning past the model context budget on workspaces
464
570
  // that have archived repeatedly. Default 10; lower if context pressure
465
571
  // bites, raise if you want longer-range archive trend visibility.
466
- archive_digest_max_sessions: z5.number().int().positive().optional().default(10),
572
+ archive_digest_max_sessions: z6.number().int().positive().optional().default(10),
467
573
  // rc.9+ (skill-contract-fix B1): max review results returned per
468
574
  // topic when `fabric-review` clusters pending entries. Pagination
469
575
  // knob analogous to archive_max_candidates_per_batch but scoped to
470
576
  // each topic cluster. Default 8; raise to 15-20 for large repos
471
577
  // where each topic legitimately groups many pending entries.
472
- review_topic_result_cap: z5.number().int().positive().optional().default(8),
578
+ review_topic_result_cap: z6.number().int().positive().optional().default(8),
473
579
  // rc.9+ (skill-contract-fix B1): age threshold (in days) above which
474
580
  // a pending entry is considered "stale" by fabric-review and surfaced
475
581
  // for explicit resolve-or-drop decision. Default 14; tighter than the
476
582
  // 7d Signal-B trigger because review specifically targets the long
477
583
  // tail. Large repos with slower cadence can raise to 30.
478
- review_stale_pending_days: z5.number().int().positive().optional().default(14),
584
+ review_stale_pending_days: z6.number().int().positive().optional().default(14),
479
585
  // v2.0.0-rc.34 TASK-05: reverse-unarchive opt-in. When true, callers of the
480
586
  // `unarchiveKnowledge` primitive (and any future doctor auto-detect lint built
481
587
  // on top) will execute the file move + ledger emit. When false (default),
482
588
  // the same callers MUST short-circuit before any mutation — the primitive is
483
589
  // shipped but inert until explicitly enabled. Opt-in posture mirrors the
484
590
  // archive-flow precedent: destructive-ish file moves stay behind a flag.
485
- reverse_unarchive_enabled: z5.boolean().optional().default(false),
591
+ reverse_unarchive_enabled: z6.boolean().optional().default(false),
486
592
  // v2.0.0-rc.34 TASK-05: forces `unarchiveKnowledge` into dry-run mode even
487
593
  // when called with `options.dryRun=false`. Lets operators preview a
488
594
  // restoration pass before flipping `reverse_unarchive_enabled` to true.
489
- reverse_unarchive_dry_run: z5.boolean().optional().default(false),
595
+ reverse_unarchive_dry_run: z6.boolean().optional().default(false),
490
596
  // v2.0.0-rc.34 TASK-06: long-session cite-policy evict window in user-prompt
491
597
  // turns. UserPromptSubmit hook (Claude Code only) maintains a per-session
492
598
  // counter and re-injects the cite contract reminder via
@@ -494,7 +600,7 @@ var fabricConfigSchema = z5.object({
494
600
  // Default 0 = OFF (opt-in). Recommend 10-20 for active sessions; 5 for
495
601
  // high-contract-criticality projects. Other strategies (time-based,
496
602
  // token-budget) deferred to rc.35 per plan locked-decisions 2026-05-26.
497
- cite_evict_interval: z5.number().int().min(0).optional().default(0),
603
+ cite_evict_interval: z6.number().int().min(0).optional().default(0),
498
604
  // v2.0.0-rc.22 Scope A T3: sliding-window retention (in days) for the
499
605
  // event ledger rotation primitive (`rotateEventLedgerIfNeeded`). Lines
500
606
  // whose `ts` is older than `now - fabric_event_retention_days * 86_400_000`
@@ -507,7 +613,7 @@ var fabricConfigSchema = z5.object({
507
613
  // Mirrors cite-policy precedent of locking enum-style numeric tunables
508
614
  // to a small literal set (vs free `.positive()`) to prevent fat-finger
509
615
  // misconfig.
510
- fabric_event_retention_days: z5.union([z5.literal(7), z5.literal(30), z5.literal(90)]).optional(),
616
+ fabric_event_retention_days: z6.union([z6.literal(7), z6.literal(30), z6.literal(90)]).optional(),
511
617
  // v2.0.0-rc.23 TASK-014 (F8c): onboard slot opt-out list. Tracks slot
512
618
  // names the user explicitly dismissed during fabric-archive's first-run
513
619
  // onboard phase (or via `fabric config dismiss-slot <slot>`). Dismissed
@@ -524,7 +630,7 @@ var fabricConfigSchema = z5.object({
524
630
  //
525
631
  // Default `[]` keeps the field optional on existing configs — fresh
526
632
  // installs land with no opt-outs.
527
- onboard_slots_opted_out: z5.array(z5.string()).optional().default([]),
633
+ onboard_slots_opted_out: z6.array(z6.string()).optional().default([]),
528
634
  // v2.0.0-rc.33 W2-1 (P0-9): TopK upper bound for the broad SessionStart hint
529
635
  // banner emitted by knowledge-hint-broad.cjs. After plan-context-hint returns
530
636
  // its full broad-scoped index, the hook slices the entries to this many
@@ -536,20 +642,40 @@ var fabricConfigSchema = z5.object({
536
642
  // Range 1..50; values above 20 effectively disable the cap because the
537
643
  // TRUNCATION_THRESHOLD=12 grouped-render kicks in. Mirrors the rc.7 T7 +
538
644
  // archive_max_* pattern of externalizing previously-hardcoded thresholds.
539
- hint_broad_top_k: z5.number().int().min(1).max(50).optional().default(8),
645
+ hint_broad_top_k: z6.number().int().min(1).max(50).optional().default(8),
646
+ // v2.2 HK2-degrade (W2-T2): char budget for the rendered SessionStart broad-menu
647
+ // body — the final rung of the degradation ladder after the hint_broad_top_k
648
+ // count slice. Once the rendered entry/group lines exceed this, the tail
649
+ // collapses to a single "N more omitted" marker so a large corpus cannot blow
650
+ // the agent's working memory. Default 2000 (~one screenful); 0 disables the
651
+ // budget. Read by knowledge-hint-broad.cjs via readConfigNumber. Range 0..20000.
652
+ hint_broad_budget_chars: z6.number().int().min(0).max(2e4).optional().default(2e3),
540
653
  // v2.0.0-rc.37 NEW-16: durable per-signal dismiss for the fabric-hint Stop
541
654
  // hook nudges. Any signal type listed here is suppressed at emit time across
542
655
  // all sessions (the session-scoped sibling lives in a .fabric/.cache sidecar
543
656
  // written on request). Mirrors the cite_evict_interval=0 opt-out convention —
544
657
  // a knob for an existing surface, not a new feature. Unknown types ignored.
545
- hint_dismiss_signals: z5.array(z5.enum(["archive", "review", "import", "maintenance"])).optional(),
658
+ hint_dismiss_signals: z6.array(z6.enum(["archive", "review", "import", "maintenance"])).optional(),
659
+ // v2.1 ADJ-NEWN-4: user-override escape hatches for the two strong behavioral
660
+ // policies (cite-before-edit + self-archive). The strong policies can make an
661
+ // agent feel like a "stubborn parrot" (D2 user-in-control red line); these
662
+ // flags let a user durably turn either off via fabric-config.json (or the
663
+ // `fabric config` panel) without editing bootstrap/AGENTS.md. Default true
664
+ // preserves rc.x behavior (policies ON); set false to opt a project out.
665
+ // The bootstrap behavior layer references these so the AGENTS.md rules degrade
666
+ // from "MUST" to "optional" when disabled — a config knob for an existing
667
+ // surface, mirroring the cite_evict_interval=0 / hint_dismiss_signals opt-out
668
+ // convention, NOT a new feature. Wave3 J32 will quantify the friction these
669
+ // relieve; until then they ship as inert-safe opt-outs.
670
+ cite_policy_enabled: z6.boolean().optional().default(true),
671
+ self_archive_policy_enabled: z6.boolean().optional().default(true),
546
672
  // v2.0.0-rc.33 W2-1 (P0-9): TopK upper bound for the narrow PreToolUse hint
547
673
  // emitted by knowledge-hint-narrow.cjs. After filtering to entries whose
548
674
  // `relevance_scope === "narrow"` (rc.27 TASK-005 audit §2.5 fix), the hook
549
675
  // slices to this many before the E3 emit-gate / renderSummary pipeline.
550
676
  // Default 5 keeps each per-Edit hint terse — five lines max so the agent's
551
677
  // working memory is not displaced by an unwieldy banner. Range 1..20.
552
- hint_narrow_top_k: z5.number().int().min(1).max(20).optional().default(5),
678
+ hint_narrow_top_k: z6.number().int().min(1).max(20).optional().default(5),
553
679
  // v2.0.0-rc.33 W2-1 (P0-9): per-file dedup window (in PreToolUse turns) for
554
680
  // the narrow hint. Same (file_path, stable_id) tuple stays silent for this
555
681
  // many turns even when the E3 cross-session cache would otherwise re-emit.
@@ -559,7 +685,7 @@ var fabricConfigSchema = z5.object({
559
685
  // Storage: .fabric/.cache/narrow-dedup-window.json — distinct from session-
560
686
  // hints cache so a window-only suppression does not poison cross-session
561
687
  // dedupe semantics.
562
- hint_narrow_dedup_window_turns: z5.number().int().min(1).max(50).optional().default(5),
688
+ hint_narrow_dedup_window_turns: z6.number().int().min(1).max(50).optional().default(5),
563
689
  // v2.0.0-rc.33 W2-5 (P1-8): cooldown between broad SessionStart hint emits,
564
690
  // in hours. Distinct from the archive_hint_cooldown_hours that gates the
565
691
  // fabric-hint Stop hook — knowledge-hint-broad re-fires on every
@@ -568,29 +694,29 @@ var fabricConfigSchema = z5.object({
568
694
  // menu at most once per hour"; 0 means "no cooldown, current behavior."
569
695
  // Range 0..168 (one week). Stored alongside fabric-hint's cooldown cache
570
696
  // under a distinct knowledge-hint-broad key.
571
- hint_broad_cooldown_hours: z5.number().int().min(0).max(168).optional().default(0),
697
+ hint_broad_cooldown_hours: z6.number().int().min(0).max(168).optional().default(0),
572
698
  // v2.0.0-rc.33 W2-5 (P1-8): cooldown for the narrow PreToolUse hint.
573
699
  // Same shape as hint_broad_cooldown_hours but applies to per-Edit hint
574
700
  // re-emission across the cooldown window — independent of E3 session-
575
701
  // hints dedupe. Default 0 preserves rc.32 behavior; set to e.g. 1 to
576
702
  // throttle hint frequency during rapid-fire editing sprints. Range
577
703
  // 0..168 (one week).
578
- hint_narrow_cooldown_hours: z5.number().int().min(0).max(168).optional().default(0),
704
+ hint_narrow_cooldown_hours: z6.number().int().min(0).max(168).optional().default(0),
579
705
  // v2.0.0-rc.33 W4-B3 (T5 P2): per-maturity inactivity thresholds (days)
580
706
  // driving orphan_demote. Hardcoded at stable=90/endorsed=30/draft=14 in
581
707
  // rc.32; chatty workspaces want them tighter, slow ones want them looser.
582
708
  // Each field optional; absent → defaults inside doctor.ts apply. Ranges
583
709
  // chosen so a typo can't accidentally disable the lint (min 1).
584
- orphan_demote_stable_days: z5.number().int().min(1).max(3650).optional(),
585
- orphan_demote_endorsed_days: z5.number().int().min(1).max(3650).optional(),
586
- orphan_demote_draft_days: z5.number().int().min(1).max(3650).optional(),
710
+ orphan_demote_stable_days: z6.number().int().min(1).max(3650).optional(),
711
+ orphan_demote_endorsed_days: z6.number().int().min(1).max(3650).optional(),
712
+ orphan_demote_draft_days: z6.number().int().min(1).max(3650).optional(),
587
713
  // v2.0.0-rc.33 W4-A3 (T4 P2): per-entry summary truncation length used by
588
714
  // knowledge-hint-{broad,narrow}.cjs. Hard-coded at 80 chars in rc.32 — too
589
715
  // short for entries with parameterized summaries (e.g. "Use bcrypt with
590
716
  // cost=12 for password hashing"), too long for terse pitfalls. Range 40..240;
591
717
  // default 80 preserves rc.32 behavior. Both hooks read the same key so the
592
718
  // banner styling stays consistent across SessionStart + PreToolUse.
593
- hint_summary_max_len: z5.number().int().min(40).max(240).optional().default(80),
719
+ hint_summary_max_len: z6.number().int().min(40).max(240).optional().default(80),
594
720
  // v2.0.0-rc.33 W2-6 (P0-7 + P0-8): when true, knowledge-hint hooks emit
595
721
  // their banners as `hookSpecificOutput.additionalContext` JSON on stdout
596
722
  // (per Claude Code PreToolUse hook contract — see
@@ -600,7 +726,7 @@ var fabricConfigSchema = z5.object({
600
726
  // coverage focus (rc.32 baseline 3.1% → primary cause: reminders never
601
727
  // entered model context). Set false to revert to legacy stderr-only mode
602
728
  // for hosts that don't honor the JSON contract.
603
- hint_reminder_to_context: z5.boolean().optional().default(true),
729
+ hint_reminder_to_context: z6.boolean().optional().default(true),
604
730
  // v2.0.0-rc.29 TASK-008 (BUG-F3): selection-token TTL override. The
605
731
  // `fab_plan_context` MCP tool hands clients a `selection_token` whose default
606
732
  // 5-minute lifetime (`SELECTION_TOKEN_TTL_MS` at
@@ -616,12 +742,36 @@ var fabricConfigSchema = z5.object({
616
742
  // so the server-side per-field reader can validate without re-running the
617
743
  // whole fabricConfigSchema on every plan_context call — that lets a corrupt
618
744
  // unrelated field stay isolated from the hot read path.
619
- selection_token_ttl_ms: selectionTokenTtlMsSchema.optional()
745
+ selection_token_ttl_ms: selectionTokenTtlMsSchema.optional(),
746
+ // v2.2 A-INFRA-3 (W1-T3-TOPK): bound on `fab_plan_context` candidate count,
747
+ // applied after BM25 ranking. Absent → library default (24). See
748
+ // planContextTopKSchema for the range/calibration rationale.
749
+ plan_context_top_k: planContextTopKSchema.optional(),
750
+ // v2.2 C5-budget (W2-T3): layered retrieval budget profile. A single coherent
751
+ // strategy across the injection + MCP layers — `balanced` (default) reproduces
752
+ // the historical per-knob defaults exactly, `conservative` / `generous` scale
753
+ // the whole truncation chain (top_k + payload bytes + injection chars) down /
754
+ // up together. Per-field knobs (plan_context_top_k, mcpPayloadLimits.*,
755
+ // hint_broad_budget_chars) still override the profile when set. See
756
+ // retrieval-budget.ts (resolveRetrievalBudget) for the resolution order.
757
+ retrieval_budget_profile: z6.enum(["conservative", "balanced", "generous"]).optional(),
758
+ // v2.2 C2-vector (W2-T7): OPTIONAL dense-embedding semantic retrieval, layered
759
+ // as a recall supplement after BM25. Default OFF (`--no-embed` is the baseline);
760
+ // requires the operator to install the optional `fastembed` package — absent →
761
+ // text-only fallback. Never grows the default install footprint.
762
+ embed_enabled: z6.boolean().optional().default(false),
763
+ // Weight applied to the 0..1 cosine similarity before it joins the additive
764
+ // score. Capped at 49 — strictly BELOW BM25_WEIGHT (50) — so a perfect vector
765
+ // match (weight × 1) can never outscore a single strong BM25 term match. This
766
+ // ENFORCES the "vectors supplement, never override lexical relevance"
767
+ // invariant in the schema rather than leaving it to a comment (W2-REVIEW codex
768
+ // MED-4). Range 0..49; default 30.
769
+ embed_weight: z6.number().int().min(0).max(49).optional().default(30)
620
770
  });
621
771
 
622
772
  // src/schemas/fabric-config-introspect.ts
623
- import { z as z6 } from "zod";
624
- var positiveIntSchema = z6.coerce.number().int().positive();
773
+ import { z as z7 } from "zod";
774
+ var positiveIntSchema = z7.coerce.number().int().positive();
625
775
  function makePositiveIntField(key, defaultValue) {
626
776
  return {
627
777
  key,
@@ -757,156 +907,1049 @@ var PANEL_FIELDS = [
757
907
  )
758
908
  ];
759
909
 
910
+ // src/schemas/scope.ts
911
+ import { z as z8 } from "zod";
912
+ var PERSONAL_SCOPE = "personal";
913
+ var KNOWN_SCOPE_PREFIXES = ["personal", "team", "project", "org"];
914
+ var SCOPE_COORDINATE_PATTERN = /^[a-z0-9_-]+(:[a-z0-9_-]+)*$/u;
915
+ var scopeCoordinateSchema = z8.string().min(1).regex(
916
+ SCOPE_COORDINATE_PATTERN,
917
+ "scope coordinate must be ':'-joined lowercase [a-z0-9_-] segments"
918
+ );
919
+ function scopeRoot(coordinate) {
920
+ const colon = coordinate.indexOf(":");
921
+ return colon === -1 ? coordinate : coordinate.slice(0, colon);
922
+ }
923
+ function isPersonalScope(coordinate) {
924
+ return scopeRoot(coordinate) === PERSONAL_SCOPE;
925
+ }
926
+ var entryScopeMetadataSchema = z8.object({
927
+ semantic_scope: scopeCoordinateSchema,
928
+ // Store alias or UUID. Validated as a non-empty string here; the resolver
929
+ // (P0.6) maps alias→UUID and verifies the store is in the read-set.
930
+ visibility_store: z8.string().min(1)
931
+ }).strict();
932
+
933
+ // src/schemas/store-stable-id.ts
934
+ import { z as z9 } from "zod";
935
+ var localKnowledgeIdSchema = StableIdSchema;
936
+ var UID_SEGMENT_PATTERN = /^[a-z0-9-]+$/u;
937
+ var uidSchema = z9.string().min(1).regex(UID_SEGMENT_PATTERN, "uid must be lowercase [a-z0-9-] segments");
938
+ var GLOBAL_REF_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(:[a-z0-9-]+)?:K[PT]-(MOD|DEC|GLD|PIT|PRO)-\d{4,}$/u;
939
+ var globalRefSchema = z9.string().regex(GLOBAL_REF_PATTERN, "global_ref must be <store_uuid>[:<uid>]:<local_id>");
940
+ function formatGlobalRef(parts) {
941
+ const { store_uuid, uid, local_id } = parts;
942
+ return uid === void 0 ? `${store_uuid}:${local_id}` : `${store_uuid}:${uid}:${local_id}`;
943
+ }
944
+ function parseGlobalRef(ref) {
945
+ if (!GLOBAL_REF_PATTERN.test(ref)) {
946
+ return null;
947
+ }
948
+ const localMatch = ref.match(/K[PT]-(?:MOD|DEC|GLD|PIT|PRO)-\d{4,}$/u);
949
+ if (localMatch === null) {
950
+ return null;
951
+ }
952
+ const local_id = localMatch[0];
953
+ const head = ref.slice(0, ref.length - local_id.length - 1);
954
+ const firstColon = head.indexOf(":");
955
+ if (firstColon === -1) {
956
+ return { store_uuid: head, local_id };
957
+ }
958
+ return {
959
+ store_uuid: head.slice(0, firstColon),
960
+ uid: head.slice(firstColon + 1),
961
+ local_id
962
+ };
963
+ }
964
+ var storeKnowledgeTypeCountersSchema = z9.object({
965
+ MOD: z9.number().int().nonnegative().default(0),
966
+ DEC: z9.number().int().nonnegative().default(0),
967
+ GLD: z9.number().int().nonnegative().default(0),
968
+ PIT: z9.number().int().nonnegative().default(0),
969
+ PRO: z9.number().int().nonnegative().default(0)
970
+ }).default({ MOD: 0, DEC: 0, GLD: 0, PIT: 0, PRO: 0 });
971
+ var storeCountersSchema = z9.object({
972
+ KP: storeKnowledgeTypeCountersSchema,
973
+ KT: storeKnowledgeTypeCountersSchema
974
+ }).default({
975
+ KP: { MOD: 0, DEC: 0, GLD: 0, PIT: 0, PRO: 0 },
976
+ KT: { MOD: 0, DEC: 0, GLD: 0, PIT: 0, PRO: 0 }
977
+ });
978
+
979
+ // src/schemas/parity-matrix.ts
980
+ import { z as z10 } from "zod";
981
+ var PARITY_CLIENTS = ["claudeCode", "codexCLI", "cursor"];
982
+ var parityClientSchema = z10.enum(PARITY_CLIENTS);
983
+ var PARITY_SURFACES = ["skill", "hook", "mcp", "render"];
984
+ var paritySurfaceSchema = z10.enum(PARITY_SURFACES);
985
+ var parityClientExpectationSchema = z10.object({
986
+ supported: z10.boolean(),
987
+ mechanism: z10.string().optional(),
988
+ notes: z10.string().optional()
989
+ }).strict();
990
+ var parityCapabilitySchema = z10.object({
991
+ id: z10.string().min(1),
992
+ surface: paritySurfaceSchema,
993
+ description: z10.string().min(1),
994
+ clients: z10.object({
995
+ claudeCode: parityClientExpectationSchema,
996
+ codexCLI: parityClientExpectationSchema,
997
+ cursor: parityClientExpectationSchema
998
+ }).strict()
999
+ }).strict();
1000
+ var parityMatrixSchema = z10.object({
1001
+ // Schema/version tag of the matrix document itself.
1002
+ version: z10.string().min(1),
1003
+ // Free-form note on what release/milestone this matrix targets.
1004
+ generated_for: z10.string().min(1),
1005
+ capabilities: z10.array(parityCapabilitySchema).min(1)
1006
+ }).strict();
1007
+
1008
+ // src/resolver/contracts.ts
1009
+ import { z as z11 } from "zod";
1010
+ var PROJECT_ROOT_SIGNALS = ["env", "marker", "cwd", "repo"];
1011
+ var projectRootSignalSchema = z11.enum(PROJECT_ROOT_SIGNALS);
1012
+ var projectRootSignalsSchema = z11.object({
1013
+ // FABRIC_PROJECT_ROOT, if set.
1014
+ env: z11.string().optional(),
1015
+ // Nearest directory AT-OR-ABOVE cwd holding `.fabric/fabric-config.json`,
1016
+ // if any (the upward marker search result; may equal cwd).
1017
+ markerDir: z11.string().optional(),
1018
+ // Always present — the process cwd.
1019
+ cwd: z11.string().min(1),
1020
+ // git repo root, if inside a repo.
1021
+ repoRoot: z11.string().optional(),
1022
+ // The `project_id` read from the winning root's fabric-config.json during
1023
+ // (fs) signal collection. The pure resolver echoes it — it cannot invent a
1024
+ // UUID. Worktrees of one repo share the committed config, hence the same
1025
+ // project_id (S45 merge). Absent when no .fabric config exists at the root
1026
+ // yet (fresh repo-fallback) → resolution still yields the root with a null
1027
+ // projectId so the caller can mint+persist one at install time.
1028
+ discoveredProjectId: z11.string().optional()
1029
+ }).strict();
1030
+ var projectRootResolutionSchema = z11.object({
1031
+ // Absolute project root directory.
1032
+ projectRoot: z11.string().min(1),
1033
+ // Stable project identity. One repo = one .fabric = one project_id (S32);
1034
+ // git worktrees of the same repo resolve to the SAME project_id (S45).
1035
+ // Null when the resolved root has no fabric-config.json yet (fresh
1036
+ // repo-fallback) — the caller mints + persists a UUID at install time.
1037
+ projectId: z11.string().min(1).nullable(),
1038
+ // Which signal won.
1039
+ signalUsed: projectRootSignalSchema
1040
+ }).strict();
1041
+ var STORE_RESOLVER_WARNING_CODES = [
1042
+ "missing_store",
1043
+ // required_stores entry has no matching mounted store (S51)
1044
+ "local_only_no_remote",
1045
+ // mounted but local-only (R5#5 nudge, non-fatal)
1046
+ "alias_unresolved"
1047
+ // referenced alias maps to no mounted store
1048
+ ];
1049
+ var storeResolverWarningCodeSchema = z11.enum(STORE_RESOLVER_WARNING_CODES);
1050
+ var storeResolverWarningSchema = z11.object({
1051
+ code: storeResolverWarningCodeSchema,
1052
+ // The alias/UUID/id the warning concerns.
1053
+ ref: z11.string().min(1),
1054
+ message: z11.string().min(1)
1055
+ }).strict();
1056
+ var readSetEntrySchema = z11.object({
1057
+ store_uuid: z11.string().min(1),
1058
+ alias: z11.string().min(1),
1059
+ remote: z11.string().min(1).optional(),
1060
+ // Whether this store accepts writes from the current context. Personal
1061
+ // store is writable; shared stores writable iff mounted with write intent.
1062
+ writable: z11.boolean()
1063
+ }).strict();
1064
+ var storeReadSetSchema = z11.object({
1065
+ stores: z11.array(readSetEntrySchema),
1066
+ warnings: z11.array(storeResolverWarningSchema)
1067
+ }).strict();
1068
+ var writeTargetSchema = z11.object({
1069
+ store_uuid: z11.string().min(1),
1070
+ alias: z11.string().min(1)
1071
+ }).strict();
1072
+ var storeResolveInputSchema = z11.object({
1073
+ // Machine identity (S33) — namespaces personal ids; identifies personal store.
1074
+ uid: z11.string().min(1),
1075
+ // Stores mounted on this machine (from global config).
1076
+ mountedStores: z11.array(
1077
+ z11.object({
1078
+ store_uuid: z11.string().min(1),
1079
+ alias: z11.string().min(1),
1080
+ remote: z11.string().min(1).optional(),
1081
+ writable: z11.boolean().default(true),
1082
+ // Marks the implicit personal store.
1083
+ personal: z11.boolean().default(false)
1084
+ }).strict()
1085
+ ),
1086
+ // The project's declared required_stores (ids/aliases + optional remote).
1087
+ requiredStores: z11.array(
1088
+ z11.object({
1089
+ id: z11.string().min(1),
1090
+ suggested_remote: z11.string().min(1).optional()
1091
+ }).strict()
1092
+ ),
1093
+ // Alias selected as the active write store for non-personal scopes, if any.
1094
+ activeWriteAlias: z11.string().min(1).optional()
1095
+ }).strict();
1096
+ var projectRootGoldenCaseSchema = z11.object({
1097
+ name: z11.string().min(1),
1098
+ note: z11.string().optional(),
1099
+ signals: projectRootSignalsSchema,
1100
+ // null expected = resolver should return no root for these signals.
1101
+ expected: projectRootResolutionSchema.nullable()
1102
+ }).strict();
1103
+ var projectRootGoldenFileSchema = z11.object({
1104
+ contract: z11.literal("project-root.golden"),
1105
+ cases: z11.array(projectRootGoldenCaseSchema).min(1)
1106
+ }).strict();
1107
+ var readSetGoldenCaseSchema = z11.object({
1108
+ name: z11.string().min(1),
1109
+ note: z11.string().optional(),
1110
+ input: storeResolveInputSchema,
1111
+ // Scope under test for the write-target expectation.
1112
+ writeScope: z11.string().min(1),
1113
+ expected: z11.object({
1114
+ readSet: storeReadSetSchema,
1115
+ writeTarget: writeTargetSchema.nullable(),
1116
+ writeWarnings: z11.array(storeResolverWarningSchema)
1117
+ }).strict()
1118
+ }).strict();
1119
+ var readSetGoldenFileSchema = z11.object({
1120
+ contract: z11.literal("read-set.golden"),
1121
+ cases: z11.array(readSetGoldenCaseSchema).min(1)
1122
+ }).strict();
1123
+
1124
+ // src/resolver/project-root-resolver.ts
1125
+ var ResolverNotImplementedError = class extends Error {
1126
+ constructor(what) {
1127
+ super(`${what} is not implemented yet (TDD target)`);
1128
+ this.name = "ResolverNotImplementedError";
1129
+ }
1130
+ };
1131
+ function createProjectRootResolver() {
1132
+ return {
1133
+ resolve(signals) {
1134
+ const projectId = signals.discoveredProjectId ?? null;
1135
+ if (signals.env !== void 0) {
1136
+ return { projectRoot: signals.env, projectId, signalUsed: "env" };
1137
+ }
1138
+ if (signals.markerDir !== void 0) {
1139
+ return {
1140
+ projectRoot: signals.markerDir,
1141
+ projectId,
1142
+ signalUsed: signals.markerDir === signals.cwd ? "cwd" : "marker"
1143
+ };
1144
+ }
1145
+ if (signals.repoRoot !== void 0) {
1146
+ return { projectRoot: signals.repoRoot, projectId, signalUsed: "repo" };
1147
+ }
1148
+ return null;
1149
+ }
1150
+ };
1151
+ }
1152
+
1153
+ // src/resolver/store-resolver.ts
1154
+ function findPersonal(input) {
1155
+ return input.mountedStores.find((s) => s.personal);
1156
+ }
1157
+ function personalEntry(input) {
1158
+ const p = findPersonal(input);
1159
+ if (p === void 0) {
1160
+ return void 0;
1161
+ }
1162
+ const entry = { store_uuid: p.store_uuid, alias: p.alias, writable: p.writable };
1163
+ if (p.remote !== void 0) {
1164
+ entry.remote = p.remote;
1165
+ }
1166
+ return entry;
1167
+ }
1168
+ function createStoreResolver() {
1169
+ return {
1170
+ resolveReadSet(input) {
1171
+ const stores = [];
1172
+ const warnings = [];
1173
+ for (const req of input.requiredStores) {
1174
+ const matched = input.mountedStores.find(
1175
+ (m) => !m.personal && (m.alias === req.id || m.store_uuid === req.id)
1176
+ );
1177
+ if (matched === void 0) {
1178
+ const suffix = req.suggested_remote === void 0 ? "" : ` (suggested remote: ${req.suggested_remote})`;
1179
+ warnings.push({
1180
+ code: "missing_store",
1181
+ ref: req.id,
1182
+ message: `required store '${req.id}' is not mounted; run \`fabric store add\`${suffix}`
1183
+ });
1184
+ continue;
1185
+ }
1186
+ const entry = {
1187
+ store_uuid: matched.store_uuid,
1188
+ alias: matched.alias,
1189
+ writable: matched.writable
1190
+ };
1191
+ if (matched.remote !== void 0) {
1192
+ entry.remote = matched.remote;
1193
+ } else {
1194
+ warnings.push({
1195
+ code: "local_only_no_remote",
1196
+ ref: matched.alias,
1197
+ message: `store '${matched.alias}' is local-only; add a git remote to back it up (\`fabric store ... \` / doctor nudge)`
1198
+ });
1199
+ }
1200
+ stores.push(entry);
1201
+ }
1202
+ const personal = personalEntry(input);
1203
+ if (personal !== void 0) {
1204
+ stores.push(personal);
1205
+ }
1206
+ return { stores, warnings };
1207
+ },
1208
+ resolveWriteTarget(input, scope) {
1209
+ if (isPersonalScope(scope)) {
1210
+ const p = findPersonal(input);
1211
+ if (p === void 0) {
1212
+ return {
1213
+ target: null,
1214
+ warnings: [
1215
+ {
1216
+ code: "missing_store",
1217
+ ref: "personal",
1218
+ message: "no personal store is mounted; run `fabric install --global` first"
1219
+ }
1220
+ ]
1221
+ };
1222
+ }
1223
+ return { target: { store_uuid: p.store_uuid, alias: p.alias }, warnings: [] };
1224
+ }
1225
+ const active = input.activeWriteAlias === void 0 ? void 0 : input.mountedStores.find((m) => m.writable && m.alias === input.activeWriteAlias);
1226
+ if (active === void 0) {
1227
+ return {
1228
+ target: null,
1229
+ warnings: [
1230
+ {
1231
+ code: "alias_unresolved",
1232
+ ref: input.activeWriteAlias ?? scope,
1233
+ message: `no writable store for scope '${scope}'; set an active write store with \`fabric store switch-write\``
1234
+ }
1235
+ ]
1236
+ };
1237
+ }
1238
+ return { target: { store_uuid: active.store_uuid, alias: active.alias }, warnings: [] };
1239
+ },
1240
+ aliasToUuid(input, alias) {
1241
+ return input.mountedStores.find((m) => m.alias === alias)?.store_uuid;
1242
+ }
1243
+ };
1244
+ }
1245
+
1246
+ // src/resolver/store-disk-reader.ts
1247
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
1248
+ import { join } from "path";
1249
+ function readStoreIdentity(absDir) {
1250
+ const identityFile = join(absDir, STORE_LAYOUT.identityFile);
1251
+ if (!existsSync(identityFile)) {
1252
+ return null;
1253
+ }
1254
+ let raw;
1255
+ try {
1256
+ raw = JSON.parse(readFileSync(identityFile, "utf8"));
1257
+ } catch {
1258
+ return null;
1259
+ }
1260
+ const parsed = storeIdentitySchema.safeParse(raw);
1261
+ return parsed.success ? parsed.data : null;
1262
+ }
1263
+ function recognizeStoreDir(absDir) {
1264
+ return readStoreIdentity(absDir) !== null;
1265
+ }
1266
+ var SCRIPT_EXTENSIONS = /* @__PURE__ */ new Set([
1267
+ ".cjs",
1268
+ ".mjs",
1269
+ ".js",
1270
+ ".ts",
1271
+ ".sh",
1272
+ ".bash",
1273
+ ".zsh",
1274
+ ".py",
1275
+ ".rb",
1276
+ ".pl"
1277
+ ]);
1278
+ function hasScriptExtension(name) {
1279
+ const dot = name.lastIndexOf(".");
1280
+ return dot !== -1 && SCRIPT_EXTENSIONS.has(name.slice(dot).toLowerCase());
1281
+ }
1282
+ var STORE_SCAN_MAX_DEPTH = 32;
1283
+ var STORE_SCAN_MAX_ENTRIES = 1e5;
1284
+ function findStoreExecutableViolations(absDir, options = {}) {
1285
+ const maxDepth = options.maxDepth ?? STORE_SCAN_MAX_DEPTH;
1286
+ const maxEntries = options.maxEntries ?? STORE_SCAN_MAX_ENTRIES;
1287
+ const violations = [];
1288
+ let entriesScanned = 0;
1289
+ let bounded = false;
1290
+ const walk = (dir, rel, depth) => {
1291
+ if (bounded) {
1292
+ return;
1293
+ }
1294
+ if (depth > maxDepth) {
1295
+ violations.push(`<scan-bounded: depth > ${maxDepth} at ${rel === "" ? "." : rel}>`);
1296
+ bounded = true;
1297
+ return;
1298
+ }
1299
+ let entries;
1300
+ try {
1301
+ entries = readdirSync(dir);
1302
+ } catch {
1303
+ return;
1304
+ }
1305
+ for (const entry of entries) {
1306
+ if (bounded) {
1307
+ return;
1308
+ }
1309
+ if (rel === "" && entry === ".git") {
1310
+ continue;
1311
+ }
1312
+ entriesScanned += 1;
1313
+ if (entriesScanned > maxEntries) {
1314
+ violations.push(`<scan-bounded: entries > ${maxEntries}>`);
1315
+ bounded = true;
1316
+ return;
1317
+ }
1318
+ const abs = join(dir, entry);
1319
+ const relPath = rel === "" ? entry : `${rel}/${entry}`;
1320
+ let stat;
1321
+ try {
1322
+ stat = statSync(abs);
1323
+ } catch {
1324
+ continue;
1325
+ }
1326
+ if (stat.isDirectory()) {
1327
+ walk(abs, relPath, depth + 1);
1328
+ continue;
1329
+ }
1330
+ if ((stat.mode & 73) !== 0 || hasScriptExtension(entry)) {
1331
+ violations.push(relPath);
1332
+ }
1333
+ }
1334
+ };
1335
+ walk(absDir, "", 0);
1336
+ return violations;
1337
+ }
1338
+
1339
+ // src/resolver/store-qualified-id.ts
1340
+ var LOCAL_ID = /^K[PT]-(MOD|DEC|GLD|PIT|PRO)-\d{4,}$/u;
1341
+ function splitRef(ref) {
1342
+ const localMatch = ref.match(/K[PT]-(?:MOD|DEC|GLD|PIT|PRO)-\d{4,}$/u);
1343
+ if (localMatch === null) {
1344
+ return null;
1345
+ }
1346
+ const localId = localMatch[0];
1347
+ if (localId === ref) {
1348
+ return { storeQualifier: null, localId };
1349
+ }
1350
+ const head = ref.slice(0, ref.length - localId.length);
1351
+ if (!head.endsWith(":")) {
1352
+ return null;
1353
+ }
1354
+ return { storeQualifier: head.slice(0, -1), localId };
1355
+ }
1356
+ function resolveStoreQualifiedId(ref, candidates) {
1357
+ const split = splitRef(ref);
1358
+ if (split === null || !LOCAL_ID.test(split.localId)) {
1359
+ return { resolved: null, ambiguous: false, matches: [] };
1360
+ }
1361
+ const { storeQualifier, localId } = split;
1362
+ if (storeQualifier !== null) {
1363
+ const match = candidates.find(
1364
+ (c) => c.local_id === localId && (c.alias === storeQualifier || c.store_uuid === storeQualifier)
1365
+ );
1366
+ return match === void 0 ? { resolved: null, ambiguous: false, matches: [] } : { resolved: match, ambiguous: false, matches: [match] };
1367
+ }
1368
+ const matches = candidates.filter((c) => c.local_id === localId);
1369
+ if (matches.length === 1) {
1370
+ return { resolved: matches[0], ambiguous: false, matches };
1371
+ }
1372
+ return { resolved: null, ambiguous: matches.length > 1, matches };
1373
+ }
1374
+
1375
+ // src/resolver/resolution.ts
1376
+ function specificity(scope) {
1377
+ return scope.split(":").length;
1378
+ }
1379
+ function resolveCandidates(candidates, options = {}) {
1380
+ const storeOrder = options.storeOrder ?? [];
1381
+ const storeRank = (uuid) => {
1382
+ const idx = storeOrder.indexOf(uuid);
1383
+ return idx === -1 ? storeOrder.length : idx;
1384
+ };
1385
+ const seen = /* @__PURE__ */ new Set();
1386
+ const deduped = [];
1387
+ for (const c of candidates) {
1388
+ if (seen.has(c.global_ref)) {
1389
+ continue;
1390
+ }
1391
+ seen.add(c.global_ref);
1392
+ deduped.push(c);
1393
+ }
1394
+ const byLocal = /* @__PURE__ */ new Map();
1395
+ for (const c of deduped) {
1396
+ const stores = byLocal.get(c.local_id) ?? /* @__PURE__ */ new Set();
1397
+ stores.add(c.store_uuid);
1398
+ byLocal.set(c.local_id, stores);
1399
+ }
1400
+ const warnings = [];
1401
+ for (const [localId, stores] of byLocal) {
1402
+ if (stores.size > 1) {
1403
+ warnings.push({
1404
+ code: "shadowed_local_id",
1405
+ ref: localId,
1406
+ message: `local id '${localId}' exists in ${stores.size} stores; references must be store-qualified`
1407
+ });
1408
+ }
1409
+ }
1410
+ for (const uuid of options.unavailableRequiredStores ?? []) {
1411
+ warnings.push({
1412
+ code: "required_store_unavailable",
1413
+ ref: uuid,
1414
+ message: `required store '${uuid}' is unavailable; results may be incomplete (not silently degraded)`
1415
+ });
1416
+ }
1417
+ const sorted = [...deduped].sort((a, b) => {
1418
+ const specDiff = specificity(b.semantic_scope) - specificity(a.semantic_scope);
1419
+ if (specDiff !== 0) {
1420
+ return specDiff;
1421
+ }
1422
+ const rankDiff = storeRank(a.store_uuid) - storeRank(b.store_uuid);
1423
+ if (rankDiff !== 0) {
1424
+ return rankDiff;
1425
+ }
1426
+ return a.global_ref < b.global_ref ? -1 : a.global_ref > b.global_ref ? 1 : 0;
1427
+ });
1428
+ const resolved = sorted.map((c, i) => ({
1429
+ ...c,
1430
+ rank: i,
1431
+ reason: `scope '${scopeRoot(c.semantic_scope)}' (specificity ${specificity(
1432
+ c.semantic_scope
1433
+ )}), store '${c.alias}' (priority ${storeRank(c.store_uuid)})`
1434
+ }));
1435
+ return { resolved, warnings };
1436
+ }
1437
+
1438
+ // src/store/core.ts
1439
+ import { execFileSync } from "child_process";
1440
+ import { existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, writeFileSync } from "fs";
1441
+ import { join as join2 } from "path";
1442
+ var STORE_PENDING_DIR = "pending";
1443
+ var STORE_GITIGNORE = [
1444
+ "# v2.1 store \u2014 volatile / derived data is never committed",
1445
+ "state/",
1446
+ "agents.meta.json",
1447
+ ".cache/",
1448
+ ""
1449
+ ].join("\n");
1450
+ function git(cwd, args) {
1451
+ execFileSync("git", args, { cwd, stdio: ["ignore", "ignore", "pipe"] });
1452
+ }
1453
+ function initStore(absDir, identity, options = {}) {
1454
+ const parsed = storeIdentitySchema.parse(identity);
1455
+ const identityFile = join2(absDir, STORE_LAYOUT.identityFile);
1456
+ if (existsSync2(identityFile)) {
1457
+ throw new Error(`store already initialized at ${absDir} (store.json exists)`);
1458
+ }
1459
+ for (const type of STORE_KNOWLEDGE_TYPE_DIRS) {
1460
+ mkdirSync(join2(absDir, STORE_LAYOUT.knowledgeDir, type), { recursive: true });
1461
+ }
1462
+ mkdirSync(join2(absDir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR), { recursive: true });
1463
+ mkdirSync(join2(absDir, STORE_LAYOUT.bindingsDir), { recursive: true });
1464
+ mkdirSync(join2(absDir, STORE_LAYOUT.stateDir), { recursive: true });
1465
+ writeFileSync(identityFile, `${JSON.stringify(parsed, null, 2)}
1466
+ `, "utf8");
1467
+ writeFileSync(join2(absDir, ".gitignore"), STORE_GITIGNORE, "utf8");
1468
+ if (options.git !== false) {
1469
+ git(absDir, ["init", "-b", "main"]);
1470
+ }
1471
+ const readBack = readStoreIdentity(absDir);
1472
+ if (readBack === null) {
1473
+ throw new Error(`store init wrote an unrecognizable store.json at ${absDir}`);
1474
+ }
1475
+ return readBack;
1476
+ }
1477
+ function listMarkdown(dir) {
1478
+ if (!existsSync2(dir)) {
1479
+ return [];
1480
+ }
1481
+ return readdirSync2(dir).filter((name) => name.endsWith(".md")).sort().map((name) => join2(dir, name));
1482
+ }
1483
+ function listStoreKnowledge(store) {
1484
+ const refs = [];
1485
+ for (const type of STORE_KNOWLEDGE_TYPE_DIRS) {
1486
+ for (const file of listMarkdown(join2(store.dir, STORE_LAYOUT.knowledgeDir, type))) {
1487
+ refs.push({ store_uuid: store.store_uuid, alias: store.alias, type, file });
1488
+ }
1489
+ }
1490
+ return refs;
1491
+ }
1492
+ function readKnowledgeAcrossStores(stores) {
1493
+ return stores.flatMap((store) => listStoreKnowledge(store));
1494
+ }
1495
+ function aggregatePendingAcrossStores(stores) {
1496
+ return stores.flatMap(
1497
+ (store) => listMarkdown(join2(store.dir, STORE_LAYOUT.knowledgeDir, STORE_PENDING_DIR)).map((file) => ({
1498
+ store_uuid: store.store_uuid,
1499
+ alias: store.alias,
1500
+ type: STORE_PENDING_DIR,
1501
+ file
1502
+ }))
1503
+ );
1504
+ }
1505
+
1506
+ // src/store/secret-scan.ts
1507
+ var SECRET_RULES = [
1508
+ { rule: "aws-access-key-id", re: /\bAKIA[0-9A-Z]{16}\b/ },
1509
+ { rule: "private-key-block", re: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/ },
1510
+ { rule: "openai-api-key", re: /\bsk-[A-Za-z0-9]{20,}\b/ },
1511
+ { rule: "github-token", re: /\bgh[pousr]_[A-Za-z0-9]{20,}\b/ },
1512
+ { rule: "slack-token", re: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/ },
1513
+ {
1514
+ rule: "credential-assignment",
1515
+ re: /(?:password|passwd|secret|api[_-]?key|access[_-]?token|token)\s*[:=]\s*['"][^'"\s]{8,}['"]/i
1516
+ }
1517
+ ];
1518
+ function scanForSecrets(content) {
1519
+ const findings = [];
1520
+ const lines = content.split(/\r?\n/u);
1521
+ for (let i = 0; i < lines.length; i++) {
1522
+ for (const { rule, re } of SECRET_RULES) {
1523
+ if (re.test(lines[i])) {
1524
+ findings.push({ rule, line: i + 1 });
1525
+ }
1526
+ }
1527
+ }
1528
+ return findings;
1529
+ }
1530
+ function hasSecrets(content) {
1531
+ return scanForSecrets(content).length > 0;
1532
+ }
1533
+ var REDACTION_PLACEHOLDER_PREFIX = "[REDACTED:";
1534
+ function redactSecrets(content) {
1535
+ let out = content;
1536
+ for (const { rule, re } of SECRET_RULES) {
1537
+ const flags = re.flags.includes("i") ? "gi" : "g";
1538
+ out = out.replace(new RegExp(re.source, flags), `${REDACTION_PLACEHOLDER_PREFIX}${rule}]`);
1539
+ }
1540
+ return out;
1541
+ }
1542
+ function scrubRemoteUrl(remote) {
1543
+ return remote.replace(
1544
+ /^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)[^/@]*:[^/@]*@/,
1545
+ "$1"
1546
+ );
1547
+ }
1548
+
1549
+ // src/scanner/scan-recommendations.ts
1550
+ function buildScanRecommendations(input, t) {
1551
+ const recs = [];
1552
+ if (input.hasExistingFabric === false) {
1553
+ recs.push(t("scan.rec.install"));
1554
+ }
1555
+ if (input.readmeOk === false) {
1556
+ recs.push(t("scan.rec.readme"));
1557
+ }
1558
+ if (input.hasContributing === false) {
1559
+ recs.push(t("scan.rec.contributing"));
1560
+ }
1561
+ switch (input.frameworkKind) {
1562
+ case "cocos-creator":
1563
+ recs.push(t("scan.rec.cocos.lifecycle"));
1564
+ recs.push(t("scan.rec.cocos.human-protect"));
1565
+ if (input.hasMeta === true) {
1566
+ recs.push(t("scan.rec.cocos.meta-lock"));
1567
+ }
1568
+ break;
1569
+ case "next":
1570
+ recs.push(t("scan.rec.next"));
1571
+ break;
1572
+ case "vite":
1573
+ recs.push(t("scan.rec.vite"));
1574
+ break;
1575
+ case "unknown":
1576
+ recs.push(t("scan.rec.unknown"));
1577
+ break;
1578
+ default:
1579
+ recs.push(t("scan.rec.generic", { kind: input.frameworkKind }));
1580
+ }
1581
+ return recs;
1582
+ }
1583
+
1584
+ // src/store/cross-store-lint.ts
1585
+ function lintCrossStoreReferences(input) {
1586
+ if (input.entryVisibility !== "shared") {
1587
+ return [];
1588
+ }
1589
+ const violations = [];
1590
+ for (const ref of input.referencedGlobalRefs) {
1591
+ const parsed = parseGlobalRef(ref);
1592
+ if (parsed === null) {
1593
+ continue;
1594
+ }
1595
+ if (input.storeVisibility[parsed.store_uuid] === "personal") {
1596
+ violations.push({
1597
+ code: "personal-ref-in-shared",
1598
+ ref,
1599
+ to_store_uuid: parsed.store_uuid,
1600
+ message: `shared-store entry references personal-store id '${ref}' \u2014 personal knowledge must not leak into a shared store`
1601
+ });
1602
+ }
1603
+ }
1604
+ return violations;
1605
+ }
1606
+ function isPersonalLeakIntoSharedStore(entryLayer, storeVisibility) {
1607
+ return entryLayer === "personal" && storeVisibility === "shared";
1608
+ }
1609
+
1610
+ // src/store/observability.ts
1611
+ function redactValue(value) {
1612
+ return typeof value === "string" ? redactSecrets(value) : value;
1613
+ }
1614
+ function buildFailureTrace(stage, error, context = {}, code) {
1615
+ const rawMessage = error instanceof Error ? error.message : typeof error === "string" ? error : String(error);
1616
+ const derivedCode = code ?? (error instanceof Error && error.name ? error.name : "error");
1617
+ const redactedContext = {};
1618
+ for (const [key, value] of Object.entries(context)) {
1619
+ redactedContext[key] = redactValue(value);
1620
+ }
1621
+ return {
1622
+ stage,
1623
+ code: derivedCode,
1624
+ message: redactSecrets(rawMessage),
1625
+ context: redactedContext
1626
+ };
1627
+ }
1628
+ function buildDebugBundle(input) {
1629
+ const redactDeep = (value) => {
1630
+ if (typeof value === "string") {
1631
+ return redactSecrets(value);
1632
+ }
1633
+ if (Array.isArray(value)) {
1634
+ return value.map(redactDeep);
1635
+ }
1636
+ if (value !== null && typeof value === "object") {
1637
+ const out = {};
1638
+ for (const [k, v] of Object.entries(value)) {
1639
+ out[k] = redactDeep(v);
1640
+ }
1641
+ return out;
1642
+ }
1643
+ return value;
1644
+ };
1645
+ return {
1646
+ version: 1,
1647
+ config: redactDeep(input.config),
1648
+ diagnostics: redactDeep(input.diagnostics) ?? [],
1649
+ events: input.includeEvents === true ? (input.events ?? []).map(redactSecrets) : [],
1650
+ redacted: true
1651
+ };
1652
+ }
1653
+
1654
+ // src/schemas/provenance.ts
1655
+ import { z as z12 } from "zod";
1656
+ var knowledgeProvenanceSchema = z12.object({
1657
+ store_uuid: storeUuidSchema,
1658
+ alias: z12.string().min(1),
1659
+ local_id: localKnowledgeIdSchema,
1660
+ global_ref: globalRefSchema,
1661
+ // Optional scope coordinate of the entry (resolution axis); present when the
1662
+ // surfacing tool has read the entry's frontmatter.
1663
+ semantic_scope: scopeCoordinateSchema.optional()
1664
+ }).strict();
1665
+
1666
+ // src/schemas/mcp-store-contracts.ts
1667
+ import { z as z13 } from "zod";
1668
+ var MCP_STORE_AWARE_TOOLS = [
1669
+ "fab_recall",
1670
+ "fab_plan_context",
1671
+ "fab_get_knowledge_sections",
1672
+ "fab_archive_scan",
1673
+ "fab_extract_knowledge",
1674
+ "fab_review"
1675
+ ];
1676
+ var storeAwareEntrySchema = z13.object({
1677
+ stable_id: z13.string(),
1678
+ global_ref: globalRefSchema,
1679
+ provenance: knowledgeProvenanceSchema
1680
+ }).strict();
1681
+ var writtenToStoreSchema = z13.object({
1682
+ store_uuid: storeUuidSchema,
1683
+ alias: z13.string().min(1)
1684
+ }).strict();
1685
+ var MCP_STORE_AWARE_CONTRACTS = {
1686
+ fab_recall: { tool: "fab_recall", surfacesEntries: true, echoesWrittenStore: false },
1687
+ fab_plan_context: { tool: "fab_plan_context", surfacesEntries: true, echoesWrittenStore: false },
1688
+ fab_get_knowledge_sections: {
1689
+ tool: "fab_get_knowledge_sections",
1690
+ surfacesEntries: true,
1691
+ echoesWrittenStore: false
1692
+ },
1693
+ fab_archive_scan: {
1694
+ tool: "fab_archive_scan",
1695
+ surfacesEntries: false,
1696
+ echoesWrittenStore: true
1697
+ },
1698
+ fab_extract_knowledge: {
1699
+ tool: "fab_extract_knowledge",
1700
+ surfacesEntries: false,
1701
+ echoesWrittenStore: true
1702
+ },
1703
+ fab_review: { tool: "fab_review", surfacesEntries: true, echoesWrittenStore: true }
1704
+ };
1705
+
1706
+ // src/schemas/bindings-snapshot.ts
1707
+ import { z as z14 } from "zod";
1708
+ var resolvedBindingsSnapshotSchema = z14.object({
1709
+ // Schema version of the snapshot document.
1710
+ version: z14.literal(1),
1711
+ // The project this snapshot is bound to (S13).
1712
+ project_id: z14.string().min(1),
1713
+ // ISO-8601 generation timestamp (provenance / staleness signal for doctor).
1714
+ generated_at: z14.string().min(1),
1715
+ // Pre-resolved read-set (required_stores ∪ implicit personal + warnings).
1716
+ read_set: storeReadSetSchema,
1717
+ // Pre-resolved active write target for non-personal scopes (null if none).
1718
+ write_target: writeTargetSchema.nullable()
1719
+ }).strict();
1720
+
1721
+ // src/store/bindings.ts
1722
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1723
+ import { join as join3 } from "path";
1724
+ function bindingsSnapshotPath(globalRoot, projectId) {
1725
+ return join3(globalRoot, GLOBAL_STATE_DIR, GLOBAL_BINDINGS_DIR, `${projectId}_resolved.json`);
1726
+ }
1727
+ function writeBindingsSnapshot(options) {
1728
+ const resolver = createStoreResolver();
1729
+ const read_set = resolver.resolveReadSet(options.resolveInput);
1730
+ const { target } = resolver.resolveWriteTarget(options.resolveInput, options.writeScope);
1731
+ const snapshot = resolvedBindingsSnapshotSchema.parse({
1732
+ version: 1,
1733
+ project_id: options.projectId,
1734
+ generated_at: options.now,
1735
+ read_set,
1736
+ write_target: target
1737
+ });
1738
+ const path = bindingsSnapshotPath(options.globalRoot, options.projectId);
1739
+ mkdirSync2(join3(path, ".."), { recursive: true });
1740
+ writeFileSync2(path, `${JSON.stringify(snapshot, null, 2)}
1741
+ `, "utf8");
1742
+ return snapshot;
1743
+ }
1744
+ function readBindingsSnapshot(globalRoot, projectId) {
1745
+ const path = bindingsSnapshotPath(globalRoot, projectId);
1746
+ if (!existsSync3(path)) {
1747
+ return null;
1748
+ }
1749
+ try {
1750
+ const parsed = resolvedBindingsSnapshotSchema.safeParse(JSON.parse(readFileSync2(path, "utf8")));
1751
+ return parsed.success ? parsed.data : null;
1752
+ } catch {
1753
+ return null;
1754
+ }
1755
+ }
1756
+
1757
+ // src/store/store-lifecycle.ts
1758
+ function findMountedStore(config, aliasOrUuid) {
1759
+ return config.stores.find((s) => s.alias === aliasOrUuid || s.store_uuid === aliasOrUuid);
1760
+ }
1761
+ function addMountedStore(config, store) {
1762
+ const aliasClash = config.stores.find(
1763
+ (s) => s.alias === store.alias && s.store_uuid !== store.store_uuid
1764
+ );
1765
+ if (aliasClash !== void 0) {
1766
+ throw new Error(
1767
+ `alias '${store.alias}' already mounts store ${aliasClash.store_uuid}; choose another alias`
1768
+ );
1769
+ }
1770
+ const sanitized = store.remote === void 0 ? store : { ...store, remote: scrubRemoteUrl(store.remote) };
1771
+ store = sanitized;
1772
+ const existing = config.stores.find((s) => s.store_uuid === store.store_uuid);
1773
+ const stores = existing === void 0 ? [...config.stores, store] : config.stores.map((s) => s.store_uuid === store.store_uuid ? store : s);
1774
+ return { ...config, stores };
1775
+ }
1776
+ function detachMountedStore(config, alias) {
1777
+ const detached = config.stores.find((s) => s.alias === alias) ?? null;
1778
+ if (detached === null) {
1779
+ return { config, detached: null };
1780
+ }
1781
+ return {
1782
+ config: { ...config, stores: config.stores.filter((s) => s.alias !== alias) },
1783
+ detached
1784
+ };
1785
+ }
1786
+ function bindRequiredStore(required, entry) {
1787
+ const safeEntry = entry.suggested_remote === void 0 ? entry : { ...entry, suggested_remote: scrubRemoteUrl(entry.suggested_remote) };
1788
+ return required.some((r) => r.id === safeEntry.id) ? required.map((r) => r.id === safeEntry.id ? safeEntry : r) : [...required, safeEntry];
1789
+ }
1790
+ function explainStore(config, alias) {
1791
+ const store = findMountedStore(config, alias);
1792
+ if (store === void 0) {
1793
+ return null;
1794
+ }
1795
+ return {
1796
+ alias: store.alias,
1797
+ store_uuid: store.store_uuid,
1798
+ remote: store.remote ?? null,
1799
+ local_only: store.remote === void 0
1800
+ };
1801
+ }
1802
+
760
1803
  // src/schemas/forensic-report.ts
761
- import { z as z7 } from "zod";
762
- var forensicCodeSampleSchema = z7.object({
763
- path: z7.string(),
764
- lines: z7.string(),
765
- snippet: z7.string(),
766
- pattern_hint: z7.string()
767
- });
768
- var forensicEvidenceAnchorSchema = z7.object({
769
- file: z7.string(),
770
- line: z7.string(),
771
- snippet: z7.string()
772
- });
773
- var forensicAssertionCoverageSchema = z7.object({
774
- ratio: z7.number().min(0).max(1),
775
- total: z7.number().int().nonnegative(),
776
- matched: z7.number().int().nonnegative(),
777
- co_occurring_patterns: z7.array(z7.string())
778
- });
779
- var forensicAssertionSchema = z7.object({
780
- type: z7.enum(["framework", "pattern", "invariant", "domain"]),
781
- statement: z7.string(),
782
- confidence: z7.enum(["HIGH", "MEDIUM", "LOW"]),
783
- evidence: z7.array(forensicEvidenceAnchorSchema),
1804
+ import { z as z15 } from "zod";
1805
+ var forensicCodeSampleSchema = z15.object({
1806
+ path: z15.string(),
1807
+ lines: z15.string(),
1808
+ snippet: z15.string(),
1809
+ pattern_hint: z15.string()
1810
+ });
1811
+ var forensicEvidenceAnchorSchema = z15.object({
1812
+ file: z15.string(),
1813
+ line: z15.string(),
1814
+ snippet: z15.string()
1815
+ });
1816
+ var forensicAssertionCoverageSchema = z15.object({
1817
+ ratio: z15.number().min(0).max(1),
1818
+ total: z15.number().int().nonnegative(),
1819
+ matched: z15.number().int().nonnegative(),
1820
+ co_occurring_patterns: z15.array(z15.string())
1821
+ });
1822
+ var forensicAssertionSchema = z15.object({
1823
+ type: z15.enum(["framework", "pattern", "invariant", "domain"]),
1824
+ statement: z15.string(),
1825
+ confidence: z15.enum(["HIGH", "MEDIUM", "LOW"]),
1826
+ evidence: z15.array(forensicEvidenceAnchorSchema),
784
1827
  coverage: forensicAssertionCoverageSchema,
785
- proposed_rule: z7.string().optional(),
786
- alternatives: z7.array(z7.string()).optional()
787
- });
788
- var forensicTopologySchema = z7.object({
789
- total_files: z7.number().int().nonnegative(),
790
- by_ext: z7.record(z7.number().int().nonnegative()),
791
- key_dirs: z7.array(z7.string()),
792
- max_depth: z7.number().int().nonnegative()
793
- });
794
- var forensicEntryPointSchema = z7.object({
795
- path: z7.string(),
796
- reason: z7.string(),
797
- size_bytes: z7.number().int().nonnegative().optional()
798
- });
799
- var forensicFrameworkSchema = z7.object({
800
- kind: z7.string(),
801
- version: z7.string(),
802
- subkind: z7.string(),
803
- evidence: z7.array(z7.string())
804
- });
805
- var forensicReadmeSchema = z7.object({
806
- quality: z7.enum(["missing", "stub", "ok"]),
807
- line_count: z7.number().int().nonnegative(),
808
- has_contributing: z7.boolean()
809
- });
810
- var candidateFileEntrySchema = z7.object({
811
- path: z7.string(),
812
- family: z7.enum(["entry", "component", "config", "test", "domain"]),
813
- rationale: z7.string()
814
- });
815
- var forensicSamplingBudgetSchema = z7.object({
816
- max_files: z7.literal(15),
817
- max_lines_per_file: z7.literal(100)
818
- });
819
- var forensicReportSchema = z7.object({
820
- version: z7.string(),
821
- generated_at: z7.string(),
822
- generated_by: z7.string(),
823
- target: z7.string(),
824
- project_name: z7.string(),
1828
+ proposed_rule: z15.string().optional(),
1829
+ alternatives: z15.array(z15.string()).optional()
1830
+ });
1831
+ var forensicTopologySchema = z15.object({
1832
+ total_files: z15.number().int().nonnegative(),
1833
+ by_ext: z15.record(z15.number().int().nonnegative()),
1834
+ key_dirs: z15.array(z15.string()),
1835
+ max_depth: z15.number().int().nonnegative()
1836
+ });
1837
+ var forensicEntryPointSchema = z15.object({
1838
+ path: z15.string(),
1839
+ reason: z15.string(),
1840
+ size_bytes: z15.number().int().nonnegative().optional()
1841
+ });
1842
+ var forensicFrameworkSchema = z15.object({
1843
+ kind: z15.string(),
1844
+ version: z15.string(),
1845
+ subkind: z15.string(),
1846
+ evidence: z15.array(z15.string())
1847
+ });
1848
+ var forensicReadmeSchema = z15.object({
1849
+ quality: z15.enum(["missing", "stub", "ok"]),
1850
+ line_count: z15.number().int().nonnegative(),
1851
+ has_contributing: z15.boolean()
1852
+ });
1853
+ var candidateFileEntrySchema = z15.object({
1854
+ path: z15.string(),
1855
+ family: z15.enum(["entry", "component", "config", "test", "domain"]),
1856
+ rationale: z15.string()
1857
+ });
1858
+ var forensicSamplingBudgetSchema = z15.object({
1859
+ max_files: z15.literal(15),
1860
+ max_lines_per_file: z15.literal(100)
1861
+ });
1862
+ var forensicReportSchema = z15.object({
1863
+ version: z15.string(),
1864
+ generated_at: z15.string(),
1865
+ generated_by: z15.string(),
1866
+ target: z15.string(),
1867
+ project_name: z15.string(),
825
1868
  framework: forensicFrameworkSchema,
826
1869
  topology: forensicTopologySchema,
827
- entry_points: z7.array(forensicEntryPointSchema),
828
- code_samples: z7.array(forensicCodeSampleSchema),
829
- assertions: z7.array(forensicAssertionSchema),
830
- candidate_files: z7.array(candidateFileEntrySchema),
1870
+ entry_points: z15.array(forensicEntryPointSchema),
1871
+ code_samples: z15.array(forensicCodeSampleSchema),
1872
+ assertions: z15.array(forensicAssertionSchema),
1873
+ candidate_files: z15.array(candidateFileEntrySchema),
831
1874
  sampling_budget: forensicSamplingBudgetSchema,
832
1875
  readme: forensicReadmeSchema,
833
- recommendations_for_skill: z7.array(z7.string()).optional()
1876
+ recommendations_for_skill: z15.array(z15.string()).optional()
834
1877
  });
835
1878
 
836
1879
  // src/schemas/init-context.ts
837
- import { z as z8 } from "zod";
838
- var initContextFrameworkSchema = z8.object({
839
- kind: z8.string(),
840
- version: z8.string(),
841
- subkind: z8.string()
842
- });
843
- var initContextInvariantConfidenceSnapshotSchema = z8.object({
844
- confidence: z8.enum(["HIGH", "MEDIUM", "LOW"]),
845
- evidence_refs: z8.array(z8.string())
846
- });
847
- var initContextSourceEvidenceSchema = z8.object({
848
- file: z8.string(),
849
- lines: z8.string()
850
- });
851
- var initContextInvariantSchema = z8.object({
852
- type: z8.enum(["ban", "require", "protect"]),
853
- rule: z8.string(),
854
- rationale: z8.string().optional(),
1880
+ import { z as z16 } from "zod";
1881
+ var initContextFrameworkSchema = z16.object({
1882
+ kind: z16.string(),
1883
+ version: z16.string(),
1884
+ subkind: z16.string()
1885
+ });
1886
+ var initContextInvariantConfidenceSnapshotSchema = z16.object({
1887
+ confidence: z16.enum(["HIGH", "MEDIUM", "LOW"]),
1888
+ evidence_refs: z16.array(z16.string())
1889
+ });
1890
+ var initContextSourceEvidenceSchema = z16.object({
1891
+ file: z16.string(),
1892
+ lines: z16.string()
1893
+ });
1894
+ var initContextInvariantSchema = z16.object({
1895
+ type: z16.enum(["ban", "require", "protect"]),
1896
+ rule: z16.string(),
1897
+ rationale: z16.string().optional(),
855
1898
  confidence_snapshot: initContextInvariantConfidenceSnapshotSchema.optional(),
856
- source_evidence: z8.array(initContextSourceEvidenceSchema).optional()
857
- });
858
- var initContextDomainGroupSchema = z8.object({
859
- name: z8.string(),
860
- paths: z8.array(z8.string()),
861
- summary: z8.string().optional(),
862
- topology_type: z8.enum(["mirror", "cross-cutting"]).optional(),
863
- target_path: z8.string().optional()
864
- });
865
- var initContextInterviewTrailEntrySchema = z8.object({
866
- phase: z8.string(),
867
- question: z8.string(),
868
- answer: z8.string(),
869
- presentation: z8.string().optional(),
870
- user_corrections: z8.array(z8.string()).optional()
871
- });
872
- var initContextSchema = z8.object({
1899
+ source_evidence: z16.array(initContextSourceEvidenceSchema).optional()
1900
+ });
1901
+ var initContextDomainGroupSchema = z16.object({
1902
+ name: z16.string(),
1903
+ paths: z16.array(z16.string()),
1904
+ summary: z16.string().optional(),
1905
+ topology_type: z16.enum(["mirror", "cross-cutting"]).optional(),
1906
+ target_path: z16.string().optional()
1907
+ });
1908
+ var initContextInterviewTrailEntrySchema = z16.object({
1909
+ phase: z16.string(),
1910
+ question: z16.string(),
1911
+ answer: z16.string(),
1912
+ presentation: z16.string().optional(),
1913
+ user_corrections: z16.array(z16.string()).optional()
1914
+ });
1915
+ var initContextSchema = z16.object({
873
1916
  framework: initContextFrameworkSchema,
874
- architecture_patterns: z8.array(z8.string()),
875
- invariants: z8.array(initContextInvariantSchema),
876
- domain_groups: z8.array(initContextDomainGroupSchema),
877
- interview_trail: z8.array(initContextInterviewTrailEntrySchema),
878
- forensic_ref: z8.string()
1917
+ architecture_patterns: z16.array(z16.string()),
1918
+ invariants: z16.array(initContextInvariantSchema),
1919
+ domain_groups: z16.array(initContextDomainGroupSchema),
1920
+ interview_trail: z16.array(initContextInterviewTrailEntrySchema),
1921
+ forensic_ref: z16.string()
879
1922
  });
880
1923
 
881
1924
  // src/schemas/events.ts
882
- import { z as z9 } from "zod";
883
- var metaUpdatedEventSchema = z9.object({
884
- type: z9.literal("meta:updated"),
1925
+ import { z as z17 } from "zod";
1926
+ var metaUpdatedEventSchema = z17.object({
1927
+ type: z17.literal("meta:updated"),
885
1928
  payload: agentsMetaSchema
886
1929
  });
887
- var lockDriftEventSchema = z9.object({
888
- type: z9.literal("lock:drift"),
889
- payload: z9.object({
890
- locked: z9.array(humanLockEntrySchema),
891
- drifted: z9.array(humanLockEntrySchema)
1930
+ var lockDriftEventSchema = z17.object({
1931
+ type: z17.literal("lock:drift"),
1932
+ payload: z17.object({
1933
+ locked: z17.array(humanLockEntrySchema),
1934
+ drifted: z17.array(humanLockEntrySchema)
892
1935
  })
893
1936
  });
894
- var lockApprovedEventSchema = z9.object({
895
- type: z9.literal("lock:approved"),
896
- payload: z9.object({
897
- locked: z9.array(humanLockEntrySchema),
898
- approved: z9.array(humanLockEntrySchema)
1937
+ var lockApprovedEventSchema = z17.object({
1938
+ type: z17.literal("lock:approved"),
1939
+ payload: z17.object({
1940
+ locked: z17.array(humanLockEntrySchema),
1941
+ approved: z17.array(humanLockEntrySchema)
899
1942
  })
900
1943
  });
901
- var ledgerAppendedEventSchema = z9.object({
902
- type: z9.literal("ledger:appended"),
1944
+ var ledgerAppendedEventSchema = z17.object({
1945
+ type: z17.literal("ledger:appended"),
903
1946
  payload: ledgerEntrySchema
904
1947
  });
905
- var driftDetectedEventSchema = z9.object({
906
- type: z9.literal("drift:detected"),
1948
+ var driftDetectedEventSchema = z17.object({
1949
+ type: z17.literal("drift:detected"),
907
1950
  payload: forensicReportSchema
908
1951
  });
909
- var fabricEventSchema = z9.discriminatedUnion("type", [
1952
+ var fabricEventSchema = z17.discriminatedUnion("type", [
910
1953
  metaUpdatedEventSchema,
911
1954
  lockDriftEventSchema,
912
1955
  lockApprovedEventSchema,
@@ -915,143 +1958,258 @@ var fabricEventSchema = z9.discriminatedUnion("type", [
915
1958
  ]);
916
1959
 
917
1960
  // src/schemas/event-ledger.ts
918
- import { z as z10 } from "zod";
1961
+ import { z as z18 } from "zod";
1962
+
1963
+ // src/cite-line-parser.ts
1964
+ var ID_RE = /^K[TP]-[A-Z]+-\d+$/;
1965
+ var SENTINEL_RE = /^KB:\s*none\b\s*(?:\[[^\]]*\])?\s*$/i;
1966
+ var QUALIFIED_ID = String.raw`(?:[^\s,:]+:)?K[TP]-[A-Z]+-\d+`;
1967
+ var FULL_RE = new RegExp(
1968
+ String.raw`^KB:\s+(${QUALIFIED_ID}(?:\s*,\s*${QUALIFIED_ID})*)(?:\s+\(([^)]*)\))?(?:\s+\[([^\]]+)\])?(?:\s+→\s*(.+))?\s*$`
1969
+ );
1970
+ function splitStorePrefix(token) {
1971
+ const colon = token.lastIndexOf(":");
1972
+ return colon === -1 ? { store: null, id: token } : { store: token.slice(0, colon), id: token.slice(colon + 1) };
1973
+ }
1974
+ var CHAINED_FROM_ID_RE = /chained-from\s+(K[TP]-[A-Z]+-\d+)/i;
1975
+ var LEGACY_CITE_TAG_REMAP = {
1976
+ planned: "applied",
1977
+ recalled: "applied",
1978
+ "chained-from": "applied"
1979
+ };
1980
+ function normalizeCiteTag(rawTag) {
1981
+ const head = rawTag.trim().split(/[\s:]+/)[0].toLowerCase();
1982
+ if (head === "applied" || head === "dismissed" || head === "none") {
1983
+ return head;
1984
+ }
1985
+ return LEGACY_CITE_TAG_REMAP[head] ?? "none";
1986
+ }
1987
+ function parseTag(rawTag) {
1988
+ if (!rawTag) return "none";
1989
+ return normalizeCiteTag(rawTag);
1990
+ }
1991
+ function parseContractTail(tail) {
1992
+ const result = { operators: [], skip_reason: null };
1993
+ if (!tail) return result;
1994
+ const tokens = tail.trim().split(/\s+/).filter((t) => t.length > 0);
1995
+ for (const token of tokens) {
1996
+ const skipMatch = token.match(/^skip:(.+)$/i);
1997
+ if (skipMatch) {
1998
+ if (result.skip_reason === null) result.skip_reason = skipMatch[1];
1999
+ continue;
2000
+ }
2001
+ const notEditMatch = token.match(/^!edit:(.+)$/i);
2002
+ if (notEditMatch) {
2003
+ result.operators.push({ kind: "not_edit", target: notEditMatch[1] });
2004
+ continue;
2005
+ }
2006
+ const opMatch = token.match(/^(edit|require|forbid):(.+)$/i);
2007
+ if (opMatch) {
2008
+ result.operators.push({
2009
+ kind: opMatch[1].toLowerCase(),
2010
+ target: opMatch[2]
2011
+ });
2012
+ }
2013
+ }
2014
+ return result;
2015
+ }
2016
+ function parseLine(line) {
2017
+ const trimmed = line.trim();
2018
+ if (trimmed.length === 0) return null;
2019
+ if (SENTINEL_RE.test(trimmed)) {
2020
+ return { ids: [], stores: [], tag: "none", commitment: null };
2021
+ }
2022
+ const fullMatch = trimmed.match(FULL_RE);
2023
+ if (fullMatch) {
2024
+ const split = fullMatch[1].split(",").map((part) => part.trim()).filter((part) => part.length > 0).map(splitStorePrefix);
2025
+ if (split.some((entry) => !ID_RE.test(entry.id))) return null;
2026
+ const primaryIds = split.map((entry) => entry.id);
2027
+ const primaryStores = split.map((entry) => entry.store);
2028
+ const rawTag = fullMatch[3];
2029
+ const tag = parseTag(rawTag);
2030
+ const chainedIds = [];
2031
+ if (rawTag !== void 0) {
2032
+ const chained = CHAINED_FROM_ID_RE.exec(rawTag);
2033
+ if (chained !== null && ID_RE.test(chained[1])) {
2034
+ chainedIds.push(chained[1]);
2035
+ }
2036
+ }
2037
+ return {
2038
+ ids: [...primaryIds, ...chainedIds],
2039
+ // chained-from ids are never store-qualified → null per chained id.
2040
+ stores: [...primaryStores, ...chainedIds.map(() => null)],
2041
+ tag,
2042
+ commitment: parseContractTail(fullMatch[4])
2043
+ };
2044
+ }
2045
+ return null;
2046
+ }
2047
+ function parseCiteLine(raw) {
2048
+ const result = {
2049
+ cite_ids: [],
2050
+ cite_tags: [],
2051
+ cite_commitments: [],
2052
+ cite_stores: []
2053
+ };
2054
+ if (typeof raw !== "string") return result;
2055
+ for (const line of raw.split(/\r?\n/)) {
2056
+ const parsed = parseLine(line);
2057
+ if (!parsed) continue;
2058
+ result.cite_tags.push(parsed.tag);
2059
+ for (let i = 0; i < parsed.ids.length; i += 1) {
2060
+ result.cite_ids.push(parsed.ids[i]);
2061
+ result.cite_stores.push(parsed.stores[i] ?? null);
2062
+ }
2063
+ if (parsed.commitment !== null) {
2064
+ for (let i = 0; i < parsed.ids.length; i += 1) {
2065
+ result.cite_commitments.push(parsed.commitment);
2066
+ }
2067
+ }
2068
+ }
2069
+ return result;
2070
+ }
2071
+
2072
+ // src/schemas/event-ledger.ts
2073
+ var citeTagSchema = z18.preprocess(
2074
+ (value) => typeof value === "string" ? normalizeCiteTag(value) : value,
2075
+ z18.enum(["applied", "dismissed", "none"])
2076
+ );
919
2077
  var eventLedgerEnvelopeSchema = {
920
- kind: z10.literal("fabric-event"),
921
- id: z10.string(),
922
- ts: z10.number().int().nonnegative(),
923
- schema_version: z10.literal(1),
924
- correlation_id: z10.string().optional(),
925
- session_id: z10.string().optional()
2078
+ kind: z18.literal("fabric-event"),
2079
+ id: z18.string(),
2080
+ ts: z18.number().int().nonnegative(),
2081
+ schema_version: z18.literal(1),
2082
+ correlation_id: z18.string().optional(),
2083
+ session_id: z18.string().optional()
926
2084
  };
927
- var stringRecordSchema = z10.record(z10.string());
928
- var knowledgeContextPlannedEventSchema = z10.object({
2085
+ var stringRecordSchema = z18.record(z18.string());
2086
+ var knowledgeContextPlannedEventSchema = z18.object({
929
2087
  ...eventLedgerEnvelopeSchema,
930
- event_type: z10.literal("knowledge_context_planned"),
931
- target_paths: z10.array(z10.string()),
932
- required_stable_ids: z10.array(z10.string()),
933
- ai_selectable_stable_ids: z10.array(z10.string()),
934
- final_stable_ids: z10.array(z10.string()),
935
- selection_token: z10.string().optional(),
936
- client_hash: z10.string().optional(),
937
- intent: z10.string().optional(),
938
- known_tech: z10.array(z10.string()).optional(),
939
- diagnostics: z10.array(z10.unknown()).optional()
940
- });
941
- var knowledgeSelectionEventSchema = z10.object({
2088
+ event_type: z18.literal("knowledge_context_planned"),
2089
+ target_paths: z18.array(z18.string()),
2090
+ required_stable_ids: z18.array(z18.string()),
2091
+ ai_selectable_stable_ids: z18.array(z18.string()),
2092
+ final_stable_ids: z18.array(z18.string()),
2093
+ selection_token: z18.string().optional(),
2094
+ client_hash: z18.string().optional(),
2095
+ intent: z18.string().optional(),
2096
+ known_tech: z18.array(z18.string()).optional(),
2097
+ diagnostics: z18.array(z18.unknown()).optional()
2098
+ });
2099
+ var knowledgeSelectionEventSchema = z18.object({
942
2100
  ...eventLedgerEnvelopeSchema,
943
- event_type: z10.literal("knowledge_selection"),
944
- selection_token: z10.string(),
945
- target_paths: z10.array(z10.string()),
946
- required_stable_ids: z10.array(z10.string()),
947
- ai_selectable_stable_ids: z10.array(z10.string()),
948
- ai_selected_stable_ids: z10.array(z10.string()),
949
- final_stable_ids: z10.array(z10.string()),
2101
+ event_type: z18.literal("knowledge_selection"),
2102
+ selection_token: z18.string(),
2103
+ target_paths: z18.array(z18.string()),
2104
+ required_stable_ids: z18.array(z18.string()),
2105
+ ai_selectable_stable_ids: z18.array(z18.string()),
2106
+ ai_selected_stable_ids: z18.array(z18.string()),
2107
+ final_stable_ids: z18.array(z18.string()),
950
2108
  ai_selection_reasons: stringRecordSchema,
951
- rejected_stable_ids: z10.array(z10.string()),
952
- ignored_stable_ids: z10.array(z10.string())
2109
+ rejected_stable_ids: z18.array(z18.string()),
2110
+ ignored_stable_ids: z18.array(z18.string())
953
2111
  });
954
- var knowledgeSectionsFetchedEventSchema = z10.object({
2112
+ var knowledgeSectionsFetchedEventSchema = z18.object({
955
2113
  ...eventLedgerEnvelopeSchema,
956
- event_type: z10.literal("knowledge_sections_fetched"),
957
- selection_token: z10.string(),
958
- target_paths: z10.array(z10.string()).optional(),
959
- requested_sections: z10.array(z10.string()),
960
- final_stable_ids: z10.array(z10.string()),
961
- ai_selected_stable_ids: z10.array(z10.string()),
962
- diagnostics: z10.array(z10.unknown()).optional()
963
- });
964
- var editIntentCheckedEventSchema = z10.object({
2114
+ event_type: z18.literal("knowledge_sections_fetched"),
2115
+ selection_token: z18.string(),
2116
+ target_paths: z18.array(z18.string()).optional(),
2117
+ requested_sections: z18.array(z18.string()),
2118
+ final_stable_ids: z18.array(z18.string()),
2119
+ ai_selected_stable_ids: z18.array(z18.string()),
2120
+ diagnostics: z18.array(z18.unknown()).optional()
2121
+ });
2122
+ var editIntentCheckedEventSchema = z18.object({
965
2123
  ...eventLedgerEnvelopeSchema,
966
- event_type: z10.literal("edit_intent_checked"),
967
- path: z10.string(),
968
- compliant: z10.boolean(),
969
- intent: z10.string(),
970
- ledger_entry_id: z10.string(),
2124
+ event_type: z18.literal("edit_intent_checked"),
2125
+ path: z18.string(),
2126
+ compliant: z18.boolean(),
2127
+ intent: z18.string(),
2128
+ ledger_entry_id: z18.string(),
971
2129
  // rc.35 TASK-07 (P0-2): add "hook" — emitted by the PreToolUse narrow hook
972
2130
  // for every Edit/Write/MultiEdit fire so cite-coverage doctor metrics see
973
2131
  // actual edit signals (previously editsTouched was permanently 0 because
974
2132
  // no production caller of appendLedgerEntry existed).
975
- ledger_source: z10.enum(["ai", "human", "hook"]).optional(),
976
- commit_sha: z10.string().optional(),
977
- parent_sha: z10.string().optional(),
978
- parent_ledger_entry_id: z10.string().optional(),
979
- diff_stat: z10.string().optional(),
980
- annotation: z10.string().optional(),
981
- matched_rule_context_ts: z10.number().int().nonnegative().nullable(),
982
- window_ms: z10.number().int().nonnegative()
983
- });
984
- var knowledgeDriftDetectedEventSchema = z10.object({
2133
+ ledger_source: z18.enum(["ai", "human", "hook"]).optional(),
2134
+ commit_sha: z18.string().optional(),
2135
+ parent_sha: z18.string().optional(),
2136
+ parent_ledger_entry_id: z18.string().optional(),
2137
+ diff_stat: z18.string().optional(),
2138
+ annotation: z18.string().optional(),
2139
+ matched_rule_context_ts: z18.number().int().nonnegative().nullable(),
2140
+ window_ms: z18.number().int().nonnegative()
2141
+ });
2142
+ var knowledgeDriftDetectedEventSchema = z18.object({
985
2143
  ...eventLedgerEnvelopeSchema,
986
- event_type: z10.literal("knowledge_drift_detected"),
987
- revision: z10.string().optional(),
988
- drifted_stable_ids: z10.array(z10.string()),
989
- missing_files: z10.array(z10.string()),
990
- stale_files: z10.array(z10.string()),
991
- details: z10.array(
992
- z10.object({
993
- file: z10.string(),
994
- stable_id: z10.string(),
995
- expected_hash: z10.string(),
996
- actual_hash: z10.string().nullable()
2144
+ event_type: z18.literal("knowledge_drift_detected"),
2145
+ revision: z18.string().optional(),
2146
+ drifted_stable_ids: z18.array(z18.string()),
2147
+ missing_files: z18.array(z18.string()),
2148
+ stale_files: z18.array(z18.string()),
2149
+ details: z18.array(
2150
+ z18.object({
2151
+ file: z18.string(),
2152
+ stable_id: z18.string(),
2153
+ expected_hash: z18.string(),
2154
+ actual_hash: z18.string().nullable()
997
2155
  })
998
2156
  ).optional()
999
2157
  });
1000
- var mcpEventLedgerEventSchema = z10.object({
2158
+ var mcpEventLedgerEventSchema = z18.object({
1001
2159
  ...eventLedgerEnvelopeSchema,
1002
- event_type: z10.literal("mcp_event"),
1003
- mcp_event_id: z10.string(),
1004
- stream_id: z10.string(),
1005
- message: z10.unknown()
2160
+ event_type: z18.literal("mcp_event"),
2161
+ mcp_event_id: z18.string(),
2162
+ stream_id: z18.string(),
2163
+ message: z18.unknown()
1006
2164
  });
1007
- var reapplyCompletedEventSchema = z10.object({
2165
+ var reapplyCompletedEventSchema = z18.object({
1008
2166
  ...eventLedgerEnvelopeSchema,
1009
- event_type: z10.literal("reapply_completed"),
1010
- preserved_ledger: z10.boolean(),
1011
- preserved_meta: z10.boolean(),
1012
- rules_count: z10.number().int().nonnegative()
2167
+ event_type: z18.literal("reapply_completed"),
2168
+ preserved_ledger: z18.boolean(),
2169
+ preserved_meta: z18.boolean(),
2170
+ rules_count: z18.number().int().nonnegative()
1013
2171
  });
1014
- var installDiffAppliedEventSchema = z10.object({
2172
+ var installDiffAppliedEventSchema = z18.object({
1015
2173
  ...eventLedgerEnvelopeSchema,
1016
- event_type: z10.literal("install_diff_applied"),
1017
- applied: z10.array(z10.string()),
1018
- canonical: z10.array(z10.string()),
1019
- drifted: z10.array(z10.string())
2174
+ event_type: z18.literal("install_diff_applied"),
2175
+ applied: z18.array(z18.string()),
2176
+ canonical: z18.array(z18.string()),
2177
+ drifted: z18.array(z18.string())
1020
2178
  });
1021
- var eventLedgerTruncatedEventSchema = z10.object({
2179
+ var eventLedgerTruncatedEventSchema = z18.object({
1022
2180
  ...eventLedgerEnvelopeSchema,
1023
- event_type: z10.literal("event_ledger_truncated"),
1024
- byte_offset: z10.number().int().nonnegative(),
1025
- byte_length: z10.number().int().nonnegative(),
1026
- corrupted_path: z10.string()
2181
+ event_type: z18.literal("event_ledger_truncated"),
2182
+ byte_offset: z18.number().int().nonnegative(),
2183
+ byte_length: z18.number().int().nonnegative(),
2184
+ corrupted_path: z18.string()
1027
2185
  });
1028
- var mcpConfigMigratedEventSchema = z10.object({
2186
+ var mcpConfigMigratedEventSchema = z18.object({
1029
2187
  ...eventLedgerEnvelopeSchema,
1030
- event_type: z10.literal("mcp_config_migrated"),
1031
- source: z10.literal("doctor_fix"),
1032
- removed_from: z10.string()
2188
+ event_type: z18.literal("mcp_config_migrated"),
2189
+ source: z18.literal("doctor_fix"),
2190
+ removed_from: z18.string()
1033
2191
  });
1034
- var bootstrapMarkerMigratedEventSchema = z10.object({
2192
+ var bootstrapMarkerMigratedEventSchema = z18.object({
1035
2193
  ...eventLedgerEnvelopeSchema,
1036
- event_type: z10.literal("bootstrap_marker_migrated"),
1037
- path: z10.string(),
1038
- migrated_count: z10.number().int().nonnegative(),
1039
- legacy_marker: z10.literal("fabric:knowledge-base"),
1040
- new_marker: z10.literal("fabric:bootstrap"),
1041
- timestamp: z10.string()
1042
- });
1043
- var metaReconciledOnStartupEventSchema = z10.object({
2194
+ event_type: z18.literal("bootstrap_marker_migrated"),
2195
+ path: z18.string(),
2196
+ migrated_count: z18.number().int().nonnegative(),
2197
+ legacy_marker: z18.literal("fabric:knowledge-base"),
2198
+ new_marker: z18.literal("fabric:bootstrap"),
2199
+ timestamp: z18.string()
2200
+ });
2201
+ var metaReconciledOnStartupEventSchema = z18.object({
1044
2202
  ...eventLedgerEnvelopeSchema,
1045
- event_type: z10.literal("meta_reconciled_on_startup"),
1046
- reconciled_files: z10.array(z10.string()),
1047
- duration_ms: z10.number().int().nonnegative(),
1048
- source: z10.literal("reconcileKnowledge")
2203
+ event_type: z18.literal("meta_reconciled_on_startup"),
2204
+ reconciled_files: z18.array(z18.string()),
2205
+ duration_ms: z18.number().int().nonnegative(),
2206
+ source: z18.literal("reconcileKnowledge")
1049
2207
  });
1050
- var metaReconciledEventSchema = z10.object({
2208
+ var metaReconciledEventSchema = z18.object({
1051
2209
  ...eventLedgerEnvelopeSchema,
1052
- event_type: z10.literal("meta_reconciled"),
1053
- reconciled_files: z10.array(z10.string()),
1054
- duration_ms: z10.number().int().nonnegative(),
2210
+ event_type: z18.literal("meta_reconciled"),
2211
+ reconciled_files: z18.array(z18.string()),
2212
+ duration_ms: z18.number().int().nonnegative(),
1055
2213
  // v2.0.0-rc.23 TASK-005 (a-B): added `auto-heal-description` trigger so the
1056
2214
  // read-path plan_context handler can drive a full reconcile when it detects
1057
2215
  // any node carrying `description === undefined` (legacy meta drift that the
@@ -1065,7 +2223,7 @@ var metaReconciledEventSchema = z10.object({
1065
2223
  // v2.0.0-rc.29 TASK-005 (BUG-G1): `auto-heal-after-drift` added so
1066
2224
  // `ensureKnowledgeFresh` hot-path can chain a paired reconcile (closing the
1067
2225
  // drift→heal gap) when the caller opts in via `autoHealOnDrift: true`.
1068
- trigger: z10.enum([
2226
+ trigger: z18.enum([
1069
2227
  "doctor",
1070
2228
  "manual",
1071
2229
  "auto-heal-description",
@@ -1073,195 +2231,195 @@ var metaReconciledEventSchema = z10.object({
1073
2231
  "post-approve",
1074
2232
  "post-modify"
1075
2233
  ]),
1076
- source: z10.literal("reconcileKnowledge"),
2234
+ source: z18.literal("reconcileKnowledge"),
1077
2235
  // v2.0.0-rc.22 TASK-014 (Scope E): set when reconcileKnowledge forced a
1078
2236
  // writeKnowledgeMeta on revision drift alone (no per-file content drift).
1079
2237
  // Distinguishes top-level schema/revision repair from the standard per-file
1080
2238
  // drift path. Optional so existing emitters stay unchanged.
1081
- force_write_reason: z10.enum(["revision_drift"]).optional()
2239
+ force_write_reason: z18.enum(["revision_drift"]).optional()
1082
2240
  });
1083
- var claudeSkillPathMigratedEventSchema = z10.object({
2241
+ var claudeSkillPathMigratedEventSchema = z18.object({
1084
2242
  ...eventLedgerEnvelopeSchema,
1085
- event_type: z10.literal("claude_skill_path_migrated"),
1086
- from: z10.string(),
1087
- to: z10.string()
2243
+ event_type: z18.literal("claude_skill_path_migrated"),
2244
+ from: z18.string(),
2245
+ to: z18.string()
1088
2246
  });
1089
- var claudeHookPathMigratedEventSchema = z10.object({
2247
+ var claudeHookPathMigratedEventSchema = z18.object({
1090
2248
  ...eventLedgerEnvelopeSchema,
1091
- event_type: z10.literal("claude_hook_path_migrated"),
1092
- from: z10.string(),
1093
- to: z10.string()
2249
+ event_type: z18.literal("claude_hook_path_migrated"),
2250
+ from: z18.string(),
2251
+ to: z18.string()
1094
2252
  });
1095
- var codexSkillPathMigratedEventSchema = z10.object({
2253
+ var codexSkillPathMigratedEventSchema = z18.object({
1096
2254
  ...eventLedgerEnvelopeSchema,
1097
- event_type: z10.literal("codex_skill_path_migrated"),
1098
- from: z10.string(),
1099
- to: z10.string()
2255
+ event_type: z18.literal("codex_skill_path_migrated"),
2256
+ from: z18.string(),
2257
+ to: z18.string()
1100
2258
  });
1101
- var initScanCompletedEventSchema = z10.object({
2259
+ var initScanCompletedEventSchema = z18.object({
1102
2260
  ...eventLedgerEnvelopeSchema,
1103
- event_type: z10.literal("init_scan_completed"),
1104
- written_stable_ids: z10.array(z10.string()),
1105
- duration_ms: z10.number().int().nonnegative(),
1106
- source: z10.enum(["init", "scan", "doctor_fix", "doctor-rescan"]).optional()
2261
+ event_type: z18.literal("init_scan_completed"),
2262
+ written_stable_ids: z18.array(z18.string()),
2263
+ duration_ms: z18.number().int().nonnegative(),
2264
+ source: z18.enum(["init", "scan", "doctor_fix", "doctor-rescan"]).optional()
1107
2265
  });
1108
- var knowledgeProposedEventSchema = z10.object({
2266
+ var knowledgeProposedEventSchema = z18.object({
1109
2267
  ...eventLedgerEnvelopeSchema,
1110
- event_type: z10.literal("knowledge_proposed"),
1111
- stable_id: z10.string().optional(),
1112
- timestamp: z10.string().datetime(),
1113
- reason: z10.string().optional()
2268
+ event_type: z18.literal("knowledge_proposed"),
2269
+ stable_id: z18.string().optional(),
2270
+ timestamp: z18.string().datetime(),
2271
+ reason: z18.string().optional()
1114
2272
  });
1115
- var knowledgePromoteStartedEventSchema = z10.object({
2273
+ var knowledgePromoteStartedEventSchema = z18.object({
1116
2274
  ...eventLedgerEnvelopeSchema,
1117
- event_type: z10.literal("knowledge_promote_started"),
1118
- stable_id: z10.string().optional(),
1119
- timestamp: z10.string().datetime(),
1120
- reason: z10.string().optional()
2275
+ event_type: z18.literal("knowledge_promote_started"),
2276
+ stable_id: z18.string().optional(),
2277
+ timestamp: z18.string().datetime(),
2278
+ reason: z18.string().optional()
1121
2279
  });
1122
- var knowledgePromotedEventSchema = z10.object({
2280
+ var knowledgePromotedEventSchema = z18.object({
1123
2281
  ...eventLedgerEnvelopeSchema,
1124
- event_type: z10.literal("knowledge_promoted"),
1125
- stable_id: z10.string().optional(),
1126
- timestamp: z10.string().datetime(),
1127
- reason: z10.string().optional()
2282
+ event_type: z18.literal("knowledge_promoted"),
2283
+ stable_id: z18.string().optional(),
2284
+ timestamp: z18.string().datetime(),
2285
+ reason: z18.string().optional()
1128
2286
  });
1129
- var knowledgePromoteFailedEventSchema = z10.object({
2287
+ var knowledgePromoteFailedEventSchema = z18.object({
1130
2288
  ...eventLedgerEnvelopeSchema,
1131
- event_type: z10.literal("knowledge_promote_failed"),
1132
- stable_id: z10.string().optional(),
1133
- timestamp: z10.string().datetime(),
1134
- reason: z10.string()
2289
+ event_type: z18.literal("knowledge_promote_failed"),
2290
+ stable_id: z18.string().optional(),
2291
+ timestamp: z18.string().datetime(),
2292
+ reason: z18.string()
1135
2293
  });
1136
- var knowledgeLayerChangedEventSchema = z10.object({
2294
+ var knowledgeLayerChangedEventSchema = z18.object({
1137
2295
  ...eventLedgerEnvelopeSchema,
1138
- event_type: z10.literal("knowledge_layer_changed"),
1139
- stable_id: z10.string().optional(),
1140
- timestamp: z10.string().datetime(),
1141
- reason: z10.string().optional(),
1142
- from_layer: z10.enum(["team", "personal"]),
1143
- to_layer: z10.enum(["team", "personal"]),
2296
+ event_type: z18.literal("knowledge_layer_changed"),
2297
+ stable_id: z18.string().optional(),
2298
+ timestamp: z18.string().datetime(),
2299
+ reason: z18.string().optional(),
2300
+ from_layer: z18.enum(["team", "personal"]),
2301
+ to_layer: z18.enum(["team", "personal"]),
1144
2302
  // v2.0.0-rc.37 NEW-24: record the pre-flip stable_id so downstream consumers
1145
2303
  // (fab_plan_context redirect surface, fab_get_knowledge_sections.redirect_to)
1146
2304
  // can map a stale caller-held id back to the post-flip canonical id without
1147
2305
  // requiring the caller to re-issue plan-context. Optional for forward-
1148
2306
  // compatibility with rc ≤36 events that never carried this field.
1149
- previous_stable_id: z10.string().optional()
2307
+ previous_stable_id: z18.string().optional()
1150
2308
  });
1151
- var knowledgeIdRedirectEventSchema = z10.object({
2309
+ var knowledgeIdRedirectEventSchema = z18.object({
1152
2310
  ...eventLedgerEnvelopeSchema,
1153
- event_type: z10.literal("knowledge_id_redirect"),
1154
- timestamp: z10.string().datetime(),
1155
- previous_stable_id: z10.string(),
1156
- new_stable_id: z10.string(),
1157
- reason: z10.string().optional()
2311
+ event_type: z18.literal("knowledge_id_redirect"),
2312
+ timestamp: z18.string().datetime(),
2313
+ previous_stable_id: z18.string(),
2314
+ new_stable_id: z18.string(),
2315
+ reason: z18.string().optional()
1158
2316
  });
1159
- var knowledgeSlugRenamedEventSchema = z10.object({
2317
+ var knowledgeSlugRenamedEventSchema = z18.object({
1160
2318
  ...eventLedgerEnvelopeSchema,
1161
- event_type: z10.literal("knowledge_slug_renamed"),
1162
- stable_id: z10.string().optional(),
1163
- timestamp: z10.string().datetime(),
1164
- reason: z10.string().optional(),
1165
- from_slug: z10.string(),
1166
- to_slug: z10.string()
1167
- });
1168
- var knowledgeDemotedEventSchema = z10.object({
2319
+ event_type: z18.literal("knowledge_slug_renamed"),
2320
+ stable_id: z18.string().optional(),
2321
+ timestamp: z18.string().datetime(),
2322
+ reason: z18.string().optional(),
2323
+ from_slug: z18.string(),
2324
+ to_slug: z18.string()
2325
+ });
2326
+ var knowledgeDemotedEventSchema = z18.object({
1169
2327
  ...eventLedgerEnvelopeSchema,
1170
- event_type: z10.literal("knowledge_demoted"),
1171
- stable_id: z10.string().optional(),
1172
- timestamp: z10.string().datetime(),
1173
- reason: z10.string().optional()
2328
+ event_type: z18.literal("knowledge_demoted"),
2329
+ stable_id: z18.string().optional(),
2330
+ timestamp: z18.string().datetime(),
2331
+ reason: z18.string().optional()
1174
2332
  });
1175
- var knowledgeArchivedEventSchema = z10.object({
2333
+ var knowledgeArchivedEventSchema = z18.object({
1176
2334
  ...eventLedgerEnvelopeSchema,
1177
- event_type: z10.literal("knowledge_archived"),
1178
- stable_id: z10.string().optional(),
1179
- timestamp: z10.string().datetime(),
1180
- reason: z10.string().optional()
2335
+ event_type: z18.literal("knowledge_archived"),
2336
+ stable_id: z18.string().optional(),
2337
+ timestamp: z18.string().datetime(),
2338
+ reason: z18.string().optional()
1181
2339
  });
1182
- var knowledgeArchiveAttemptedEventSchema = z10.object({
2340
+ var knowledgeArchiveAttemptedEventSchema = z18.object({
1183
2341
  ...eventLedgerEnvelopeSchema,
1184
- event_type: z10.literal("knowledge_archive_attempted"),
1185
- stable_id: z10.string().optional(),
1186
- timestamp: z10.string().datetime(),
1187
- reason: z10.string().optional()
2342
+ event_type: z18.literal("knowledge_archive_attempted"),
2343
+ stable_id: z18.string().optional(),
2344
+ timestamp: z18.string().datetime(),
2345
+ reason: z18.string().optional()
1188
2346
  });
1189
- var knowledgeUnarchivedEventSchema = z10.object({
2347
+ var knowledgeUnarchivedEventSchema = z18.object({
1190
2348
  ...eventLedgerEnvelopeSchema,
1191
- event_type: z10.literal("knowledge_unarchived"),
1192
- stable_id: z10.string().optional(),
1193
- timestamp: z10.string().datetime(),
1194
- reason: z10.string().optional(),
2349
+ event_type: z18.literal("knowledge_unarchived"),
2350
+ stable_id: z18.string().optional(),
2351
+ timestamp: z18.string().datetime(),
2352
+ reason: z18.string().optional(),
1195
2353
  // Pre-move archive path (e.g. ".fabric/.archive/decisions/KT-D-0007--single-cjs-hook.md").
1196
- archive_path: z10.string().optional(),
2354
+ archive_path: z18.string().optional(),
1197
2355
  // Post-move canonical path (e.g. ".fabric/knowledge/team/decisions/KT-D-0007--single-cjs-hook.md").
1198
- restored_to: z10.string().optional()
2356
+ restored_to: z18.string().optional()
1199
2357
  });
1200
- var knowledgeDeferredEventSchema = z10.object({
2358
+ var knowledgeDeferredEventSchema = z18.object({
1201
2359
  ...eventLedgerEnvelopeSchema,
1202
- event_type: z10.literal("knowledge_deferred"),
1203
- stable_id: z10.string().optional(),
1204
- timestamp: z10.string().datetime(),
1205
- reason: z10.string().optional(),
1206
- until: z10.string().datetime().optional()
2360
+ event_type: z18.literal("knowledge_deferred"),
2361
+ stable_id: z18.string().optional(),
2362
+ timestamp: z18.string().datetime(),
2363
+ reason: z18.string().optional(),
2364
+ until: z18.string().datetime().optional()
1207
2365
  });
1208
- var knowledgeRejectedEventSchema = z10.object({
2366
+ var knowledgeRejectedEventSchema = z18.object({
1209
2367
  ...eventLedgerEnvelopeSchema,
1210
- event_type: z10.literal("knowledge_rejected"),
1211
- stable_id: z10.string().optional(),
1212
- timestamp: z10.string().datetime(),
1213
- reason: z10.string()
2368
+ event_type: z18.literal("knowledge_rejected"),
2369
+ stable_id: z18.string().optional(),
2370
+ timestamp: z18.string().datetime(),
2371
+ reason: z18.string()
1214
2372
  });
1215
- var knowledgeConsumedEventSchema = z10.object({
2373
+ var knowledgeConsumedEventSchema = z18.object({
1216
2374
  ...eventLedgerEnvelopeSchema,
1217
- event_type: z10.literal("knowledge_consumed"),
1218
- stable_id: z10.string(),
1219
- consumed_at: z10.string().datetime(),
1220
- client_hash: z10.string()
2375
+ event_type: z18.literal("knowledge_consumed"),
2376
+ stable_id: z18.string(),
2377
+ consumed_at: z18.string().datetime(),
2378
+ client_hash: z18.string()
1221
2379
  });
1222
- var knowledgeScopeDegradedEventSchema = z10.object({
2380
+ var knowledgeScopeDegradedEventSchema = z18.object({
1223
2381
  ...eventLedgerEnvelopeSchema,
1224
- event_type: z10.literal("knowledge_scope_degraded"),
1225
- stable_id: z10.string(),
1226
- timestamp: z10.string().datetime(),
1227
- from_scope: z10.enum(["narrow", "broad"]),
1228
- to_scope: z10.enum(["narrow", "broad"]),
1229
- reason: z10.string()
1230
- });
1231
- var doctorRunEventSchema = z10.object({
2382
+ event_type: z18.literal("knowledge_scope_degraded"),
2383
+ stable_id: z18.string(),
2384
+ timestamp: z18.string().datetime(),
2385
+ from_scope: z18.enum(["narrow", "broad"]),
2386
+ to_scope: z18.enum(["narrow", "broad"]),
2387
+ reason: z18.string()
2388
+ });
2389
+ var doctorRunEventSchema = z18.object({
1232
2390
  ...eventLedgerEnvelopeSchema,
1233
- event_type: z10.literal("doctor_run"),
1234
- mode: z10.enum(["lint", "fix-knowledge"]),
1235
- issues: z10.number().int().nonnegative(),
1236
- mutations: z10.number().int().nonnegative().optional(),
1237
- timestamp: z10.string().datetime()
2391
+ event_type: z18.literal("doctor_run"),
2392
+ mode: z18.enum(["lint", "fix-knowledge"]),
2393
+ issues: z18.number().int().nonnegative(),
2394
+ mutations: z18.number().int().nonnegative().optional(),
2395
+ timestamp: z18.string().datetime()
1238
2396
  });
1239
- var knowledgePathDangledEventSchema = z10.object({
2397
+ var knowledgePathDangledEventSchema = z18.object({
1240
2398
  ...eventLedgerEnvelopeSchema,
1241
- event_type: z10.literal("knowledge_path_dangled"),
1242
- stable_id: z10.string(),
1243
- removed_glob: z10.string()
2399
+ event_type: z18.literal("knowledge_path_dangled"),
2400
+ stable_id: z18.string(),
2401
+ removed_glob: z18.string()
1244
2402
  });
1245
- var relevanceMigrationRunEventSchema = z10.object({
2403
+ var relevanceMigrationRunEventSchema = z18.object({
1246
2404
  ...eventLedgerEnvelopeSchema,
1247
- event_type: z10.literal("relevance_migration_run"),
1248
- timestamp: z10.string().datetime(),
1249
- scanned_count: z10.number().int().nonnegative(),
1250
- touched_count: z10.number().int().nonnegative()
2405
+ event_type: z18.literal("relevance_migration_run"),
2406
+ timestamp: z18.string().datetime(),
2407
+ scanned_count: z18.number().int().nonnegative(),
2408
+ touched_count: z18.number().int().nonnegative()
1251
2409
  });
1252
- var pendingAutoArchivedEventSchema = z10.object({
2410
+ var pendingAutoArchivedEventSchema = z18.object({
1253
2411
  ...eventLedgerEnvelopeSchema,
1254
- event_type: z10.literal("pending_auto_archived"),
1255
- pending_path: z10.string(),
1256
- archived_to: z10.string(),
1257
- reason: z10.string()
2412
+ event_type: z18.literal("pending_auto_archived"),
2413
+ pending_path: z18.string(),
2414
+ archived_to: z18.string(),
2415
+ reason: z18.string()
1258
2416
  });
1259
- var assistantTurnObservedEventSchema = z10.object({
2417
+ var assistantTurnObservedEventSchema = z18.object({
1260
2418
  ...eventLedgerEnvelopeSchema,
1261
- event_type: z10.literal("assistant_turn_observed"),
1262
- kb_line_raw: z10.string().nullable(),
1263
- cite_ids: z10.array(z10.string()).default([]),
1264
- cite_tags: z10.array(z10.enum(["planned", "recalled", "chained-from", "dismissed", "none"])).default([]),
2419
+ event_type: z18.literal("assistant_turn_observed"),
2420
+ kb_line_raw: z18.string().nullable(),
2421
+ cite_ids: z18.array(z18.string()).default([]),
2422
+ cite_tags: z18.array(citeTagSchema).default([]),
1265
2423
  // v2.0.0-rc.24 TASK-01: per-cite contract commitments. Index-aligned with
1266
2424
  // cite_ids/cite_tags (commitments[i] belongs to cite_ids[i]). Each slot
1267
2425
  // carries `operators[]` (kind + glob target) or `skip_reason` when the cite
@@ -1269,72 +2427,160 @@ var assistantTurnObservedEventSchema = z10.object({
1269
2427
  // empty array via `.default([])` and are excluded from contract-policy
1270
2428
  // audits by the marker-gate (see cite_contract_policy_activated below).
1271
2429
  // Mirrors the rc.20 cite_tags parallel-array evolution exactly.
1272
- cite_commitments: z10.array(
1273
- z10.object({
1274
- operators: z10.array(
1275
- z10.object({
1276
- kind: z10.enum(["edit", "not_edit", "require", "forbid"]),
1277
- target: z10.string()
2430
+ cite_commitments: z18.array(
2431
+ z18.object({
2432
+ operators: z18.array(
2433
+ z18.object({
2434
+ kind: z18.enum(["edit", "not_edit", "require", "forbid"]),
2435
+ target: z18.string()
1278
2436
  })
1279
2437
  ),
1280
- skip_reason: z10.string().nullable()
2438
+ skip_reason: z18.string().nullable()
1281
2439
  })
1282
2440
  ).default([]),
1283
- client: z10.enum(["cc", "codex", "cursor"]).optional(),
1284
- turn_id: z10.string(),
1285
- envelope_index: z10.number().int().nonnegative().optional(),
1286
- timestamp: z10.string().datetime()
2441
+ client: z18.enum(["cc", "codex", "cursor"]).optional(),
2442
+ turn_id: z18.string(),
2443
+ envelope_index: z18.number().int().nonnegative().optional(),
2444
+ timestamp: z18.string().datetime()
2445
+ });
2446
+ var citePolicyActivatedEventSchema = z18.object({
2447
+ ...eventLedgerEnvelopeSchema,
2448
+ event_type: z18.literal("cite_policy_activated"),
2449
+ policy_version: z18.string(),
2450
+ timestamp: z18.string().datetime()
1287
2451
  });
1288
- var citePolicyActivatedEventSchema = z10.object({
2452
+ var citeContractPolicyActivatedEventSchema = z18.object({
1289
2453
  ...eventLedgerEnvelopeSchema,
1290
- event_type: z10.literal("cite_policy_activated"),
1291
- policy_version: z10.string(),
1292
- timestamp: z10.string().datetime()
2454
+ event_type: z18.literal("cite_contract_policy_activated")
1293
2455
  });
1294
- var citeContractPolicyActivatedEventSchema = z10.object({
2456
+ var eventsRotatedEventSchema = z18.object({
1295
2457
  ...eventLedgerEnvelopeSchema,
1296
- event_type: z10.literal("cite_contract_policy_activated")
2458
+ event_type: z18.literal("events_rotated"),
2459
+ cutoff_ts: z18.string().datetime(),
2460
+ archived_count: z18.number().int().nonnegative(),
2461
+ kept_count: z18.number().int().nonnegative(),
2462
+ archive_path: z18.string()
1297
2463
  });
1298
- var eventsRotatedEventSchema = z10.object({
2464
+ var knowledgeMetaAutoHealedEventSchema = z18.object({
1299
2465
  ...eventLedgerEnvelopeSchema,
1300
- event_type: z10.literal("events_rotated"),
1301
- cutoff_ts: z10.string().datetime(),
1302
- archived_count: z10.number().int().nonnegative(),
1303
- kept_count: z10.number().int().nonnegative(),
1304
- archive_path: z10.string()
2466
+ event_type: z18.literal("knowledge_meta_auto_healed"),
2467
+ previous_revision_hash: z18.string(),
2468
+ revision_hash: z18.string(),
2469
+ trigger: z18.literal("read"),
2470
+ caller: z18.enum(["planContext", "getKnowledgeSections", "getKnowledge", "extractKnowledge"]).optional()
1305
2471
  });
1306
- var knowledgeMetaAutoHealedEventSchema = z10.object({
2472
+ var serveLockClearedEventSchema = z18.object({
1307
2473
  ...eventLedgerEnvelopeSchema,
1308
- event_type: z10.literal("knowledge_meta_auto_healed"),
1309
- previous_revision_hash: z10.string(),
1310
- revision_hash: z10.string(),
1311
- trigger: z10.literal("read"),
1312
- caller: z10.enum(["planContext", "getKnowledgeSections", "getKnowledge", "extractKnowledge"]).optional()
2474
+ event_type: z18.literal("serve_lock_cleared"),
2475
+ pid: z18.number().int().nonnegative(),
2476
+ age_ms: z18.number().int().nonnegative(),
2477
+ timestamp: z18.string().datetime()
1313
2478
  });
1314
- var serveLockClearedEventSchema = z10.object({
2479
+ var knowledgeEnrichedEventSchema = z18.object({
1315
2480
  ...eventLedgerEnvelopeSchema,
1316
- event_type: z10.literal("serve_lock_cleared"),
1317
- pid: z10.number().int().nonnegative(),
1318
- age_ms: z10.number().int().nonnegative(),
1319
- timestamp: z10.string().datetime()
2481
+ event_type: z18.literal("knowledge_enriched"),
2482
+ path: z18.string(),
2483
+ added_fields: z18.array(z18.enum(["intent_clues", "tech_stack", "impact", "must_read_if"])),
2484
+ mode: z18.enum(["auto", "preview", "readonly", "interactive"]),
2485
+ timestamp: z18.string().datetime()
1320
2486
  });
1321
- var knowledgeEnrichedEventSchema = z10.object({
2487
+ var sessionArchiveAttemptedEventSchema = z18.object({
1322
2488
  ...eventLedgerEnvelopeSchema,
1323
- event_type: z10.literal("knowledge_enriched"),
1324
- path: z10.string(),
1325
- added_fields: z10.array(z10.enum(["intent_clues", "tech_stack", "impact", "must_read_if"])),
1326
- mode: z10.enum(["auto", "preview", "readonly", "interactive"]),
1327
- timestamp: z10.string().datetime()
2489
+ event_type: z18.literal("session_archive_attempted"),
2490
+ outcome: z18.enum(["proposed", "viability_failed", "user_dismissed", "skipped_no_signal"]),
2491
+ covered_through_ts: z18.number().int().nonnegative(),
2492
+ candidates_proposed: z18.number().int().nonnegative().default(0),
2493
+ knowledge_proposed_ids: z18.array(z18.string()).default([])
1328
2494
  });
1329
- var sessionArchiveAttemptedEventSchema = z10.object({
2495
+ var hookSurfaceEmittedEventSchema = z18.object({
1330
2496
  ...eventLedgerEnvelopeSchema,
1331
- event_type: z10.literal("session_archive_attempted"),
1332
- outcome: z10.enum(["proposed", "viability_failed", "user_dismissed", "skipped_no_signal"]),
1333
- covered_through_ts: z10.number().int().nonnegative(),
1334
- candidates_proposed: z10.number().int().nonnegative().default(0),
1335
- knowledge_proposed_ids: z10.array(z10.string()).default([])
2497
+ event_type: z18.literal("hook_surface_emitted"),
2498
+ hook_name: z18.string(),
2499
+ client: z18.enum(["cc", "codex", "cursor"]),
2500
+ target_channel: z18.string(),
2501
+ rendered_ids: z18.array(z18.string()),
2502
+ delivery_status: z18.enum(["delivered", "suppressed", "error"]),
2503
+ suppression_reason: z18.string().optional()
2504
+ });
2505
+ var hookSignalEmittedEventSchema = z18.object({
2506
+ ...eventLedgerEnvelopeSchema,
2507
+ event_type: z18.literal("hook_signal_emitted"),
2508
+ signal_type: z18.enum(["archive", "review", "maintenance", "other"]),
2509
+ threshold: z18.number(),
2510
+ actual_value: z18.number(),
2511
+ fired: z18.boolean()
1336
2512
  });
1337
- var eventLedgerEventSchema = z10.discriminatedUnion("event_type", [
2513
+ var mcpStdioTraceEventSchema = z18.object({
2514
+ ...eventLedgerEnvelopeSchema,
2515
+ event_type: z18.literal("mcp_stdio_trace"),
2516
+ tool_name: z18.string(),
2517
+ request_id: z18.string(),
2518
+ duration_ms: z18.number().nonnegative(),
2519
+ status: z18.enum(["ok", "error"]),
2520
+ payload_bytes_in: z18.number().int().nonnegative(),
2521
+ payload_bytes_out: z18.number().int().nonnegative(),
2522
+ error_code: z18.string().optional()
2523
+ });
2524
+ var payloadGuardObservedEventSchema = z18.object({
2525
+ ...eventLedgerEnvelopeSchema,
2526
+ event_type: z18.literal("payload_guard_observed"),
2527
+ tool_name: z18.string(),
2528
+ path_count: z18.number().int().nonnegative(),
2529
+ tokens_estimated: z18.number().int().nonnegative(),
2530
+ truncated: z18.boolean(),
2531
+ cap: z18.number().int().positive()
2532
+ });
2533
+ var skillInvocationStartedEventSchema = z18.object({
2534
+ ...eventLedgerEnvelopeSchema,
2535
+ event_type: z18.literal("skill_invocation_started"),
2536
+ skill_name: z18.string(),
2537
+ trigger_source: z18.enum(["user", "auto_invoke", "ai_self_trigger", "chained"]),
2538
+ entry_point: z18.string()
2539
+ });
2540
+ var skillInvocationCompletedEventSchema = z18.object({
2541
+ ...eventLedgerEnvelopeSchema,
2542
+ event_type: z18.literal("skill_invocation_completed"),
2543
+ skill_name: z18.string(),
2544
+ trigger_source: z18.enum(["user", "auto_invoke", "ai_self_trigger", "chained"]),
2545
+ entry_point: z18.string(),
2546
+ outcome: z18.enum(["completed", "aborted", "error", "no_op"]),
2547
+ elapsed_ms: z18.number().nonnegative().optional()
2548
+ });
2549
+ var skillPhaseTransitionEventSchema = z18.object({
2550
+ ...eventLedgerEnvelopeSchema,
2551
+ event_type: z18.literal("skill_phase_transition"),
2552
+ skill_name: z18.string(),
2553
+ phase: z18.string(),
2554
+ status: z18.enum(["entered", "completed", "skipped", "failed"]),
2555
+ checkpoint: z18.string().optional(),
2556
+ elapsed_ms: z18.number().nonnegative().optional()
2557
+ });
2558
+ var skillTriggerCandidateEventSchema = z18.object({
2559
+ ...eventLedgerEnvelopeSchema,
2560
+ event_type: z18.literal("skill_trigger_candidate"),
2561
+ skill_name: z18.string(),
2562
+ trigger_source: z18.enum(["user", "auto_invoke", "ai_self_trigger", "chained"]),
2563
+ signal: z18.string(),
2564
+ invoked: z18.boolean()
2565
+ });
2566
+ var llmJudgeRunEventSchema = z18.object({
2567
+ ...eventLedgerEnvelopeSchema,
2568
+ event_type: z18.literal("llm_judge_run"),
2569
+ prompt: z18.string(),
2570
+ version: z18.string(),
2571
+ model: z18.string(),
2572
+ input_trace_id: z18.string(),
2573
+ score: z18.number(),
2574
+ rationale: z18.string()
2575
+ });
2576
+ var clientCapabilitySnapshotEventSchema = z18.object({
2577
+ ...eventLedgerEnvelopeSchema,
2578
+ event_type: z18.literal("client_capability_snapshot"),
2579
+ client: z18.enum(["cc", "codex", "cursor"]),
2580
+ capabilities: z18.array(z18.string()),
2581
+ version: z18.string()
2582
+ });
2583
+ var eventLedgerEventSchema = z18.discriminatedUnion("event_type", [
1338
2584
  knowledgeContextPlannedEventSchema,
1339
2585
  knowledgeSelectionEventSchema,
1340
2586
  knowledgeSectionsFetchedEventSchema,
@@ -1415,99 +2661,82 @@ var eventLedgerEventSchema = z10.discriminatedUnion("event_type", [
1415
2661
  // fabric-archive skill at the end of every invocation. Drives Phase 0.0
1416
2662
  // cross-session digest, outcome-based rescan filter (skips user_dismissed),
1417
2663
  // covered_through_ts watermark, and `fabric doctor --archive-history`.
1418
- sessionArchiveAttemptedEventSchema
2664
+ sessionArchiveAttemptedEventSchema,
2665
+ // v2.1 GATE-INSTR (NEW-N-3): 9 interaction-axis instrumentation events.
2666
+ hookSurfaceEmittedEventSchema,
2667
+ hookSignalEmittedEventSchema,
2668
+ mcpStdioTraceEventSchema,
2669
+ payloadGuardObservedEventSchema,
2670
+ skillInvocationStartedEventSchema,
2671
+ skillInvocationCompletedEventSchema,
2672
+ skillPhaseTransitionEventSchema,
2673
+ skillTriggerCandidateEventSchema,
2674
+ llmJudgeRunEventSchema,
2675
+ clientCapabilitySnapshotEventSchema
1419
2676
  ]);
1420
2677
 
1421
- // src/cite-line-parser.ts
1422
- var ID_RE = /^K[TP]-[A-Z]+-\d+$/;
1423
- var SENTINEL_RE = /^KB:\s*none\b\s*(?:\[[^\]]*\])?\s*$/i;
1424
- var FULL_RE = /^KB:\s+(K[TP]-[A-Z]+-\d+(?:\s*,\s*K[TP]-[A-Z]+-\d+)*)(?:\s+\(([^)]*)\))?(?:\s+\[([^\]]+)\])?(?:\s+→\s*(.+))?\s*$/;
1425
- var CHAINED_FROM_ID_RE = /chained-from\s+(K[TP]-[A-Z]+-\d+)/i;
1426
- var ALLOWED_TAGS = /* @__PURE__ */ new Set([
1427
- "planned",
1428
- "recalled",
1429
- "chained-from",
1430
- "dismissed",
1431
- "none"
1432
- ]);
1433
- function parseTag(rawTag) {
1434
- if (!rawTag) return "none";
1435
- const head = rawTag.trim().split(/[\s:]+/)[0].toLowerCase();
1436
- return ALLOWED_TAGS.has(head) ? head : "none";
1437
- }
1438
- function parseContractTail(tail) {
1439
- const result = { operators: [], skip_reason: null };
1440
- if (!tail) return result;
1441
- const tokens = tail.trim().split(/\s+/).filter((t) => t.length > 0);
1442
- for (const token of tokens) {
1443
- const skipMatch = token.match(/^skip:(.+)$/i);
1444
- if (skipMatch) {
1445
- if (result.skip_reason === null) result.skip_reason = skipMatch[1];
1446
- continue;
1447
- }
1448
- const notEditMatch = token.match(/^!edit:(.+)$/i);
1449
- if (notEditMatch) {
1450
- result.operators.push({ kind: "not_edit", target: notEditMatch[1] });
1451
- continue;
1452
- }
1453
- const opMatch = token.match(/^(edit|require|forbid):(.+)$/i);
1454
- if (opMatch) {
1455
- result.operators.push({
1456
- kind: opMatch[1].toLowerCase(),
1457
- target: opMatch[2]
1458
- });
1459
- }
1460
- }
1461
- return result;
1462
- }
1463
- function parseLine(line) {
1464
- const trimmed = line.trim();
1465
- if (trimmed.length === 0) return null;
1466
- if (SENTINEL_RE.test(trimmed)) {
1467
- return { ids: [], tag: "none", commitment: null };
2678
+ // src/text-tokenize.ts
2679
+ var CJK_CLASS = "\\u3400-\\u4dbf\\u4e00-\\u9fff\\uf900-\\ufaff\\u3040-\\u30ff\\uac00-\\ud7af";
2680
+ var RUN_RE = new RegExp(`[a-z0-9]+|[${CJK_CLASS}]+`, "gu");
2681
+ var CJK_FIRST_RE = new RegExp(`[${CJK_CLASS}]`, "u");
2682
+ function tokenize(text) {
2683
+ if (text.length === 0) {
2684
+ return [];
1468
2685
  }
1469
- const fullMatch = trimmed.match(FULL_RE);
1470
- if (fullMatch) {
1471
- const primaryIds = fullMatch[1].split(",").map((part) => part.trim()).filter((part) => part.length > 0);
1472
- if (primaryIds.some((id) => !ID_RE.test(id))) return null;
1473
- const rawTag = fullMatch[3];
1474
- const tag = parseTag(rawTag);
1475
- const chainedIds = [];
1476
- if (rawTag !== void 0) {
1477
- const chained = CHAINED_FROM_ID_RE.exec(rawTag);
1478
- if (chained !== null && ID_RE.test(chained[1])) {
1479
- chainedIds.push(chained[1]);
2686
+ const tokens = [];
2687
+ const lowered = text.toLowerCase();
2688
+ RUN_RE.lastIndex = 0;
2689
+ let match;
2690
+ while ((match = RUN_RE.exec(lowered)) !== null) {
2691
+ const run = match[0];
2692
+ if (CJK_FIRST_RE.test(run[0])) {
2693
+ if (run.length === 1) {
2694
+ tokens.push(run);
2695
+ } else {
2696
+ for (let i = 0; i < run.length - 1; i += 1) {
2697
+ tokens.push(run.slice(i, i + 2));
2698
+ }
1480
2699
  }
2700
+ } else {
2701
+ tokens.push(run);
1481
2702
  }
1482
- return {
1483
- ids: [...primaryIds, ...chainedIds],
1484
- tag,
1485
- commitment: parseContractTail(fullMatch[4])
1486
- };
1487
2703
  }
1488
- return null;
2704
+ return tokens;
1489
2705
  }
1490
- function parseCiteLine(raw) {
1491
- const result = {
1492
- cite_ids: [],
1493
- cite_tags: [],
1494
- cite_commitments: []
1495
- };
1496
- if (typeof raw !== "string") return result;
1497
- for (const line of raw.split(/\r?\n/)) {
1498
- const parsed = parseLine(line);
1499
- if (!parsed) continue;
1500
- result.cite_tags.push(parsed.tag);
1501
- for (const id of parsed.ids) {
1502
- result.cite_ids.push(id);
1503
- }
1504
- if (parsed.commitment !== null) {
1505
- for (let i = 0; i < parsed.ids.length; i += 1) {
1506
- result.cite_commitments.push(parsed.commitment);
1507
- }
1508
- }
2706
+
2707
+ // src/retrieval-budget.ts
2708
+ var PROFILES = {
2709
+ conservative: {
2710
+ topK: 12,
2711
+ payloadWarnBytes: 8192,
2712
+ payloadHardBytes: 32768,
2713
+ injectionChars: 1e3
2714
+ },
2715
+ balanced: {
2716
+ topK: 24,
2717
+ payloadWarnBytes: 16384,
2718
+ payloadHardBytes: 65536,
2719
+ injectionChars: 2e3
2720
+ },
2721
+ generous: {
2722
+ topK: 48,
2723
+ payloadWarnBytes: 32768,
2724
+ payloadHardBytes: 131072,
2725
+ injectionChars: 4e3
1509
2726
  }
1510
- return result;
2727
+ };
2728
+ var DEFAULT_RETRIEVAL_BUDGET_PROFILE = "balanced";
2729
+ function resolveRetrievalBudget(overrides) {
2730
+ const base = PROFILES[overrides?.profile ?? DEFAULT_RETRIEVAL_BUDGET_PROFILE];
2731
+ return {
2732
+ topK: overrides?.topK ?? base.topK,
2733
+ payloadWarnBytes: overrides?.payloadWarnBytes ?? base.payloadWarnBytes,
2734
+ payloadHardBytes: overrides?.payloadHardBytes ?? base.payloadHardBytes,
2735
+ injectionChars: overrides?.injectionChars ?? base.injectionChars
2736
+ };
2737
+ }
2738
+ function retrievalBudgetProfile(profile) {
2739
+ return PROFILES[profile];
1511
2740
  }
1512
2741
  export {
1513
2742
  AGENTS_META_IDENTITY_SOURCES,
@@ -1518,6 +2747,7 @@ export {
1518
2747
  BOOTSTRAP_MARKER_BEGIN,
1519
2748
  BOOTSTRAP_MARKER_END,
1520
2749
  BOOTSTRAP_REGEX,
2750
+ DEFAULT_RETRIEVAL_BUDGET_PROFILE,
1521
2751
  FabExtractKnowledgeInputSchema,
1522
2752
  FabExtractKnowledgeInputShape,
1523
2753
  FabExtractKnowledgeOutputSchema,
@@ -1525,26 +2755,50 @@ export {
1525
2755
  FabReviewInputShape,
1526
2756
  FabReviewOutputSchema,
1527
2757
  FabReviewOutputShape,
2758
+ GLOBAL_BINDINGS_DIR,
2759
+ GLOBAL_REF_PATTERN,
2760
+ GLOBAL_STATE_DIR,
1528
2761
  KNOWLEDGE_TEST_INDEX_SCHEMA_VERSION,
1529
2762
  KNOWLEDGE_TYPE_CODES,
2763
+ KNOWN_SCOPE_PREFIXES,
1530
2764
  KnowledgeEntryFrontmatterSchema,
1531
2765
  KnowledgeTypeSchema,
1532
2766
  LEGACY_KB_MARKER_BEGIN,
1533
2767
  LEGACY_KB_MARKER_END,
1534
2768
  LEGACY_KB_REGEX,
1535
2769
  LayerSchema,
2770
+ MCP_STORE_AWARE_CONTRACTS,
2771
+ MCP_STORE_AWARE_TOOLS,
1536
2772
  MaturitySchema,
1537
2773
  ONBOARD_SLOT_NAMES,
1538
2774
  ONBOARD_SLOT_TOTAL,
2775
+ PARITY_CLIENTS,
2776
+ PARITY_SURFACES,
2777
+ PERSONAL_SCOPE,
2778
+ PERSONAL_STORE_SENTINEL,
2779
+ PROJECT_ROOT_SIGNALS,
1539
2780
  PROPOSED_REASON_DESCRIPTIONS,
1540
2781
  PROTECTED_TOKENS,
1541
2782
  ProposedReasonSchema,
2783
+ REDACTION_PLACEHOLDER_PREFIX,
2784
+ ResolverNotImplementedError,
2785
+ SCOPE_COORDINATE_PATTERN,
2786
+ STORES_ROOT_DIR,
2787
+ STORE_GITIGNORE,
2788
+ STORE_KNOWLEDGE_TYPE_DIRS,
2789
+ STORE_LAYOUT,
2790
+ STORE_PENDING_DIR,
2791
+ STORE_RESOLVER_WARNING_CODES,
2792
+ STORE_UUID_PATTERN,
1542
2793
  StableIdSchema,
2794
+ UID_SEGMENT_PATTERN,
2795
+ addMountedStore,
1543
2796
  agentsIdentitySourceSchema,
1544
2797
  agentsLayerSchema,
1545
2798
  agentsMetaNodeSchema,
1546
2799
  agentsMetaSchema,
1547
2800
  agentsTopologyTypeSchema,
2801
+ aggregatePendingAcrossStores,
1548
2802
  aiLedgerEntrySchema,
1549
2803
  allocateKnowledgeId,
1550
2804
  annotateIntentRequestSchema,
@@ -1553,7 +2807,12 @@ export {
1553
2807
  archiveScanOutputSchema,
1554
2808
  assistantTurnObservedEventSchema,
1555
2809
  auditModeSchema,
2810
+ bindRequiredStore,
2811
+ bindingsSnapshotPath,
1556
2812
  bootstrapMarkerMigratedEventSchema,
2813
+ buildDebugBundle,
2814
+ buildFailureTrace,
2815
+ buildScanRecommendations,
1557
2816
  candidateFileEntrySchema,
1558
2817
  citeContractMetricsSchema,
1559
2818
  citeContractPolicyActivatedEventSchema,
@@ -1562,8 +2821,11 @@ export {
1562
2821
  citePolicyActivatedEventSchema,
1563
2822
  claudeHookPathMigratedEventSchema,
1564
2823
  claudeSkillPathMigratedEventSchema,
2824
+ clientCapabilitySnapshotEventSchema,
1565
2825
  clientPathsSchema,
1566
2826
  codexSkillPathMigratedEventSchema,
2827
+ createProjectRootResolver,
2828
+ createStoreResolver,
1567
2829
  createTranslator,
1568
2830
  defaultAgentsMetaCounters,
1569
2831
  defaultLayerFilterSchema,
@@ -1572,19 +2834,24 @@ export {
1572
2834
  deriveAgentsMetaLayer,
1573
2835
  deriveAgentsMetaStableId,
1574
2836
  deriveAgentsMetaTopologyType,
2837
+ detachMountedStore,
1575
2838
  detectNodeLocale,
1576
2839
  doctorRunEventSchema,
1577
2840
  driftDetectedEventSchema,
1578
2841
  editIntentCheckedEventSchema,
1579
2842
  enMessages,
2843
+ entryScopeMetadataSchema,
1580
2844
  eventLedgerEventSchema,
1581
2845
  eventLedgerTruncatedEventSchema,
1582
2846
  eventsRotatedEventSchema,
2847
+ explainStore,
1583
2848
  fabExtractKnowledgeAnnotations,
1584
2849
  fabReviewAnnotations,
1585
2850
  fabricConfigSchema,
1586
2851
  fabricEventSchema,
1587
2852
  fabricLanguageSchema,
2853
+ findMountedStore,
2854
+ findStoreExecutableViolations,
1588
2855
  forensicAssertionCoverageSchema,
1589
2856
  forensicAssertionSchema,
1590
2857
  forensicCodeSampleSchema,
@@ -1595,10 +2862,16 @@ export {
1595
2862
  forensicReportSchema,
1596
2863
  forensicSamplingBudgetSchema,
1597
2864
  forensicTopologySchema,
2865
+ formatGlobalRef,
1598
2866
  formatKnowledgeId,
1599
2867
  getPanelFieldByKey,
1600
2868
  getPanelFields,
2869
+ globalConfigSchema,
2870
+ globalRefSchema,
2871
+ hasSecrets,
1601
2872
  historyStateQuerySchema,
2873
+ hookSignalEmittedEventSchema,
2874
+ hookSurfaceEmittedEventSchema,
1602
2875
  humanLedgerEntrySchema,
1603
2876
  humanLockApproveRequestSchema,
1604
2877
  humanLockEntrySchema,
@@ -1612,8 +2885,11 @@ export {
1612
2885
  initContextSchema,
1613
2886
  initContextSourceEvidenceSchema,
1614
2887
  initScanCompletedEventSchema,
2888
+ initStore,
1615
2889
  installDiffAppliedEventSchema,
1616
2890
  isKnowledgeStableId,
2891
+ isPersonalLeakIntoSharedStore,
2892
+ isPersonalScope,
1617
2893
  knowledgeArchiveAttemptedEventSchema,
1618
2894
  knowledgeArchivedEventSchema,
1619
2895
  knowledgeConsumedEventSchema,
@@ -1630,6 +2906,7 @@ export {
1630
2906
  knowledgePromoteStartedEventSchema,
1631
2907
  knowledgePromotedEventSchema,
1632
2908
  knowledgeProposedEventSchema,
2909
+ knowledgeProvenanceSchema,
1633
2910
  knowledgeRejectedEventSchema,
1634
2911
  knowledgeScopeDegradedEventSchema,
1635
2912
  knowledgeSectionsAnnotations,
@@ -1646,36 +2923,93 @@ export {
1646
2923
  ledgerEntrySchema,
1647
2924
  ledgerQuerySchema,
1648
2925
  ledgerSourceSchema,
2926
+ lintCrossStoreReferences,
2927
+ listStoreKnowledge,
2928
+ llmJudgeRunEventSchema,
2929
+ localKnowledgeIdSchema,
1649
2930
  lockApprovedEventSchema,
1650
2931
  lockDriftEventSchema,
1651
2932
  mcpConfigMigratedEventSchema,
1652
2933
  mcpEventLedgerEventSchema,
1653
2934
  mcpPayloadLimitsSchema,
2935
+ mcpStdioTraceEventSchema,
1654
2936
  metaReconciledEventSchema,
1655
2937
  metaReconciledOnStartupEventSchema,
1656
2938
  metaUpdatedEventSchema,
2939
+ mountedStoreSchema,
2940
+ normalizeCiteTag,
1657
2941
  normalizeLocale,
1658
2942
  onboardSlotSchema,
2943
+ parityCapabilitySchema,
2944
+ parityClientExpectationSchema,
2945
+ parityClientSchema,
2946
+ parityMatrixSchema,
2947
+ paritySurfaceSchema,
1659
2948
  parseCiteLine,
2949
+ parseGlobalRef,
1660
2950
  parseKnowledgeId,
2951
+ payloadGuardObservedEventSchema,
1661
2952
  pendingAutoArchivedEventSchema,
1662
2953
  planContextAnnotations,
1663
2954
  planContextHintNarrowEntrySchema,
1664
2955
  planContextHintOutputSchema,
1665
2956
  planContextInputSchema,
1666
2957
  planContextOutputSchema,
2958
+ planContextTopKSchema,
2959
+ projectRootGoldenCaseSchema,
2960
+ projectRootGoldenFileSchema,
2961
+ projectRootResolutionSchema,
2962
+ projectRootSignalSchema,
2963
+ projectRootSignalsSchema,
2964
+ readBindingsSnapshot,
2965
+ readKnowledgeAcrossStores,
2966
+ readSetEntrySchema,
2967
+ readSetGoldenCaseSchema,
2968
+ readSetGoldenFileSchema,
2969
+ readStoreIdentity,
1667
2970
  reapplyCompletedEventSchema,
1668
2971
  recallAnnotations,
1669
2972
  recallInputSchema,
1670
2973
  recallOutputSchema,
2974
+ recognizeStoreDir,
2975
+ redactSecrets,
1671
2976
  relevanceMigrationRunEventSchema,
2977
+ requiredStoreEntrySchema,
2978
+ resolveCandidates,
1672
2979
  resolveFabricLocale,
2980
+ resolveRetrievalBudget,
2981
+ resolveStoreQualifiedId,
2982
+ resolvedBindingsSnapshotSchema,
2983
+ retrievalBudgetProfile,
1673
2984
  ruleDescriptionIndexItemSchema,
1674
2985
  ruleDescriptionSchema,
2986
+ scanForSecrets,
2987
+ scopeCoordinateSchema,
2988
+ scopeRoot,
2989
+ scrubRemoteUrl,
1675
2990
  selectionTokenTtlMsSchema,
1676
2991
  serveLockClearedEventSchema,
1677
2992
  sessionArchiveAttemptedEventSchema,
2993
+ skillInvocationCompletedEventSchema,
2994
+ skillInvocationStartedEventSchema,
2995
+ skillPhaseTransitionEventSchema,
2996
+ skillTriggerCandidateEventSchema,
2997
+ storeAwareEntrySchema,
2998
+ storeCountersSchema,
2999
+ storeIdentitySchema,
3000
+ storeKnowledgeTypeDir,
3001
+ storeReadSetSchema,
3002
+ storeRelativePath,
3003
+ storeResolveInputSchema,
3004
+ storeResolverWarningCodeSchema,
3005
+ storeResolverWarningSchema,
3006
+ storeUuidSchema,
1678
3007
  structuredWarningSchema,
3008
+ tokenize,
3009
+ uidSchema,
1679
3010
  withDerivedAgentsMetaNodeDefaults,
3011
+ writeBindingsSnapshot,
3012
+ writeTargetSchema,
3013
+ writtenToStoreSchema,
1680
3014
  zhCNMessages
1681
3015
  };