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