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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,12 +1,11 @@
1
1
  # @fenglimg/fabric-server
2
2
 
3
- Fabric MCP knowledge server. Runs over stdio transport and serves Claude Code, Cursor, and Codex CLI from a single `.fabric/` directory.
3
+ Fabric MCP knowledge server. Runs over stdio transport and serves Claude Code and Codex CLI from a single `.fabric/` directory.
4
4
 
5
5
  ## Tools exposed
6
6
 
7
- - `fab_plan_context` — neutral rule description index + selection token
8
- - `fab_get_knowledge_sections` — fetch full markdown bodies by stable_id
9
- - `fab_recall` — combined one-call recall (plan + sections), the rc.37+ default
7
+ - `fab_recall` — single-step recall: returns candidate descriptions + native read paths (no body delivery over MCP; read a body on demand via a native Read of the returned path)
8
+ - `fab_archive_scan` — scan recent work for archive-worthy knowledge candidates
10
9
  - `fab_extract_knowledge` — persist a pending knowledge entry
11
10
  - `fab_review` — list / approve / reject / modify / defer pending entries
12
11
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { AgentsMeta, KnowledgeTestIndex, AgentsLayer, AgentsTopologyType, KnowledgeType, Layer, StableId, AgentsMetaCounters, EventLedgerEventInput, EventLedgerEvent, RuleDescriptionIndexItem, LedgerEntry } from '@fenglimg/fabric-shared';
3
2
  import { FabExtractKnowledgeInput, FabExtractKnowledgeOutput, FabReviewInput, FabReviewOutput } from '@fenglimg/fabric-shared/schemas/api-contracts';
3
+ import { EventLedgerEventInput, EventLedgerEvent, RuleDescriptionIndexItem, LedgerEntry, AgentsMeta } from '@fenglimg/fabric-shared';
4
+ import { PayloadGuardOptions } from '@fenglimg/fabric-shared/node/mcp-payload-guard';
4
5
 
