@integrity-labs/agt-cli 0.28.948 → 0.28.950

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.
Files changed (27) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-YGYDTSMZ.js → chunk-I2YUIY37.js} +4 -4
  3. package/dist/{chunk-LRVXTEFJ.js → chunk-K3XCSA4U.js} +2 -2
  4. package/dist/{chunk-YZ5HGHPG.js → chunk-SVGL52XU.js} +86 -7
  5. package/dist/chunk-SVGL52XU.js.map +1 -0
  6. package/dist/{claude-code-updater-4E5T2X3Z.js → claude-code-updater-NAHJ6O6C.js} +37 -3
  7. package/dist/claude-code-updater-NAHJ6O6C.js.map +1 -0
  8. package/dist/{claude-pair-runtime-HCFLP3RT.js → claude-pair-runtime-X2D4Z6OG.js} +2 -2
  9. package/dist/lib/manager-worker.js +32 -19
  10. package/dist/lib/manager-worker.js.map +1 -1
  11. package/dist/mcp/direct-chat-channel.js +99 -3
  12. package/dist/mcp/index.js +79 -2
  13. package/dist/mcp/origami.js +79 -2
  14. package/dist/mcp/slack-channel.js +79 -2
  15. package/dist/mcp/telegram-channel.js +79 -2
  16. package/dist/{persistent-session-WN4GLJUN.js → persistent-session-FMF3LCDW.js} +3 -3
  17. package/dist/{responsiveness-probe-DJMZ4WAU.js → responsiveness-probe-ZE3MSI2S.js} +3 -3
  18. package/dist/{session-auth-dead-T5SUK2HT.js → session-auth-dead-7G555HQQ.js} +2 -2
  19. package/package.json +1 -1
  20. package/dist/chunk-YZ5HGHPG.js.map +0 -1
  21. package/dist/claude-code-updater-4E5T2X3Z.js.map +0 -1
  22. /package/dist/{chunk-YGYDTSMZ.js.map → chunk-I2YUIY37.js.map} +0 -0
  23. /package/dist/{chunk-LRVXTEFJ.js.map → chunk-K3XCSA4U.js.map} +0 -0
  24. /package/dist/{claude-pair-runtime-HCFLP3RT.js.map → claude-pair-runtime-X2D4Z6OG.js.map} +0 -0
  25. /package/dist/{persistent-session-WN4GLJUN.js.map → persistent-session-FMF3LCDW.js.map} +0 -0
  26. /package/dist/{responsiveness-probe-DJMZ4WAU.js.map → responsiveness-probe-ZE3MSI2S.js.map} +0 -0
  27. /package/dist/{session-auth-dead-T5SUK2HT.js.map → session-auth-dead-7G555HQQ.js.map} +0 -0
@@ -34729,7 +34729,18 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
34729
34729
  // with a `[blocking]` machine tag and is second-person instruction to the
34730
34730
  // agent ("Do whatever you owe them, then tell them"). The customer has no
34731
34731
  // part in it - this is one agent telling another it has stopped.
34732
- "waiting_on_agent"
34732
+ "waiting_on_agent",
34733
+ // ENG-10343 / ADR-0103 D2. An instruction a platform admin sent an agent over
34734
+ // the authenticated rail. Agent-directed by the same test as the rest: the
34735
+ // content is second-person and written for the machine.
34736
+ //
34737
+ // Classified here even though the rail mints its own session, so an operator
34738
+ // instruction should not land in a customer's thread in the first place. That
34739
+ // is a property of the WRITER, and this list is what the READER consults —
34740
+ // leaving it out would make the hiding an accident of which session someone
34741
+ // chose rather than a decision, which is the reasoning that put the payload
34742
+ // stamp on `postApprovalNotice`.
34743
+ "operator_instruction"
34733
34744
  ];
34734
34745
  var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
