@integrity-labs/agt-cli 0.28.1030 → 0.28.1031
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/bin/agt.js +5 -5
- package/dist/{chunk-TBCJ5NNP.js → chunk-HQSQLPHD.js} +8 -7
- package/dist/chunk-HQSQLPHD.js.map +1 -0
- package/dist/{chunk-VUC5XNUP.js → chunk-TFFXAGBJ.js} +61 -2
- package/dist/chunk-TFFXAGBJ.js.map +1 -0
- package/dist/{chunk-4KNUH4DQ.js → chunk-XD5GMJGJ.js} +2 -2
- package/dist/{claude-pair-runtime-3LB2CNFQ.js → claude-pair-runtime-NBF54YQD.js} +2 -2
- package/dist/lib/manager-worker.js +14 -14
- package/dist/mcp/direct-chat-channel.js +60 -1
- package/dist/mcp/index.js +60 -1
- package/dist/mcp/origami.js +60 -1
- package/dist/mcp/slack-channel.js +60 -1
- package/dist/mcp/telegram-channel.js +60 -1
- package/dist/{persistent-session-BCEKKB2Y.js → persistent-session-AMUXFQKY.js} +3 -3
- package/dist/{responsiveness-probe-6S6ZELJG.js → responsiveness-probe-73AXZT6D.js} +3 -3
- package/dist/{session-auth-dead-M43W63XW.js → session-auth-dead-VINCM3ZI.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-TBCJ5NNP.js.map +0 -1
- package/dist/chunk-VUC5XNUP.js.map +0 -1
- /package/dist/{chunk-4KNUH4DQ.js.map → chunk-XD5GMJGJ.js.map} +0 -0
- /package/dist/{claude-pair-runtime-3LB2CNFQ.js.map → claude-pair-runtime-NBF54YQD.js.map} +0 -0
- /package/dist/{persistent-session-BCEKKB2Y.js.map → persistent-session-AMUXFQKY.js.map} +0 -0
- /package/dist/{responsiveness-probe-6S6ZELJG.js.map → responsiveness-probe-73AXZT6D.js.map} +0 -0
- /package/dist/{session-auth-dead-M43W63XW.js.map → session-auth-dead-VINCM3ZI.js.map} +0 -0
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
rotateDailySession,
|
|
24
24
|
sessionFileExists,
|
|
25
25
|
todayLocalIso
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-TFFXAGBJ.js";
|
|
27
27
|
import {
|
|
28
28
|
classifyUnanswerablePane,
|
|
29
29
|
findUsageLimitResetHint,
|
|
@@ -5930,4 +5930,4 @@ export {
|
|
|
5930
5930
|
stopAllSessionsAndWait,
|
|
5931
5931
|
getProjectDir
|
|
5932
5932
|
};
|
|
5933
|
-
//# sourceMappingURL=chunk-
|
|
5933
|
+
//# sourceMappingURL=chunk-XD5GMJGJ.js.map
|
|
@@ -266,7 +266,7 @@ async function spawnPairSession(session) {
|
|
|
266
266
|
return { ok: true };
|
|
267
267
|
} catch {
|
|
268
268
|
}
|
|
269
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
269
|
+
const { resolveClaudeBinary } = await import("./persistent-session-AMUXFQKY.js");
|
|
270
270
|
const claudeBin = resolveClaudeBinary();
|
|
271
271
|
const pairEnv = {
|
|
272
272
|
...process.env,
|
|
@@ -734,4 +734,4 @@ export {
|
|
|
734
734
|
startClaudePair,
|
|
735
735
|
submitClaudePairCode
|
|
736
736
|
};
|
|
737
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
737
|
+
//# sourceMappingURL=claude-pair-runtime-NBF54YQD.js.map
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
safeWriteJsonAtomic,
|
|
67
67
|
setConfigHash,
|
|
68
68
|
tripClass
|
|
69
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-HQSQLPHD.js";
|
|
70
70
|
import {
|
|
71
71
|
getProjectDir as getProjectDir2,
|
|
72
72
|
getReadyTasks,
|
|
@@ -149,7 +149,7 @@ import {
|
|
|
149
149
|
takeZombieDetection,
|
|
150
150
|
toOpencodeModel,
|
|
151
151
|
writeEgressAllowlist
|
|
152
|
-
} from "../chunk-
|
|
152
|
+
} from "../chunk-XD5GMJGJ.js";
|
|
153
153
|
import {
|
|
154
154
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
155
155
|
AnchorSessionClient,
|
|
@@ -254,7 +254,7 @@ import {
|
|
|
254
254
|
subagentActivityAgeSeconds,
|
|
255
255
|
sumTranscriptUsageInWindow,
|
|
256
256
|
transcriptActivityAgeSeconds
|
|
257
|
-
} from "../chunk-
|
|
257
|
+
} from "../chunk-TFFXAGBJ.js";
|
|
258
258
|
import {
|
|
259
259
|
classifyUnanswerablePane,
|
|
260
260
|
paneRemedy
|
|
@@ -13927,7 +13927,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13927
13927
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13928
13928
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13929
13929
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13930
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13930
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-73AXZT6D.js");
|
|
13931
13931
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13932
13932
|
if (newest === null) return null;
|
|
13933
13933
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -14673,7 +14673,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
14673
14673
|
var lastVersionCheckAt = 0;
|
|
14674
14674
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14675
14675
|
var lastResponsivenessProbeAt = 0;
|
|
14676
|
-
var agtCliVersion = true ? "0.28.
|
|
14676
|
+
var agtCliVersion = true ? "0.28.1031" : "dev";
|
|
14677
14677
|
function resolveBrewPath(execFileSync3) {
|
|
14678
14678
|
try {
|
|
14679
14679
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -16308,7 +16308,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
16308
16308
|
if (codeNames.length === 0) return;
|
|
16309
16309
|
void (async () => {
|
|
16310
16310
|
try {
|
|
16311
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16311
|
+
const { collectDiagnostics } = await import("../persistent-session-AMUXFQKY.js");
|
|
16312
16312
|
await api.post("/host/heartbeat", {
|
|
16313
16313
|
host_id: hostId,
|
|
16314
16314
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -16450,7 +16450,7 @@ async function pollCycleInner() {
|
|
|
16450
16450
|
}
|
|
16451
16451
|
try {
|
|
16452
16452
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
16453
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16453
|
+
const { collectDiagnostics } = await import("../persistent-session-AMUXFQKY.js");
|
|
16454
16454
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
16455
16455
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
|
|
16456
16456
|
let tailscaleHostname;
|
|
@@ -16626,7 +16626,7 @@ async function pollCycleInner() {
|
|
|
16626
16626
|
collectPanelessActivityProbes,
|
|
16627
16627
|
getResponsivenessIntervalMs,
|
|
16628
16628
|
occupancyQualificationClassifications
|
|
16629
|
-
} = await import("../responsiveness-probe-
|
|
16629
|
+
} = await import("../responsiveness-probe-73AXZT6D.js");
|
|
16630
16630
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
16631
16631
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
16632
16632
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -16743,7 +16743,7 @@ async function pollCycleInner() {
|
|
|
16743
16743
|
collectResponsivenessProbes,
|
|
16744
16744
|
livePendingInboundOldestAgeSeconds,
|
|
16745
16745
|
parkPendingInbound
|
|
16746
|
-
} = await import("../responsiveness-probe-
|
|
16746
|
+
} = await import("../responsiveness-probe-73AXZT6D.js");
|
|
16747
16747
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
16748
16748
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
16749
16749
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -16899,7 +16899,7 @@ async function pollCycleInner() {
|
|
|
16899
16899
|
}
|
|
16900
16900
|
try {
|
|
16901
16901
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
16902
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
16902
|
+
const { probeSessionAuth } = await import("../session-auth-dead-VINCM3ZI.js");
|
|
16903
16903
|
const observations = [];
|
|
16904
16904
|
const pendingCacheCommits = [];
|
|
16905
16905
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -21442,7 +21442,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
21442
21442
|
try {
|
|
21443
21443
|
const freshId = rotateSessionForWedge(codeName);
|
|
21444
21444
|
consecutiveWedgeCycles.delete(codeName);
|
|
21445
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
21445
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-73AXZT6D.js");
|
|
21446
21446
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
21447
21447
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
21448
21448
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -21485,7 +21485,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
21485
21485
|
void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
|
|
21486
21486
|
void (async () => {
|
|
21487
21487
|
try {
|
|
21488
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
21488
|
+
const { collectDiagnostics } = await import("../persistent-session-AMUXFQKY.js");
|
|
21489
21489
|
await api.post("/host/heartbeat", {
|
|
21490
21490
|
host_id: hostId,
|
|
21491
21491
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -21536,7 +21536,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
21536
21536
|
}
|
|
21537
21537
|
try {
|
|
21538
21538
|
const hostId = await getHostId();
|
|
21539
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
21539
|
+
const { collectDiagnostics } = await import("../persistent-session-AMUXFQKY.js");
|
|
21540
21540
|
await api.post("/host/heartbeat", {
|
|
21541
21541
|
host_id: hostId,
|
|
21542
21542
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -22208,7 +22208,7 @@ async function processClaudePairSessions(agents) {
|
|
|
22208
22208
|
// cannot take it for itself — by the time it runs, the write it is looking
|
|
22209
22209
|
// for may already have happened.
|
|
22210
22210
|
snapshotPairConfig
|
|
22211
|
-
} = await import("../claude-pair-runtime-
|
|
22211
|
+
} = await import("../claude-pair-runtime-NBF54YQD.js");
|
|
22212
22212
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
22213
22213
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
22214
22214
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -36419,7 +36419,10 @@ var FLAG_REGISTRY = [
|
|
|
36419
36419
|
// Disabling this RESTORES the shared host-wide key to every container, and
|
|
36420
36420
|
// with it the cross-agent credential read ENG-8992 closes. A credential-scope
|
|
36421
36421
|
// reduction should not be one click away without confirmation — same posture
|
|
36422
|
-
// as `github-broker-credentials
|
|
36422
|
+
// as the credential-delivery flags `github-broker-credentials` and
|
|
36423
|
+
// `xero-broker-credentials`. (This said "the OTHER credential-delivery flag"
|
|
36424
|
+
// while there was one; ENG-10939 added the second, so the singular had to go
|
|
36425
|
+
// rather than silently become a claim that github is the only sibling.)
|
|
36423
36426
|
sensitive: true,
|
|
36424
36427
|
// The reader is host-side (`hostFlagStore().getBoolean(...)` in the manager),
|
|
36425
36428
|
// so a host on an older agt-cli has no consumer code: it keeps forwarding the
|
|
@@ -37566,6 +37569,12 @@ var FLAG_REGISTRY = [
|
|
|
37566
37569
|
// are the precedent: pinned ABOVE every published release ON PURPOSE,
|
|
37567
37570
|
// labelled as a placeholder, and gated on a post-publish bisect.
|
|
37568
37571
|
//
|
|
37572
|
+
// ENG-10939: `xero-broker-credentials` is the worked example of the other
|
|
37573
|
+
// half of that convention - the bisect that DISCHARGES a placeholder. Its
|
|
37574
|
+
// `since` is a real published version read off `npm pack` tarballs, with the
|
|
37575
|
+
// markers it was bisected on written down, so the two entries together show
|
|
37576
|
+
// both states this field is allowed to be in.
|
|
37577
|
+
//
|
|
37569
37578
|
// (This cited `claudecode-agt-bin-credential-helpers` until obi-wan
|
|
37570
37579
|
// `8f9d3c43076c` pointed out no such key exists anywhere in the repo - the
|
|
37571
37580
|
// only occurrence in the tree was this citation. The precedent was real and
|
|
@@ -38332,6 +38341,56 @@ var FLAG_REGISTRY = [
|
|
|
38332
38341
|
// flips); shipping a guessed number is not.
|
|
38333
38342
|
since: "0.29.0"
|
|
38334
38343
|
},
|
|
38344
|
+
{
|
|
38345
|
+
key: "xero-broker-credentials",
|
|
38346
|
+
description: 'Deliver the Xero OAuth access token to the vendor Xero MCP server through the broker credential endpoint at USE time, instead of materializing it onto the agent host at spawn (ENG-10939, step 1 of the Xero lockdown ENG-10927). Mechanically the sibling of `github-broker-credentials`; the REASON and the cost of a bad flip are both different. ON: POST /host/agent-integrations strips `access_token`, `refresh_token` and `token_expires_at` from the xero row and marks it credential_delivery=broker, so XERO_ACCESS_TOKEN stops being written to .env.integrations. Nothing replaces it host-side and nothing needs to: the vendor MCP server has fetched a fresh token per call from POST /host/agent-integrations/:id/credential since ENG-4920, and `brokerMode` is true for every install carrying an id - so XERO_CLIENT_BEARER_TOKEN: ${XERO_ACCESS_TOKEN} is already not emitted and no dangling reference is left behind. `granted_scopes` and `read_only` are deliberately KEPT: they are consent metadata the host reports scope drift from, not credentials. OFF (default): byte-for-byte today\'s behaviour. WHY THIS IS NOT THE GITHUB FLAG. For github, an under-`since` host on a flipped flag LOSES `git`/`gh` - an outage. For xero the equivalent host LEAKS: before ENG-10939 the ENG-8344 broker guard was a loop-level `continue` that also skipped the config-derived env vars, so a broker-marked xero row dropped XERO_TENANT_ID, and per ENG-4898 the vendor MCP server then falls back to `tenants[0]` - a CROSS-TENANT DATA LEAK with no error anywhere. The dangerous fleet is therefore an INTERVAL, not "old hosts", and BOTH edges are bisected from published tarballs rather than named by issue: below agt-cli 0.28.508 a host carries no `credentialDelivery` handling at all, so it ignores the marker and is SAFE; from 0.28.508 up to (not including) 0.28.1015 it honours the marker with the WIDE skip and LEAKS; at 0.28.1015 and above the skip is narrowed and the behaviour is correct. `since` is a lower bound, so it classifies BOTH ends of that interval as `stale` and cannot tell a safe pre-0.28.508 host from a leaking-middle one. THE FLIP GATE IS THEREFORE NOT "the modal shows reach": it is zero xero-bearing hosts below 0.28.1015 per hosts.agt_version, counting NULL and stale as UNCONVERGED (the heartbeat writes that column conditionally on presence, so a host that stopped reporting keeps its last value - the async-export-rollout pattern). AND A SECOND GATE THE MODAL CANNOT SEE AT ALL: the rewritten Xero skills (ENG-10961) must be live in the catalog AND have reached hosts BEFORE this is flipped. Reversed, a host has no token while its own skills still tell it to read one - a silent read outage with no error at the write site. The catalog reaches prod through `pnpm db:catalog:seed` on deploy, not through the code deploy itself, so "merged" is not "live". EXPECTED ON FLIP DAY, so it is not a surprise: the payload shrinks, so computeIntegrationsHash moves once and XERO_ACCESS_TOKEN reads present->absent in the env diff. That does NOT respawn the session. `liveProxyTokenVars` collects AGT_REMOTE_MCP_TOKEN_VAR from .mcp.json (= XERO_ACCESS_TOKEN in broker mode) and the manager filters it out of `respawnVars` BY NAME, kind-blind - so a removal is exempt on exactly the same line a rotation is (ENG-8264). The ENG-5318 child-kill path is likewise unreachable, because broker mode never emits the ${XERO_ACCESS_TOKEN} reference the stale-mcp-reaper keys on. Both restart paths that touch this var are already quiet. Evaluated API-side only, per agent, in POST /host/agent-integrations. The host does not read this flag - it keys off the resulting credential_delivery marker - so there is deliberately NO host-side envVar that could put the token back on its own. Roll back from the flag.',
|
|
38347
|
+
flagType: "boolean",
|
|
38348
|
+
// Declared safe value is `false` = today's env delivery. Fail-safe here is
|
|
38349
|
+
// not symmetrical with github's: OFF leaves a credential on the host (bad,
|
|
38350
|
+
// but the status quo this epic is closing), while a wrongly-ON flip on an
|
|
38351
|
+
// under-`since` host LEAKS ANOTHER TENANT'S DATA. `false` is still the right
|
|
38352
|
+
// default, because the ON path is the one with a reach precondition — but
|
|
38353
|
+
// the reason is "do not arm this until the fleet is measured", not "a flag
|
|
38354
|
+
// blip must not break the agent".
|
|
38355
|
+
defaultValue: false,
|
|
38356
|
+
// Flipping ON changes how every Xero agent on the scope authenticates, and
|
|
38357
|
+
// on an unconverged host it is a cross-tenant leak rather than an outage. A
|
|
38358
|
+
// deliberate, confirmed action (ADR-0022 §4).
|
|
38359
|
+
sensitive: true,
|
|
38360
|
+
// A REAL bisected threshold, not the placeholder `github-broker-credentials`
|
|
38361
|
+
// and `per-agent-host-credentials` had to ship with: the host-side code this
|
|
38362
|
+
// flag depends on (ENG-10939 item 0, narrowing the ENG-8344 broker guard so
|
|
38363
|
+
// it skips the CREDENTIAL and not the whole row's config) landed in PR #6443
|
|
38364
|
+
// and has already published.
|
|
38365
|
+
//
|
|
38366
|
+
// Read off the published tarballs rather than inferred from the merge
|
|
38367
|
+
// timestamp. #6443 merged at 2026-09-24T01:54:41Z; 0.28.1015 published at
|
|
38368
|
+
// 01:59:23Z. `npm pack` of 0.28.1013/1014/1015/1016 + grep of the extracted
|
|
38369
|
+
// bundle agrees in both directions on four independent markers:
|
|
38370
|
+
// 0.28.1014 — `writeTokenFile` present (4 files), `isRespawnExemptEnvVar`
|
|
38371
|
+
// and `RESPAWN_EXEMPT_CONFIG_TAILS` absent, and the only
|
|
38372
|
+
// broker-guard spelling is `credentialDelivery === "broker"`
|
|
38373
|
+
// (the wide skip).
|
|
38374
|
+
// 0.28.1015 — `writeTokenFile` gone, both new exports present, and
|
|
38375
|
+
// `credentialDelivery !== "broker"` (the narrowed block form)
|
|
38376
|
+
// appears for the first time.
|
|
38377
|
+
// The `!==` form is the one that matters: it is the guard that keeps
|
|
38378
|
+
// XERO_TENANT_ID on a broker-marked row, i.e. the thing whose absence is the
|
|
38379
|
+
// ENG-4898 leak.
|
|
38380
|
+
//
|
|
38381
|
+
// The interval's OTHER edge was bisected the same way, so the description
|
|
38382
|
+
// above can name a version instead of an issue: `credentialDelivery` appears
|
|
38383
|
+
// in no file of 0.28.507 and in five files of 0.28.508, so ENG-8344's marker
|
|
38384
|
+
// handling first shipped in 0.28.508. A host below that is genuinely safe
|
|
38385
|
+
// rather than merely old — it has no code to honour the marker with.
|
|
38386
|
+
//
|
|
38387
|
+
// Same caveat as every other `since` in this registry: it is ADVISORY. It is
|
|
38388
|
+
// read only by `computeFlagReach` behind GET /flags/admin/reach, so it
|
|
38389
|
+
// changes what an operator is TOLD and does not stop a flip on an
|
|
38390
|
+
// under-`since` host. What holds the line is `defaultValue: false`, plus
|
|
38391
|
+
// `sensitive: true`, plus the two gates spelled out in the description.
|
|
38392
|
+
since: "0.28.1015"
|
|
38393
|
+
},
|
|
38335
38394
|
{
|
|
38336
38395
|
key: "help-kb-auto-grant",
|
|
38337
38396
|
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|
package/dist/mcp/index.js
CHANGED
|
@@ -28716,7 +28716,10 @@ var FLAG_REGISTRY = [
|
|
|
28716
28716
|
// Disabling this RESTORES the shared host-wide key to every container, and
|
|
28717
28717
|
// with it the cross-agent credential read ENG-8992 closes. A credential-scope
|
|
28718
28718
|
// reduction should not be one click away without confirmation — same posture
|
|
28719
|
-
// as `github-broker-credentials
|
|
28719
|
+
// as the credential-delivery flags `github-broker-credentials` and
|
|
28720
|
+
// `xero-broker-credentials`. (This said "the OTHER credential-delivery flag"
|
|
28721
|
+
// while there was one; ENG-10939 added the second, so the singular had to go
|
|
28722
|
+
// rather than silently become a claim that github is the only sibling.)
|
|
28720
28723
|
sensitive: true,
|
|
28721
28724
|
// The reader is host-side (`hostFlagStore().getBoolean(...)` in the manager),
|
|
28722
28725
|
// so a host on an older agt-cli has no consumer code: it keeps forwarding the
|
|
@@ -29863,6 +29866,12 @@ var FLAG_REGISTRY = [
|
|
|
29863
29866
|
// are the precedent: pinned ABOVE every published release ON PURPOSE,
|
|
29864
29867
|
// labelled as a placeholder, and gated on a post-publish bisect.
|
|
29865
29868
|
//
|
|
29869
|
+
// ENG-10939: `xero-broker-credentials` is the worked example of the other
|
|
29870
|
+
// half of that convention - the bisect that DISCHARGES a placeholder. Its
|
|
29871
|
+
// `since` is a real published version read off `npm pack` tarballs, with the
|
|
29872
|
+
// markers it was bisected on written down, so the two entries together show
|
|
29873
|
+
// both states this field is allowed to be in.
|
|
29874
|
+
//
|
|
29866
29875
|
// (This cited `claudecode-agt-bin-credential-helpers` until obi-wan
|
|
29867
29876
|
// `8f9d3c43076c` pointed out no such key exists anywhere in the repo - the
|
|
29868
29877
|
// only occurrence in the tree was this citation. The precedent was real and
|
|
@@ -30629,6 +30638,56 @@ var FLAG_REGISTRY = [
|
|
|
30629
30638
|
// flips); shipping a guessed number is not.
|
|
30630
30639
|
since: "0.29.0"
|
|
30631
30640
|
},
|
|
30641
|
+
{
|
|
30642
|
+
key: "xero-broker-credentials",
|
|
30643
|
+
description: 'Deliver the Xero OAuth access token to the vendor Xero MCP server through the broker credential endpoint at USE time, instead of materializing it onto the agent host at spawn (ENG-10939, step 1 of the Xero lockdown ENG-10927). Mechanically the sibling of `github-broker-credentials`; the REASON and the cost of a bad flip are both different. ON: POST /host/agent-integrations strips `access_token`, `refresh_token` and `token_expires_at` from the xero row and marks it credential_delivery=broker, so XERO_ACCESS_TOKEN stops being written to .env.integrations. Nothing replaces it host-side and nothing needs to: the vendor MCP server has fetched a fresh token per call from POST /host/agent-integrations/:id/credential since ENG-4920, and `brokerMode` is true for every install carrying an id - so XERO_CLIENT_BEARER_TOKEN: ${XERO_ACCESS_TOKEN} is already not emitted and no dangling reference is left behind. `granted_scopes` and `read_only` are deliberately KEPT: they are consent metadata the host reports scope drift from, not credentials. OFF (default): byte-for-byte today\'s behaviour. WHY THIS IS NOT THE GITHUB FLAG. For github, an under-`since` host on a flipped flag LOSES `git`/`gh` - an outage. For xero the equivalent host LEAKS: before ENG-10939 the ENG-8344 broker guard was a loop-level `continue` that also skipped the config-derived env vars, so a broker-marked xero row dropped XERO_TENANT_ID, and per ENG-4898 the vendor MCP server then falls back to `tenants[0]` - a CROSS-TENANT DATA LEAK with no error anywhere. The dangerous fleet is therefore an INTERVAL, not "old hosts", and BOTH edges are bisected from published tarballs rather than named by issue: below agt-cli 0.28.508 a host carries no `credentialDelivery` handling at all, so it ignores the marker and is SAFE; from 0.28.508 up to (not including) 0.28.1015 it honours the marker with the WIDE skip and LEAKS; at 0.28.1015 and above the skip is narrowed and the behaviour is correct. `since` is a lower bound, so it classifies BOTH ends of that interval as `stale` and cannot tell a safe pre-0.28.508 host from a leaking-middle one. THE FLIP GATE IS THEREFORE NOT "the modal shows reach": it is zero xero-bearing hosts below 0.28.1015 per hosts.agt_version, counting NULL and stale as UNCONVERGED (the heartbeat writes that column conditionally on presence, so a host that stopped reporting keeps its last value - the async-export-rollout pattern). AND A SECOND GATE THE MODAL CANNOT SEE AT ALL: the rewritten Xero skills (ENG-10961) must be live in the catalog AND have reached hosts BEFORE this is flipped. Reversed, a host has no token while its own skills still tell it to read one - a silent read outage with no error at the write site. The catalog reaches prod through `pnpm db:catalog:seed` on deploy, not through the code deploy itself, so "merged" is not "live". EXPECTED ON FLIP DAY, so it is not a surprise: the payload shrinks, so computeIntegrationsHash moves once and XERO_ACCESS_TOKEN reads present->absent in the env diff. That does NOT respawn the session. `liveProxyTokenVars` collects AGT_REMOTE_MCP_TOKEN_VAR from .mcp.json (= XERO_ACCESS_TOKEN in broker mode) and the manager filters it out of `respawnVars` BY NAME, kind-blind - so a removal is exempt on exactly the same line a rotation is (ENG-8264). The ENG-5318 child-kill path is likewise unreachable, because broker mode never emits the ${XERO_ACCESS_TOKEN} reference the stale-mcp-reaper keys on. Both restart paths that touch this var are already quiet. Evaluated API-side only, per agent, in POST /host/agent-integrations. The host does not read this flag - it keys off the resulting credential_delivery marker - so there is deliberately NO host-side envVar that could put the token back on its own. Roll back from the flag.',
|
|
30644
|
+
flagType: "boolean",
|
|
30645
|
+
// Declared safe value is `false` = today's env delivery. Fail-safe here is
|
|
30646
|
+
// not symmetrical with github's: OFF leaves a credential on the host (bad,
|
|
30647
|
+
// but the status quo this epic is closing), while a wrongly-ON flip on an
|
|
30648
|
+
// under-`since` host LEAKS ANOTHER TENANT'S DATA. `false` is still the right
|
|
30649
|
+
// default, because the ON path is the one with a reach precondition — but
|
|
30650
|
+
// the reason is "do not arm this until the fleet is measured", not "a flag
|
|
30651
|
+
// blip must not break the agent".
|
|
30652
|
+
defaultValue: false,
|
|
30653
|
+
// Flipping ON changes how every Xero agent on the scope authenticates, and
|
|
30654
|
+
// on an unconverged host it is a cross-tenant leak rather than an outage. A
|
|
30655
|
+
// deliberate, confirmed action (ADR-0022 §4).
|
|
30656
|
+
sensitive: true,
|
|
30657
|
+
// A REAL bisected threshold, not the placeholder `github-broker-credentials`
|
|
30658
|
+
// and `per-agent-host-credentials` had to ship with: the host-side code this
|
|
30659
|
+
// flag depends on (ENG-10939 item 0, narrowing the ENG-8344 broker guard so
|
|
30660
|
+
// it skips the CREDENTIAL and not the whole row's config) landed in PR #6443
|
|
30661
|
+
// and has already published.
|
|
30662
|
+
//
|
|
30663
|
+
// Read off the published tarballs rather than inferred from the merge
|
|
30664
|
+
// timestamp. #6443 merged at 2026-09-24T01:54:41Z; 0.28.1015 published at
|
|
30665
|
+
// 01:59:23Z. `npm pack` of 0.28.1013/1014/1015/1016 + grep of the extracted
|
|
30666
|
+
// bundle agrees in both directions on four independent markers:
|
|
30667
|
+
// 0.28.1014 — `writeTokenFile` present (4 files), `isRespawnExemptEnvVar`
|
|
30668
|
+
// and `RESPAWN_EXEMPT_CONFIG_TAILS` absent, and the only
|
|
30669
|
+
// broker-guard spelling is `credentialDelivery === "broker"`
|
|
30670
|
+
// (the wide skip).
|
|
30671
|
+
// 0.28.1015 — `writeTokenFile` gone, both new exports present, and
|
|
30672
|
+
// `credentialDelivery !== "broker"` (the narrowed block form)
|
|
30673
|
+
// appears for the first time.
|
|
30674
|
+
// The `!==` form is the one that matters: it is the guard that keeps
|
|
30675
|
+
// XERO_TENANT_ID on a broker-marked row, i.e. the thing whose absence is the
|
|
30676
|
+
// ENG-4898 leak.
|
|
30677
|
+
//
|
|
30678
|
+
// The interval's OTHER edge was bisected the same way, so the description
|
|
30679
|
+
// above can name a version instead of an issue: `credentialDelivery` appears
|
|
30680
|
+
// in no file of 0.28.507 and in five files of 0.28.508, so ENG-8344's marker
|
|
30681
|
+
// handling first shipped in 0.28.508. A host below that is genuinely safe
|
|
30682
|
+
// rather than merely old — it has no code to honour the marker with.
|
|
30683
|
+
//
|
|
30684
|
+
// Same caveat as every other `since` in this registry: it is ADVISORY. It is
|
|
30685
|
+
// read only by `computeFlagReach` behind GET /flags/admin/reach, so it
|
|
30686
|
+
// changes what an operator is TOLD and does not stop a flip on an
|
|
30687
|
+
// under-`since` host. What holds the line is `defaultValue: false`, plus
|
|
30688
|
+
// `sensitive: true`, plus the two gates spelled out in the description.
|
|
30689
|
+
since: "0.28.1015"
|
|
30690
|
+
},
|
|
30632
30691
|
{
|
|
30633
30692
|
key: "help-kb-auto-grant",
|
|
30634
30693
|
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|
package/dist/mcp/origami.js
CHANGED
|
@@ -42664,7 +42664,10 @@ var FLAG_REGISTRY = [
|
|
|
42664
42664
|
// Disabling this RESTORES the shared host-wide key to every container, and
|
|
42665
42665
|
// with it the cross-agent credential read ENG-8992 closes. A credential-scope
|
|
42666
42666
|
// reduction should not be one click away without confirmation — same posture
|
|
42667
|
-
// as `github-broker-credentials
|
|
42667
|
+
// as the credential-delivery flags `github-broker-credentials` and
|
|
42668
|
+
// `xero-broker-credentials`. (This said "the OTHER credential-delivery flag"
|
|
42669
|
+
// while there was one; ENG-10939 added the second, so the singular had to go
|
|
42670
|
+
// rather than silently become a claim that github is the only sibling.)
|
|
42668
42671
|
sensitive: true,
|
|
42669
42672
|
// The reader is host-side (`hostFlagStore().getBoolean(...)` in the manager),
|
|
42670
42673
|
// so a host on an older agt-cli has no consumer code: it keeps forwarding the
|
|
@@ -43811,6 +43814,12 @@ var FLAG_REGISTRY = [
|
|
|
43811
43814
|
// are the precedent: pinned ABOVE every published release ON PURPOSE,
|
|
43812
43815
|
// labelled as a placeholder, and gated on a post-publish bisect.
|
|
43813
43816
|
//
|
|
43817
|
+
// ENG-10939: `xero-broker-credentials` is the worked example of the other
|
|
43818
|
+
// half of that convention - the bisect that DISCHARGES a placeholder. Its
|
|
43819
|
+
// `since` is a real published version read off `npm pack` tarballs, with the
|
|
43820
|
+
// markers it was bisected on written down, so the two entries together show
|
|
43821
|
+
// both states this field is allowed to be in.
|
|
43822
|
+
//
|
|
43814
43823
|
// (This cited `claudecode-agt-bin-credential-helpers` until obi-wan
|
|
43815
43824
|
// `8f9d3c43076c` pointed out no such key exists anywhere in the repo - the
|
|
43816
43825
|
// only occurrence in the tree was this citation. The precedent was real and
|
|
@@ -44577,6 +44586,56 @@ var FLAG_REGISTRY = [
|
|
|
44577
44586
|
// flips); shipping a guessed number is not.
|
|
44578
44587
|
since: "0.29.0"
|
|
44579
44588
|
},
|
|
44589
|
+
{
|
|
44590
|
+
key: "xero-broker-credentials",
|
|
44591
|
+
description: 'Deliver the Xero OAuth access token to the vendor Xero MCP server through the broker credential endpoint at USE time, instead of materializing it onto the agent host at spawn (ENG-10939, step 1 of the Xero lockdown ENG-10927). Mechanically the sibling of `github-broker-credentials`; the REASON and the cost of a bad flip are both different. ON: POST /host/agent-integrations strips `access_token`, `refresh_token` and `token_expires_at` from the xero row and marks it credential_delivery=broker, so XERO_ACCESS_TOKEN stops being written to .env.integrations. Nothing replaces it host-side and nothing needs to: the vendor MCP server has fetched a fresh token per call from POST /host/agent-integrations/:id/credential since ENG-4920, and `brokerMode` is true for every install carrying an id - so XERO_CLIENT_BEARER_TOKEN: ${XERO_ACCESS_TOKEN} is already not emitted and no dangling reference is left behind. `granted_scopes` and `read_only` are deliberately KEPT: they are consent metadata the host reports scope drift from, not credentials. OFF (default): byte-for-byte today\'s behaviour. WHY THIS IS NOT THE GITHUB FLAG. For github, an under-`since` host on a flipped flag LOSES `git`/`gh` - an outage. For xero the equivalent host LEAKS: before ENG-10939 the ENG-8344 broker guard was a loop-level `continue` that also skipped the config-derived env vars, so a broker-marked xero row dropped XERO_TENANT_ID, and per ENG-4898 the vendor MCP server then falls back to `tenants[0]` - a CROSS-TENANT DATA LEAK with no error anywhere. The dangerous fleet is therefore an INTERVAL, not "old hosts", and BOTH edges are bisected from published tarballs rather than named by issue: below agt-cli 0.28.508 a host carries no `credentialDelivery` handling at all, so it ignores the marker and is SAFE; from 0.28.508 up to (not including) 0.28.1015 it honours the marker with the WIDE skip and LEAKS; at 0.28.1015 and above the skip is narrowed and the behaviour is correct. `since` is a lower bound, so it classifies BOTH ends of that interval as `stale` and cannot tell a safe pre-0.28.508 host from a leaking-middle one. THE FLIP GATE IS THEREFORE NOT "the modal shows reach": it is zero xero-bearing hosts below 0.28.1015 per hosts.agt_version, counting NULL and stale as UNCONVERGED (the heartbeat writes that column conditionally on presence, so a host that stopped reporting keeps its last value - the async-export-rollout pattern). AND A SECOND GATE THE MODAL CANNOT SEE AT ALL: the rewritten Xero skills (ENG-10961) must be live in the catalog AND have reached hosts BEFORE this is flipped. Reversed, a host has no token while its own skills still tell it to read one - a silent read outage with no error at the write site. The catalog reaches prod through `pnpm db:catalog:seed` on deploy, not through the code deploy itself, so "merged" is not "live". EXPECTED ON FLIP DAY, so it is not a surprise: the payload shrinks, so computeIntegrationsHash moves once and XERO_ACCESS_TOKEN reads present->absent in the env diff. That does NOT respawn the session. `liveProxyTokenVars` collects AGT_REMOTE_MCP_TOKEN_VAR from .mcp.json (= XERO_ACCESS_TOKEN in broker mode) and the manager filters it out of `respawnVars` BY NAME, kind-blind - so a removal is exempt on exactly the same line a rotation is (ENG-8264). The ENG-5318 child-kill path is likewise unreachable, because broker mode never emits the ${XERO_ACCESS_TOKEN} reference the stale-mcp-reaper keys on. Both restart paths that touch this var are already quiet. Evaluated API-side only, per agent, in POST /host/agent-integrations. The host does not read this flag - it keys off the resulting credential_delivery marker - so there is deliberately NO host-side envVar that could put the token back on its own. Roll back from the flag.',
|
|
44592
|
+
flagType: "boolean",
|
|
44593
|
+
// Declared safe value is `false` = today's env delivery. Fail-safe here is
|
|
44594
|
+
// not symmetrical with github's: OFF leaves a credential on the host (bad,
|
|
44595
|
+
// but the status quo this epic is closing), while a wrongly-ON flip on an
|
|
44596
|
+
// under-`since` host LEAKS ANOTHER TENANT'S DATA. `false` is still the right
|
|
44597
|
+
// default, because the ON path is the one with a reach precondition — but
|
|
44598
|
+
// the reason is "do not arm this until the fleet is measured", not "a flag
|
|
44599
|
+
// blip must not break the agent".
|
|
44600
|
+
defaultValue: false,
|
|
44601
|
+
// Flipping ON changes how every Xero agent on the scope authenticates, and
|
|
44602
|
+
// on an unconverged host it is a cross-tenant leak rather than an outage. A
|
|
44603
|
+
// deliberate, confirmed action (ADR-0022 §4).
|
|
44604
|
+
sensitive: true,
|
|
44605
|
+
// A REAL bisected threshold, not the placeholder `github-broker-credentials`
|
|
44606
|
+
// and `per-agent-host-credentials` had to ship with: the host-side code this
|
|
44607
|
+
// flag depends on (ENG-10939 item 0, narrowing the ENG-8344 broker guard so
|
|
44608
|
+
// it skips the CREDENTIAL and not the whole row's config) landed in PR #6443
|
|
44609
|
+
// and has already published.
|
|
44610
|
+
//
|
|
44611
|
+
// Read off the published tarballs rather than inferred from the merge
|
|
44612
|
+
// timestamp. #6443 merged at 2026-09-24T01:54:41Z; 0.28.1015 published at
|
|
44613
|
+
// 01:59:23Z. `npm pack` of 0.28.1013/1014/1015/1016 + grep of the extracted
|
|
44614
|
+
// bundle agrees in both directions on four independent markers:
|
|
44615
|
+
// 0.28.1014 — `writeTokenFile` present (4 files), `isRespawnExemptEnvVar`
|
|
44616
|
+
// and `RESPAWN_EXEMPT_CONFIG_TAILS` absent, and the only
|
|
44617
|
+
// broker-guard spelling is `credentialDelivery === "broker"`
|
|
44618
|
+
// (the wide skip).
|
|
44619
|
+
// 0.28.1015 — `writeTokenFile` gone, both new exports present, and
|
|
44620
|
+
// `credentialDelivery !== "broker"` (the narrowed block form)
|
|
44621
|
+
// appears for the first time.
|
|
44622
|
+
// The `!==` form is the one that matters: it is the guard that keeps
|
|
44623
|
+
// XERO_TENANT_ID on a broker-marked row, i.e. the thing whose absence is the
|
|
44624
|
+
// ENG-4898 leak.
|
|
44625
|
+
//
|
|
44626
|
+
// The interval's OTHER edge was bisected the same way, so the description
|
|
44627
|
+
// above can name a version instead of an issue: `credentialDelivery` appears
|
|
44628
|
+
// in no file of 0.28.507 and in five files of 0.28.508, so ENG-8344's marker
|
|
44629
|
+
// handling first shipped in 0.28.508. A host below that is genuinely safe
|
|
44630
|
+
// rather than merely old — it has no code to honour the marker with.
|
|
44631
|
+
//
|
|
44632
|
+
// Same caveat as every other `since` in this registry: it is ADVISORY. It is
|
|
44633
|
+
// read only by `computeFlagReach` behind GET /flags/admin/reach, so it
|
|
44634
|
+
// changes what an operator is TOLD and does not stop a flip on an
|
|
44635
|
+
// under-`since` host. What holds the line is `defaultValue: false`, plus
|
|
44636
|
+
// `sensitive: true`, plus the two gates spelled out in the description.
|
|
44637
|
+
since: "0.28.1015"
|
|
44638
|
+
},
|
|
44580
44639
|
{
|
|
44581
44640
|
key: "help-kb-auto-grant",
|
|
44582
44641
|
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|
|
@@ -37303,7 +37303,10 @@ var FLAG_REGISTRY = [
|
|
|
37303
37303
|
// Disabling this RESTORES the shared host-wide key to every container, and
|
|
37304
37304
|
// with it the cross-agent credential read ENG-8992 closes. A credential-scope
|
|
37305
37305
|
// reduction should not be one click away without confirmation — same posture
|
|
37306
|
-
// as `github-broker-credentials
|
|
37306
|
+
// as the credential-delivery flags `github-broker-credentials` and
|
|
37307
|
+
// `xero-broker-credentials`. (This said "the OTHER credential-delivery flag"
|
|
37308
|
+
// while there was one; ENG-10939 added the second, so the singular had to go
|
|
37309
|
+
// rather than silently become a claim that github is the only sibling.)
|
|
37307
37310
|
sensitive: true,
|
|
37308
37311
|
// The reader is host-side (`hostFlagStore().getBoolean(...)` in the manager),
|
|
37309
37312
|
// so a host on an older agt-cli has no consumer code: it keeps forwarding the
|
|
@@ -38450,6 +38453,12 @@ var FLAG_REGISTRY = [
|
|
|
38450
38453
|
// are the precedent: pinned ABOVE every published release ON PURPOSE,
|
|
38451
38454
|
// labelled as a placeholder, and gated on a post-publish bisect.
|
|
38452
38455
|
//
|
|
38456
|
+
// ENG-10939: `xero-broker-credentials` is the worked example of the other
|
|
38457
|
+
// half of that convention - the bisect that DISCHARGES a placeholder. Its
|
|
38458
|
+
// `since` is a real published version read off `npm pack` tarballs, with the
|
|
38459
|
+
// markers it was bisected on written down, so the two entries together show
|
|
38460
|
+
// both states this field is allowed to be in.
|
|
38461
|
+
//
|
|
38453
38462
|
// (This cited `claudecode-agt-bin-credential-helpers` until obi-wan
|
|
38454
38463
|
// `8f9d3c43076c` pointed out no such key exists anywhere in the repo - the
|
|
38455
38464
|
// only occurrence in the tree was this citation. The precedent was real and
|
|
@@ -39216,6 +39225,56 @@ var FLAG_REGISTRY = [
|
|
|
39216
39225
|
// flips); shipping a guessed number is not.
|
|
39217
39226
|
since: "0.29.0"
|
|
39218
39227
|
},
|
|
39228
|
+
{
|
|
39229
|
+
key: "xero-broker-credentials",
|
|
39230
|
+
description: 'Deliver the Xero OAuth access token to the vendor Xero MCP server through the broker credential endpoint at USE time, instead of materializing it onto the agent host at spawn (ENG-10939, step 1 of the Xero lockdown ENG-10927). Mechanically the sibling of `github-broker-credentials`; the REASON and the cost of a bad flip are both different. ON: POST /host/agent-integrations strips `access_token`, `refresh_token` and `token_expires_at` from the xero row and marks it credential_delivery=broker, so XERO_ACCESS_TOKEN stops being written to .env.integrations. Nothing replaces it host-side and nothing needs to: the vendor MCP server has fetched a fresh token per call from POST /host/agent-integrations/:id/credential since ENG-4920, and `brokerMode` is true for every install carrying an id - so XERO_CLIENT_BEARER_TOKEN: ${XERO_ACCESS_TOKEN} is already not emitted and no dangling reference is left behind. `granted_scopes` and `read_only` are deliberately KEPT: they are consent metadata the host reports scope drift from, not credentials. OFF (default): byte-for-byte today\'s behaviour. WHY THIS IS NOT THE GITHUB FLAG. For github, an under-`since` host on a flipped flag LOSES `git`/`gh` - an outage. For xero the equivalent host LEAKS: before ENG-10939 the ENG-8344 broker guard was a loop-level `continue` that also skipped the config-derived env vars, so a broker-marked xero row dropped XERO_TENANT_ID, and per ENG-4898 the vendor MCP server then falls back to `tenants[0]` - a CROSS-TENANT DATA LEAK with no error anywhere. The dangerous fleet is therefore an INTERVAL, not "old hosts", and BOTH edges are bisected from published tarballs rather than named by issue: below agt-cli 0.28.508 a host carries no `credentialDelivery` handling at all, so it ignores the marker and is SAFE; from 0.28.508 up to (not including) 0.28.1015 it honours the marker with the WIDE skip and LEAKS; at 0.28.1015 and above the skip is narrowed and the behaviour is correct. `since` is a lower bound, so it classifies BOTH ends of that interval as `stale` and cannot tell a safe pre-0.28.508 host from a leaking-middle one. THE FLIP GATE IS THEREFORE NOT "the modal shows reach": it is zero xero-bearing hosts below 0.28.1015 per hosts.agt_version, counting NULL and stale as UNCONVERGED (the heartbeat writes that column conditionally on presence, so a host that stopped reporting keeps its last value - the async-export-rollout pattern). AND A SECOND GATE THE MODAL CANNOT SEE AT ALL: the rewritten Xero skills (ENG-10961) must be live in the catalog AND have reached hosts BEFORE this is flipped. Reversed, a host has no token while its own skills still tell it to read one - a silent read outage with no error at the write site. The catalog reaches prod through `pnpm db:catalog:seed` on deploy, not through the code deploy itself, so "merged" is not "live". EXPECTED ON FLIP DAY, so it is not a surprise: the payload shrinks, so computeIntegrationsHash moves once and XERO_ACCESS_TOKEN reads present->absent in the env diff. That does NOT respawn the session. `liveProxyTokenVars` collects AGT_REMOTE_MCP_TOKEN_VAR from .mcp.json (= XERO_ACCESS_TOKEN in broker mode) and the manager filters it out of `respawnVars` BY NAME, kind-blind - so a removal is exempt on exactly the same line a rotation is (ENG-8264). The ENG-5318 child-kill path is likewise unreachable, because broker mode never emits the ${XERO_ACCESS_TOKEN} reference the stale-mcp-reaper keys on. Both restart paths that touch this var are already quiet. Evaluated API-side only, per agent, in POST /host/agent-integrations. The host does not read this flag - it keys off the resulting credential_delivery marker - so there is deliberately NO host-side envVar that could put the token back on its own. Roll back from the flag.',
|
|
39231
|
+
flagType: "boolean",
|
|
39232
|
+
// Declared safe value is `false` = today's env delivery. Fail-safe here is
|
|
39233
|
+
// not symmetrical with github's: OFF leaves a credential on the host (bad,
|
|
39234
|
+
// but the status quo this epic is closing), while a wrongly-ON flip on an
|
|
39235
|
+
// under-`since` host LEAKS ANOTHER TENANT'S DATA. `false` is still the right
|
|
39236
|
+
// default, because the ON path is the one with a reach precondition — but
|
|
39237
|
+
// the reason is "do not arm this until the fleet is measured", not "a flag
|
|
39238
|
+
// blip must not break the agent".
|
|
39239
|
+
defaultValue: false,
|
|
39240
|
+
// Flipping ON changes how every Xero agent on the scope authenticates, and
|
|
39241
|
+
// on an unconverged host it is a cross-tenant leak rather than an outage. A
|
|
39242
|
+
// deliberate, confirmed action (ADR-0022 §4).
|
|
39243
|
+
sensitive: true,
|
|
39244
|
+
// A REAL bisected threshold, not the placeholder `github-broker-credentials`
|
|
39245
|
+
// and `per-agent-host-credentials` had to ship with: the host-side code this
|
|
39246
|
+
// flag depends on (ENG-10939 item 0, narrowing the ENG-8344 broker guard so
|
|
39247
|
+
// it skips the CREDENTIAL and not the whole row's config) landed in PR #6443
|
|
39248
|
+
// and has already published.
|
|
39249
|
+
//
|
|
39250
|
+
// Read off the published tarballs rather than inferred from the merge
|
|
39251
|
+
// timestamp. #6443 merged at 2026-09-24T01:54:41Z; 0.28.1015 published at
|
|
39252
|
+
// 01:59:23Z. `npm pack` of 0.28.1013/1014/1015/1016 + grep of the extracted
|
|
39253
|
+
// bundle agrees in both directions on four independent markers:
|
|
39254
|
+
// 0.28.1014 — `writeTokenFile` present (4 files), `isRespawnExemptEnvVar`
|
|
39255
|
+
// and `RESPAWN_EXEMPT_CONFIG_TAILS` absent, and the only
|
|
39256
|
+
// broker-guard spelling is `credentialDelivery === "broker"`
|
|
39257
|
+
// (the wide skip).
|
|
39258
|
+
// 0.28.1015 — `writeTokenFile` gone, both new exports present, and
|
|
39259
|
+
// `credentialDelivery !== "broker"` (the narrowed block form)
|
|
39260
|
+
// appears for the first time.
|
|
39261
|
+
// The `!==` form is the one that matters: it is the guard that keeps
|
|
39262
|
+
// XERO_TENANT_ID on a broker-marked row, i.e. the thing whose absence is the
|
|
39263
|
+
// ENG-4898 leak.
|
|
39264
|
+
//
|
|
39265
|
+
// The interval's OTHER edge was bisected the same way, so the description
|
|
39266
|
+
// above can name a version instead of an issue: `credentialDelivery` appears
|
|
39267
|
+
// in no file of 0.28.507 and in five files of 0.28.508, so ENG-8344's marker
|
|
39268
|
+
// handling first shipped in 0.28.508. A host below that is genuinely safe
|
|
39269
|
+
// rather than merely old — it has no code to honour the marker with.
|
|
39270
|
+
//
|
|
39271
|
+
// Same caveat as every other `since` in this registry: it is ADVISORY. It is
|
|
39272
|
+
// read only by `computeFlagReach` behind GET /flags/admin/reach, so it
|
|
39273
|
+
// changes what an operator is TOLD and does not stop a flip on an
|
|
39274
|
+
// under-`since` host. What holds the line is `defaultValue: false`, plus
|
|
39275
|
+
// `sensitive: true`, plus the two gates spelled out in the description.
|
|
39276
|
+
since: "0.28.1015"
|
|
39277
|
+
},
|
|
39219
39278
|
{
|
|
39220
39279
|
key: "help-kb-auto-grant",
|
|
39221
39280
|
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|
|
@@ -37409,7 +37409,10 @@ var FLAG_REGISTRY = [
|
|
|
37409
37409
|
// Disabling this RESTORES the shared host-wide key to every container, and
|
|
37410
37410
|
// with it the cross-agent credential read ENG-8992 closes. A credential-scope
|
|
37411
37411
|
// reduction should not be one click away without confirmation — same posture
|
|
37412
|
-
// as `github-broker-credentials
|
|
37412
|
+
// as the credential-delivery flags `github-broker-credentials` and
|
|
37413
|
+
// `xero-broker-credentials`. (This said "the OTHER credential-delivery flag"
|
|
37414
|
+
// while there was one; ENG-10939 added the second, so the singular had to go
|
|
37415
|
+
// rather than silently become a claim that github is the only sibling.)
|
|
37413
37416
|
sensitive: true,
|
|
37414
37417
|
// The reader is host-side (`hostFlagStore().getBoolean(...)` in the manager),
|
|
37415
37418
|
// so a host on an older agt-cli has no consumer code: it keeps forwarding the
|
|
@@ -38556,6 +38559,12 @@ var FLAG_REGISTRY = [
|
|
|
38556
38559
|
// are the precedent: pinned ABOVE every published release ON PURPOSE,
|
|
38557
38560
|
// labelled as a placeholder, and gated on a post-publish bisect.
|
|
38558
38561
|
//
|
|
38562
|
+
// ENG-10939: `xero-broker-credentials` is the worked example of the other
|
|
38563
|
+
// half of that convention - the bisect that DISCHARGES a placeholder. Its
|
|
38564
|
+
// `since` is a real published version read off `npm pack` tarballs, with the
|
|
38565
|
+
// markers it was bisected on written down, so the two entries together show
|
|
38566
|
+
// both states this field is allowed to be in.
|
|
38567
|
+
//
|
|
38559
38568
|
// (This cited `claudecode-agt-bin-credential-helpers` until obi-wan
|
|
38560
38569
|
// `8f9d3c43076c` pointed out no such key exists anywhere in the repo - the
|
|
38561
38570
|
// only occurrence in the tree was this citation. The precedent was real and
|
|
@@ -39322,6 +39331,56 @@ var FLAG_REGISTRY = [
|
|
|
39322
39331
|
// flips); shipping a guessed number is not.
|
|
39323
39332
|
since: "0.29.0"
|
|
39324
39333
|
},
|
|
39334
|
+
{
|
|
39335
|
+
key: "xero-broker-credentials",
|
|
39336
|
+
description: 'Deliver the Xero OAuth access token to the vendor Xero MCP server through the broker credential endpoint at USE time, instead of materializing it onto the agent host at spawn (ENG-10939, step 1 of the Xero lockdown ENG-10927). Mechanically the sibling of `github-broker-credentials`; the REASON and the cost of a bad flip are both different. ON: POST /host/agent-integrations strips `access_token`, `refresh_token` and `token_expires_at` from the xero row and marks it credential_delivery=broker, so XERO_ACCESS_TOKEN stops being written to .env.integrations. Nothing replaces it host-side and nothing needs to: the vendor MCP server has fetched a fresh token per call from POST /host/agent-integrations/:id/credential since ENG-4920, and `brokerMode` is true for every install carrying an id - so XERO_CLIENT_BEARER_TOKEN: ${XERO_ACCESS_TOKEN} is already not emitted and no dangling reference is left behind. `granted_scopes` and `read_only` are deliberately KEPT: they are consent metadata the host reports scope drift from, not credentials. OFF (default): byte-for-byte today\'s behaviour. WHY THIS IS NOT THE GITHUB FLAG. For github, an under-`since` host on a flipped flag LOSES `git`/`gh` - an outage. For xero the equivalent host LEAKS: before ENG-10939 the ENG-8344 broker guard was a loop-level `continue` that also skipped the config-derived env vars, so a broker-marked xero row dropped XERO_TENANT_ID, and per ENG-4898 the vendor MCP server then falls back to `tenants[0]` - a CROSS-TENANT DATA LEAK with no error anywhere. The dangerous fleet is therefore an INTERVAL, not "old hosts", and BOTH edges are bisected from published tarballs rather than named by issue: below agt-cli 0.28.508 a host carries no `credentialDelivery` handling at all, so it ignores the marker and is SAFE; from 0.28.508 up to (not including) 0.28.1015 it honours the marker with the WIDE skip and LEAKS; at 0.28.1015 and above the skip is narrowed and the behaviour is correct. `since` is a lower bound, so it classifies BOTH ends of that interval as `stale` and cannot tell a safe pre-0.28.508 host from a leaking-middle one. THE FLIP GATE IS THEREFORE NOT "the modal shows reach": it is zero xero-bearing hosts below 0.28.1015 per hosts.agt_version, counting NULL and stale as UNCONVERGED (the heartbeat writes that column conditionally on presence, so a host that stopped reporting keeps its last value - the async-export-rollout pattern). AND A SECOND GATE THE MODAL CANNOT SEE AT ALL: the rewritten Xero skills (ENG-10961) must be live in the catalog AND have reached hosts BEFORE this is flipped. Reversed, a host has no token while its own skills still tell it to read one - a silent read outage with no error at the write site. The catalog reaches prod through `pnpm db:catalog:seed` on deploy, not through the code deploy itself, so "merged" is not "live". EXPECTED ON FLIP DAY, so it is not a surprise: the payload shrinks, so computeIntegrationsHash moves once and XERO_ACCESS_TOKEN reads present->absent in the env diff. That does NOT respawn the session. `liveProxyTokenVars` collects AGT_REMOTE_MCP_TOKEN_VAR from .mcp.json (= XERO_ACCESS_TOKEN in broker mode) and the manager filters it out of `respawnVars` BY NAME, kind-blind - so a removal is exempt on exactly the same line a rotation is (ENG-8264). The ENG-5318 child-kill path is likewise unreachable, because broker mode never emits the ${XERO_ACCESS_TOKEN} reference the stale-mcp-reaper keys on. Both restart paths that touch this var are already quiet. Evaluated API-side only, per agent, in POST /host/agent-integrations. The host does not read this flag - it keys off the resulting credential_delivery marker - so there is deliberately NO host-side envVar that could put the token back on its own. Roll back from the flag.',
|
|
39337
|
+
flagType: "boolean",
|
|
39338
|
+
// Declared safe value is `false` = today's env delivery. Fail-safe here is
|
|
39339
|
+
// not symmetrical with github's: OFF leaves a credential on the host (bad,
|
|
39340
|
+
// but the status quo this epic is closing), while a wrongly-ON flip on an
|
|
39341
|
+
// under-`since` host LEAKS ANOTHER TENANT'S DATA. `false` is still the right
|
|
39342
|
+
// default, because the ON path is the one with a reach precondition — but
|
|
39343
|
+
// the reason is "do not arm this until the fleet is measured", not "a flag
|
|
39344
|
+
// blip must not break the agent".
|
|
39345
|
+
defaultValue: false,
|
|
39346
|
+
// Flipping ON changes how every Xero agent on the scope authenticates, and
|
|
39347
|
+
// on an unconverged host it is a cross-tenant leak rather than an outage. A
|
|
39348
|
+
// deliberate, confirmed action (ADR-0022 §4).
|
|
39349
|
+
sensitive: true,
|
|
39350
|
+
// A REAL bisected threshold, not the placeholder `github-broker-credentials`
|
|
39351
|
+
// and `per-agent-host-credentials` had to ship with: the host-side code this
|
|
39352
|
+
// flag depends on (ENG-10939 item 0, narrowing the ENG-8344 broker guard so
|
|
39353
|
+
// it skips the CREDENTIAL and not the whole row's config) landed in PR #6443
|
|
39354
|
+
// and has already published.
|
|
39355
|
+
//
|
|
39356
|
+
// Read off the published tarballs rather than inferred from the merge
|
|
39357
|
+
// timestamp. #6443 merged at 2026-09-24T01:54:41Z; 0.28.1015 published at
|
|
39358
|
+
// 01:59:23Z. `npm pack` of 0.28.1013/1014/1015/1016 + grep of the extracted
|
|
39359
|
+
// bundle agrees in both directions on four independent markers:
|
|
39360
|
+
// 0.28.1014 — `writeTokenFile` present (4 files), `isRespawnExemptEnvVar`
|
|
39361
|
+
// and `RESPAWN_EXEMPT_CONFIG_TAILS` absent, and the only
|
|
39362
|
+
// broker-guard spelling is `credentialDelivery === "broker"`
|
|
39363
|
+
// (the wide skip).
|
|
39364
|
+
// 0.28.1015 — `writeTokenFile` gone, both new exports present, and
|
|
39365
|
+
// `credentialDelivery !== "broker"` (the narrowed block form)
|
|
39366
|
+
// appears for the first time.
|
|
39367
|
+
// The `!==` form is the one that matters: it is the guard that keeps
|
|
39368
|
+
// XERO_TENANT_ID on a broker-marked row, i.e. the thing whose absence is the
|
|
39369
|
+
// ENG-4898 leak.
|
|
39370
|
+
//
|
|
39371
|
+
// The interval's OTHER edge was bisected the same way, so the description
|
|
39372
|
+
// above can name a version instead of an issue: `credentialDelivery` appears
|
|
39373
|
+
// in no file of 0.28.507 and in five files of 0.28.508, so ENG-8344's marker
|
|
39374
|
+
// handling first shipped in 0.28.508. A host below that is genuinely safe
|
|
39375
|
+
// rather than merely old — it has no code to honour the marker with.
|
|
39376
|
+
//
|
|
39377
|
+
// Same caveat as every other `since` in this registry: it is ADVISORY. It is
|
|
39378
|
+
// read only by `computeFlagReach` behind GET /flags/admin/reach, so it
|
|
39379
|
+
// changes what an operator is TOLD and does not stop a flip on an
|
|
39380
|
+
// under-`since` host. What holds the line is `defaultValue: false`, plus
|
|
39381
|
+
// `sensitive: true`, plus the two gates spelled out in the description.
|
|
39382
|
+
since: "0.28.1015"
|
|
39383
|
+
},
|
|
39325
39384
|
{
|
|
39326
39385
|
key: "help-kb-auto-grant",
|
|
39327
39386
|
description: "Auto-grant the `augmented-help-kb` integration at ORG scope when an organization is provisioned (ENG-8542), so every agent in that org gets product-doc search without a per-agent operator action. One organization_integrations row reaches every agent in the org: POST /host/agent-integrations merges org -> team -> agent and buildMcpJson's predicate reads that merged set with no scope filter. ON: the two org-provisioning call sites write the row (status=active, created_by=the org owner). OFF (default): they write nothing - byte-for-byte today's behaviour. STAGED ROLLOUT IS THE POINT. ENG-8332 argues against widening distribution of the help KB until two things close, because distributing a corpus with wrong articles \"converts one agent's wrong answer into everyone's\": (1) a live 200 from GET /host/kb/search as the anon role has still never been observed - ENG-7260 was closed on remediation evidence, not on a live call, and the deploy seed log is SERVICE-ROLE evidence that says nothing about the anon grant; (2) the `site-structure` article is unverified against the current IA. Turning this on for ONE org and watching that org's help-kb connectivity-probe verdicts (ENG-8332 added a real mcp_stdio probe that calls search_knowledge_base) is the cheap positive control for (1) - an ENG-7260-class 500 then reports as `down` per agent instead of as silence. Widen only after it comes back healthy. REVOKING IS DELETING THE ROW, not flipping this off: the flag gates GRANTING, so an already-granted org keeps its row when the flag goes off. Evaluated API-side only, per org, inside grantHelpKbToOrg; no host-side envVar and deliberately no sst.config.ts entry (a literal default there would pin it - ENG-8303).",
|