5
6
  interface InFlightTracker {
6
7
  enter(requestId: string): void;
@@ -22,6 +23,67 @@ declare function getLegacyLedgerPath(projectRoot: string): string;
22
23
  declare function getEventLedgerPath(projectRoot: string): string;
23
24
  declare function getMetricsLedgerPath(projectRoot: string): string;
24
25
 
26
+ type DoctorHealth = {
27
+ score: number;
28
+ grade: "A" | "B" | "C" | "D" | "F";
29
+ penalties: {
30
+ manual_errors: number;
31
+ fixable_errors: number;
32
+ warnings: number;
33
+ };
34
+ };
35
+
36
+ interface AlwaysActiveBody {
37
+ /** store-qualified id (`<alias>:<stableId>`). */
38
+ stable_id: string;
39
+ /** knowledge_type — one of ALWAYS_ACTIVE_TYPES. */
40
+ type: string;
41
+ layer: "team" | "personal";
42
+ /** description.summary — the overflow-degrade fallback when the body cannot
43
+ * fit the injection char budget (the budget is enforced hook-side, D10). */
44
+ summary: string;
45
+ /** frontmatter-stripped markdown body. */
46
+ body: string;
47
+ }
48
+ /**
49
+ * Collect the always-active (guidelines + models) entries from the project's
50
+ * read-set, project-filtered identically to recall (filterByActiveProject), with
51
+ * their frontmatter-stripped bodies. The SessionStart hook injects these bodies
52
+ * into the AI context and renders category counts for the on-demand remainder.
53
+ *
54
+ * Returns [] (never throws) on any read-set resolution failure — the SessionStart
55
+ * banner must degrade gracefully, never crash session start.
56
+ */
57
+ interface KnowledgeCensus {
58
+ /** knowledge_type → count (decisions/pitfalls/guidelines/models/processes). */
59
+ by_type: Record<string, number>;
60
+ by_layer: {
61
+ team: number;
62
+ personal: number;
63
+ project: number;
64
+ };
65
+ /** entries专属 to OTHER projects that filterByActiveProject removed. */
66
+ dropped_other_project: number;
67
+ /** kept (post-filter) total. */
68
+ total: number;
69
+ }
70
+ /**
71
+ * Build the read-set census (project-filtered counts + dropped-other-project).
72
+ * Reuses the cached read-set walk, so calling alongside buildAlwaysActiveBodies
73
+ * in one SessionStart fire costs a single walk. Never throws — degrades to an
74
+ * all-zero census so the banner stays renderable.
75
+ */
76
+ declare function buildKnowledgeCensus(projectRoot: string): Promise<KnowledgeCensus>;
77
+ declare function buildAlwaysActiveBodies(projectRoot: string): Promise<AlwaysActiveBody[]>;
78
+
79
+ interface UnboundProjectViolation {
80
+ /** The store already bound as the active write target. */
81
+ alias: string;
82
+ /** Which project-scope fields are absent: `project_id` and/or `active_project`. */
83
+ missing: string[];
84
+ }
85
+ declare function detectUnboundProject(projectRoot: string): UnboundProjectViolation | null;
86
+
25
87
  /**
26
88
  * O(1) in-memory increment for a named counter. Safe to call from any MCP
27
89
  * tool handler; no I/O happens until the next `flushMetrics()` call.
@@ -81,11 +143,15 @@ type MetricsRow = {
81
143
  counters: Record<string, number>;
82
144
  };
83
145
  /**
84
- * Canonical metric counter names used by the high-frequency emitters that
85
- * left events.jsonl as part of the rc.37 Wave B clean-slate. Centralized
86
- * here so the B5 hard-gate (`metric_event_in_jsonl`) can grep for these
87
- * exact strings and fail when one accidentally re-appears in the audit
88
- * ledger emit path.
146
+ * Canonical metric counter names. rc.37 Wave B added a metrics.jsonl counter
147
+ * rollup for each (the forward-compatible signal), but contrary to the
148
+ * original "these left events.jsonl" plan every one is ALSO still appended to
149
+ * the audit ledger as a structured event, because a doctor lint consumes its
150
+ * per-id / per-path payload (see LEDGER_DUAL_WRITE_METRIC_NAMES below). The
151
+ * promised counter-only cutover (rc.38+; tracked by the G11 invariant test) has
152
+ * not happened. Centralized here so the B5 hard-gate (`metric_event_in_jsonl`)
153
+ * can grep for these exact strings; the gate only flags names NOT in the
154
+ * dual-write allowlist below.
89
155
  */
90
156
  declare const METRIC_COUNTER_NAMES: {
91
157
  readonly knowledge_consumed: "knowledge_consumed";
@@ -113,7 +179,7 @@ type CiteCoverageReport = {
113
179
  marker_ts: number;
114
180
  marker_emitted_now: boolean;
115
181
  since_ts: number;
116
- client_filter: "cc" | "codex" | "cursor" | "all";
182
+ client_filter: "cc" | "codex" | "all";
117
183
  layer_filter?: "team" | "personal" | "all";
118
184
  metrics: {
119
185
  edits_touched: number;
@@ -162,7 +228,7 @@ type CiteCoverageReport = {
162
228
  };
163
229
  declare function runDoctorCiteCoverage(projectRoot: string, options: {
164
230
  since: number;
165
- client: "cc" | "codex" | "cursor" | "all";
231
+ client: "cc" | "codex" | "all";
166
232
  layer?: "team" | "personal" | "all";
167
233
  until?: number;
168
234
  recallWindowMs?: number;
@@ -250,15 +316,6 @@ type DoctorSummary = {
250
316
  payload_limits: DoctorPayloadLimits;
251
317
  health: DoctorHealth;
252
318
  };
253
- type DoctorHealth = {
254
- score: number;
255
- grade: "A" | "B" | "C" | "D" | "F";
256
- penalties: {
257
- manual_errors: number;
258
- fixable_errors: number;
259
- warnings: number;
260
- };
261
- };
262
319
  type DoctorReport = {
263
320
  status: DoctorStatus;
264
321
  checks: DoctorCheck[];
@@ -287,6 +344,7 @@ type DoctorApplyLintMutation = {
287
344
  type DoctorApplyLintReport = {
288
345
  changed: boolean;
289
346
  mutations: DoctorApplyLintMutation[];
347
+ warnings: DoctorIssue[];
290
348
  manual_errors: DoctorIssue[];
291
349
  aborted: boolean;
292
350
  abort_reason?: string;
@@ -296,6 +354,7 @@ type DoctorApplyLintReport = {
296
354
  declare function runDoctorReport(target: string): Promise<DoctorReport>;
297
355
  declare function runDoctorFix(target: string): Promise<DoctorFixReport>;
298
356
  declare function runDoctorApplyLint(target: string): Promise<DoctorApplyLintReport>;
357
+
299
358
  type EnrichDescriptionsMode = "auto" | "preview" | "readonly" | "interactive";
300
359
  type EnrichDescriptionsCandidate = {
301
360
  path: string;
@@ -421,10 +480,12 @@ interface ConflictLintReport {
421
480
  pairs: ConflictPair[];
422
481
  }
423
482
  /**
424
- * Load canonical knowledge entries with bodies from the agents.meta node index.
425
- * Skips pending/draft staging entries (conflict detection targets the curated
426
- * corpus) and any node missing a stable_id or knowledge_type. Bodies are read
427
- * best-effort an unreadable file contributes no entry.
483
+ * v2.2 W5 R6 (读侧 cutover): load canonical knowledge entries with bodies from
484
+ * the read-set STORES (cross-store on-the-fly) instead of the retired
485
+ * co-location agents.meta node index. Skips pending/draft staging entries
486
+ * (conflict detection targets the curated corpus) and any entry missing a
487
+ * knowledge_type. collectStoreCanonicalEntries already reads each store entry's
488
+ * body + parsed frontmatter and degrades to [] when no store is in the read-set.
428
489
  */
429
490
  declare function loadConflictEntries(projectRoot: string): Promise<ConflictEntry[]>;
430
491
  /**
@@ -441,85 +502,6 @@ declare function runDoctorConflictLint(projectRoot: string, opts?: {
441
502
  judge?: ConflictJudge;
442
503
  }): Promise<ConflictLintReport>;
443
504
 
444
- type KnowledgeMetaBuildSource = "doctor_fix" | "sync_meta";
445
- type KnowledgeMetaBuildResult = {
446
- meta: AgentsMeta;
447
- knowledgeTestIndex: KnowledgeTestIndex;
448
- changed: boolean;
449
- };
450
- type WriteKnowledgeMetaOptions = {
451
- source: KnowledgeMetaBuildSource;
452
- };
453
- /**
454
- * v2.0-rc.24 TASK-07: Load a Map<stable_id, knowledge_type> from the
455
- * project's `.fabric/agents.meta.json`. Consumed by the doctor cite-coverage
456
- * routing (TASK-08) to dispatch cites to the correct policy bucket
457
- * (decision/pitfall = strict contract / model = reference-only /
458
- * guideline+process = deferred to rc.25 LLM-judge). Cited ids absent from
459
- * this map fall into the `cite_id_unresolved` bucket.
460
- *
461
- * **Plural knowledge_type contract (rc.29 BUG-C1 unification):** the returned
462
- * map values are the PLURAL `KnowledgeType` enum (`"models" | "decisions" |
463
- * "guidelines" | "pitfalls" | "processes"`) — matching disk frontmatter,
464
- * filesystem layout, MCP I/O surface, and the canonical `KnowledgeTypeSchema`
465
- * exported from `@fenglimg/fabric-shared`. Legacy singular frontmatter is
466
- * normalized at parse time (see `SINGULAR_TO_PLURAL` in `parseFrontmatter`);
467
- * downstream callers (TASK-08 doctor) match against the plural enum.
468
- *
469
- * Both team (KT-*) and personal (KP-*) entries are included — they live in
470
- * the same `meta.nodes` map.
471
- *
472
- * Graceful on failure: a missing meta file, malformed JSON, or schema
473
- * validation failure all yield an empty Map (no throw). The doctor will then
474
- * surface every cite as `cite_id_unresolved`, which is the safe degraded
475
- * mode.
476
- */
477
- declare function loadKbIdTypeMap(projectRootInput: string): Promise<Map<string, KnowledgeType>>;
478
- declare function buildKnowledgeMeta(projectRootInput: string): Promise<KnowledgeMetaBuildResult>;
479
- declare function writeKnowledgeMeta(projectRootInput: string, options: WriteKnowledgeMetaOptions): Promise<KnowledgeMetaBuildResult>;
480
- declare function computeKnowledgeBasedAgentsMeta(projectRootInput: string, existingMeta?: AgentsMeta): Promise<AgentsMeta>;
481
- declare function computeKnowledgeTestIndex(projectRootInput: string, computedMeta: AgentsMeta, previousIndex?: KnowledgeTestIndex): Promise<KnowledgeTestIndex>;
482
- declare function deriveKnowledgeMetaLayer(relativePath: string): AgentsLayer;
483
- declare function deriveKnowledgeMetaTopologyType(relativePath: string): AgentsTopologyType;
484
- declare function isSameKnowledgeTestIndex(left: KnowledgeTestIndex, right: KnowledgeTestIndex): boolean;
485
- declare function stableStringify(value: unknown): string;
486
-
487
- /**
488
- * v2.0 KnowledgeIdAllocator
489
- *
490
- * Wraps the pure `allocateKnowledgeId` allocator with persistence: it reads
491
- * `agents.meta.json`, advances the counter for the requested (layer, type)
492
- * pair, and writes the updated meta atomically (write-to-tmp + rename) so
493
- * concurrent readers always see a consistent file.
494
- *
495
- * Counters are MONOTONIC across the lifetime of the meta file: deleting a
496
- * knowledge entry does NOT free its counter slot, so previously-allocated
497
- * stable_ids remain unique even after their files are removed.
498
- *
499
- * Key invariants:
500
- * - Counters envelope is initialized to zeros if absent (v1.x meta compat).
501
- * - Each allocate() call performs read → mutate → atomic-write in sequence.
502
- * - The returned id is guaranteed to differ from every previously-returned
503
- * id for the same meta path.
504
- */
505
- declare class KnowledgeIdAllocator {
506
- private readonly metaPath;
507
- constructor(metaPath: string);
508
- /**
509
- * Allocate the next stable_id for the given (layer, type) pair and persist
510
- * the advanced counter to `agents.meta.json`.
511
- */
512
- allocate(layer: Layer, type: KnowledgeType): Promise<StableId>;
513
- /**
514
- * Returns the current counters envelope, defaulting to all-zero slots when
515
- * the meta file is absent or pre-v2.0 (counters key missing).
516
- */
517
- getCounters(): Promise<AgentsMetaCounters>;
518
- private readMeta;
519
- private normalizeCounters;
520
- private writeMetaAtomic;
521
- }
522
-
523
505
  /**
524
506
  * Append-evidence-on-collision service for fab_extract_knowledge.
525
507
  *
@@ -606,11 +588,26 @@ type PlanContextInput = {
606
588
  target_paths?: string[];
607
589
  layer_filter?: "team" | "personal" | "both";
608
590
  include_related?: boolean;
591
+ /**
592
+ * Internal MCP presentation budget. When supplied by the tool layer,
593
+ * candidates are byte-trimmed before the selection token is cached so the
594
+ * token cannot reference candidates omitted from the response.
595
+ */
596
+ payload_budget?: PlanContextPayloadBudget;
597
+ };
598
+ type PlanContextPayloadWarning = {
599
+ code: string;
600
+ file?: string;
601
+ action_hint?: string;
602
+ };
603
+ type PlanContextPayloadBudget = {
604
+ limits?: PayloadGuardOptions;
605
+ warnings?: PlanContextPayloadWarning[];
606
+ trim_warning?: PlanContextPayloadWarning;
609
607
  };
610
608
  type RequirementProfile = {
611
609
  target_path: string;
612
610
  known_tech: string[];
613
- user_intent: string;
614
611
  detected_entities: string[];
615
612
  };
616
613
  type PlanContextEntry = {
@@ -629,6 +626,7 @@ type PlanContextResult = {
629
626
  stale: boolean;
630
627
  selection_token: string;
631
628
  entries: PlanContextEntry[];
629
+ intent?: string;
632
630
  candidates: RuleDescriptionIndexItem[];
633
631
  omitted_candidate_count?: number;
634
632
  preflight_diagnostics: PreflightDiagnostic[];
@@ -636,6 +634,10 @@ type PlanContextResult = {
636
634
  previous_revision_hash?: string;
637
635
  redirects?: Record<string, string>;
638
636
  related_appended?: Record<string, string>;
637
+ /** Internal service→tool signal; stripped before MCP output. */
638
+ payload_trimmed?: boolean;
639
+ /** Internal service→tool signal; stripped before MCP output. */
640
+ payload_over_budget?: boolean;
639
641
  };
640
642
  type SelectionTokenState = {
641
643
  token: string;
@@ -651,45 +653,33 @@ declare function readSelectionToken(token: string, now?: number): SelectionToken
651
653
 
652
654
  type RecallInput = PlanContextInput & {
653
655
  /**
654
- * Optional explicit set of stable_ids to fetch bodies for. When omitted,
655
- * fab_recall picks up every stable_id surfaced in the shared description
656
- * index (the common case after rc.37 selectable-filter removal). When
657
- * provided, filters the fetched body set to this intersection.
656
+ * Optional explicit set of stable_ids to SCOPE the returned read paths to.
657
+ * When omitted, `paths` carries one entry per surfaced candidate. The candidate
658
+ * DESCRIPTION index is always returned in full for discovery — `ids` only narrows
659
+ * which read paths are surfaced (e.g. `recall(ids)` when the agent already knows
660
+ * which entries it wants to Read). Stale (pre layer-flip) ids are redirect-rewritten
661
+ * before the match.
658
662
  */
659
663
  ids?: string[];
660
664
  /**
661
- * v2.2 MC1-recall-pack (W2-T4): when true, expand the fetched set with the
662
- * one-hop `related` graph neighbours (H2) of the selected entries that are
663
- * also present in the candidate index. Lets a scoped `ids` recall pull in the
664
- * connected knowledge without a second round-trip. No-op when `ids` is omitted
665
- * (every candidate is already fetched) or no related edges resolve in-corpus.
665
+ * When true, forwarded to planContext, which appends the one-hop `related` graph
666
+ * neighbours (H2) of the surfaced set to the candidate index (descriptions only —
667
+ * NO body). Their read paths are included in `paths` like any other candidate
668
+ * (W1-3 / KT-DEC-0031: surface the related id, do not fetch its body).
666
669
  */
667
670
  include_related?: boolean;
668
671
  };
669
- type RecallTruncation = {
670
- omitted_candidate_count: number;
671
- returned_candidate_count: number;
672
+ type RecallPath = {
673
+ stable_id: string;
674
+ path: string;
675
+ store?: {
676
+ alias: string;
677
+ };
672
678
  };
673
- type RecallResult = PlanContextResult & {
674
- rules: Array<{
675
- stable_id: string;
676
- level: "L0" | "L1" | "L2";
677
- path: string;
678
- body: string;
679
- store?: {
680
- alias: string;
681
- };
682
- }>;
683
- selected_stable_ids: string[];
684
- diagnostics: Array<{
685
- code: "missing_knowledge_metadata" | "unresolved_selected_id";
686
- severity: "warn";
687
- stable_id: string;
688
- message: string;
689
- }>;
679
+ type RecallResult = Omit<PlanContextResult, "selection_token" | "payload_trimmed" | "payload_over_budget"> & {
680
+ paths: RecallPath[];
690
681
  directive: string;
691
682
  next_steps?: string[];
692
- truncation?: RecallTruncation;
693
683
  };
694
684
  declare function recall(projectRoot: string, input: RecallInput): Promise<RecallResult>;
695
685
 
@@ -757,92 +747,6 @@ declare class ContextCache {
757
747
  }
758
748
  declare const contextCache: ContextCache;
759
749
 
760
- interface KnowledgeSyncOptions {
761
- mode?: "incremental" | "full";
762
- /** When true, invalid frontmatter throws RuleValidationError (default: false — collect as warning). */
763
- throwOnInvalidFrontmatter?: boolean;
764
- /**
765
- * v2.0.0-rc.29 TASK-005 (BUG-G1): when true, `ensureKnowledgeFresh`
766
- * synchronously follows a drift detection with a `reconcileKnowledge`
767
- * call to materialize the auto-heal (rewrite agents.meta.json + emit a
768
- * paired `knowledge_meta_auto_healed` event). Default false preserves
769
- * the rc.28 hot-path semantics where drift detection never blocks the
770
- * MCP read on a meta rebuild. Opt-in is intended for callers that can
771
- * tolerate ~tens-of-ms extra latency in exchange for the invariant
772
- * "every knowledge_drift_detected has a paired heal event in the same
773
- * tail window." Audit (BUG-G1) found 5/72 drifts healed on this repo
774
- * (~7%) because the hot path emitted detect-only events.
775
- */
776
- autoHealOnDrift?: boolean;
777
- }
778
- interface StructuredWarning {
779
- code: string;
780
- file: string;
781
- line?: number;
782
- action_hint: string;
783
- }
784
- /**
785
- * Granular ledger event shape for knowledge-sync operations.
786
- * These are returned in KnowledgeSyncReport and also appended to the event ledger
787
- * using the nearest available ledger event type (knowledge_drift_detected).
788
- * The shape below is what callers receive in `.events`.
789
- */
790
- interface KnowledgeSyncLedgerEvent {
791
- type: "rule_content_changed" | "rule_added" | "rule_removed";
792
- stable_id: string;
793
- path: string;
794
- prev_hash: string | null;
795
- new_hash: string | null;
796
- changed_fields: string[];
797
- source: "ensureKnowledgeFresh" | "reconcileKnowledge";
798
- }
799
- /** Alias so the public API says LedgerEvent (as documented). */
800
- type LedgerEvent = KnowledgeSyncLedgerEvent;
801
- interface KnowledgeSyncReport {
802
- status: "fresh" | "reconciled" | "errors";
803
- events: LedgerEvent[];
804
- warnings: StructuredWarning[];
805
- reconciled_files?: string[];
806
- }
807
- /**
808
- * Clear the knowledge-sync cooldown for a projectRoot so the next ensureKnowledgeFresh
809
- * call performs a real I/O scan. Called by the chokidar watcher when a rule
810
- * file changes (see http.ts handleCacheWatcherEvent).
811
- */
812
- declare function invalidateKnowledgeSyncCooldown(projectRoot: string): void;
813
- /**
814
- * Detects drift between disk and agents.meta.json, emits ledger events, and
815
- * invalidates the cache. Does NOT rewrite agents.meta.json. Optimised for
816
- * hot-path consumers (MCP tools).
817
- */
818
- declare function ensureKnowledgeFresh(projectRoot: string, opts?: KnowledgeSyncOptions): Promise<KnowledgeSyncReport>;
819
- interface ReconcileKnowledgeOptions {
820
- /**
821
- * Identifies who triggered the reconcile; controls which summary ledger event is written.
822
- *
823
- * v2.0.0-rc.23 TASK-005 (a-B): `auto-heal-description` added so plan_context
824
- * can drive a full reconcile when it detects nodes with `description === undefined`
825
- * (legacy meta drift the revision-hash gate cannot detect).
826
- *
827
- * v2.0.0-rc.27 TASK-001 (§2.9 root): `post-approve` / `post-modify` added so
828
- * `fab_review` approve/modify-layer-flip can drive an immediate meta rebuild
829
- * — without this the new entry's `nodes[id]` stays empty until the next
830
- * plan_context call's auto-heal, which leaves the entry undiscoverable in
831
- * the description_index window between approve and the next hint call.
832
- */
833
- trigger?: "startup" | "doctor" | "manual" | "auto-heal-description" | "auto-heal-after-drift" | "post-approve" | "post-modify";
834
- }
835
- /**
836
- * Full scan + rewrites agents.meta.json with ground-truth disk state + emits
837
- * ledger events. Used by startup (TASK-022) and doctor repair (TASK-023).
838
- * Returns reconciled_files listing all paths whose meta was updated.
839
- *
840
- * When `opts.trigger` is `'startup'`, a `meta_reconciled_on_startup` summary
841
- * ledger event is appended after per-file drift events. Other trigger values
842
- * append a `meta_reconciled` event. Omitting the trigger skips the summary.
843
- */
844
- declare function reconcileKnowledge(projectRoot: string, opts?: ReconcileKnowledgeOptions): Promise<KnowledgeSyncReport>;
845
-
846
750
  type LedgerSourceFilter = "ai" | "human";
847
751
  type StoredLedgerEntry = LedgerEntry & {
848
752
  id: string;
@@ -877,40 +781,6 @@ type RehydratedAgentsMetaSnapshot = {
877
781
  };
878
782
  declare function rehydrateAgentsMetaAt(projectRoot: string, target: RehydrateTarget): Promise<RehydratedAgentsMetaSnapshot>;
879
783
 
880
- declare function readAgentsMeta(projectRoot: string): Promise<AgentsMeta>;
881
-
882
- type KnowledgeEntryItem = {
883
- path: string;
884
- content: string;
885
- };
886
- type DescriptionStub = {
887
- path: string;
888
- description: string;
889
- };
890
- type HumanLockedNearby = {
891
- file: string;
892
- excerpt: string;
893
- };
894
- type KnowledgePayload = {
895
- L0: string;
896
- L1: KnowledgeEntryItem[];
897
- L2: KnowledgeEntryItem[];
898
- human_locked_nearby: HumanLockedNearby[];
899
- description_stubs?: DescriptionStub[];
900
- };
901
- type GetKnowledgeInput = {
902
- path: string;
903
- client_hash?: string;
904
- correlation_id?: string;
905
- session_id?: string;
906
- };
907
- type GetKnowledgeResult = {
908
- revision_hash: string;
909
- stale: boolean;
910
- rules: KnowledgePayload;
911
- };
912
- declare function getKnowledge(projectRoot: string, input: GetKnowledgeInput): Promise<GetKnowledgeResult>;
913
-
914
784
  /**
915
785
  * Shared constants used across the server package.
916
786
  */
@@ -953,4 +823,4 @@ interface ShutdownHandlerDeps {
953
823
  */
954
824
  declare function createShutdownHandler(deps: ShutdownHandlerDeps): () => void;
955
825
 
956
- export { AGENTS_MD_RESOURCE_URI, type ArchiveHistoryEntry, type ArchiveHistoryReport, type CiteCoverageReport, type ConflictEntry, type ConflictJudge, type ConflictLintReport, type ConflictPair, type ConflictVerdict, DEFAULT_CONFLICT_SIMILARITY_THRESHOLD, type DoctorApplyLintMutation, type DoctorApplyLintMutationKind, type DoctorApplyLintReport, type DoctorFixReport, type DoctorIssue, type DoctorReport, EVENT_LEDGER_PATH, type EnrichDescriptionsCandidate, type EnrichDescriptionsMode, type EnrichDescriptionsReport, FABRIC_SERVER_INSTRUCTIONS, type HistoryAllReport, type HistoryDayRow, type InFlightTracker, KnowledgeIdAllocator, type KnowledgeMetaBuildResult, type KnowledgeMetaBuildSource, type KnowledgeSyncLedgerEvent, type KnowledgeSyncOptions, type KnowledgeSyncReport, LEDGER_PATH, LEGACY_LEDGER_PATH, type LedgerEvent, METRICS_LEDGER_PATH, METRIC_COUNTER_NAMES, type MetricCounterName, type MetricsRow, type PlanContextInput, type PlanContextResult, type RecallInput, type RecallResult, type ReconcileKnowledgeOptions, type RequirementProfile, type SelectionTokenState, type ShutdownHandlerDeps, type StructuredWarning, type WriteKnowledgeMetaOptions, appendEventLedgerEvent, buildKnowledgeMeta, bumpCounter, computeKnowledgeBasedAgentsMeta, computeKnowledgeTestIndex, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, deriveKnowledgeMetaLayer, deriveKnowledgeMetaTopologyType, drainCounters, enrichDescriptions, ensureKnowledgeFresh, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getKnowledge, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, invalidateKnowledgeSyncCooldown, isSameKnowledgeTestIndex, lintConflicts, loadConflictEntries, loadKbIdTypeMap, pairSimilarity, planContext, readAgentsMeta, readEventLedger, readLedger, readMetrics, readSelectionToken, recall, reconcileKnowledge, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, stableStringify, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick, writeKnowledgeMeta };
826
+ export { AGENTS_MD_RESOURCE_URI, type AlwaysActiveBody, type ArchiveHistoryEntry, type ArchiveHistoryReport, type CiteCoverageReport, type ConflictEntry, type ConflictJudge, type ConflictLintReport, type ConflictPair, type ConflictVerdict, DEFAULT_CONFLICT_SIMILARITY_THRESHOLD, type DoctorApplyLintMutation, type DoctorApplyLintMutationKind, type DoctorApplyLintReport, type DoctorFixReport, type DoctorIssue, type DoctorReport, EVENT_LEDGER_PATH, type EnrichDescriptionsCandidate, type EnrichDescriptionsMode, type EnrichDescriptionsReport, FABRIC_SERVER_INSTRUCTIONS, type HistoryAllReport, type HistoryDayRow, type InFlightTracker, type KnowledgeCensus, LEDGER_PATH, LEGACY_LEDGER_PATH, METRICS_LEDGER_PATH, METRIC_COUNTER_NAMES, type MetricCounterName, type MetricsRow, type PlanContextInput, type PlanContextResult, type RecallInput, type RecallResult, type RequirementProfile, type SelectionTokenState, type ShutdownHandlerDeps, type UnboundProjectViolation, appendEventLedgerEvent, buildAlwaysActiveBodies, buildKnowledgeCensus, bumpCounter, contextCache, createFabricServer, createInFlightTracker, createShutdownHandler, detectUnboundProject, drainCounters, enrichDescriptions, extractKnowledge, findConflictCandidates, flushAndSyncEventLedger, flushMetrics, formatPreexistingRootMessage, getEventLedgerPath, getLedgerPath, getLegacyLedgerPath, getMetricsLedgerPath, lintConflicts, loadConflictEntries, pairSimilarity, planContext, readEventLedger, readLedger, readMetrics, readSelectionToken, recall, rehydrateAgentsMetaAt, resolveLedgerPaths, reviewKnowledge, runDoctorApplyLint, runDoctorArchiveHistory, runDoctorCiteCoverage, runDoctorConflictLint, runDoctorFix, runDoctorHistoryAll, runDoctorReport, startMetricsFlush, startRotationTick, startStdioServer, stopMetricsFlush, stopRotationTick };