@sanctuary-framework/mcp-server 1.2.11 → 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 +594 -31
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +594 -31
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +567 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +567 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -17631,6 +17631,281 @@ var init_handoff_log = __esm({
|
|
|
17631
17631
|
}
|
|
17632
17632
|
});
|
|
17633
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
|
+
|
|
17634
17909
|
// src/coordination/handoff-routes.ts
|
|
17635
17910
|
function writeJSON6(res, status, payload) {
|
|
17636
17911
|
res.writeHead(status, {
|
|
@@ -17755,7 +18030,29 @@ async function handleCoordinationRoute(deps, req, res) {
|
|
|
17755
18030
|
target_agent_id: detail.entry.target_agent_id
|
|
17756
18031
|
}
|
|
17757
18032
|
);
|
|
17758
|
-
|
|
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 });
|
|
17759
18056
|
return true;
|
|
17760
18057
|
}
|
|
17761
18058
|
writeJSON6(res, 404, { ok: false, error: "not_found", path });
|
|
@@ -17771,6 +18068,7 @@ var init_handoff_routes = __esm({
|
|
|
17771
18068
|
"src/coordination/handoff-routes.ts"() {
|
|
17772
18069
|
init_auth_middleware();
|
|
17773
18070
|
init_handoff_log();
|
|
18071
|
+
init_context_transfer_extractor();
|
|
17774
18072
|
COORDINATION_API_PREFIX = "/api/coordination";
|
|
17775
18073
|
COORDINATION_HANDOFFS_PREFIX = "/api/coordination/handoffs";
|
|
17776
18074
|
COORDINATION_LIST_DEFAULT_LIMIT = 50;
|
|
@@ -22311,15 +22609,52 @@ var init_sentinel_dispatcher = __esm({
|
|
|
22311
22609
|
};
|
|
22312
22610
|
}
|
|
22313
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
|
+
});
|
|
22314
22637
|
|
|
22315
22638
|
// src/anomaly-detection/types.ts
|
|
22316
22639
|
var init_types4 = __esm({
|
|
22317
22640
|
"src/anomaly-detection/types.ts"() {
|
|
22318
22641
|
}
|
|
22319
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
|
+
}
|
|
22320
22653
|
var ANOMALY_AUDIT_OPS, DEFAULT_TICK_INTERVAL_MS2, AnomalyPipelineDispatcher;
|
|
22321
22654
|
var init_anomaly_pipeline = __esm({
|
|
22322
22655
|
"src/anomaly-detection/anomaly-pipeline.ts"() {
|
|
22656
|
+
init_cusum();
|
|
22657
|
+
init_psi();
|
|
22323
22658
|
init_types4();
|
|
22324
22659
|
ANOMALY_AUDIT_OPS = {
|
|
22325
22660
|
DETECTOR_REGISTERED: "anomaly_detector_registered",
|
|
@@ -22327,7 +22662,15 @@ var init_anomaly_pipeline = __esm({
|
|
|
22327
22662
|
FINDING_EMITTED: "anomaly_finding_emitted",
|
|
22328
22663
|
EVALUATION_FAILED: "anomaly_evaluation_failed",
|
|
22329
22664
|
TRAINING_COMPLETED: "anomaly_training_completed",
|
|
22330
|
-
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"
|
|
22331
22674
|
};
|
|
22332
22675
|
DEFAULT_TICK_INTERVAL_MS2 = 6e4;
|
|
22333
22676
|
AnomalyPipelineDispatcher = class {
|
|
@@ -22418,34 +22761,37 @@ var init_anomaly_pipeline = __esm({
|
|
|
22418
22761
|
const stamped = await this.routeFinding(detectorId, raw);
|
|
22419
22762
|
findings.push(stamped);
|
|
22420
22763
|
}
|
|
22421
|
-
|
|
22422
|
-
|
|
22423
|
-
|
|
22424
|
-
|
|
22425
|
-
|
|
22426
|
-
|
|
22427
|
-
|
|
22428
|
-
|
|
22429
|
-
|
|
22430
|
-
|
|
22431
|
-
|
|
22432
|
-
|
|
22433
|
-
|
|
22434
|
-
|
|
22435
|
-
|
|
22436
|
-
|
|
22437
|
-
|
|
22438
|
-
|
|
22439
|
-
|
|
22440
|
-
|
|
22441
|
-
|
|
22442
|
-
|
|
22443
|
-
|
|
22444
|
-
|
|
22445
|
-
|
|
22446
|
-
|
|
22447
|
-
|
|
22448
|
-
|
|
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
|
+
}
|
|
22449
22795
|
}
|
|
22450
22796
|
} catch (err) {
|
|
22451
22797
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -22508,6 +22854,7 @@ var init_anomaly_pipeline = __esm({
|
|
|
22508
22854
|
observed_at: raw.observed_at || this.now().toISOString()
|
|
22509
22855
|
};
|
|
22510
22856
|
await this.findingStore.saveFinding(stamped);
|
|
22857
|
+
const classifierId = stamped.details["classifier_id"] ?? null;
|
|
22511
22858
|
this.auditLog.append(
|
|
22512
22859
|
"l2",
|
|
22513
22860
|
ANOMALY_AUDIT_OPS.FINDING_EMITTED,
|
|
@@ -22517,13 +22864,79 @@ var init_anomaly_pipeline = __esm({
|
|
|
22517
22864
|
finding_id: stamped.finding_id,
|
|
22518
22865
|
severity: stamped.severity,
|
|
22519
22866
|
anomaly_score: stamped.details["anomaly_score"] ?? null,
|
|
22867
|
+
...classifierId !== null ? { classifier_id: classifierId } : {},
|
|
22520
22868
|
...stamped.agent_id !== void 0 ? { agent_id: stamped.agent_id } : {},
|
|
22521
22869
|
fortress_id: this.fortressId
|
|
22522
22870
|
}
|
|
22523
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
|
+
}
|
|
22524
22883
|
this.emit({ type: "finding", finding: stamped });
|
|
22525
22884
|
return stamped;
|
|
22526
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
|
+
}
|
|
22527
22940
|
emit(event) {
|
|
22528
22941
|
for (const listener of this.listeners) {
|
|
22529
22942
|
try {
|
|
@@ -39833,6 +40246,141 @@ ${redactedItems.map((r) => `- ${r.redacted}`).join("\n")}`,
|
|
|
39833
40246
|
}
|
|
39834
40247
|
});
|
|
39835
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
|
+
|
|
39836
40384
|
// src/intelligence/substrates/hybrid/per-surface-router.ts
|
|
39837
40385
|
function resolveHybridChoice(rules, surface) {
|
|
39838
40386
|
if (!rules) return null;
|
|
@@ -39954,6 +40502,7 @@ var init_selector = __esm({
|
|
|
39954
40502
|
init_local();
|
|
39955
40503
|
init_venice();
|
|
39956
40504
|
init_frontier();
|
|
40505
|
+
init_header_strip();
|
|
39957
40506
|
init_per_surface_router();
|
|
39958
40507
|
DISABLED_CAPABILITY = {
|
|
39959
40508
|
summarize: false,
|
|
@@ -39988,7 +40537,21 @@ var init_selector = __esm({
|
|
|
39988
40537
|
this.auditLog = cfg.auditLog;
|
|
39989
40538
|
this.identityId = cfg.identityId;
|
|
39990
40539
|
this.redactor = cfg.redactor ?? IDENTITY_REDACTOR;
|
|
39991
|
-
|
|
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
|
+
});
|
|
39992
40555
|
this.config = buildDefaultConfig();
|
|
39993
40556
|
}
|
|
39994
40557
|
/**
|