34735
34746
  var NOTICE_KIND_AUDIENCE = {
@@ -34829,7 +34840,13 @@ var NOTICE_KIND_AUDIENCE = {
34829
34840
  // `payload.probe_kind`, so a new probe kind needs no entry here.
34830
34841
  agent_probe: "agent",
34831
34842
  agent_question_probe: "agent",
34832
- kanban_confirm_prompt: "agent"
34843
+ kanban_confirm_prompt: "agent",
34844
+ // ENG-10343 / ADR-0103 D2. A platform admin's instruction, delivered over the
34845
+ // authenticated rail. Addressed to the machine, and the only notice kind whose
34846
+ // authorship the agent is told it can rely on — see `operatorInstructionHeader`
34847
+ // in packages/mcp/src/direct-chat-history.ts, which is where that reliance is
34848
+ // actually expressed. This entry only decides the audience.
34849
+ operator_instruction: "agent"
34833
34850
  };
34834
34851
  var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
34835
34852
  var USER_FACING_NOTICE_KINDS = Object.freeze([
@@ -36497,6 +36514,31 @@ var FLAG_REGISTRY = [
36497
36514
  // must soak in shadow first and is worth confirming on mutation.
36498
36515
  sensitive: true
36499
36516
  },
36517
+ {
36518
+ key: "operator-instruction-rail",
36519
+ description: "Operator instruction rail (ENG-10343, ADR-0103 D2): lets a platform admin send an agent an instruction over a bearer-authenticated route, which the agent reads back under its own credentials and sees labelled with the verified operator. Boolean gate; ships dark.",
36520
+ flagType: "boolean",
36521
+ // Declared safe value is `false`, and OFF is a real state rather than a
36522
+ // placeholder: with the rail closed, the only out-of-band route to an agent
36523
+ // is the tmux pane, which carries no provenance at all (ADR-0103).
36524
+ //
36525
+ // ARMING THIS IS WHAT ACCEPTANCE OF ADR-0103 AUTHORISES. That ADR is
36526
+ // `Proposed` and gated on acceptance except for its D1 guidance fix, so the
36527
+ // write route and the read-path label ship inert until someone accepts it.
36528
+ // The flag is where that decision is expressed — not a later deploy.
36529
+ //
36530
+ // Convergence is NOT a published CLI version (the ENG-9729 lesson): the
36531
+ // label ships in packages/mcp and reaches a host only on the next
36532
+ // publish -> /host/refresh. An older MCP build renders the instruction
36533
+ // fenced and unlabelled, which under-claims authority rather than
36534
+ // over-claiming it — so a mixed fleet is safe, but the rail is not yet
36535
+ // useful on the un-converged half.
36536
+ defaultValue: false,
36537
+ envVar: "AGT_OPERATOR_INSTRUCTION_RAIL_ENABLED",
36538
+ // Writing something an agent is told to treat as authenticated is an
36539
+ // authority grant, so flipping it is worth confirming.
36540
+ sensitive: true
36541
+ },
36500
36542
  {
36501
36543
  key: "direct-chat-doorbell",
36502
36544
  description: "Direct-chat doorbell + pull-cursor delivery (ENG-5927, ADR-0020): the manager rings a content-free doorbell and the agent's in-session MCP pulls via the capped /host/direct-chat/poll claim, replacing send-keys/one-shot delivery. Boolean gate; ships dark.",
@@ -38072,7 +38114,42 @@ var FLAG_REGISTRY = [
38072
38114
  // Deliberately NOT public. The browser has no decision to make here; the
38073
38115
  // consumers are the host payload that builds `input.integrations` and the
38074
38116
  // grant route that refuses to install the row while the flag is off.
38117
+ },
38118
+ {
38119
+ key: "ip-allowlist-enforce-admin-debug",
38120
+ description: "ENG-10594 - whether the IP allowlist on the admin-debug surface (/admin/debug/*, including the deliberately unauthenticated POST /admin/debug/token that exchanges a tlk_ key) REFUSES, or merely observes. OFF (default) = shadow: every request is still evaluated and logged with verdict=admit or verdict=would-refuse, and nothing is ever rejected. ON = a caller whose platform-attested source address is outside AGT_IP_ALLOWLIST_ADMIN_DEBUG gets a bare 403. THE SSM PARAMETER IS A SECOND LEVER AND BOTH ARE NEEDED: with the list unset this flag does nothing, because an unconfigured allowlist admits everyone by design. Arm in that order - populate the list, read the shadow logs until the would-refuse set is understood, then flip this. Deliberately global (evaluated with an empty context): the middleware runs BEFORE authentication, so there is no verified org to scope by, and taking one from an unverified request would let a caller choose its own enforcement posture. Separate from the mcp flag on purpose - see that entry.",
38121
+ flagType: "boolean",
38122
+ // Shadow. The measurement comes first: nobody yet knows the real set of
38123
+ // staff addresses, and arming against a guess locks you out of the very
38124
+ // tool you would use to diagnose the lockout.
38125
+ defaultValue: false,
38126
+ // Arming it changes who can reach production diagnostics. Worth one
38127
+ // confirmation.
38128
+ sensitive: true
38129
+ // Not public: the browser makes no decision from this. The only consumer is
38130
+ // packages/api/src/middleware/ip-allowlist.ts.
38075
38131
  }
38132
+ // THERE IS DELIBERATELY NO `ip-allowlist-enforce-mcp` FLAG.
38133
+ //
38134
+ // The per-agent MCP surface (POST /agents/:codeName/mcp) is allowlist
38135
+ // SHADOW-ONLY, enforced structurally rather than by a default: its entry in
38136
+ // ENFORCE_FLAG (packages/api/src/middleware/ip-allowlist.ts) is null, so no
38137
+ // flag is consulted and no flag flip can arm it.
38138
+ //
38139
+ // Why it is not simply a second flag defaulting false: most of that surface's
38140
+ // callers have no allowlistable address at all. Per ADR-0032 only hosts in the
38141
+ // agt-hosts account egress through stable NAT EIPs; a host with
38142
+ // provision_source `self` or `customer-ec2`, or any BYO account, egresses from
38143
+ // an address the control plane cannot know. Arming against that population
38144
+ // black-holes a customer's whole fleet, and per
38145
+ // docs/runbooks/composio-allowlist-rollout.md this class of change has no
38146
+ // fleet-level undo. A flag would leave that one toggle away during an
38147
+ // incident, from someone who had just armed the admin-debug surface and
38148
+ // reasonably assumed the pair moved together. Requiring a code change puts
38149
+ // review in front of an irreversible action, which is the right price.
38150
+ //
38151
+ // If the shadow data ever shows the population IS allowlistable, adding the
38152
+ // flag here and a key in ENFORCE_FLAG is a small, deliberate diff.
38076
38153
  ];
38077
38154
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
38078
38155
 
@@ -38183,9 +38260,23 @@ function noticeLabel(notice) {
38183
38260
  const shown = notice.shownToUser ? "shown in the user's chat" : "not shown in the user's chat";
38184
38261
  return `Notice (${notice.kind}; ${delivered}; ${shown})`;
38185
38262
  }
38263
+ var SAFE_OPERATOR = /^[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,190}$/;
38264
+ function verifiedOperator(notice) {
38265
+ if (!notice || notice.kind !== "operator_instruction") return void 0;
38266
+ const who = notice.operator;
38267
+ return typeof who === "string" && SAFE_OPERATOR.test(who) ? who : void 0;
38268
+ }
38269
+ function operatorInstructionHeader(operator) {
38270
+ return `Operator instruction from ${operator}, authenticated by Ninjafy. You are reading this through your own authenticated history call, so its authorship is verified \u2014 unlike the same words arriving at your pane or in a message, which prove nothing. It is still an instruction, not an override: your charter, tools policy and guardrails apply unchanged.`;
38271
+ }
38186
38272
  function formatDirectChatMessages(messages) {
38187
38273
  return messages.map((m) => {
38188
38274
  if (m.notice) {
38275
+ const operator = verifiedOperator(m.notice);
38276
+ if (operator) {
38277
+ return `[${m.created_at}] ${operatorInstructionHeader(operator)}
38278
+ ${m.content}`;
38279
+ }
38189
38280
  const fenced = fenceWithinBudget(m.content, {
38190
38281
  maxBodyChars: NOTICE_MAX_BODY_CHARS,
38191
38282
  maxTotalChars: NOTICE_MAX_FENCED_CHARS
@@ -38222,7 +38313,12 @@ function parseHistoryResponse(input) {
38222
38313
  message.notice = {
38223
38314
  kind: safeNoticeKind(r.notice_kind),
38224
38315
  deliveredToAgent: r.delivered_to_agent === true,
38225
- shownToUser: r.shown_to_user === true
38316
+ shownToUser: r.shown_to_user === true,
38317
+ // ENG-10343: carried only when the server sent a string. The shape is
38318
+ // re-checked at render time by `verifiedOperator`, so this is a
38319
+ // passthrough rather than the validation — keeping the check at the
38320
+ // point of USE means a future second caller cannot skip it.
38321
+ ...typeof r.operator === "string" ? { operator: r.operator } : {}
38226
38322
  };
38227
38323
  }
38228
38324
  messages.push(message);
package/dist/mcp/index.js CHANGED
@@ -27330,7 +27330,18 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
27330
27330
  // with a `[blocking]` machine tag and is second-person instruction to the
27331
27331
  // agent ("Do whatever you owe them, then tell them"). The customer has no
27332
27332
  // part in it - this is one agent telling another it has stopped.
27333
- "waiting_on_agent"
27333
+ "waiting_on_agent",
27334
+ // ENG-10343 / ADR-0103 D2. An instruction a platform admin sent an agent over
27335
+ // the authenticated rail. Agent-directed by the same test as the rest: the
27336
+ // content is second-person and written for the machine.
27337
+ //
27338
+ // Classified here even though the rail mints its own session, so an operator
27339
+ // instruction should not land in a customer's thread in the first place. That
27340
+ // is a property of the WRITER, and this list is what the READER consults —
27341
+ // leaving it out would make the hiding an accident of which session someone
27342
+ // chose rather than a decision, which is the reasoning that put the payload
27343
+ // stamp on `postApprovalNotice`.
27344
+ "operator_instruction"
27334
27345
  ];
27335
27346
  var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
27336
27347
  var NOTICE_KIND_AUDIENCE = {
@@ -27430,7 +27441,13 @@ var NOTICE_KIND_AUDIENCE = {
27430
27441
  // `payload.probe_kind`, so a new probe kind needs no entry here.
27431
27442
  agent_probe: "agent",
27432
27443
  agent_question_probe: "agent",
27433
- kanban_confirm_prompt: "agent"
27444
+ kanban_confirm_prompt: "agent",
27445
+ // ENG-10343 / ADR-0103 D2. A platform admin's instruction, delivered over the
27446
+ // authenticated rail. Addressed to the machine, and the only notice kind whose
27447
+ // authorship the agent is told it can rely on — see `operatorInstructionHeader`
27448
+ // in packages/mcp/src/direct-chat-history.ts, which is where that reliance is
27449
+ // actually expressed. This entry only decides the audience.
27450
+ operator_instruction: "agent"
27434
27451
  };
27435
27452
  var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
27436
27453
  var USER_FACING_NOTICE_KINDS = Object.freeze([
@@ -28813,6 +28830,31 @@ var FLAG_REGISTRY = [
28813
28830
  // must soak in shadow first and is worth confirming on mutation.
28814
28831
  sensitive: true
28815
28832
  },
28833
+ {
28834
+ key: "operator-instruction-rail",
28835
+ description: "Operator instruction rail (ENG-10343, ADR-0103 D2): lets a platform admin send an agent an instruction over a bearer-authenticated route, which the agent reads back under its own credentials and sees labelled with the verified operator. Boolean gate; ships dark.",
28836
+ flagType: "boolean",
28837
+ // Declared safe value is `false`, and OFF is a real state rather than a
28838
+ // placeholder: with the rail closed, the only out-of-band route to an agent
28839
+ // is the tmux pane, which carries no provenance at all (ADR-0103).
28840
+ //
28841
+ // ARMING THIS IS WHAT ACCEPTANCE OF ADR-0103 AUTHORISES. That ADR is
28842
+ // `Proposed` and gated on acceptance except for its D1 guidance fix, so the
28843
+ // write route and the read-path label ship inert until someone accepts it.
28844
+ // The flag is where that decision is expressed — not a later deploy.
28845
+ //
28846
+ // Convergence is NOT a published CLI version (the ENG-9729 lesson): the
28847
+ // label ships in packages/mcp and reaches a host only on the next
28848
+ // publish -> /host/refresh. An older MCP build renders the instruction
28849
+ // fenced and unlabelled, which under-claims authority rather than
28850
+ // over-claiming it — so a mixed fleet is safe, but the rail is not yet
28851
+ // useful on the un-converged half.
28852
+ defaultValue: false,
28853
+ envVar: "AGT_OPERATOR_INSTRUCTION_RAIL_ENABLED",
28854
+ // Writing something an agent is told to treat as authenticated is an
28855
+ // authority grant, so flipping it is worth confirming.
28856
+ sensitive: true
28857
+ },
28816
28858
  {
28817
28859
  key: "direct-chat-doorbell",
28818
28860
  description: "Direct-chat doorbell + pull-cursor delivery (ENG-5927, ADR-0020): the manager rings a content-free doorbell and the agent's in-session MCP pulls via the capped /host/direct-chat/poll claim, replacing send-keys/one-shot delivery. Boolean gate; ships dark.",
@@ -30388,7 +30430,42 @@ var FLAG_REGISTRY = [
30388
30430
  // Deliberately NOT public. The browser has no decision to make here; the
30389
30431
  // consumers are the host payload that builds `input.integrations` and the
30390
30432
  // grant route that refuses to install the row while the flag is off.
30433
+ },
30434
+ {
30435
+ key: "ip-allowlist-enforce-admin-debug",
30436
+ description: "ENG-10594 - whether the IP allowlist on the admin-debug surface (/admin/debug/*, including the deliberately unauthenticated POST /admin/debug/token that exchanges a tlk_ key) REFUSES, or merely observes. OFF (default) = shadow: every request is still evaluated and logged with verdict=admit or verdict=would-refuse, and nothing is ever rejected. ON = a caller whose platform-attested source address is outside AGT_IP_ALLOWLIST_ADMIN_DEBUG gets a bare 403. THE SSM PARAMETER IS A SECOND LEVER AND BOTH ARE NEEDED: with the list unset this flag does nothing, because an unconfigured allowlist admits everyone by design. Arm in that order - populate the list, read the shadow logs until the would-refuse set is understood, then flip this. Deliberately global (evaluated with an empty context): the middleware runs BEFORE authentication, so there is no verified org to scope by, and taking one from an unverified request would let a caller choose its own enforcement posture. Separate from the mcp flag on purpose - see that entry.",
30437
+ flagType: "boolean",
30438
+ // Shadow. The measurement comes first: nobody yet knows the real set of
30439
+ // staff addresses, and arming against a guess locks you out of the very
30440
+ // tool you would use to diagnose the lockout.
30441
+ defaultValue: false,
30442
+ // Arming it changes who can reach production diagnostics. Worth one
30443
+ // confirmation.
30444
+ sensitive: true
30445
+ // Not public: the browser makes no decision from this. The only consumer is
30446
+ // packages/api/src/middleware/ip-allowlist.ts.
30391
30447
  }
30448
+ // THERE IS DELIBERATELY NO `ip-allowlist-enforce-mcp` FLAG.
30449
+ //
30450
+ // The per-agent MCP surface (POST /agents/:codeName/mcp) is allowlist
30451
+ // SHADOW-ONLY, enforced structurally rather than by a default: its entry in
30452
+ // ENFORCE_FLAG (packages/api/src/middleware/ip-allowlist.ts) is null, so no
30453
+ // flag is consulted and no flag flip can arm it.
30454
+ //
30455
+ // Why it is not simply a second flag defaulting false: most of that surface's
30456
+ // callers have no allowlistable address at all. Per ADR-0032 only hosts in the
30457
+ // agt-hosts account egress through stable NAT EIPs; a host with
30458
+ // provision_source `self` or `customer-ec2`, or any BYO account, egresses from
30459
+ // an address the control plane cannot know. Arming against that population
30460
+ // black-holes a customer's whole fleet, and per
30461
+ // docs/runbooks/composio-allowlist-rollout.md this class of change has no
30462
+ // fleet-level undo. A flag would leave that one toggle away during an
30463
+ // incident, from someone who had just armed the admin-debug surface and
30464
+ // reasonably assumed the pair moved together. Requiring a code change puts
30465
+ // review in front of an irreversible action, which is the right price.
30466
+ //
30467
+ // If the shadow data ever shows the population IS allowlistable, adding the
30468
+ // flag here and a key in ENFORCE_FLAG is a small, deliberate diff.
30392
30469
  ];
30393
30470
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
30394
30471
 
@@ -41460,7 +41460,18 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
41460
41460
  // with a `[blocking]` machine tag and is second-person instruction to the
41461
41461
  // agent ("Do whatever you owe them, then tell them"). The customer has no
41462
41462
  // part in it - this is one agent telling another it has stopped.
41463
- "waiting_on_agent"
41463
+ "waiting_on_agent",
41464
+ // ENG-10343 / ADR-0103 D2. An instruction a platform admin sent an agent over
41465
+ // the authenticated rail. Agent-directed by the same test as the rest: the
41466
+ // content is second-person and written for the machine.
41467
+ //
41468
+ // Classified here even though the rail mints its own session, so an operator
41469
+ // instruction should not land in a customer's thread in the first place. That
41470
+ // is a property of the WRITER, and this list is what the READER consults —
41471
+ // leaving it out would make the hiding an accident of which session someone
41472
+ // chose rather than a decision, which is the reasoning that put the payload
41473
+ // stamp on `postApprovalNotice`.
41474
+ "operator_instruction"
41464
41475
  ];
41465
41476
  var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
41466
41477
  var NOTICE_KIND_AUDIENCE = {
@@ -41560,7 +41571,13 @@ var NOTICE_KIND_AUDIENCE = {
41560
41571
  // `payload.probe_kind`, so a new probe kind needs no entry here.
41561
41572
  agent_probe: "agent",
41562
41573
  agent_question_probe: "agent",
41563
- kanban_confirm_prompt: "agent"
41574
+ kanban_confirm_prompt: "agent",
41575
+ // ENG-10343 / ADR-0103 D2. A platform admin's instruction, delivered over the
41576
+ // authenticated rail. Addressed to the machine, and the only notice kind whose
41577
+ // authorship the agent is told it can rely on — see `operatorInstructionHeader`
41578
+ // in packages/mcp/src/direct-chat-history.ts, which is where that reliance is
41579
+ // actually expressed. This entry only decides the audience.
41580
+ operator_instruction: "agent"
41564
41581
  };
41565
41582
  var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
41566
41583
  var USER_FACING_NOTICE_KINDS = Object.freeze([
@@ -42740,6 +42757,31 @@ var FLAG_REGISTRY = [
42740
42757
  // must soak in shadow first and is worth confirming on mutation.
42741
42758
  sensitive: true
42742
42759
  },
42760
+ {
42761
+ key: "operator-instruction-rail",
42762
+ description: "Operator instruction rail (ENG-10343, ADR-0103 D2): lets a platform admin send an agent an instruction over a bearer-authenticated route, which the agent reads back under its own credentials and sees labelled with the verified operator. Boolean gate; ships dark.",
42763
+ flagType: "boolean",
42764
+ // Declared safe value is `false`, and OFF is a real state rather than a
42765
+ // placeholder: with the rail closed, the only out-of-band route to an agent
42766
+ // is the tmux pane, which carries no provenance at all (ADR-0103).
42767
+ //
42768
+ // ARMING THIS IS WHAT ACCEPTANCE OF ADR-0103 AUTHORISES. That ADR is
42769
+ // `Proposed` and gated on acceptance except for its D1 guidance fix, so the
42770
+ // write route and the read-path label ship inert until someone accepts it.
42771
+ // The flag is where that decision is expressed — not a later deploy.
42772
+ //
42773
+ // Convergence is NOT a published CLI version (the ENG-9729 lesson): the
42774
+ // label ships in packages/mcp and reaches a host only on the next
42775
+ // publish -> /host/refresh. An older MCP build renders the instruction
42776
+ // fenced and unlabelled, which under-claims authority rather than
42777
+ // over-claiming it — so a mixed fleet is safe, but the rail is not yet
42778
+ // useful on the un-converged half.
42779
+ defaultValue: false,
42780
+ envVar: "AGT_OPERATOR_INSTRUCTION_RAIL_ENABLED",
42781
+ // Writing something an agent is told to treat as authenticated is an
42782
+ // authority grant, so flipping it is worth confirming.
42783
+ sensitive: true
42784
+ },
42743
42785
  {
42744
42786
  key: "direct-chat-doorbell",
42745
42787
  description: "Direct-chat doorbell + pull-cursor delivery (ENG-5927, ADR-0020): the manager rings a content-free doorbell and the agent's in-session MCP pulls via the capped /host/direct-chat/poll claim, replacing send-keys/one-shot delivery. Boolean gate; ships dark.",
@@ -44315,7 +44357,42 @@ var FLAG_REGISTRY = [
44315
44357
  // Deliberately NOT public. The browser has no decision to make here; the
44316
44358
  // consumers are the host payload that builds `input.integrations` and the
44317
44359
  // grant route that refuses to install the row while the flag is off.
44360
+ },
44361
+ {
44362
+ key: "ip-allowlist-enforce-admin-debug",
44363
+ description: "ENG-10594 - whether the IP allowlist on the admin-debug surface (/admin/debug/*, including the deliberately unauthenticated POST /admin/debug/token that exchanges a tlk_ key) REFUSES, or merely observes. OFF (default) = shadow: every request is still evaluated and logged with verdict=admit or verdict=would-refuse, and nothing is ever rejected. ON = a caller whose platform-attested source address is outside AGT_IP_ALLOWLIST_ADMIN_DEBUG gets a bare 403. THE SSM PARAMETER IS A SECOND LEVER AND BOTH ARE NEEDED: with the list unset this flag does nothing, because an unconfigured allowlist admits everyone by design. Arm in that order - populate the list, read the shadow logs until the would-refuse set is understood, then flip this. Deliberately global (evaluated with an empty context): the middleware runs BEFORE authentication, so there is no verified org to scope by, and taking one from an unverified request would let a caller choose its own enforcement posture. Separate from the mcp flag on purpose - see that entry.",
44364
+ flagType: "boolean",
44365
+ // Shadow. The measurement comes first: nobody yet knows the real set of
44366
+ // staff addresses, and arming against a guess locks you out of the very
44367
+ // tool you would use to diagnose the lockout.
44368
+ defaultValue: false,
44369
+ // Arming it changes who can reach production diagnostics. Worth one
44370
+ // confirmation.
44371
+ sensitive: true
44372
+ // Not public: the browser makes no decision from this. The only consumer is
44373
+ // packages/api/src/middleware/ip-allowlist.ts.
44318
44374
  }
44375
+ // THERE IS DELIBERATELY NO `ip-allowlist-enforce-mcp` FLAG.
44376
+ //
44377
+ // The per-agent MCP surface (POST /agents/:codeName/mcp) is allowlist
44378
+ // SHADOW-ONLY, enforced structurally rather than by a default: its entry in
44379
+ // ENFORCE_FLAG (packages/api/src/middleware/ip-allowlist.ts) is null, so no
44380
+ // flag is consulted and no flag flip can arm it.
44381
+ //
44382
+ // Why it is not simply a second flag defaulting false: most of that surface's
44383
+ // callers have no allowlistable address at all. Per ADR-0032 only hosts in the
44384
+ // agt-hosts account egress through stable NAT EIPs; a host with
44385
+ // provision_source `self` or `customer-ec2`, or any BYO account, egresses from
44386
+ // an address the control plane cannot know. Arming against that population
44387
+ // black-holes a customer's whole fleet, and per
44388
+ // docs/runbooks/composio-allowlist-rollout.md this class of change has no
44389
+ // fleet-level undo. A flag would leave that one toggle away during an
44390
+ // incident, from someone who had just armed the admin-debug surface and
44391
+ // reasonably assumed the pair moved together. Requiring a code change puts
44392
+ // review in front of an irreversible action, which is the right price.
44393
+ //
44394
+ // If the shadow data ever shows the population IS allowlistable, adding the
44395
+ // flag here and a key in ENFORCE_FLAG is a small, deliberate diff.
44319
44396
  ];
44320
44397
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
44321
44398
 
@@ -35704,7 +35704,18 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
35704
35704
  // with a `[blocking]` machine tag and is second-person instruction to the
35705
35705
  // agent ("Do whatever you owe them, then tell them"). The customer has no
35706
35706
  // part in it - this is one agent telling another it has stopped.
35707
- "waiting_on_agent"
35707
+ "waiting_on_agent",
35708
+ // ENG-10343 / ADR-0103 D2. An instruction a platform admin sent an agent over
35709
+ // the authenticated rail. Agent-directed by the same test as the rest: the
35710
+ // content is second-person and written for the machine.
35711
+ //
35712
+ // Classified here even though the rail mints its own session, so an operator
35713
+ // instruction should not land in a customer's thread in the first place. That
35714
+ // is a property of the WRITER, and this list is what the READER consults —
35715
+ // leaving it out would make the hiding an accident of which session someone
35716
+ // chose rather than a decision, which is the reasoning that put the payload
35717
+ // stamp on `postApprovalNotice`.
35718
+ "operator_instruction"
35708
35719
  ];
35709
35720
  var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
35710
35721
  var NOTICE_KIND_AUDIENCE = {
@@ -35804,7 +35815,13 @@ var NOTICE_KIND_AUDIENCE = {
35804
35815
  // `payload.probe_kind`, so a new probe kind needs no entry here.
35805
35816
  agent_probe: "agent",
35806
35817
  agent_question_probe: "agent",
35807
- kanban_confirm_prompt: "agent"
35818
+ kanban_confirm_prompt: "agent",
35819
+ // ENG-10343 / ADR-0103 D2. A platform admin's instruction, delivered over the
35820
+ // authenticated rail. Addressed to the machine, and the only notice kind whose
35821
+ // authorship the agent is told it can rely on — see `operatorInstructionHeader`
35822
+ // in packages/mcp/src/direct-chat-history.ts, which is where that reliance is
35823
+ // actually expressed. This entry only decides the audience.
35824
+ operator_instruction: "agent"
35808
35825
  };
35809
35826
  var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
35810
35827
  var USER_FACING_NOTICE_KINDS = Object.freeze([
@@ -37397,6 +37414,31 @@ var FLAG_REGISTRY = [
37397
37414
  // must soak in shadow first and is worth confirming on mutation.
37398
37415
  sensitive: true
37399
37416
  },
37417
+ {
37418
+ key: "operator-instruction-rail",
37419
+ description: "Operator instruction rail (ENG-10343, ADR-0103 D2): lets a platform admin send an agent an instruction over a bearer-authenticated route, which the agent reads back under its own credentials and sees labelled with the verified operator. Boolean gate; ships dark.",
37420
+ flagType: "boolean",
37421
+ // Declared safe value is `false`, and OFF is a real state rather than a
37422
+ // placeholder: with the rail closed, the only out-of-band route to an agent
37423
+ // is the tmux pane, which carries no provenance at all (ADR-0103).
37424
+ //
37425
+ // ARMING THIS IS WHAT ACCEPTANCE OF ADR-0103 AUTHORISES. That ADR is
37426
+ // `Proposed` and gated on acceptance except for its D1 guidance fix, so the
37427
+ // write route and the read-path label ship inert until someone accepts it.
37428
+ // The flag is where that decision is expressed — not a later deploy.
37429
+ //
37430
+ // Convergence is NOT a published CLI version (the ENG-9729 lesson): the
37431
+ // label ships in packages/mcp and reaches a host only on the next
37432
+ // publish -> /host/refresh. An older MCP build renders the instruction
37433
+ // fenced and unlabelled, which under-claims authority rather than
37434
+ // over-claiming it — so a mixed fleet is safe, but the rail is not yet
37435
+ // useful on the un-converged half.
37436
+ defaultValue: false,
37437
+ envVar: "AGT_OPERATOR_INSTRUCTION_RAIL_ENABLED",
37438
+ // Writing something an agent is told to treat as authenticated is an
37439
+ // authority grant, so flipping it is worth confirming.
37440
+ sensitive: true
37441
+ },
37400
37442
  {
37401
37443
  key: "direct-chat-doorbell",
37402
37444
  description: "Direct-chat doorbell + pull-cursor delivery (ENG-5927, ADR-0020): the manager rings a content-free doorbell and the agent's in-session MCP pulls via the capped /host/direct-chat/poll claim, replacing send-keys/one-shot delivery. Boolean gate; ships dark.",
@@ -38972,7 +39014,42 @@ var FLAG_REGISTRY = [
38972
39014
  // Deliberately NOT public. The browser has no decision to make here; the
38973
39015
  // consumers are the host payload that builds `input.integrations` and the
38974
39016
  // grant route that refuses to install the row while the flag is off.
39017
+ },
39018
+ {
39019
+ key: "ip-allowlist-enforce-admin-debug",
39020
+ description: "ENG-10594 - whether the IP allowlist on the admin-debug surface (/admin/debug/*, including the deliberately unauthenticated POST /admin/debug/token that exchanges a tlk_ key) REFUSES, or merely observes. OFF (default) = shadow: every request is still evaluated and logged with verdict=admit or verdict=would-refuse, and nothing is ever rejected. ON = a caller whose platform-attested source address is outside AGT_IP_ALLOWLIST_ADMIN_DEBUG gets a bare 403. THE SSM PARAMETER IS A SECOND LEVER AND BOTH ARE NEEDED: with the list unset this flag does nothing, because an unconfigured allowlist admits everyone by design. Arm in that order - populate the list, read the shadow logs until the would-refuse set is understood, then flip this. Deliberately global (evaluated with an empty context): the middleware runs BEFORE authentication, so there is no verified org to scope by, and taking one from an unverified request would let a caller choose its own enforcement posture. Separate from the mcp flag on purpose - see that entry.",
39021
+ flagType: "boolean",
39022
+ // Shadow. The measurement comes first: nobody yet knows the real set of
39023
+ // staff addresses, and arming against a guess locks you out of the very
39024
+ // tool you would use to diagnose the lockout.
39025
+ defaultValue: false,
39026
+ // Arming it changes who can reach production diagnostics. Worth one
39027
+ // confirmation.
39028
+ sensitive: true
39029
+ // Not public: the browser makes no decision from this. The only consumer is
39030
+ // packages/api/src/middleware/ip-allowlist.ts.
38975
39031
  }
39032
+ // THERE IS DELIBERATELY NO `ip-allowlist-enforce-mcp` FLAG.
39033
+ //
39034
+ // The per-agent MCP surface (POST /agents/:codeName/mcp) is allowlist
39035
+ // SHADOW-ONLY, enforced structurally rather than by a default: its entry in
39036
+ // ENFORCE_FLAG (packages/api/src/middleware/ip-allowlist.ts) is null, so no
39037
+ // flag is consulted and no flag flip can arm it.
39038
+ //
39039
+ // Why it is not simply a second flag defaulting false: most of that surface's
39040
+ // callers have no allowlistable address at all. Per ADR-0032 only hosts in the
39041
+ // agt-hosts account egress through stable NAT EIPs; a host with
39042
+ // provision_source `self` or `customer-ec2`, or any BYO account, egresses from
39043
+ // an address the control plane cannot know. Arming against that population
39044
+ // black-holes a customer's whole fleet, and per
39045
+ // docs/runbooks/composio-allowlist-rollout.md this class of change has no
39046
+ // fleet-level undo. A flag would leave that one toggle away during an
39047
+ // incident, from someone who had just armed the admin-debug surface and
39048
+ // reasonably assumed the pair moved together. Requiring a code change puts
39049
+ // review in front of an irreversible action, which is the right price.
39050
+ //
39051
+ // If the shadow data ever shows the population IS allowlistable, adding the
39052
+ // flag here and a key in ENFORCE_FLAG is a small, deliberate diff.
38976
39053
  ];
38977
39054
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
38978
39055
 
@@ -35716,7 +35716,18 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
35716
35716
  // with a `[blocking]` machine tag and is second-person instruction to the
35717
35717
  // agent ("Do whatever you owe them, then tell them"). The customer has no
35718
35718
  // part in it - this is one agent telling another it has stopped.
35719
- "waiting_on_agent"
35719
+ "waiting_on_agent",
35720
+ // ENG-10343 / ADR-0103 D2. An instruction a platform admin sent an agent over
35721
+ // the authenticated rail. Agent-directed by the same test as the rest: the
35722
+ // content is second-person and written for the machine.
35723
+ //
35724
+ // Classified here even though the rail mints its own session, so an operator
35725
+ // instruction should not land in a customer's thread in the first place. That
35726
+ // is a property of the WRITER, and this list is what the READER consults —
35727
+ // leaving it out would make the hiding an accident of which session someone
35728
+ // chose rather than a decision, which is the reasoning that put the payload
35729
+ // stamp on `postApprovalNotice`.
35730
+ "operator_instruction"
35720
35731
  ];
35721
35732
  var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
35722
35733
  var NOTICE_KIND_AUDIENCE = {
@@ -35816,7 +35827,13 @@ var NOTICE_KIND_AUDIENCE = {
35816
35827
  // `payload.probe_kind`, so a new probe kind needs no entry here.
35817
35828
  agent_probe: "agent",
35818
35829
  agent_question_probe: "agent",
35819
- kanban_confirm_prompt: "agent"
35830
+ kanban_confirm_prompt: "agent",
35831
+ // ENG-10343 / ADR-0103 D2. A platform admin's instruction, delivered over the
35832
+ // authenticated rail. Addressed to the machine, and the only notice kind whose
35833
+ // authorship the agent is told it can rely on — see `operatorInstructionHeader`
35834
+ // in packages/mcp/src/direct-chat-history.ts, which is where that reliance is
35835
+ // actually expressed. This entry only decides the audience.
35836
+ operator_instruction: "agent"
35820
35837
  };
35821
35838
  var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
35822
35839
  var USER_FACING_NOTICE_KINDS = Object.freeze([
@@ -37409,6 +37426,31 @@ var FLAG_REGISTRY = [
37409
37426
  // must soak in shadow first and is worth confirming on mutation.
37410
37427
  sensitive: true
37411
37428
  },
37429
+ {
37430
+ key: "operator-instruction-rail",
37431
+ description: "Operator instruction rail (ENG-10343, ADR-0103 D2): lets a platform admin send an agent an instruction over a bearer-authenticated route, which the agent reads back under its own credentials and sees labelled with the verified operator. Boolean gate; ships dark.",
37432
+ flagType: "boolean",
37433
+ // Declared safe value is `false`, and OFF is a real state rather than a
37434
+ // placeholder: with the rail closed, the only out-of-band route to an agent
37435
+ // is the tmux pane, which carries no provenance at all (ADR-0103).
37436
+ //
37437
+ // ARMING THIS IS WHAT ACCEPTANCE OF ADR-0103 AUTHORISES. That ADR is
37438
+ // `Proposed` and gated on acceptance except for its D1 guidance fix, so the
37439
+ // write route and the read-path label ship inert until someone accepts it.
37440
+ // The flag is where that decision is expressed — not a later deploy.
37441
+ //
37442
+ // Convergence is NOT a published CLI version (the ENG-9729 lesson): the
37443
+ // label ships in packages/mcp and reaches a host only on the next
37444
+ // publish -> /host/refresh. An older MCP build renders the instruction
37445
+ // fenced and unlabelled, which under-claims authority rather than
37446
+ // over-claiming it — so a mixed fleet is safe, but the rail is not yet
37447
+ // useful on the un-converged half.
37448
+ defaultValue: false,
37449
+ envVar: "AGT_OPERATOR_INSTRUCTION_RAIL_ENABLED",
37450
+ // Writing something an agent is told to treat as authenticated is an
37451
+ // authority grant, so flipping it is worth confirming.
37452
+ sensitive: true
37453
+ },
37412
37454
  {
37413
37455
  key: "direct-chat-doorbell",
37414
37456
  description: "Direct-chat doorbell + pull-cursor delivery (ENG-5927, ADR-0020): the manager rings a content-free doorbell and the agent's in-session MCP pulls via the capped /host/direct-chat/poll claim, replacing send-keys/one-shot delivery. Boolean gate; ships dark.",
@@ -38984,7 +39026,42 @@ var FLAG_REGISTRY = [
38984
39026
  // Deliberately NOT public. The browser has no decision to make here; the
38985
39027
  // consumers are the host payload that builds `input.integrations` and the
38986
39028
  // grant route that refuses to install the row while the flag is off.
39029
+ },
39030
+ {
39031
+ key: "ip-allowlist-enforce-admin-debug",
39032
+ description: "ENG-10594 - whether the IP allowlist on the admin-debug surface (/admin/debug/*, including the deliberately unauthenticated POST /admin/debug/token that exchanges a tlk_ key) REFUSES, or merely observes. OFF (default) = shadow: every request is still evaluated and logged with verdict=admit or verdict=would-refuse, and nothing is ever rejected. ON = a caller whose platform-attested source address is outside AGT_IP_ALLOWLIST_ADMIN_DEBUG gets a bare 403. THE SSM PARAMETER IS A SECOND LEVER AND BOTH ARE NEEDED: with the list unset this flag does nothing, because an unconfigured allowlist admits everyone by design. Arm in that order - populate the list, read the shadow logs until the would-refuse set is understood, then flip this. Deliberately global (evaluated with an empty context): the middleware runs BEFORE authentication, so there is no verified org to scope by, and taking one from an unverified request would let a caller choose its own enforcement posture. Separate from the mcp flag on purpose - see that entry.",
39033
+ flagType: "boolean",
39034
+ // Shadow. The measurement comes first: nobody yet knows the real set of
39035
+ // staff addresses, and arming against a guess locks you out of the very
39036
+ // tool you would use to diagnose the lockout.
39037
+ defaultValue: false,
39038
+ // Arming it changes who can reach production diagnostics. Worth one
39039
+ // confirmation.
39040
+ sensitive: true
39041
+ // Not public: the browser makes no decision from this. The only consumer is
39042
+ // packages/api/src/middleware/ip-allowlist.ts.
38987
39043
  }
39044
+ // THERE IS DELIBERATELY NO `ip-allowlist-enforce-mcp` FLAG.
39045
+ //
39046
+ // The per-agent MCP surface (POST /agents/:codeName/mcp) is allowlist
39047
+ // SHADOW-ONLY, enforced structurally rather than by a default: its entry in
39048
+ // ENFORCE_FLAG (packages/api/src/middleware/ip-allowlist.ts) is null, so no
39049
+ // flag is consulted and no flag flip can arm it.
39050
+ //
39051
+ // Why it is not simply a second flag defaulting false: most of that surface's
39052
+ // callers have no allowlistable address at all. Per ADR-0032 only hosts in the
39053
+ // agt-hosts account egress through stable NAT EIPs; a host with
39054
+ // provision_source `self` or `customer-ec2`, or any BYO account, egresses from
39055
+ // an address the control plane cannot know. Arming against that population
39056
+ // black-holes a customer's whole fleet, and per
39057
+ // docs/runbooks/composio-allowlist-rollout.md this class of change has no
39058
+ // fleet-level undo. A flag would leave that one toggle away during an
39059
+ // incident, from someone who had just armed the admin-debug surface and
39060
+ // reasonably assumed the pair moved together. Requiring a code change puts
39061
+ // review in front of an irreversible action, which is the right price.
39062
+ //
39063
+ // If the shadow data ever shows the population IS allowlistable, adding the
39064
+ // flag here and a key in ENFORCE_FLAG is a small, deliberate diff.
38988
39065
  ];
38989
39066
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
38990
39067
 
@@ -62,8 +62,8 @@ import {
62
62
  writeDirectChatSessionState,
63
63
  writeEgressAllowlist,
64
64
  writePersistentClaudeWrapper
65
- } from "./chunk-LRVXTEFJ.js";
66
- import "./chunk-YZ5HGHPG.js";
65
+ } from "./chunk-K3XCSA4U.js";
66
+ import "./chunk-SVGL52XU.js";
67
67
  import "./chunk-DHWNVVX4.js";
68
68
  import "./chunk-XWVM4KPK.js";
69
69
  export {
@@ -131,4 +131,4 @@ export {
131
131
  writeEgressAllowlist,
132
132
  writePersistentClaudeWrapper
133
133
  };
134
- //# sourceMappingURL=persistent-session-WN4GLJUN.js.map
134
+ //# sourceMappingURL=persistent-session-FMF3LCDW.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-LRVXTEFJ.js";
4
- import "./chunk-YZ5HGHPG.js";
3
+ } from "./chunk-K3XCSA4U.js";
4
+ import "./chunk-SVGL52XU.js";
5
5
  import "./chunk-DHWNVVX4.js";
6
6
  import "./chunk-XWVM4KPK.js";
7
7
 
@@ -800,4 +800,4 @@ export {
800
800
  readAndResetSlackReplyBindingClassifications,
801
801
  readAndResetSlackReplyTargetClassifications
802
802
  };
803
- //# sourceMappingURL=responsiveness-probe-DJMZ4WAU.js.map
803
+ //# sourceMappingURL=responsiveness-probe-ZE3MSI2S.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sessionTranscriptDir
3
- } from "./chunk-YZ5HGHPG.js";
3
+ } from "./chunk-SVGL52XU.js";
4
4
 
5
5
  // src/lib/session-auth-dead.ts
6
6
  import { closeSync, openSync, readSync, readdirSync, statSync } from "fs";
@@ -203,4 +203,4 @@ export {
203
203
  decideSessionAuthState,
204
204
  probeSessionAuth
205
205
  };
206
- //# sourceMappingURL=session-auth-dead-T5SUK2HT.js.map
206
+ //# sourceMappingURL=session-auth-dead-7G555HQQ.js.map