@suveren/gateway 0.3.2 → 0.3.4
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/control-plane/index.mjs +2 -2
- package/dist/mcp-server/http.mjs +73 -68
- package/dist/ui/assets/index-mg8gMTzG.js +105 -0
- package/dist/ui/index.html +1 -1
- package/node_modules/@hap/core/dist/index.d.mts +7 -2
- package/node_modules/@hap/core/dist/index.d.ts +7 -2
- package/node_modules/@hap/core/dist/index.js +2 -2
- package/node_modules/@hap/core/dist/index.mjs +2 -2
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/identity.ts +9 -4
- package/node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.d.ts +64 -25
- package/node_modules/@types/node/crypto.d.ts +18 -5
- package/node_modules/@types/node/diagnostics_channel.d.ts +237 -3
- package/node_modules/@types/node/dns.d.ts +1 -1
- package/node_modules/@types/node/ffi.d.ts +486 -0
- package/node_modules/@types/node/fs/promises.d.ts +3 -0
- package/node_modules/@types/node/fs.d.ts +21 -6
- package/node_modules/@types/node/http.d.ts +25 -0
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +14 -1
- package/node_modules/@types/node/quic.d.ts +92 -11
- package/node_modules/@types/node/sqlite.d.ts +55 -0
- package/node_modules/@types/node/stream/iter.d.ts +150 -0
- package/node_modules/@types/node/stream.d.ts +32 -0
- package/node_modules/@types/node/test.d.ts +112 -2
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -0
- package/node_modules/@types/node/util.d.ts +19 -2
- package/node_modules/@types/node/v8.d.ts +84 -2
- package/node_modules/@types/node/worker_threads.d.ts +8 -7
- package/node_modules/raw-body/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/raw-body/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/raw-body/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/raw-body/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/package.json +2 -2
- package/dist/ui/assets/index-RkZBhIxU.js +0 -105
|
@@ -2009,8 +2009,8 @@ app.get("/active-authorizations", authGuard, async (_req, res) => {
|
|
|
2009
2009
|
});
|
|
2010
2010
|
app.post("/gate-content", jsonParser, authGuard, async (req, res) => {
|
|
2011
2011
|
try {
|
|
2012
|
-
const {
|
|
2013
|
-
await pushGateContent({
|
|
2012
|
+
const { authorizationId, boundsHash, contextHash, context, path, gateContent } = req.body;
|
|
2013
|
+
await pushGateContent({ authorizationId, boundsHash, contextHash, context, path, gateContent });
|
|
2014
2014
|
res.json({ ok: true });
|
|
2015
2015
|
} catch (err) {
|
|
2016
2016
|
console.error("[Control Plane] Gate content forward error:", err);
|
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -63,8 +63,8 @@ var SPClient = class {
|
|
|
63
63
|
/**
|
|
64
64
|
* Get all attestations for a frame hash.
|
|
65
65
|
*/
|
|
66
|
-
async getAttestations(
|
|
67
|
-
const res = await this.fetch(`/api/attestations?
|
|
66
|
+
async getAttestations(authorizationId) {
|
|
67
|
+
const res = await this.fetch(`/api/attestations?authorization_id=${encodeURIComponent(authorizationId)}`);
|
|
68
68
|
if (!res.ok) throw new Error(`SP attestations request failed: ${res.status}`);
|
|
69
69
|
return res.json();
|
|
70
70
|
}
|
|
@@ -138,7 +138,7 @@ var SPClient = class {
|
|
|
138
138
|
const res = await this.fetch("/api/proposals", {
|
|
139
139
|
method: "POST",
|
|
140
140
|
body: JSON.stringify({
|
|
141
|
-
|
|
141
|
+
authorization_id: data.authorizationId,
|
|
142
142
|
profile_id: data.profileId,
|
|
143
143
|
path: data.path,
|
|
144
144
|
pending_domains: data.pendingDomains,
|
|
@@ -157,11 +157,11 @@ var SPClient = class {
|
|
|
157
157
|
return res.json();
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
|
-
* Phase 6: Fetch
|
|
160
|
+
* Phase 6: Fetch the authorization summary by its per-ceremony id.
|
|
161
161
|
* Used to read aboveCap and approversFrozen at action time.
|
|
162
162
|
*/
|
|
163
|
-
async
|
|
164
|
-
const res = await this.fetch(`/api/
|
|
163
|
+
async getAuthorizationSummary(authorizationId) {
|
|
164
|
+
const res = await this.fetch(`/api/authorizations/${encodeURIComponent(authorizationId)}`);
|
|
165
165
|
if (res.status === 404) return null;
|
|
166
166
|
if (!res.ok) return null;
|
|
167
167
|
return res.json();
|
|
@@ -228,16 +228,19 @@ var AttestationCache = class {
|
|
|
228
228
|
/**
|
|
229
229
|
* Fetch attestation data from SP for a frame hash and cache it.
|
|
230
230
|
*/
|
|
231
|
-
async syncAuthorization(
|
|
232
|
-
const result = await this.spClient.getAttestations(
|
|
233
|
-
if (!result.profile_id
|
|
231
|
+
async syncAuthorization(authorizationId) {
|
|
232
|
+
const result = await this.spClient.getAttestations(authorizationId);
|
|
233
|
+
if (!result.profile_id) return null;
|
|
234
234
|
if (result.revoked) {
|
|
235
|
-
this.authorizations.delete(
|
|
236
|
-
if (result.frame_hash) this.authorizations.delete(result.frame_hash);
|
|
235
|
+
this.authorizations.delete(authorizationId);
|
|
237
236
|
return null;
|
|
238
237
|
}
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
if (!result.authorization_id) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
"Authority Server response lacks authorization_id \u2014 the AS predates per-ceremony identity. Update the Authority Server (lockstep deploy)."
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
const bounds = result.bounds ?? result.frame ?? {};
|
|
241
244
|
let signedCommitmentMode;
|
|
242
245
|
let subjects;
|
|
243
246
|
const firstBlob = result.attestations[0]?.blob;
|
|
@@ -251,12 +254,12 @@ var AttestationCache = class {
|
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
const auth = {
|
|
254
|
-
|
|
257
|
+
authorizationId: result.authorization_id,
|
|
255
258
|
boundsHash: result.bounds_hash,
|
|
256
259
|
// content fingerprint (undefined for pre-v0.4 records)
|
|
257
260
|
contextHash: result.context_hash,
|
|
258
261
|
profileId: result.profile_id,
|
|
259
|
-
path: result.
|
|
262
|
+
path: result.profile_id,
|
|
260
263
|
frame: bounds,
|
|
261
264
|
// compat alias
|
|
262
265
|
bounds: result.bounds,
|
|
@@ -273,7 +276,7 @@ var AttestationCache = class {
|
|
|
273
276
|
subjects,
|
|
274
277
|
complete: result.complete
|
|
275
278
|
};
|
|
276
|
-
this.authorizations.set(auth.
|
|
279
|
+
this.authorizations.set(auth.authorizationId, auth);
|
|
277
280
|
return auth;
|
|
278
281
|
}
|
|
279
282
|
/**
|
|
@@ -302,7 +305,7 @@ var AttestationCache = class {
|
|
|
302
305
|
* Cache an authorization directly (e.g., from SP response after creation).
|
|
303
306
|
*/
|
|
304
307
|
cacheAuthorization(auth) {
|
|
305
|
-
this.authorizations.set(auth.
|
|
308
|
+
this.authorizations.set(auth.authorizationId, auth);
|
|
306
309
|
}
|
|
307
310
|
/**
|
|
308
311
|
* Remove a cached authorization by path. Called when the SP reports the
|
|
@@ -717,9 +720,9 @@ var SharedState = class {
|
|
|
717
720
|
this.executionLog = new ExecutionLog(gateStorePath);
|
|
718
721
|
this.gatekeeper = new MCPGatekeeper(this.cache, this.executionLog);
|
|
719
722
|
}
|
|
720
|
-
setGateContent(path,
|
|
721
|
-
this.gateStore.set(
|
|
722
|
-
|
|
723
|
+
setGateContent(path, authorizationId, profileId, content, opts) {
|
|
724
|
+
this.gateStore.set(authorizationId, {
|
|
725
|
+
authorizationId,
|
|
723
726
|
boundsHash: opts?.boundsHash,
|
|
724
727
|
contextHash: opts?.contextHash,
|
|
725
728
|
path,
|
|
@@ -739,7 +742,7 @@ var SharedState = class {
|
|
|
739
742
|
getEnrichedAuthorizations() {
|
|
740
743
|
const authorizations = this.cache.getAllAuthorizations();
|
|
741
744
|
return authorizations.map((auth) => {
|
|
742
|
-
const gateEntry =
|
|
745
|
+
const gateEntry = this.gateStore.get(auth.authorizationId) ?? null;
|
|
743
746
|
return {
|
|
744
747
|
...auth,
|
|
745
748
|
gateContent: gateEntry?.gateContent ?? null,
|
|
@@ -932,20 +935,29 @@ import { getProfile as getProfile3 } from "@hap/core";
|
|
|
932
935
|
import { deriveIdentityLine } from "@hap/core";
|
|
933
936
|
var AS_BASE = (process.env.SUVEREN_AS_URL ?? "https://www.suveren.ai").replace(/\/$/, "");
|
|
934
937
|
var OPERATOR_NAME = process.env.SUVEREN_OPERATOR_NAME ?? "Suveren";
|
|
938
|
+
var HAP_URL = "https://www.humanagencyprotocol.org/";
|
|
935
939
|
var FOOTER_PROFILES = /* @__PURE__ */ new Set(["email", "calendar", "publish"]);
|
|
936
940
|
var CONTENT_FIELD_CANDIDATES = ["body", "text", "description", "content"];
|
|
937
|
-
var
|
|
941
|
+
var FOOTER_RE = /\n*(?:—|--) (?:Sent|Published) by an AI agent[\s\S]*$/;
|
|
938
942
|
function shouldAttachFooter() {
|
|
939
943
|
return true;
|
|
940
944
|
}
|
|
941
|
-
function
|
|
945
|
+
function receiptUrl(receiptId) {
|
|
942
946
|
return `${AS_BASE}/r/${receiptId}`;
|
|
943
947
|
}
|
|
944
|
-
function
|
|
945
|
-
|
|
948
|
+
function verbForProfile(profile) {
|
|
949
|
+
return profile === "publish" ? "Published" : "Sent";
|
|
950
|
+
}
|
|
951
|
+
function hapLine() {
|
|
952
|
+
return `-- ${OPERATOR_NAME} is an implementation of the Human Agency Protocol (HAP), an open protocol to delegate execution to AI agents under human authority. ${HAP_URL}`;
|
|
953
|
+
}
|
|
954
|
+
function footerText(receiptId, verb, subject) {
|
|
955
|
+
const identity = deriveIdentityLine(subject, { operatorName: OPERATOR_NAME }).replace(/^Sent\b/, verb);
|
|
946
956
|
return `
|
|
947
957
|
|
|
948
|
-
|
|
958
|
+
-- ${identity}. Receipt: ${receiptUrl(receiptId)}
|
|
959
|
+
|
|
960
|
+
${hapLine()}`;
|
|
949
961
|
}
|
|
950
962
|
function isStringType(t) {
|
|
951
963
|
return t === "string" || Array.isArray(t) && t.includes("string");
|
|
@@ -960,9 +972,7 @@ function detectContentField(tool) {
|
|
|
960
972
|
return null;
|
|
961
973
|
}
|
|
962
974
|
function stripFooter(value) {
|
|
963
|
-
|
|
964
|
-
if (i === -1) return value;
|
|
965
|
-
return value.slice(0, i).replace(/\n+$/, "");
|
|
975
|
+
return value.replace(FOOTER_RE, "").replace(/\n+$/, "");
|
|
966
976
|
}
|
|
967
977
|
function appendVerificationFooter(tool, args, receiptId, subject) {
|
|
968
978
|
const profile = tool.gating?.profile;
|
|
@@ -970,7 +980,7 @@ function appendVerificationFooter(tool, args, receiptId, subject) {
|
|
|
970
980
|
const field = detectContentField(tool);
|
|
971
981
|
if (!field) return args;
|
|
972
982
|
const current = typeof args[field] === "string" ? args[field] : "";
|
|
973
|
-
return { ...args, [field]: stripFooter(current) + footerText(receiptId, subject) };
|
|
983
|
+
return { ...args, [field]: stripFooter(current) + footerText(receiptId, verbForProfile(profile), subject) };
|
|
974
984
|
}
|
|
975
985
|
|
|
976
986
|
// src/lib/content-binding.ts
|
|
@@ -1127,14 +1137,14 @@ function createGatedToolHandler(tool, integrationManager2, state2) {
|
|
|
1127
1137
|
}
|
|
1128
1138
|
const errors = [];
|
|
1129
1139
|
for (const auth of matchingAuths) {
|
|
1130
|
-
const { result } = await state2.gatekeeper.verifyExecution(auth.
|
|
1140
|
+
const { result } = await state2.gatekeeper.verifyExecution(auth.authorizationId, execution, {
|
|
1131
1141
|
bounds: auth.bounds,
|
|
1132
1142
|
context: auth.context
|
|
1133
1143
|
});
|
|
1134
1144
|
if (!result.approved) {
|
|
1135
1145
|
}
|
|
1136
1146
|
if (result.approved) {
|
|
1137
|
-
const
|
|
1147
|
+
const authzId = auth.authorizationId;
|
|
1138
1148
|
if (isCommitmentDowngrade(auth)) {
|
|
1139
1149
|
return {
|
|
1140
1150
|
content: [{
|
|
@@ -1148,7 +1158,7 @@ function createGatedToolHandler(tool, integrationManager2, state2) {
|
|
|
1148
1158
|
try {
|
|
1149
1159
|
const enrichedArgs = await attachImagePreview(args);
|
|
1150
1160
|
const { proposal } = await state2.spClient.submitProposal({
|
|
1151
|
-
|
|
1161
|
+
authorizationId: authzId,
|
|
1152
1162
|
profileId: auth.profileId,
|
|
1153
1163
|
path: auth.path,
|
|
1154
1164
|
pendingDomains: auth.deferredCommitmentDomains,
|
|
@@ -1180,10 +1190,9 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
|
|
|
1180
1190
|
}
|
|
1181
1191
|
const binding = computeContentBinding(auth.profileId, tool, args);
|
|
1182
1192
|
const { receipt } = await state2.spClient.postReceipt({
|
|
1183
|
-
|
|
1184
|
-
//
|
|
1185
|
-
|
|
1186
|
-
boundsHash: auth.boundsHash ?? authHash,
|
|
1193
|
+
authorizationId: authzId,
|
|
1194
|
+
// Optional cross-check — the AS fails closed on a mismatch.
|
|
1195
|
+
boundsHash: auth.boundsHash,
|
|
1187
1196
|
profileId: auth.profileId,
|
|
1188
1197
|
action: tool.namespacedName,
|
|
1189
1198
|
actionType,
|
|
@@ -1199,20 +1208,20 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
|
|
|
1199
1208
|
let pendingApprovers = spBody.approvers ?? [];
|
|
1200
1209
|
if (pendingApprovers.length === 0) {
|
|
1201
1210
|
try {
|
|
1202
|
-
const
|
|
1203
|
-
if (
|
|
1204
|
-
pendingApprovers =
|
|
1211
|
+
const summary = await state2.spClient.getAuthorizationSummary(authzId);
|
|
1212
|
+
if (summary?.approvers_frozen) {
|
|
1213
|
+
pendingApprovers = summary.approvers_frozen;
|
|
1205
1214
|
}
|
|
1206
|
-
if (
|
|
1207
|
-
pendingApprovers = [
|
|
1215
|
+
if (summary?.created_by) {
|
|
1216
|
+
pendingApprovers = [summary.created_by, ...pendingApprovers];
|
|
1208
1217
|
}
|
|
1209
1218
|
} catch {
|
|
1210
1219
|
}
|
|
1211
1220
|
} else {
|
|
1212
1221
|
try {
|
|
1213
|
-
const
|
|
1214
|
-
if (
|
|
1215
|
-
pendingApprovers = [
|
|
1222
|
+
const summary = await state2.spClient.getAuthorizationSummary(authzId);
|
|
1223
|
+
if (summary?.created_by) {
|
|
1224
|
+
pendingApprovers = [summary.created_by, ...pendingApprovers];
|
|
1216
1225
|
}
|
|
1217
1226
|
} catch {
|
|
1218
1227
|
}
|
|
@@ -1221,7 +1230,7 @@ Proposal ID: ${proposal.id}. Check status with check-pending-commitments(proposa
|
|
|
1221
1230
|
try {
|
|
1222
1231
|
const enrichedArgs = await attachImagePreview(args);
|
|
1223
1232
|
const { proposal } = await state2.spClient.submitProposal({
|
|
1224
|
-
|
|
1233
|
+
authorizationId: authzId,
|
|
1225
1234
|
profileId: auth.profileId,
|
|
1226
1235
|
path: auth.path,
|
|
1227
1236
|
pendingDomains: [],
|
|
@@ -1252,7 +1261,7 @@ Proposal ID: ${proposal.id}. Use check-pending-commitments to track status.`
|
|
|
1252
1261
|
}
|
|
1253
1262
|
if (err instanceof SPReceiptError && err.statusCode === 403) {
|
|
1254
1263
|
if (/revoked/i.test(err.message)) {
|
|
1255
|
-
state2.cache.invalidate(auth.
|
|
1264
|
+
state2.cache.invalidate(auth.authorizationId);
|
|
1256
1265
|
}
|
|
1257
1266
|
return {
|
|
1258
1267
|
content: [{ type: "text", text: `Blocked by SP: ${err.message}` }],
|
|
@@ -1418,8 +1427,8 @@ function listAuthorizationsHandler(state2, integrationManager2, contextDir) {
|
|
|
1418
1427
|
const reviewDomains = auth.deferredCommitmentDomains ?? [];
|
|
1419
1428
|
output2.push(reviewDomains.length > 0 ? " Mode: review \u2014 each action requires your approval before it runs (a proposal is created, not executed)" : " Mode: automatic \u2014 actions run immediately within bounds");
|
|
1420
1429
|
try {
|
|
1421
|
-
const meta = await state2.spClient.
|
|
1422
|
-
if (meta?.
|
|
1430
|
+
const meta = await state2.spClient.getAuthorizationSummary(auth.authorizationId);
|
|
1431
|
+
if (meta?.above_cap) {
|
|
1423
1432
|
output2.push(" \u26A0 Above team cap \u2014 actions here require approval even within these bounds.");
|
|
1424
1433
|
}
|
|
1425
1434
|
} catch {
|
|
@@ -1631,10 +1640,9 @@ async function executeCommitted(proposal, state2, integrationManager2) {
|
|
|
1631
1640
|
}
|
|
1632
1641
|
let receiptId;
|
|
1633
1642
|
try {
|
|
1634
|
-
const boundsHash = proposal.frameHash.split(":").slice(0, 2).join(":");
|
|
1635
1643
|
const binding = computeContentBinding(proposal.profileId, discovered, proposal.toolArgs);
|
|
1636
1644
|
const { receipt } = await state2.spClient.postReceipt({
|
|
1637
|
-
|
|
1645
|
+
authorizationId: proposal.authorizationId,
|
|
1638
1646
|
profileId: proposal.profileId,
|
|
1639
1647
|
action: proposal.tool,
|
|
1640
1648
|
actionType: proposalActionType,
|
|
@@ -2494,18 +2502,17 @@ app.post("/internal/configure", internalOnly, (req, res) => {
|
|
|
2494
2502
|
});
|
|
2495
2503
|
app.post("/internal/gate-content", internalOnly, async (req, res) => {
|
|
2496
2504
|
try {
|
|
2497
|
-
const {
|
|
2498
|
-
const storageHash = frameHash ?? boundsHash;
|
|
2505
|
+
const { authorizationId, boundsHash, contextHash, context, path: rawPath, gateContent } = req.body;
|
|
2499
2506
|
const hasIntent = !!gateContent?.intent;
|
|
2500
2507
|
const legacy = gateContent;
|
|
2501
2508
|
const hasLegacy = !!legacy?.problem && !!legacy?.objective && !!legacy?.tradeoffs;
|
|
2502
|
-
if (!
|
|
2503
|
-
res.status(400).json({ error: "Missing required fields:
|
|
2509
|
+
if (!authorizationId || !hasIntent && !hasLegacy) {
|
|
2510
|
+
res.status(400).json({ error: "Missing required fields: authorizationId, gateContent.{intent} or gateContent.{problem,objective,tradeoffs}" });
|
|
2504
2511
|
return;
|
|
2505
2512
|
}
|
|
2506
|
-
const auth = await state.cache.syncAuthorization(
|
|
2513
|
+
const auth = await state.cache.syncAuthorization(authorizationId);
|
|
2507
2514
|
if (!auth) {
|
|
2508
|
-
res.status(404).json({ error: `No
|
|
2515
|
+
res.status(404).json({ error: `No authorization found for ${authorizationId}` });
|
|
2509
2516
|
return;
|
|
2510
2517
|
}
|
|
2511
2518
|
const verification = verifyGateContentHashes(gateContent, auth);
|
|
@@ -2513,8 +2520,8 @@ app.post("/internal/gate-content", internalOnly, async (req, res) => {
|
|
|
2513
2520
|
res.status(400).json({ error: "Gate content hash mismatch", details: verification.errors });
|
|
2514
2521
|
return;
|
|
2515
2522
|
}
|
|
2516
|
-
const path = rawPath ||
|
|
2517
|
-
state.setGateContent(path,
|
|
2523
|
+
const path = rawPath || authorizationId;
|
|
2524
|
+
state.setGateContent(path, authorizationId, auth.profileId, gateContent, {
|
|
2518
2525
|
boundsHash,
|
|
2519
2526
|
contextHash,
|
|
2520
2527
|
context
|
|
@@ -2570,10 +2577,10 @@ app.post("/internal/resync-gates", internalOnly, async (_req, res) => {
|
|
|
2570
2577
|
let orphaned = 0;
|
|
2571
2578
|
for (const gate of gates) {
|
|
2572
2579
|
try {
|
|
2573
|
-
const
|
|
2574
|
-
const auth = await state.cache.syncAuthorization(
|
|
2580
|
+
const authzId = gate.authorizationId;
|
|
2581
|
+
const auth = await state.cache.syncAuthorization(authzId);
|
|
2575
2582
|
if (auth) {
|
|
2576
|
-
state.setGateContent(
|
|
2583
|
+
state.setGateContent(auth.path, authzId, auth.profileId, gate.gateContent, {
|
|
2577
2584
|
boundsHash: gate.boundsHash,
|
|
2578
2585
|
contextHash: gate.contextHash,
|
|
2579
2586
|
context: gate.context
|
|
@@ -2581,8 +2588,8 @@ app.post("/internal/resync-gates", internalOnly, async (_req, res) => {
|
|
|
2581
2588
|
synced++;
|
|
2582
2589
|
console.error(`[Suveren MCP] Re-synced gate: ${gate.path}`);
|
|
2583
2590
|
} else {
|
|
2584
|
-
state.cache.invalidate(
|
|
2585
|
-
state.gateStore.delete(
|
|
2591
|
+
state.cache.invalidate(authzId);
|
|
2592
|
+
state.gateStore.delete(authzId);
|
|
2586
2593
|
orphaned++;
|
|
2587
2594
|
console.error(`[Suveren MCP] Orphan gate purged (SP attestation deleted): ${gate.path}`);
|
|
2588
2595
|
}
|
|
@@ -2737,9 +2744,7 @@ app.get("/internal/gate-content", internalOnly, (req, res) => {
|
|
|
2737
2744
|
const path = req.query.path;
|
|
2738
2745
|
const gates = state.gateStore.getAll();
|
|
2739
2746
|
if (path) {
|
|
2740
|
-
const entry = gates.find(
|
|
2741
|
-
(g) => g.path === path || g.profileId === path || g.boundsHash === path || g.frameHash === path
|
|
2742
|
-
);
|
|
2747
|
+
const entry = gates.find((g) => g.authorizationId === path);
|
|
2743
2748
|
res.json({ entry: entry ?? null });
|
|
2744
2749
|
} else {
|
|
2745
2750
|
res.json({ entries: gates });
|
|
@@ -2748,7 +2753,7 @@ app.get("/internal/gate-content", internalOnly, (req, res) => {
|
|
|
2748
2753
|
app.get("/internal/authorizations", internalOnly, (_req, res) => {
|
|
2749
2754
|
const authorizations = state.getEnrichedAuthorizations().map((a) => ({
|
|
2750
2755
|
profileId: a.profileId,
|
|
2751
|
-
|
|
2756
|
+
authorizationId: a.authorizationId,
|
|
2752
2757
|
bounds: a.frame,
|
|
2753
2758
|
context: a.context ?? {},
|
|
2754
2759
|
intent: a.gateContent?.intent ?? null,
|