@sanctuary-framework/mcp-server 1.2.10 → 1.2.12

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/cli.cjs CHANGED
@@ -17480,6 +17480,616 @@ var init_sentinel_routes = __esm({
17480
17480
  FINDINGS_MAX_LIMIT = 500;
17481
17481
  }
17482
17482
  });
17483
+ function makeEntryId(auditEventId) {
17484
+ return crypto.createHash("sha256").update(auditEventId).digest("hex").slice(0, 32);
17485
+ }
17486
+ function optString(details, key) {
17487
+ if (!details) return null;
17488
+ const value = details[key];
17489
+ if (typeof value !== "string" || value.length === 0) return null;
17490
+ return value;
17491
+ }
17492
+ function auditEventIdFallback(audit) {
17493
+ return `${audit.timestamp}:${audit.operation}`;
17494
+ }
17495
+ function localHandoffSummary(details, sender, recipient) {
17496
+ const taskScope = optString(details, "task_scope");
17497
+ const reasonClass = optString(details, "reason_class");
17498
+ if (taskScope) {
17499
+ return `${sender} -> ${recipient} handoff: ${taskScope}`;
17500
+ }
17501
+ if (reasonClass) {
17502
+ return `${sender} -> ${recipient} handoff (${reasonClass})`;
17503
+ }
17504
+ return `${sender} -> ${recipient} handoff`;
17505
+ }
17506
+ function crossHarnessSummary(details, sender) {
17507
+ const policyRule = optString(details, "policy_rule_id");
17508
+ if (policyRule) {
17509
+ return `${sender} -> operator approval (${policyRule})`;
17510
+ }
17511
+ return `${sender} -> operator approval`;
17512
+ }
17513
+ var HANDOFF_LOG_OBSERVED_OPS, OBSERVED_OP_LIST, OPERATOR_PSEUDO_AGENT, DEFAULT_LIMIT, MAX_LIMIT, AUDIT_QUERY_LIMIT, HandoffLog, COORDINATION_VIEW_AUDIT_OPS;
17514
+ var init_handoff_log = __esm({
17515
+ "src/coordination/handoff-log.ts"() {
17516
+ HANDOFF_LOG_OBSERVED_OPS = {
17517
+ /** Tau-3 in-process coordination handoff. */
17518
+ LOCAL_HANDOFF: "v1.1_local_handoff",
17519
+ /** Upsilon-1 cross-harness approval (wrapped-agent -> operator). */
17520
+ CROSS_HARNESS_APPROVAL: "cross_harness_approval_aggregated"
17521
+ };
17522
+ OBSERVED_OP_LIST = [
17523
+ HANDOFF_LOG_OBSERVED_OPS.LOCAL_HANDOFF,
17524
+ HANDOFF_LOG_OBSERVED_OPS.CROSS_HARNESS_APPROVAL
17525
+ ];
17526
+ OPERATOR_PSEUDO_AGENT = "operator";
17527
+ DEFAULT_LIMIT = 50;
17528
+ MAX_LIMIT = 500;
17529
+ AUDIT_QUERY_LIMIT = 1e4;
17530
+ HandoffLog = class {
17531
+ auditLog;
17532
+ fortressId;
17533
+ constructor(opts) {
17534
+ this.auditLog = opts.auditLog;
17535
+ this.fortressId = opts.fortressId;
17536
+ }
17537
+ /** Stable fortress id this HandoffLog reads. */
17538
+ getFortressId() {
17539
+ return this.fortressId;
17540
+ }
17541
+ /**
17542
+ * Query handoffs in chronological-newest-first order. Filters
17543
+ * applied after normalization so the per-event-class shape
17544
+ * differences (sender field name, recipient inference) are handled
17545
+ * once.
17546
+ */
17547
+ async query(opts) {
17548
+ const limit = Math.min(opts.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
17549
+ const queryResult = await this.auditLog.query({
17550
+ ...opts.since !== void 0 ? { since: opts.since } : {},
17551
+ layer: "l2",
17552
+ limit: AUDIT_QUERY_LIMIT
17553
+ });
17554
+ const normalized = [];
17555
+ for (const entry of queryResult.entries) {
17556
+ if (!OBSERVED_OP_LIST.includes(entry.operation)) continue;
17557
+ const handoff = this.normalize(entry);
17558
+ if (!handoff) continue;
17559
+ if (opts.until && handoff.observed_at > opts.until) continue;
17560
+ if (opts.since && handoff.observed_at < opts.since) continue;
17561
+ if (opts.agent_id) {
17562
+ if (handoff.source_agent_id !== opts.agent_id && handoff.target_agent_id !== opts.agent_id) {
17563
+ continue;
17564
+ }
17565
+ }
17566
+ normalized.push(handoff);
17567
+ }
17568
+ normalized.sort((a, b) => a.observed_at < b.observed_at ? 1 : -1);
17569
+ return normalized.slice(0, limit);
17570
+ }
17571
+ /**
17572
+ * Look up a single entry by id. Returns the normalized entry +
17573
+ * the source audit payload for operator-facing detail rendering.
17574
+ * Returns null when no audit entry maps to the given id.
17575
+ */
17576
+ async getEntry(entryId) {
17577
+ const queryResult = await this.auditLog.query({
17578
+ layer: "l2",
17579
+ limit: AUDIT_QUERY_LIMIT
17580
+ });
17581
+ for (const audit of queryResult.entries) {
17582
+ if (!OBSERVED_OP_LIST.includes(audit.operation)) continue;
17583
+ const handoff = this.normalize(audit);
17584
+ if (!handoff) continue;
17585
+ if (handoff.entry_id === entryId) {
17586
+ return { entry: handoff, source_audit_entry: audit };
17587
+ }
17588
+ }
17589
+ return null;
17590
+ }
17591
+ normalize(audit) {
17592
+ const details = audit.details;
17593
+ if (audit.operation === HANDOFF_LOG_OBSERVED_OPS.LOCAL_HANDOFF) {
17594
+ const sender = optString(details, "sender_agent_id");
17595
+ const recipient = optString(details, "recipient_agent_id");
17596
+ if (!sender || !recipient || sender === recipient) return null;
17597
+ const auditEventId = optString(details, "event_id") ?? auditEventIdFallback(audit);
17598
+ return {
17599
+ entry_id: makeEntryId(auditEventId),
17600
+ audit_event_id: auditEventId,
17601
+ source_agent_id: sender,
17602
+ target_agent_id: recipient,
17603
+ observed_at: audit.timestamp,
17604
+ event_class: audit.operation,
17605
+ context_transfer_summary: localHandoffSummary(details, sender, recipient),
17606
+ workflow_link: null
17607
+ };
17608
+ }
17609
+ if (audit.operation === HANDOFF_LOG_OBSERVED_OPS.CROSS_HARNESS_APPROVAL) {
17610
+ const sender = optString(details, "source_harness") ?? optString(details, "source_agent_id");
17611
+ if (!sender) return null;
17612
+ const auditEventId = optString(details, "aggregator_id") ?? auditEventIdFallback(audit);
17613
+ return {
17614
+ entry_id: makeEntryId(auditEventId),
17615
+ audit_event_id: auditEventId,
17616
+ source_agent_id: sender,
17617
+ target_agent_id: OPERATOR_PSEUDO_AGENT,
17618
+ observed_at: audit.timestamp,
17619
+ event_class: audit.operation,
17620
+ context_transfer_summary: crossHarnessSummary(details, sender),
17621
+ workflow_link: null
17622
+ };
17623
+ }
17624
+ return null;
17625
+ }
17626
+ };
17627
+ COORDINATION_VIEW_AUDIT_OPS = {
17628
+ VIEW_OPENED: "operator_coordination_view_opened",
17629
+ ENTRY_DRILLED: "operator_handoff_entry_drilled"
17630
+ };
17631
+ }
17632
+ });
17633
+
17634
+ // src/coordination/context-transfer-extractor.ts
17635
+ async function extractContextTransferBreakdown(detail, deps = {}) {
17636
+ const pathA = tryStructuredPath(detail);
17637
+ if (pathA) return pathA;
17638
+ const pathB = tryCompositionPath(detail);
17639
+ if (pathB) return pathB;
17640
+ const pathC = tryHeuristicPath(detail);
17641
+ if (pathC.confidence >= 0.5 || !deps.substrateSelector) {
17642
+ return pathC;
17643
+ }
17644
+ const assist = await tryLlmAssistPath(detail, deps.substrateSelector);
17645
+ return assist ?? pathC;
17646
+ }
17647
+ function tryStructuredPath(detail) {
17648
+ const details = sourceDetails(detail.source_audit_entry);
17649
+ if (!details) return null;
17650
+ const transferredRaw = details["transferred"];
17651
+ const withheldRaw = details["withheld"];
17652
+ if (transferredRaw === void 0 && withheldRaw === void 0) return null;
17653
+ const transferred = parseExplicitContextItems(transferredRaw);
17654
+ const withheld = parseExplicitContextItems(withheldRaw);
17655
+ return {
17656
+ handoff_entry_id: detail.entry.entry_id,
17657
+ transferred,
17658
+ withheld,
17659
+ source: "structured",
17660
+ confidence: 1
17661
+ };
17662
+ }
17663
+ function tryCompositionPath(detail) {
17664
+ const op = detail.source_audit_entry.operation;
17665
+ if (!op.startsWith("composition_completed")) return null;
17666
+ const details = sourceDetails(detail.source_audit_entry);
17667
+ if (!details) return null;
17668
+ const receiptRaw = details["receipt"];
17669
+ const sourceStateRaw = details["source_state_snapshot"];
17670
+ if (receiptRaw === void 0) return null;
17671
+ const transferred = parseExplicitContextItems(receiptRaw);
17672
+ const withheld = [];
17673
+ if (Array.isArray(sourceStateRaw)) {
17674
+ const transferredKeys = new Set(
17675
+ transferred.map((t) => `${t.category}:${t.summary}`)
17676
+ );
17677
+ for (const item of parseExplicitContextItems(sourceStateRaw)) {
17678
+ const key = `${item.category}:${item.summary}`;
17679
+ if (!transferredKeys.has(key)) withheld.push(item);
17680
+ }
17681
+ }
17682
+ return {
17683
+ handoff_entry_id: detail.entry.entry_id,
17684
+ transferred,
17685
+ withheld,
17686
+ source: "composition",
17687
+ confidence: 0.9
17688
+ };
17689
+ }
17690
+ function tryHeuristicPath(detail) {
17691
+ const entry = detail.entry;
17692
+ const audit = detail.source_audit_entry;
17693
+ const details = sourceDetails(audit);
17694
+ if (audit.operation === "cross_harness_approval_aggregated") {
17695
+ const ruleId = optString2(details, "policy_rule_id");
17696
+ if (ruleId) {
17697
+ const category = categoryFromPolicyRuleId(ruleId);
17698
+ const summary = `${ruleId} (${entry.source_agent_id} -> operator)`;
17699
+ return {
17700
+ handoff_entry_id: entry.entry_id,
17701
+ transferred: [
17702
+ {
17703
+ category,
17704
+ summary: truncate(summary, SUMMARY_MAX_CHARS),
17705
+ size_hint: "minimal"
17706
+ }
17707
+ ],
17708
+ withheld: [],
17709
+ source: "heuristic",
17710
+ confidence: 0.5
17711
+ };
17712
+ }
17713
+ }
17714
+ if (audit.operation === "v1.1_local_handoff") {
17715
+ const reasonClass = optString2(details, "reason_class");
17716
+ const newStatus = optString2(details, "new_status");
17717
+ const previousStatus = optString2(details, "previous_status");
17718
+ const transferred = [];
17719
+ const withheld = [];
17720
+ if (newStatus === "denied" || newStatus === "failed") {
17721
+ withheld.push({
17722
+ category: "other",
17723
+ summary: truncate(
17724
+ `handoff ${newStatus}${reasonClass ? ` (${reasonClass})` : ""}: ${entry.source_agent_id} -> ${entry.target_agent_id}`,
17725
+ SUMMARY_MAX_CHARS
17726
+ ),
17727
+ size_hint: "minimal"
17728
+ });
17729
+ } else if (newStatus === "accepted" || newStatus === "completed") {
17730
+ transferred.push({
17731
+ category: "other",
17732
+ summary: truncate(
17733
+ `handoff ${newStatus}${previousStatus ? ` (from ${previousStatus})` : ""}: ${entry.source_agent_id} -> ${entry.target_agent_id}`,
17734
+ SUMMARY_MAX_CHARS
17735
+ ),
17736
+ size_hint: "small"
17737
+ });
17738
+ } else {
17739
+ transferred.push({
17740
+ category: "other",
17741
+ summary: truncate(
17742
+ `handoff ${entry.source_agent_id} -> ${entry.target_agent_id}${newStatus ? ` (${newStatus})` : ""}`,
17743
+ SUMMARY_MAX_CHARS
17744
+ ),
17745
+ size_hint: "minimal"
17746
+ });
17747
+ }
17748
+ return {
17749
+ handoff_entry_id: entry.entry_id,
17750
+ transferred,
17751
+ withheld,
17752
+ source: "heuristic",
17753
+ confidence: reasonClass || newStatus ? 0.5 : 0.3
17754
+ };
17755
+ }
17756
+ return {
17757
+ handoff_entry_id: entry.entry_id,
17758
+ transferred: [
17759
+ {
17760
+ category: "other",
17761
+ summary: truncate(
17762
+ `handoff ${entry.source_agent_id} -> ${entry.target_agent_id}`,
17763
+ SUMMARY_MAX_CHARS
17764
+ ),
17765
+ size_hint: "minimal"
17766
+ }
17767
+ ],
17768
+ withheld: [],
17769
+ source: "heuristic",
17770
+ confidence: 0.3
17771
+ };
17772
+ }
17773
+ async function tryLlmAssistPath(detail, selector) {
17774
+ const entry = detail.entry;
17775
+ const audit = detail.source_audit_entry;
17776
+ const probe = `event=${audit.operation} sender=${entry.source_agent_id} target=${entry.target_agent_id} summary=${entry.context_transfer_summary}`;
17777
+ try {
17778
+ const response = await selector.invokeClassify("sentinel-scoring", {
17779
+ kind: "classify",
17780
+ items: [probe],
17781
+ categories: [...CATEGORY_VALUES]
17782
+ });
17783
+ if (response.body.kind !== "classify") return null;
17784
+ const top = response.body.results[0];
17785
+ if (!top || !isCategory(top.category) || top.confidence < 0.4) {
17786
+ return null;
17787
+ }
17788
+ return {
17789
+ handoff_entry_id: entry.entry_id,
17790
+ transferred: [
17791
+ {
17792
+ category: top.category,
17793
+ summary: truncate(
17794
+ `LLM-classified handoff ${entry.source_agent_id} -> ${entry.target_agent_id}: ${top.category} (confidence ${top.confidence.toFixed(2)})`,
17795
+ SUMMARY_MAX_CHARS
17796
+ ),
17797
+ size_hint: "minimal"
17798
+ }
17799
+ ],
17800
+ withheld: [],
17801
+ source: "llm-assist",
17802
+ confidence: 0.6
17803
+ };
17804
+ } catch {
17805
+ return null;
17806
+ }
17807
+ }
17808
+ function sourceDetails(audit) {
17809
+ return audit.details;
17810
+ }
17811
+ function optString2(details, key) {
17812
+ if (!details) return null;
17813
+ const value = details[key];
17814
+ if (typeof value !== "string" || value.length === 0) return null;
17815
+ return value;
17816
+ }
17817
+ function isCategory(value) {
17818
+ return CATEGORY_VALUES.includes(value);
17819
+ }
17820
+ function truncate(s, cap) {
17821
+ return s.length <= cap ? s : `${s.slice(0, cap - 3)}...`;
17822
+ }
17823
+ function parseExplicitContextItems(raw) {
17824
+ if (raw === null || raw === void 0) return [];
17825
+ if (Array.isArray(raw)) {
17826
+ const out = [];
17827
+ for (const entry of raw) {
17828
+ if (typeof entry === "string") {
17829
+ out.push({
17830
+ category: "other",
17831
+ summary: truncate(entry, SUMMARY_MAX_CHARS),
17832
+ size_hint: "minimal"
17833
+ });
17834
+ continue;
17835
+ }
17836
+ if (entry && typeof entry === "object") {
17837
+ const obj = entry;
17838
+ const category = isCategoryValue(obj["category"]) ? obj["category"] : "other";
17839
+ const summary = typeof obj["summary"] === "string" ? truncate(obj["summary"], SUMMARY_MAX_CHARS) : "(unspecified)";
17840
+ const sizeHint = isSizeHintValue(obj["size_hint"]) ? obj["size_hint"] : "minimal";
17841
+ out.push({ category, summary, size_hint: sizeHint });
17842
+ }
17843
+ }
17844
+ return out;
17845
+ }
17846
+ if (typeof raw === "object" && raw !== null) {
17847
+ const out = [];
17848
+ for (const [k, v] of Object.entries(raw)) {
17849
+ const category = isCategoryValue(k) ? k : "other";
17850
+ if (Array.isArray(v)) {
17851
+ for (const item of v) {
17852
+ if (typeof item === "string") {
17853
+ out.push({
17854
+ category,
17855
+ summary: truncate(item, SUMMARY_MAX_CHARS),
17856
+ size_hint: "minimal"
17857
+ });
17858
+ }
17859
+ }
17860
+ }
17861
+ }
17862
+ return out;
17863
+ }
17864
+ return [];
17865
+ }
17866
+ function isCategoryValue(v) {
17867
+ return typeof v === "string" && CATEGORY_VALUES.includes(v);
17868
+ }
17869
+ function isSizeHintValue(v) {
17870
+ return typeof v === "string" && (v === "minimal" || v === "small" || v === "medium" || v === "large");
17871
+ }
17872
+ function categoryFromPolicyRuleId(ruleId) {
17873
+ const lower = ruleId.toLowerCase();
17874
+ if (lower.includes("credential") || lower.includes("broker_secret")) {
17875
+ return "credentials";
17876
+ }
17877
+ if (lower.includes("memory") || lower.includes("state_read")) {
17878
+ return "memory";
17879
+ }
17880
+ if (lower.includes("plan")) {
17881
+ return "plans";
17882
+ }
17883
+ if (lower.includes("export") || lower.includes("output")) {
17884
+ return "outputs";
17885
+ }
17886
+ if (lower.includes("audit")) {
17887
+ return "audit-refs";
17888
+ }
17889
+ return "other";
17890
+ }
17891
+ var SUMMARY_MAX_CHARS, CATEGORY_VALUES, CONTEXT_TRANSFER_AUDIT_OPS;
17892
+ var init_context_transfer_extractor = __esm({
17893
+ "src/coordination/context-transfer-extractor.ts"() {
17894
+ SUMMARY_MAX_CHARS = 240;
17895
+ CATEGORY_VALUES = [
17896
+ "memory",
17897
+ "credentials",
17898
+ "plans",
17899
+ "outputs",
17900
+ "audit-refs",
17901
+ "other"
17902
+ ];
17903
+ CONTEXT_TRANSFER_AUDIT_OPS = {
17904
+ DECODED: "operator_handoff_context_transfer_decoded"
17905
+ };
17906
+ }
17907
+ });
17908
+
17909
+ // src/coordination/handoff-routes.ts
17910
+ function writeJSON6(res, status, payload) {
17911
+ res.writeHead(status, {
17912
+ "Content-Type": "application/json",
17913
+ "Cache-Control": "no-store"
17914
+ });
17915
+ res.end(JSON.stringify(payload));
17916
+ }
17917
+ function parseLimit4(raw, defaultValue, max) {
17918
+ if (raw === null || raw === "") return defaultValue;
17919
+ const parsed = Number.parseInt(raw, 10);
17920
+ if (Number.isNaN(parsed) || parsed < 0) return defaultValue;
17921
+ return Math.min(parsed, max);
17922
+ }
17923
+ function matchEntryRoute2(path) {
17924
+ const prefix = `${COORDINATION_HANDOFFS_PREFIX}/`;
17925
+ if (!path.startsWith(prefix)) return null;
17926
+ const rest = path.slice(prefix.length);
17927
+ if (rest.length === 0 || rest === "stream") return null;
17928
+ if (rest.includes("/")) return null;
17929
+ return { entryId: decodeURIComponent(rest) };
17930
+ }
17931
+ async function handleStream3(deps, res) {
17932
+ res.writeHead(200, {
17933
+ "Content-Type": "text/event-stream",
17934
+ "Cache-Control": "no-cache, no-transform",
17935
+ Connection: "keep-alive",
17936
+ "X-Accel-Buffering": "no"
17937
+ });
17938
+ const snapshot = await deps.handoffLog.query({ limit: 50 });
17939
+ res.write(
17940
+ `event: handoff_snapshot
17941
+ data: ${JSON.stringify({ entries: snapshot })}
17942
+
17943
+ `
17944
+ );
17945
+ const unsubscribe = deps.events.subscribe((entry) => {
17946
+ try {
17947
+ res.write(
17948
+ `event: handoff_added
17949
+ data: ${JSON.stringify(entry)}
17950
+
17951
+ `
17952
+ );
17953
+ } catch {
17954
+ }
17955
+ });
17956
+ const keepAlive = setInterval(() => {
17957
+ try {
17958
+ res.write(": keepalive\n\n");
17959
+ } catch {
17960
+ }
17961
+ }, 25e3);
17962
+ const cleanup = () => {
17963
+ clearInterval(keepAlive);
17964
+ unsubscribe();
17965
+ };
17966
+ res.on("close", cleanup);
17967
+ res.on("error", cleanup);
17968
+ }
17969
+ async function handleCoordinationRoute(deps, req, res) {
17970
+ const host = req.headers.host || "localhost";
17971
+ const url = new URL(req.url ?? "/", `http://${host}`);
17972
+ const method = (req.method ?? "GET").toUpperCase();
17973
+ const path = url.pathname;
17974
+ if (path !== COORDINATION_API_PREFIX && !path.startsWith(`${COORDINATION_API_PREFIX}/`)) {
17975
+ return false;
17976
+ }
17977
+ const checkAuth = authMiddleware(deps.authConfig);
17978
+ if (!checkAuth(req, res, url)) return true;
17979
+ try {
17980
+ if (method === "GET" && path === `${COORDINATION_HANDOFFS_PREFIX}/stream`) {
17981
+ await handleStream3(deps, res);
17982
+ return true;
17983
+ }
17984
+ if (method === "GET" && path === COORDINATION_HANDOFFS_PREFIX) {
17985
+ const limit = parseLimit4(
17986
+ url.searchParams.get("limit"),
17987
+ COORDINATION_LIST_DEFAULT_LIMIT,
17988
+ COORDINATION_LIST_MAX_LIMIT
17989
+ );
17990
+ const since = url.searchParams.get("since") ?? void 0;
17991
+ const until = url.searchParams.get("until") ?? void 0;
17992
+ const agentId = url.searchParams.get("agent_id") ?? void 0;
17993
+ const entries = await deps.handoffLog.query({
17994
+ limit,
17995
+ ...since !== void 0 ? { since } : {},
17996
+ ...until !== void 0 ? { until } : {},
17997
+ ...agentId !== void 0 ? { agent_id: agentId } : {}
17998
+ });
17999
+ deps.auditLog.append(
18000
+ "l2",
18001
+ COORDINATION_VIEW_AUDIT_OPS.VIEW_OPENED,
18002
+ deps.operatorId,
18003
+ {
18004
+ fortress_id: deps.handoffLog.getFortressId(),
18005
+ result_count: entries.length,
18006
+ ...since !== void 0 ? { since } : {},
18007
+ ...until !== void 0 ? { until } : {},
18008
+ ...agentId !== void 0 ? { agent_id: agentId } : {}
18009
+ }
18010
+ );
18011
+ writeJSON6(res, 200, { ok: true, data: { entries } });
18012
+ return true;
18013
+ }
18014
+ const entryMatch = matchEntryRoute2(path);
18015
+ if (method === "GET" && entryMatch) {
18016
+ const detail = await deps.handoffLog.getEntry(entryMatch.entryId);
18017
+ if (!detail) {
18018
+ writeJSON6(res, 404, { ok: false, error: "not_found" });
18019
+ return true;
18020
+ }
18021
+ deps.auditLog.append(
18022
+ "l2",
18023
+ COORDINATION_VIEW_AUDIT_OPS.ENTRY_DRILLED,
18024
+ deps.operatorId,
18025
+ {
18026
+ fortress_id: deps.handoffLog.getFortressId(),
18027
+ entry_id: detail.entry.entry_id,
18028
+ event_class: detail.entry.event_class,
18029
+ source_agent_id: detail.entry.source_agent_id,
18030
+ target_agent_id: detail.entry.target_agent_id
18031
+ }
18032
+ );
18033
+ let breakdown = null;
18034
+ try {
18035
+ breakdown = await extractContextTransferBreakdown(
18036
+ detail,
18037
+ deps.contextTransfer ?? {}
18038
+ );
18039
+ deps.auditLog.append(
18040
+ "l2",
18041
+ CONTEXT_TRANSFER_AUDIT_OPS.DECODED,
18042
+ deps.operatorId,
18043
+ {
18044
+ fortress_id: deps.handoffLog.getFortressId(),
18045
+ entry_id: detail.entry.entry_id,
18046
+ extractor_path: breakdown.source,
18047
+ confidence: breakdown.confidence,
18048
+ transferred_count: breakdown.transferred.length,
18049
+ withheld_count: breakdown.withheld.length
18050
+ }
18051
+ );
18052
+ } catch {
18053
+ }
18054
+ const responseData = breakdown !== null ? { ...detail, context_transfer_breakdown: breakdown } : detail;
18055
+ writeJSON6(res, 200, { ok: true, data: responseData });
18056
+ return true;
18057
+ }
18058
+ writeJSON6(res, 404, { ok: false, error: "not_found", path });
18059
+ return true;
18060
+ } catch (err) {
18061
+ const msg = err instanceof Error ? err.message : String(err);
18062
+ writeJSON6(res, 500, { ok: false, error: "internal", detail: msg });
18063
+ return true;
18064
+ }
18065
+ }
18066
+ var COORDINATION_API_PREFIX, COORDINATION_HANDOFFS_PREFIX, COORDINATION_LIST_DEFAULT_LIMIT, COORDINATION_LIST_MAX_LIMIT, HandoffEventBridge;
18067
+ var init_handoff_routes = __esm({
18068
+ "src/coordination/handoff-routes.ts"() {
18069
+ init_auth_middleware();
18070
+ init_handoff_log();
18071
+ init_context_transfer_extractor();
18072
+ COORDINATION_API_PREFIX = "/api/coordination";
18073
+ COORDINATION_HANDOFFS_PREFIX = "/api/coordination/handoffs";
18074
+ COORDINATION_LIST_DEFAULT_LIMIT = 50;
18075
+ COORDINATION_LIST_MAX_LIMIT = 500;
18076
+ HandoffEventBridge = class {
18077
+ listeners = /* @__PURE__ */ new Set();
18078
+ subscribe(listener) {
18079
+ this.listeners.add(listener);
18080
+ return () => this.listeners.delete(listener);
18081
+ }
18082
+ emit(entry) {
18083
+ for (const listener of this.listeners) {
18084
+ try {
18085
+ listener(entry);
18086
+ } catch {
18087
+ }
18088
+ }
18089
+ }
18090
+ };
18091
+ }
18092
+ });
17483
18093
  function isDashboardViewRoute(method, path) {
17484
18094
  if (method !== "GET") return false;
17485
18095
  return path === "/" || path === "/dashboard" || path === "/v1.0" || path === "/fortress" || path === "/events";
@@ -17495,6 +18105,7 @@ var init_dashboard = __esm({
17495
18105
  init_dispatch();
17496
18106
  init_approval_aggregator_routes();
17497
18107
  init_sentinel_routes();
18108
+ init_handoff_routes();
17498
18109
  SESSION_TTL_REMOTE_MS = 5 * 60 * 1e3;
17499
18110
  SESSION_TTL_LOCAL_MS = 24 * 60 * 60 * 1e3;
17500
18111
  MAX_SESSIONS = 1e3;
@@ -17569,6 +18180,17 @@ var init_dashboard = __esm({
17569
18180
  * dispatcher's audited paths.
17570
18181
  */
17571
18182
  sentinelDispatcher = null;
18183
+ /**
18184
+ * v1.3 WP-V1.3-3 Omega-1 Coordination Handoff Visualization.
18185
+ * Mounted additively at `/api/coordination/*` when set. Read-only
18186
+ * against the audit log; the only writes are operator-action audit
18187
+ * events (operator_coordination_view_opened,
18188
+ * operator_handoff_entry_drilled).
18189
+ */
18190
+ handoffLog = null;
18191
+ handoffEventBridge = null;
18192
+ handoffAuditLog = null;
18193
+ handoffOperatorId = null;
17572
18194
  constructor(config) {
17573
18195
  this.config = config;
17574
18196
  this.authToken = config.auth_token;
@@ -17636,6 +18258,18 @@ var init_dashboard = __esm({
17636
18258
  setSentinelDispatcher(dispatcher) {
17637
18259
  this.sentinelDispatcher = dispatcher;
17638
18260
  }
18261
+ /**
18262
+ * v1.3 WP-V1.3-3 Omega-1: bind the Coordination handoff log +
18263
+ * event bridge + audit log + operator id. Once set, requests to
18264
+ * `/api/coordination/*` route through `handleCoordinationRoute`.
18265
+ * Pass `null` for any field to detach.
18266
+ */
18267
+ setHandoffLog(opts) {
18268
+ this.handoffLog = opts.handoffLog;
18269
+ this.handoffEventBridge = opts.eventBridge ?? null;
18270
+ this.handoffAuditLog = opts.auditLog ?? null;
18271
+ this.handoffOperatorId = opts.operatorId ?? null;
18272
+ }
17639
18273
  /**
17640
18274
  * v1.3 WP-V1.3-10 dispatch entry point. Called from `handleRequest`
17641
18275
  * before the legacy approval route table. Returns true when served.
@@ -17674,6 +18308,30 @@ var init_dashboard = __esm({
17674
18308
  res
17675
18309
  );
17676
18310
  }
18311
+ /**
18312
+ * v1.3 WP-V1.3-3 Omega-1 dispatch entry point. Routes
18313
+ * `/api/coordination/*` requests through the coordination router
18314
+ * when a HandoffLog has been bound. Returns true when served.
18315
+ */
18316
+ async dispatchCoordination(req, res) {
18317
+ if (!this.handoffLog || !this.handoffEventBridge || !this.handoffAuditLog) {
18318
+ return false;
18319
+ }
18320
+ return handleCoordinationRoute(
18321
+ {
18322
+ authConfig: {
18323
+ loopbackAutoAuth: this._autoAuthLocalhost,
18324
+ ...this.authToken !== void 0 ? { authToken: this.authToken } : {}
18325
+ },
18326
+ handoffLog: this.handoffLog,
18327
+ auditLog: this.handoffAuditLog,
18328
+ operatorId: this.handoffOperatorId ?? this.identityManager?.getPrimaryIdentityId() ?? "operator_dashboard",
18329
+ events: this.handoffEventBridge
18330
+ },
18331
+ req,
18332
+ res
18333
+ );
18334
+ }
17677
18335
  /**
17678
18336
  * v1.1 dispatch entry point. Called from `handleRequest` before the
17679
18337
  * legacy route table. Returns true when the request was served by v1.1
@@ -18073,6 +18731,18 @@ var init_dashboard = __esm({
18073
18731
  });
18074
18732
  return;
18075
18733
  }
18734
+ if (this.handoffLog && url.pathname.startsWith(COORDINATION_API_PREFIX)) {
18735
+ this.dispatchCoordination(req, res).then((handled) => {
18736
+ if (handled) return;
18737
+ this.handleLegacyRequest(req, res, url, method);
18738
+ }).catch(() => {
18739
+ if (!res.headersSent) {
18740
+ res.writeHead(500, { "Content-Type": "application/json" });
18741
+ res.end(JSON.stringify({ error: "Internal server error" }));
18742
+ }
18743
+ });
18744
+ return;
18745
+ }
18076
18746
  if (this.v11Bindings) {
18077
18747
  this.dispatchV11(req, res, url, method).then((handled) => {
18078
18748
  if (handled) return;
@@ -21939,15 +22609,52 @@ var init_sentinel_dispatcher = __esm({
21939
22609
  };
21940
22610
  }
21941
22611
  });
22612
+ var init_classifier_state_store = __esm({
22613
+ "src/anomaly-detection/classifier-state-store.ts"() {
22614
+ init_encryption();
22615
+ init_key_derivation();
22616
+ init_encoding();
22617
+ }
22618
+ });
22619
+
22620
+ // src/anomaly-detection/classifiers/cusum.ts
22621
+ var CUSUM_CLASSIFIER_ID;
22622
+ var init_cusum = __esm({
22623
+ "src/anomaly-detection/classifiers/cusum.ts"() {
22624
+ init_classifier_state_store();
22625
+ CUSUM_CLASSIFIER_ID = "cusum";
22626
+ }
22627
+ });
22628
+
22629
+ // src/anomaly-detection/classifiers/psi.ts
22630
+ var PSI_CLASSIFIER_ID;
22631
+ var init_psi = __esm({
22632
+ "src/anomaly-detection/classifiers/psi.ts"() {
22633
+ init_classifier_state_store();
22634
+ PSI_CLASSIFIER_ID = "psi";
22635
+ }
22636
+ });
21942
22637
 
21943
22638
  // src/anomaly-detection/types.ts
21944
22639
  var init_types4 = __esm({
21945
22640
  "src/anomaly-detection/types.ts"() {
21946
22641
  }
21947
22642
  });
22643
+ function classifierSpecificAuditOp(classifierId) {
22644
+ if (classifierId === null) return null;
22645
+ if (classifierId === CUSUM_CLASSIFIER_ID) {
22646
+ return ANOMALY_AUDIT_OPS.CUSUM_DRIFT_DETECTED;
22647
+ }
22648
+ if (classifierId === PSI_CLASSIFIER_ID) {
22649
+ return ANOMALY_AUDIT_OPS.PSI_DISTRIBUTION_SHIFT_DETECTED;
22650
+ }
22651
+ return null;
22652
+ }
21948
22653
  var ANOMALY_AUDIT_OPS, DEFAULT_TICK_INTERVAL_MS2, AnomalyPipelineDispatcher;
21949
22654
  var init_anomaly_pipeline = __esm({
21950
22655
  "src/anomaly-detection/anomaly-pipeline.ts"() {
22656
+ init_cusum();
22657
+ init_psi();
21951
22658
  init_types4();
21952
22659
  ANOMALY_AUDIT_OPS = {
21953
22660
  DETECTOR_REGISTERED: "anomaly_detector_registered",
@@ -21955,7 +22662,15 @@ var init_anomaly_pipeline = __esm({
21955
22662
  FINDING_EMITTED: "anomaly_finding_emitted",
21956
22663
  EVALUATION_FAILED: "anomaly_evaluation_failed",
21957
22664
  TRAINING_COMPLETED: "anomaly_training_completed",
21958
- TRAINING_FAILED: "anomaly_training_failed"
22665
+ TRAINING_FAILED: "anomaly_training_failed",
22666
+ /** Chi-2: a classifier was attached to an existing detector. */
22667
+ CLASSIFIER_SUBSCRIBED: "anomaly_classifier_subscribed",
22668
+ /** Chi-2: a classifier was detached from an existing detector. */
22669
+ CLASSIFIER_UNSUBSCRIBED: "anomaly_classifier_unsubscribed",
22670
+ /** Chi-2: CUSUM-flagged mean-shift drift on a per-agent feature. */
22671
+ CUSUM_DRIFT_DETECTED: "anomaly_cusum_drift_detected",
22672
+ /** Chi-2: PSI-flagged distribution shift on a per-agent feature. */
22673
+ PSI_DISTRIBUTION_SHIFT_DETECTED: "anomaly_psi_distribution_shift_detected"
21959
22674
  };
21960
22675
  DEFAULT_TICK_INTERVAL_MS2 = 6e4;
21961
22676
  AnomalyPipelineDispatcher = class {
@@ -22046,34 +22761,37 @@ var init_anomaly_pipeline = __esm({
22046
22761
  const stamped = await this.routeFinding(detectorId, raw);
22047
22762
  findings.push(stamped);
22048
22763
  }
22049
- try {
22050
- const trainingResult = await detector.classifier.train();
22051
- this.auditLog.append(
22052
- "l2",
22053
- ANOMALY_AUDIT_OPS.TRAINING_COMPLETED,
22054
- this.identityId,
22055
- {
22056
- detector_id: detectorId,
22057
- classifier_id: detector.classifier.classifierId,
22058
- trained_at: trainingResult.trained_at,
22059
- sample_count: trainingResult.sample_count,
22060
- agent_count: trainingResult.agent_count,
22061
- fortress_id: this.fortressId
22062
- }
22063
- );
22064
- } catch (trainErr) {
22065
- const message = trainErr instanceof Error ? trainErr.message : String(trainErr);
22066
- this.auditLog.append(
22067
- "l2",
22068
- ANOMALY_AUDIT_OPS.TRAINING_FAILED,
22069
- this.identityId,
22070
- {
22071
- detector_id: detectorId,
22072
- error_message: message,
22073
- fortress_id: this.fortressId
22074
- },
22075
- "failure"
22076
- );
22764
+ for (const classifier of detector.getAllClassifiers()) {
22765
+ try {
22766
+ const trainingResult = await classifier.train();
22767
+ this.auditLog.append(
22768
+ "l2",
22769
+ ANOMALY_AUDIT_OPS.TRAINING_COMPLETED,
22770
+ this.identityId,
22771
+ {
22772
+ detector_id: detectorId,
22773
+ classifier_id: classifier.classifierId,
22774
+ trained_at: trainingResult.trained_at,
22775
+ sample_count: trainingResult.sample_count,
22776
+ agent_count: trainingResult.agent_count,
22777
+ fortress_id: this.fortressId
22778
+ }
22779
+ );
22780
+ } catch (trainErr) {
22781
+ const message = trainErr instanceof Error ? trainErr.message : String(trainErr);
22782
+ this.auditLog.append(
22783
+ "l2",
22784
+ ANOMALY_AUDIT_OPS.TRAINING_FAILED,
22785
+ this.identityId,
22786
+ {
22787
+ detector_id: detectorId,
22788
+ classifier_id: classifier.classifierId,
22789
+ error_message: message,
22790
+ fortress_id: this.fortressId
22791
+ },
22792
+ "failure"
22793
+ );
22794
+ }
22077
22795
  }
22078
22796
  } catch (err) {
22079
22797
  const message = err instanceof Error ? err.message : String(err);
@@ -22136,6 +22854,7 @@ var init_anomaly_pipeline = __esm({
22136
22854
  observed_at: raw.observed_at || this.now().toISOString()
22137
22855
  };
22138
22856
  await this.findingStore.saveFinding(stamped);
22857
+ const classifierId = stamped.details["classifier_id"] ?? null;
22139
22858
  this.auditLog.append(
22140
22859
  "l2",
22141
22860
  ANOMALY_AUDIT_OPS.FINDING_EMITTED,
@@ -22145,13 +22864,79 @@ var init_anomaly_pipeline = __esm({
22145
22864
  finding_id: stamped.finding_id,
22146
22865
  severity: stamped.severity,
22147
22866
  anomaly_score: stamped.details["anomaly_score"] ?? null,
22867
+ ...classifierId !== null ? { classifier_id: classifierId } : {},
22148
22868
  ...stamped.agent_id !== void 0 ? { agent_id: stamped.agent_id } : {},
22149
22869
  fortress_id: this.fortressId
22150
22870
  }
22151
22871
  );
22872
+ const specificOp = classifierSpecificAuditOp(classifierId);
22873
+ if (specificOp !== null) {
22874
+ this.auditLog.append("l2", specificOp, this.identityId, {
22875
+ detector_id: detectorId,
22876
+ finding_id: stamped.finding_id,
22877
+ severity: stamped.severity,
22878
+ anomaly_score: stamped.details["anomaly_score"] ?? null,
22879
+ ...stamped.agent_id !== void 0 ? { agent_id: stamped.agent_id } : {},
22880
+ fortress_id: this.fortressId
22881
+ });
22882
+ }
22152
22883
  this.emit({ type: "finding", finding: stamped });
22153
22884
  return stamped;
22154
22885
  }
22886
+ /**
22887
+ * Chi-2: attach an additional classifier to an already-registered
22888
+ * detector. Emits ANOMALY_CLASSIFIER_SUBSCRIBED on success. The
22889
+ * factory is called with the fortress AnomalyContext so the
22890
+ * classifier can build its own state-store binding. Idempotent: a
22891
+ * second call with the same classifierId returns false.
22892
+ */
22893
+ async addClassifierToDetector(detectorId, factory) {
22894
+ const detector = this.detectors.get(detectorId);
22895
+ if (!detector) return false;
22896
+ const context = {
22897
+ fortressId: this.fortressId,
22898
+ auditLog: this.auditLog,
22899
+ storage: this.storage,
22900
+ masterKey: this.masterKey,
22901
+ now: this.now
22902
+ };
22903
+ const classifier = factory(context);
22904
+ const added = detector.addClassifier(classifier);
22905
+ if (!added) return false;
22906
+ this.auditLog.append(
22907
+ "l2",
22908
+ ANOMALY_AUDIT_OPS.CLASSIFIER_SUBSCRIBED,
22909
+ this.identityId,
22910
+ {
22911
+ detector_id: detectorId,
22912
+ classifier_id: classifier.classifierId,
22913
+ fortress_id: this.fortressId
22914
+ }
22915
+ );
22916
+ return true;
22917
+ }
22918
+ /**
22919
+ * Chi-2: detach an additional classifier from an already-registered
22920
+ * detector. Emits ANOMALY_CLASSIFIER_UNSUBSCRIBED on success. The
22921
+ * primary classifier cannot be detached (returns false).
22922
+ */
22923
+ async removeClassifierFromDetector(detectorId, classifierId) {
22924
+ const detector = this.detectors.get(detectorId);
22925
+ if (!detector) return false;
22926
+ const removed = detector.removeClassifier(classifierId);
22927
+ if (!removed) return false;
22928
+ this.auditLog.append(
22929
+ "l2",
22930
+ ANOMALY_AUDIT_OPS.CLASSIFIER_UNSUBSCRIBED,
22931
+ this.identityId,
22932
+ {
22933
+ detector_id: detectorId,
22934
+ classifier_id: classifierId,
22935
+ fortress_id: this.fortressId
22936
+ }
22937
+ );
22938
+ return true;
22939
+ }
22155
22940
  emit(event) {
22156
22941
  for (const listener of this.listeners) {
22157
22942
  try {
@@ -22428,7 +23213,7 @@ function extractInterAgentEvents(entries) {
22428
23213
  if (!sender) continue;
22429
23214
  out.push({
22430
23215
  sender,
22431
- recipient: OPERATOR_PSEUDO_AGENT,
23216
+ recipient: OPERATOR_PSEUDO_AGENT2,
22432
23217
  timestampMs: Date.parse(entry.timestamp),
22433
23218
  auditId: `${entry.timestamp}:${entry.operation}`
22434
23219
  });
@@ -22442,7 +23227,7 @@ function optionalString(details, key) {
22442
23227
  if (typeof value !== "string" || value.length === 0) return null;
22443
23228
  return value;
22444
23229
  }
22445
- var CROSS_AGENT_CHATTER_SENTINEL_ID, WARN_SIGMA2, ALERT_SIGMA2, BASELINE_WINDOWS2, QUERY_LIMIT2, MULTI_NEW_PARTNER_ALERT_THRESHOLD, OPERATOR_PSEUDO_AGENT, HANDOFF_OP, CROSS_HARNESS_OPS, CrossAgentChatterWatcher;
23230
+ var CROSS_AGENT_CHATTER_SENTINEL_ID, WARN_SIGMA2, ALERT_SIGMA2, BASELINE_WINDOWS2, QUERY_LIMIT2, MULTI_NEW_PARTNER_ALERT_THRESHOLD, OPERATOR_PSEUDO_AGENT2, HANDOFF_OP, CROSS_HARNESS_OPS, CrossAgentChatterWatcher;
22446
23231
  var init_cross_agent_chatter_watcher = __esm({
22447
23232
  "src/sentinel/sentinels/cross-agent-chatter-watcher.ts"() {
22448
23233
  init_sentinel();
@@ -22452,7 +23237,7 @@ var init_cross_agent_chatter_watcher = __esm({
22452
23237
  BASELINE_WINDOWS2 = 7;
22453
23238
  QUERY_LIMIT2 = 1e4;
22454
23239
  MULTI_NEW_PARTNER_ALERT_THRESHOLD = 3;
22455
- OPERATOR_PSEUDO_AGENT = "operator";
23240
+ OPERATOR_PSEUDO_AGENT2 = "operator";
22456
23241
  HANDOFF_OP = "v1.1_local_handoff";
22457
23242
  CROSS_HARNESS_OPS = /* @__PURE__ */ new Set([
22458
23243
  "cross_harness_approval_aggregated",
@@ -25514,7 +26299,7 @@ function createBridgeCommitment(outcome, identity, identityEncryptionKey, includ
25514
26299
  const now = (/* @__PURE__ */ new Date()).toISOString();
25515
26300
  const canonicalBytes = canonicalize2(outcome);
25516
26301
  const canonicalString = new TextDecoder().decode(canonicalBytes);
25517
- const sha25611 = createCommitment(canonicalString);
26302
+ const sha25612 = createCommitment(canonicalString);
25518
26303
  let pedersenData;
25519
26304
  if (includePedersen && Number.isInteger(outcome.rounds) && outcome.rounds >= 0) {
25520
26305
  const pedersen = createPedersenCommitment(outcome.rounds);
@@ -25526,7 +26311,7 @@ function createBridgeCommitment(outcome, identity, identityEncryptionKey, includ
25526
26311
  const commitmentPayload = {
25527
26312
  bridge_commitment_id: commitmentId,
25528
26313
  session_id: outcome.session_id,
25529
- sha256_commitment: sha25611.commitment,
26314
+ sha256_commitment: sha25612.commitment,
25530
26315
  terms_hash: outcome.terms_hash,
25531
26316
  committer_did: identity.did,
25532
26317
  committed_at: now,
@@ -25537,8 +26322,8 @@ function createBridgeCommitment(outcome, identity, identityEncryptionKey, includ
25537
26322
  return {
25538
26323
  bridge_commitment_id: commitmentId,
25539
26324
  session_id: outcome.session_id,
25540
- sha256_commitment: sha25611.commitment,
25541
- blinding_factor: sha25611.blinding_factor,
26325
+ sha256_commitment: sha25612.commitment,
26326
+ blinding_factor: sha25612.blinding_factor,
25542
26327
  committer_did: identity.did,
25543
26328
  signature: toBase64url(signature),
25544
26329
  pedersen_commitment: pedersenData,
@@ -39461,6 +40246,141 @@ ${redactedItems.map((r) => `- ${r.redacted}`).join("\n")}`,
39461
40246
  }
39462
40247
  });
39463
40248
 
40249
+ // src/query-anonymity/header-strip.ts
40250
+ function stripHeaders(headers) {
40251
+ const stripped = {};
40252
+ const removed = [];
40253
+ for (const [name, value] of Object.entries(headers)) {
40254
+ const lower = name.toLowerCase();
40255
+ if (REQUIRED_HEADER_SET.has(lower)) {
40256
+ stripped[name] = value;
40257
+ continue;
40258
+ }
40259
+ const reason = STRIP_REASON_BY_NAME.get(lower);
40260
+ if (reason !== void 0) {
40261
+ removed.push({ name, reason });
40262
+ continue;
40263
+ }
40264
+ stripped[name] = value;
40265
+ }
40266
+ return { stripped, removed };
40267
+ }
40268
+ function defeatUndiciDefaultsInto(headers) {
40269
+ if (headers["user-agent"] === void 0 && headers["User-Agent"] === void 0) {
40270
+ headers["User-Agent"] = "";
40271
+ }
40272
+ if (headers["accept-language"] === void 0 && headers["Accept-Language"] === void 0) {
40273
+ headers["Accept-Language"] = "";
40274
+ }
40275
+ return headers;
40276
+ }
40277
+ function createAnonymizedFetch(baseFetch, onAudit) {
40278
+ const wrapped = async (input, init) => {
40279
+ const headers = normalizeHeadersInit(init?.headers);
40280
+ const result = stripHeaders(headers);
40281
+ defeatUndiciDefaultsInto(result.stripped);
40282
+ const preservedRequired = Object.keys(result.stripped).filter(
40283
+ (k) => REQUIRED_HEADER_SET.has(k.toLowerCase())
40284
+ );
40285
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
40286
+ const method = init?.method ?? (input instanceof Request ? input.method : "GET");
40287
+ if (onAudit) {
40288
+ onAudit({
40289
+ url,
40290
+ method,
40291
+ stripped_count: result.removed.length,
40292
+ removed: result.removed,
40293
+ required_preserved: preservedRequired
40294
+ });
40295
+ }
40296
+ return baseFetch(input, { ...init, headers: result.stripped });
40297
+ };
40298
+ return wrapped;
40299
+ }
40300
+ function normalizeHeadersInit(raw) {
40301
+ if (raw === void 0) return {};
40302
+ if (typeof Headers !== "undefined" && raw instanceof Headers) {
40303
+ const out = {};
40304
+ raw.forEach((value, key) => {
40305
+ out[key] = value;
40306
+ });
40307
+ return out;
40308
+ }
40309
+ if (Array.isArray(raw)) {
40310
+ const out = {};
40311
+ for (const [k, v] of raw) {
40312
+ if (k !== void 0 && v !== void 0) out[k] = v;
40313
+ }
40314
+ return out;
40315
+ }
40316
+ return { ...raw };
40317
+ }
40318
+ var QUERY_ANONYMITY_AUDIT_OPS, CANONICAL_STRIP_LIST, REQUIRED_HEADERS, REQUIRED_HEADER_SET, STRIP_REASON_BY_NAME;
40319
+ var init_header_strip = __esm({
40320
+ "src/query-anonymity/header-strip.ts"() {
40321
+ QUERY_ANONYMITY_AUDIT_OPS = {
40322
+ HEADERS_STRIPPED: "query_anonymity_headers_stripped"
40323
+ };
40324
+ CANONICAL_STRIP_LIST = [
40325
+ // Browser / runtime fingerprinting.
40326
+ { name: "user-agent", reason: "user-agent" },
40327
+ { name: "sec-ch-ua", reason: "fingerprintable-extension" },
40328
+ { name: "sec-ch-ua-mobile", reason: "fingerprintable-extension" },
40329
+ { name: "sec-ch-ua-platform", reason: "fingerprintable-extension" },
40330
+ { name: "sec-ch-ua-platform-version", reason: "fingerprintable-extension" },
40331
+ { name: "sec-ch-ua-arch", reason: "fingerprintable-extension" },
40332
+ { name: "sec-ch-ua-bitness", reason: "fingerprintable-extension" },
40333
+ { name: "sec-ch-ua-model", reason: "fingerprintable-extension" },
40334
+ { name: "sec-ch-ua-full-version-list", reason: "fingerprintable-extension" },
40335
+ // Locale fingerprint.
40336
+ { name: "accept-language", reason: "locale-fingerprint" },
40337
+ // Request-origin leak.
40338
+ { name: "referer", reason: "leaking-network-info" },
40339
+ { name: "referrer-policy", reason: "leaking-network-info" },
40340
+ { name: "origin", reason: "leaking-network-info" },
40341
+ // Forwarded-by / IP-derived network info.
40342
+ { name: "via", reason: "leaking-network-info" },
40343
+ { name: "forwarded", reason: "leaking-network-info" },
40344
+ { name: "x-forwarded-for", reason: "leaking-network-info" },
40345
+ { name: "x-real-ip", reason: "leaking-network-info" },
40346
+ { name: "x-client-ip", reason: "leaking-network-info" },
40347
+ // DNT / GPC are technically anti-tracking signals but they
40348
+ // themselves form a fingerprint (operators who set DNT=1 are a
40349
+ // smaller subset). Strip to keep the substrate ignorant of
40350
+ // operator preferences.
40351
+ { name: "dnt", reason: "unnecessary-metadata" },
40352
+ { name: "sec-gpc", reason: "unnecessary-metadata" }
40353
+ ];
40354
+ REQUIRED_HEADERS = [
40355
+ "authorization",
40356
+ "content-type",
40357
+ "content-length",
40358
+ "host",
40359
+ "accept",
40360
+ "x-api-key",
40361
+ // Anthropic API auth
40362
+ "anthropic-version",
40363
+ // Anthropic API contract version
40364
+ "anthropic-beta",
40365
+ // optional Anthropic beta opt-in
40366
+ "openai-organization",
40367
+ // optional OpenAI org id
40368
+ "x-stainless-package-version",
40369
+ // allowed for Anthropic + OpenAI SDK contract compat
40370
+ "x-goog-api-key",
40371
+ // Google AI Studio
40372
+ "x-goog-user-project"
40373
+ // Google AI Studio
40374
+ ];
40375
+ REQUIRED_HEADER_SET = new Set(
40376
+ REQUIRED_HEADERS.map((h) => h.toLowerCase())
40377
+ );
40378
+ STRIP_REASON_BY_NAME = new Map(
40379
+ CANONICAL_STRIP_LIST.map((h) => [h.name.toLowerCase(), h.reason])
40380
+ );
40381
+ }
40382
+ });
40383
+
39464
40384
  // src/intelligence/substrates/hybrid/per-surface-router.ts
39465
40385
  function resolveHybridChoice(rules, surface) {
39466
40386
  if (!rules) return null;
@@ -39582,6 +40502,7 @@ var init_selector = __esm({
39582
40502
  init_local();
39583
40503
  init_venice();
39584
40504
  init_frontier();
40505
+ init_header_strip();
39585
40506
  init_per_surface_router();
39586
40507
  DISABLED_CAPABILITY = {
39587
40508
  summarize: false,
@@ -39616,7 +40537,21 @@ var init_selector = __esm({
39616
40537
  this.auditLog = cfg.auditLog;
39617
40538
  this.identityId = cfg.identityId;
39618
40539
  this.redactor = cfg.redactor ?? IDENTITY_REDACTOR;
39619
- this.fetchImpl = cfg.fetchImpl;
40540
+ const baseFetch = cfg.fetchImpl ?? globalThis.fetch;
40541
+ this.fetchImpl = createAnonymizedFetch(baseFetch, (event) => {
40542
+ this.auditLog.append(
40543
+ "l2",
40544
+ QUERY_ANONYMITY_AUDIT_OPS.HEADERS_STRIPPED,
40545
+ this.identityId,
40546
+ {
40547
+ url: event.url,
40548
+ method: event.method,
40549
+ stripped_count: event.stripped_count,
40550
+ removed: event.removed,
40551
+ required_preserved: event.required_preserved
40552
+ }
40553
+ );
40554
+ });
39620
40555
  this.config = buildDefaultConfig();
39621
40556
  }
39622
40557
  /**
@@ -42660,6 +43595,19 @@ ${err.message}
42660
43595
  identityId: aggregatorIdentityId
42661
43596
  });
42662
43597
  anomalyDispatcher.start();
43598
+ const handoffLog = new HandoffLog({
43599
+ auditLog,
43600
+ fortressId: fortressIdForAggregator
43601
+ });
43602
+ const handoffEventBridge = new HandoffEventBridge();
43603
+ if (dashboard) {
43604
+ dashboard.setHandoffLog({
43605
+ handoffLog,
43606
+ eventBridge: handoffEventBridge,
43607
+ auditLog,
43608
+ operatorId: aggregatorIdentityId
43609
+ });
43610
+ }
42663
43611
  const policyTools = createPrincipalPolicyTools(policy, baseline, auditLog);
42664
43612
  const { tools: sanctuaryMetaTools } = createSanctuaryTools({
42665
43613
  config,
@@ -42857,6 +43805,8 @@ var init_src = __esm({
42857
43805
  init_sentinel_registry();
42858
43806
  init_sentinel_dispatcher();
42859
43807
  init_anomaly_pipeline();
43808
+ init_handoff_log();
43809
+ init_handoff_routes();
42860
43810
  init_sentinels();
42861
43811
  init_subscription_store();
42862
43812
  init_tools4();
@@ -44957,32 +45907,32 @@ endstream`;
44957
45907
  const offsets = new Array(totalObjects + 1).fill(0);
44958
45908
  const chunks = [];
44959
45909
  let bytePos = 0;
44960
- const write3 = (s) => {
45910
+ const write4 = (s) => {
44961
45911
  const buf = Buffer.from(s, "latin1");
44962
45912
  chunks.push(buf);
44963
45913
  bytePos += buf.length;
44964
45914
  };
44965
- write3("%PDF-1.4\n%\xE2\xE3\xCF\xD3\n");
45915
+ write4("%PDF-1.4\n%\xE2\xE3\xCF\xD3\n");
44966
45916
  for (let i = 1; i <= totalObjects; i++) {
44967
45917
  offsets[i] = bytePos;
44968
- write3(`${i} 0 obj
45918
+ write4(`${i} 0 obj
44969
45919
  ${objectBodies[i]}
44970
45920
  endobj
44971
45921
  `);
44972
45922
  }
44973
45923
  const xrefPos = bytePos;
44974
- write3(`xref
45924
+ write4(`xref
44975
45925
  0 ${totalObjects + 1}
44976
45926
  `);
44977
- write3("0000000000 65535 f \n");
45927
+ write4("0000000000 65535 f \n");
44978
45928
  for (let i = 1; i <= totalObjects; i++) {
44979
- write3(`${offsets[i].toString().padStart(10, "0")} 00000 n
45929
+ write4(`${offsets[i].toString().padStart(10, "0")} 00000 n
44980
45930
  `);
44981
45931
  }
44982
- write3(`trailer
45932
+ write4(`trailer
44983
45933
  << /Size ${totalObjects + 1} /Root 1 0 R >>
44984
45934
  `);
44985
- write3(`startxref
45935
+ write4(`startxref
44986
45936
  ${xrefPos}
44987
45937
  %%EOF
44988
45938
  `);
@@ -48253,6 +49203,365 @@ var init_sentinel2 = __esm({
48253
49203
  init_sentinels();
48254
49204
  }
48255
49205
  });
49206
+ async function issueDidWeb(opts) {
49207
+ if (!opts.authority_host || !HOST_RE.test(opts.authority_host)) {
49208
+ throw new Error(
49209
+ `did-web: authority_host '${opts.authority_host}' is not a valid DNS host`
49210
+ );
49211
+ }
49212
+ if (!FORTRESS_LABEL_RE.test(opts.fortress_id)) {
49213
+ throw new Error(
49214
+ `did-web: fortress_id '${opts.fortress_id}' is not a valid label`
49215
+ );
49216
+ }
49217
+ if (opts.agent_label !== void 0 && !AGENT_LABEL_RE.test(opts.agent_label)) {
49218
+ throw new Error(
49219
+ `did-web: agent_label '${opts.agent_label}' is not a valid label`
49220
+ );
49221
+ }
49222
+ if (opts.public_key.length !== 32) {
49223
+ throw new Error(
49224
+ `did-web: public_key must be exactly 32 bytes (Ed25519), got ${opts.public_key.length}`
49225
+ );
49226
+ }
49227
+ const did = buildDid(opts);
49228
+ const verificationMethodId = `${did}#key-1`;
49229
+ const verificationMethod = {
49230
+ id: verificationMethodId,
49231
+ type: "JsonWebKey2020",
49232
+ controller: did,
49233
+ publicKeyJwk: {
49234
+ kty: "OKP",
49235
+ crv: "Ed25519",
49236
+ x: toBase64url(opts.public_key)
49237
+ }
49238
+ };
49239
+ const didDocument = {
49240
+ "@context": [...DID_CONTEXT],
49241
+ id: did,
49242
+ verificationMethod: [verificationMethod],
49243
+ authentication: [verificationMethodId],
49244
+ assertionMethod: [verificationMethodId]
49245
+ };
49246
+ const now = (opts.now ?? (() => /* @__PURE__ */ new Date()))();
49247
+ return {
49248
+ did,
49249
+ did_document: didDocument,
49250
+ public_key: opts.public_key,
49251
+ created_at: now.toISOString(),
49252
+ authority_host: opts.authority_host,
49253
+ fortress_id: opts.fortress_id,
49254
+ ...opts.agent_label !== void 0 ? { agent_label: opts.agent_label } : {}
49255
+ };
49256
+ }
49257
+ function publishDidWebDocument(identifier, opts = {}) {
49258
+ const path = opts.publish_path ?? canonicalPublishPath(identifier);
49259
+ const artifact = canonicalSerializeDidDocument(identifier.did_document);
49260
+ const digest = sha256.sha256(stringToBytes(artifact));
49261
+ const url = `https://${identifier.authority_host}${path}`;
49262
+ return {
49263
+ url,
49264
+ publish_path: path,
49265
+ artifact,
49266
+ sha256: hashToString(digest)
49267
+ };
49268
+ }
49269
+ function buildDid(opts) {
49270
+ if (opts.agent_label === void 0) {
49271
+ return `did:web:${opts.authority_host}`;
49272
+ }
49273
+ return `did:web:${opts.authority_host}:fortress:${opts.fortress_id}:agent:${opts.agent_label}`;
49274
+ }
49275
+ function canonicalPublishPath(identifier) {
49276
+ if (identifier.agent_label === void 0) {
49277
+ return "/.well-known/did.json";
49278
+ }
49279
+ return `/fortress/${identifier.fortress_id}/agent/${identifier.agent_label}/did.json`;
49280
+ }
49281
+ function canonicalSerializeDidDocument(doc) {
49282
+ return JSON.stringify(
49283
+ {
49284
+ "@context": doc["@context"],
49285
+ id: doc.id,
49286
+ verificationMethod: doc.verificationMethod,
49287
+ authentication: doc.authentication,
49288
+ assertionMethod: doc.assertionMethod
49289
+ },
49290
+ null,
49291
+ 2
49292
+ );
49293
+ }
49294
+ var DID_CONTEXT, HOST_RE, FORTRESS_LABEL_RE, AGENT_LABEL_RE;
49295
+ var init_did_web = __esm({
49296
+ "src/recognition/did-web.ts"() {
49297
+ init_encoding();
49298
+ init_hashing();
49299
+ DID_CONTEXT = [
49300
+ "https://www.w3.org/ns/did/v1",
49301
+ "https://w3id.org/security/suites/jws-2020/v1"
49302
+ ];
49303
+ HOST_RE = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/i;
49304
+ FORTRESS_LABEL_RE = /^[a-zA-Z0-9_-]{1,64}$/;
49305
+ AGENT_LABEL_RE = /^[a-zA-Z0-9_-]{1,64}$/;
49306
+ }
49307
+ });
49308
+
49309
+ // src/cli/did-web.ts
49310
+ var did_web_exports = {};
49311
+ __export(did_web_exports, {
49312
+ runDidWebCommand: () => runDidWebCommand
49313
+ });
49314
+ function write3(stream, text) {
49315
+ stream.write(text);
49316
+ }
49317
+ function flagValue3(argv, name) {
49318
+ const i = argv.indexOf(name);
49319
+ if (i === -1) return void 0;
49320
+ return argv[i + 1];
49321
+ }
49322
+ function hasFlag3(argv, name) {
49323
+ return argv.includes(name);
49324
+ }
49325
+ function printUsage7(out) {
49326
+ write3(
49327
+ out,
49328
+ `Usage: sanctuary did-web <command> [options]
49329
+
49330
+ Commands:
49331
+ issue --authority-host <host> [--agent-label <label>] [--json]
49332
+ Generate a did:web identifier bound to the operator's
49333
+ fortress Ed25519 public key. Writes the DID Document
49334
+ artifact to <storage>/recognition/did-web.json and
49335
+ prints publication instructions for the operator's
49336
+ HTTPS server.
49337
+
49338
+ show [--json] Display the previously issued did:web identifier.
49339
+ Exits non-zero if none issued.
49340
+
49341
+ Options:
49342
+ --authority-host <host> HTTPS host the operator controls and will
49343
+ serve /.well-known/did.json from.
49344
+ --agent-label <label> Optional agent-scoped identifier (label-safe;
49345
+ alphanumeric + dash + underscore, 1-64 chars).
49346
+ --fortress <path> Override the storage path.
49347
+ --passphrase <val> Passphrase for master-key derivation.
49348
+ --json Output as JSON.
49349
+ --help, -h Show this help.
49350
+
49351
+ Castle-walking note: did:web resolution is outbound HTTPS by design.
49352
+ This CLI never opens an outbound socket. The opt-in surface is your
49353
+ choice to run "did-web issue" with --authority-host; the resulting
49354
+ artifact is yours to publish on your own infrastructure. Sanctuary
49355
+ does not phone home.
49356
+ `
49357
+ );
49358
+ }
49359
+ async function runDidWebCommand(args) {
49360
+ const argv = args.argv;
49361
+ const out = args.out ?? process.stdout;
49362
+ const err = args.err ?? process.stderr;
49363
+ const env = args.env ?? process.env;
49364
+ if (argv.length === 0 || hasFlag3(argv, "--help") || hasFlag3(argv, "-h")) {
49365
+ printUsage7(out);
49366
+ return 0;
49367
+ }
49368
+ const command = argv[0];
49369
+ if (command === "issue") {
49370
+ return await cmdIssue(argv.slice(1), out, err, env);
49371
+ }
49372
+ if (command === "show") {
49373
+ return await cmdShow3(argv.slice(1), out, err);
49374
+ }
49375
+ write3(err, `Unknown did-web command: ${command}
49376
+ `);
49377
+ write3(err, `Run "sanctuary did-web --help" for usage.
49378
+ `);
49379
+ return 2;
49380
+ }
49381
+ async function loadFortressIdentity(argv, env, err) {
49382
+ const fortressFlag = flagValue3(argv, "--fortress");
49383
+ if (fortressFlag) {
49384
+ process.env.SANCTUARY_STORAGE_PATH = fortressFlag;
49385
+ }
49386
+ const passphrase = flagValue3(argv, "--passphrase") ?? env.SANCTUARY_PASSPHRASE;
49387
+ const recoveryKey = env.SANCTUARY_RECOVERY_KEY;
49388
+ if (!passphrase && !recoveryKey) {
49389
+ write3(
49390
+ err,
49391
+ "Error: sanctuary did-web requires SANCTUARY_PASSPHRASE, --passphrase, or SANCTUARY_RECOVERY_KEY.\n"
49392
+ );
49393
+ return null;
49394
+ }
49395
+ const config = await loadConfig();
49396
+ await promises.mkdir(config.storage_path, { recursive: true, mode: 448 });
49397
+ const stateStoragePath = path.join(config.storage_path, "state");
49398
+ const storage = new FilesystemStorage(stateStoragePath);
49399
+ let masterKey;
49400
+ if (passphrase) {
49401
+ let existingParams;
49402
+ const raw = await storage.read("_meta", "key-params");
49403
+ if (raw) {
49404
+ existingParams = JSON.parse(bytesToString(raw));
49405
+ }
49406
+ const derivation = await deriveMasterKey(passphrase, existingParams);
49407
+ masterKey = derivation.key;
49408
+ } else if (recoveryKey) {
49409
+ masterKey = fromBase64url(recoveryKey);
49410
+ } else {
49411
+ return null;
49412
+ }
49413
+ const identityManager = new IdentityManager(storage, masterKey);
49414
+ const loadResult = await identityManager.load();
49415
+ if (loadResult.loaded === 0) {
49416
+ write3(
49417
+ err,
49418
+ loadResult.total > 0 ? "Error: identity files found but none could be decrypted. Wrong passphrase?\n" : "Error: no identities on this fortress yet. Run sanctuary wrap first.\n"
49419
+ );
49420
+ return null;
49421
+ }
49422
+ const primary = identityManager.getDefault();
49423
+ if (!primary) {
49424
+ write3(err, "Error: no primary identity on this fortress yet. Run sanctuary wrap first.\n");
49425
+ return null;
49426
+ }
49427
+ return {
49428
+ publicKey: fromBase64url(primary.public_key),
49429
+ identityId: primary.identity_id,
49430
+ storagePath: config.storage_path
49431
+ };
49432
+ }
49433
+ async function cmdIssue(argv, out, err, env) {
49434
+ const authorityHost = flagValue3(argv, "--authority-host");
49435
+ const agentLabel = flagValue3(argv, "--agent-label");
49436
+ const json = hasFlag3(argv, "--json");
49437
+ if (!authorityHost) {
49438
+ write3(err, "Error: --authority-host is required.\n");
49439
+ write3(err, "Example: sanctuary did-web issue --authority-host alice.example.com\n");
49440
+ return 1;
49441
+ }
49442
+ const snapshot = await loadFortressIdentity(argv, env, err);
49443
+ if (!snapshot) return 1;
49444
+ let identifier;
49445
+ try {
49446
+ identifier = await issueDidWeb({
49447
+ fortress_id: snapshot.identityId,
49448
+ authority_host: authorityHost,
49449
+ public_key: snapshot.publicKey,
49450
+ ...agentLabel !== void 0 ? { agent_label: agentLabel } : {}
49451
+ });
49452
+ } catch (e) {
49453
+ const message = e instanceof Error ? e.message : String(e);
49454
+ write3(err, `Error: ${message}
49455
+ `);
49456
+ return 1;
49457
+ }
49458
+ const artifact = publishDidWebDocument(identifier);
49459
+ const persistDir = path.join(snapshot.storagePath, "recognition");
49460
+ await promises.mkdir(persistDir, { recursive: true, mode: 448 });
49461
+ const persistPath = path.join(persistDir, "did-web.json");
49462
+ const record = {
49463
+ version: 1,
49464
+ identifier: {
49465
+ did: identifier.did,
49466
+ created_at: identifier.created_at,
49467
+ authority_host: identifier.authority_host,
49468
+ fortress_id: identifier.fortress_id,
49469
+ ...identifier.agent_label !== void 0 ? { agent_label: identifier.agent_label } : {},
49470
+ did_document: identifier.did_document
49471
+ },
49472
+ artifact: {
49473
+ url: artifact.url,
49474
+ publish_path: artifact.publish_path,
49475
+ sha256: artifact.sha256
49476
+ }
49477
+ };
49478
+ await promises.writeFile(persistPath, JSON.stringify(record, null, 2), {
49479
+ mode: 384
49480
+ });
49481
+ if (json) {
49482
+ write3(out, JSON.stringify(record, null, 2) + "\n");
49483
+ return 0;
49484
+ }
49485
+ write3(out, `did:web identifier issued.
49486
+ `);
49487
+ write3(out, ` DID: ${identifier.did}
49488
+ `);
49489
+ write3(out, ` Authority host: ${identifier.authority_host}
49490
+ `);
49491
+ write3(out, ` Created at: ${identifier.created_at}
49492
+ `);
49493
+ write3(out, ` Persisted: ${persistPath}
49494
+ `);
49495
+ write3(out, `
49496
+ Next step: publish the DID Document to your HTTPS host.
49497
+ `);
49498
+ write3(out, ` Target URL: ${artifact.url}
49499
+ `);
49500
+ write3(out, ` SHA-256: ${artifact.sha256}
49501
+ `);
49502
+ write3(out, ` Artifact: ${path.join(persistDir, "did.json")}
49503
+ `);
49504
+ const artifactPath = path.join(persistDir, "did.json");
49505
+ await promises.writeFile(artifactPath, artifact.artifact, { mode: 420 });
49506
+ write3(out, `
49507
+ Castle-walking note: this CLI never opens an outbound socket.
49508
+ `);
49509
+ write3(out, `Publishing the DID Document is your operation; serve the artifact
49510
+ `);
49511
+ write3(out, `at the URL above from infrastructure you control.
49512
+ `);
49513
+ return 0;
49514
+ }
49515
+ async function cmdShow3(argv, out, err, _env) {
49516
+ const json = hasFlag3(argv, "--json");
49517
+ const fortressFlag = flagValue3(argv, "--fortress");
49518
+ if (fortressFlag) {
49519
+ process.env.SANCTUARY_STORAGE_PATH = fortressFlag;
49520
+ }
49521
+ const config = await loadConfig();
49522
+ const persistPath = path.join(config.storage_path, "recognition", "did-web.json");
49523
+ let bytes;
49524
+ try {
49525
+ bytes = await promises.readFile(persistPath);
49526
+ } catch {
49527
+ write3(
49528
+ err,
49529
+ `No did:web identifier configured on this fortress.
49530
+ Run "sanctuary did-web issue --authority-host <host>" to issue one.
49531
+ `
49532
+ );
49533
+ return 1;
49534
+ }
49535
+ if (json) {
49536
+ write3(out, bytes.toString("utf-8"));
49537
+ if (!bytes.toString("utf-8").endsWith("\n")) write3(out, "\n");
49538
+ return 0;
49539
+ }
49540
+ const parsed = JSON.parse(bytes.toString("utf-8"));
49541
+ write3(out, `did:web identifier on this fortress:
49542
+ `);
49543
+ write3(out, ` DID: ${parsed.identifier.did}
49544
+ `);
49545
+ write3(out, ` Authority host: ${parsed.identifier.authority_host}
49546
+ `);
49547
+ write3(out, ` Created at: ${parsed.identifier.created_at}
49548
+ `);
49549
+ write3(out, ` Publish URL: ${parsed.artifact.url}
49550
+ `);
49551
+ write3(out, ` SHA-256: ${parsed.artifact.sha256}
49552
+ `);
49553
+ return 0;
49554
+ }
49555
+ var init_did_web2 = __esm({
49556
+ "src/cli/did-web.ts"() {
49557
+ init_filesystem();
49558
+ init_tools();
49559
+ init_key_derivation();
49560
+ init_encoding();
49561
+ init_config();
49562
+ init_did_web();
49563
+ }
49564
+ });
48256
49565
 
48257
49566
  // src/mcp/broker-server.ts
48258
49567
  var broker_server_exports = {};
@@ -49118,6 +50427,11 @@ async function main() {
49118
50427
  const code = await runSentinelCommand2({ argv: args.slice(1) });
49119
50428
  process.exit(code);
49120
50429
  }
50430
+ if (args[0] === "did-web") {
50431
+ const { runDidWebCommand: runDidWebCommand2 } = await Promise.resolve().then(() => (init_did_web2(), did_web_exports));
50432
+ const code = await runDidWebCommand2({ argv: args.slice(1) });
50433
+ process.exit(code);
50434
+ }
49121
50435
  if (args[0] === "broker-server") {
49122
50436
  const { openBroker: openBroker2 } = await Promise.resolve().then(() => (init_open(), open_exports));
49123
50437
  const { createBrokerMcpServer: createBrokerMcpServer2 } = await Promise.resolve().then(() => (init_broker_server(), broker_server_exports));