@integrity-labs/agt-cli 0.28.716 → 0.28.718
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-LHYYO4NY.js → chunk-7LH3SVAD.js} +124 -1
- package/dist/chunk-7LH3SVAD.js.map +1 -0
- package/dist/{chunk-OOYUWMTR.js → chunk-EEZHSNQ2.js} +4 -4
- package/dist/{chunk-ILDRNSOB.js → chunk-FNALM4HG.js} +120 -19
- package/dist/chunk-FNALM4HG.js.map +1 -0
- package/dist/{claude-pair-runtime-JK7GQU25.js → claude-pair-runtime-PDG74SAT.js} +2 -2
- package/dist/lib/manager-worker.js +535 -347
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +123 -0
- package/dist/mcp/index.js +123 -0
- package/dist/mcp/origami.js +123 -0
- package/dist/mcp/slack-channel.js +123 -0
- package/dist/mcp/telegram-channel.js +132 -9
- package/dist/{persistent-session-DJSSEIR6.js → persistent-session-2AWYIUCX.js} +7 -3
- package/dist/{responsiveness-probe-A5335ORT.js → responsiveness-probe-JQS4WA2L.js} +3 -3
- package/dist/{session-auth-dead-KUYVUOK5.js → session-auth-dead-VBMZW4GG.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-ILDRNSOB.js.map +0 -1
- package/dist/chunk-LHYYO4NY.js.map +0 -1
- /package/dist/{chunk-OOYUWMTR.js.map → chunk-EEZHSNQ2.js.map} +0 -0
- /package/dist/{claude-pair-runtime-JK7GQU25.js.map → claude-pair-runtime-PDG74SAT.js.map} +0 -0
- /package/dist/{persistent-session-DJSSEIR6.js.map → persistent-session-2AWYIUCX.js.map} +0 -0
- /package/dist/{responsiveness-probe-A5335ORT.js.map → responsiveness-probe-JQS4WA2L.js.map} +0 -0
- /package/dist/{session-auth-dead-KUYVUOK5.js.map → session-auth-dead-VBMZW4GG.js.map} +0 -0
|
@@ -34307,6 +34307,104 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
|
|
|
34307
34307
|
"waiting_on_agent"
|
|
34308
34308
|
];
|
|
34309
34309
|
var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
|
|
34310
|
+
var NOTICE_KIND_AUDIENCE = {
|
|
34311
|
+
// ---- USER -------------------------------------------------------------
|
|
34312
|
+
// An integration broke and only the customer can reconnect it. Carries the
|
|
34313
|
+
// ENG-7652 deep link and renders as the ENG-9256 card — the one notice kind
|
|
34314
|
+
// that already earned a bespoke renderer.
|
|
34315
|
+
integration_failure: "user",
|
|
34316
|
+
// The other half of that pair: the thing you were asked to reconnect is working
|
|
34317
|
+
// again. Kept visible even though it needs no ACTION, because it closes a loop
|
|
34318
|
+
// the customer was explicitly pulled into — hiding it would leave the reconnect
|
|
34319
|
+
// card as the last word on a problem that is now fixed.
|
|
34320
|
+
//
|
|
34321
|
+
// ENG-9592 left a wart here and recorded it: two of the three recovery arms
|
|
34322
|
+
// were written in the second person to the AGENT ("mention it to your owner",
|
|
34323
|
+
// "your session will pick it up"), which reads as nonsense to the customer now
|
|
34324
|
+
// seeing the same string. ENG-9609 rewrote all three to be true for both
|
|
34325
|
+
// readers and pinned it in `eng-9609-recovery-copy-dual-audience.test.ts`.
|
|
34326
|
+
// The note is deleted rather than updated: a deferral that outlives the thing
|
|
34327
|
+
// it defers is just a false claim about the code.
|
|
34328
|
+
integration_recovered: "user",
|
|
34329
|
+
// The form itself. `direct-chat-form.ts` calls it "the agent→user render
|
|
34330
|
+
// message"; hiding it would remove the control the user is meant to fill in.
|
|
34331
|
+
form_request_render: "user",
|
|
34332
|
+
// ENG-9592: the outcome chip for a button the user just pressed — "already
|
|
34333
|
+
// resolved", "only the manager can approve", the re-prompt. Its producer says
|
|
34334
|
+
// it exists so the click does not "look like it did nothing", which is exactly
|
|
34335
|
+
// an answer owed to a person. See the note on the stamped payload below.
|
|
34336
|
+
approval_outcome: "user",
|
|
34337
|
+
// ---- AGENT ------------------------------------------------------------
|
|
34338
|
+
// The ENG-9592 report's headline kind: parked-card pickup instructions, in the
|
|
34339
|
+
// second person, ending in an order not to reply in direct-chat.
|
|
34340
|
+
waiting_response: "agent",
|
|
34341
|
+
// Already agent-directed before this change; each is summarised above and its
|
|
34342
|
+
// reasoning lives beside its entry in AGENT_DIRECTED_NOTICE_KINDS.
|
|
34343
|
+
scheduled_task_nudge: "agent",
|
|
34344
|
+
kanban_check: "agent",
|
|
34345
|
+
manager_feedback: "agent",
|
|
34346
|
+
form_timeout: "agent",
|
|
34347
|
+
integration_connected: "agent",
|
|
34348
|
+
offer_result: "agent",
|
|
34349
|
+
waiting_on_agent: "agent",
|
|
34350
|
+
// "The user submitted your form … Use payload.values to continue the user's
|
|
34351
|
+
// task" — a delivery mechanism, with a raw request uuid. The user submitted it;
|
|
34352
|
+
// they do not need to be told they did.
|
|
34353
|
+
form_result: "agent",
|
|
34354
|
+
// Same shape for a tapped button: "The user tapped X on your button prompt
|
|
34355
|
+
// (request `<uuid>`)". They tapped it.
|
|
34356
|
+
button_click: "agent",
|
|
34357
|
+
// ENG-9397: tells the agent a question was answered AFTER it stopped listening
|
|
34358
|
+
// so it does not report the person as silent. The person's own answer goes
|
|
34359
|
+
// back on the channel they tapped in, not here.
|
|
34360
|
+
late_button_click: "agent",
|
|
34361
|
+
// Broker grant resolutions. Second person to the agent, and each carries the
|
|
34362
|
+
// grant uuid the tool contracts explicitly forbid showing a user ("NEVER paste
|
|
34363
|
+
// the grant UUID into user-facing prose"). Two of these are in the report.
|
|
34364
|
+
supabase_grant_resolved: "agent",
|
|
34365
|
+
supabase_grant_denied: "agent",
|
|
34366
|
+
aws_grant_resolved: "agent",
|
|
34367
|
+
aws_grant_denied: "agent",
|
|
34368
|
+
gcp_grant_resolved: "agent",
|
|
34369
|
+
gcp_grant_denied: "agent",
|
|
34370
|
+
// HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
|
|
34371
|
+
// action happened, and do NOT poll".
|
|
34372
|
+
integration_invoke_resolved: "agent",
|
|
34373
|
+
integration_invoke_denied: "agent",
|
|
34374
|
+
// Support/recruit approvals — same shape, agent resumes the provisioning.
|
|
34375
|
+
recruit_resolved: "agent",
|
|
34376
|
+
recruit_denied: "agent",
|
|
34377
|
+
// "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
|
|
34378
|
+
// uuid and all.
|
|
34379
|
+
approval_expired: "agent",
|
|
34380
|
+
// A routine fired; the agent picks the work up.
|
|
34381
|
+
routine_firing_result: "agent",
|
|
34382
|
+
// Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
|
|
34383
|
+
// call addressed to the machine.
|
|
34384
|
+
live_advisor_escalation: "agent",
|
|
34385
|
+
live_advisor_session_open: "agent",
|
|
34386
|
+
// The assigner reopened a card and the agent must work it again.
|
|
34387
|
+
assigner_reopen: "agent",
|
|
34388
|
+
// An inbound trigger event delivered onto the rail for the agent to handle.
|
|
34389
|
+
// Named `trigger_event` by `triggerDeliveryPayload` — NOT `trigger_delivery`,
|
|
34390
|
+
// which is what the producing module is called. Read from the builder.
|
|
34391
|
+
trigger_event: "agent",
|
|
34392
|
+
// Operational degradation routed into the agent's chat by the alert bridge.
|
|
34393
|
+
degradation_alert: "agent",
|
|
34394
|
+
// ENG-9592: probes and synthetic prompts, previously carrying NO payload at
|
|
34395
|
+
// all and therefore unclassifiable. Stamped at their producers so the verdict
|
|
34396
|
+
// is recorded rather than inherited from the default. `agent_probe` covers
|
|
34397
|
+
// both probe kinds (liveness and the board nudge); the specific one is
|
|
34398
|
+
// `payload.probe_kind`, so a new probe kind needs no entry here.
|
|
34399
|
+
agent_probe: "agent",
|
|
34400
|
+
agent_question_probe: "agent",
|
|
34401
|
+
kanban_confirm_prompt: "agent"
|
|
34402
|
+
};
|
|
34403
|
+
var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
|
|
34404
|
+
var USER_FACING_NOTICE_KINDS = Object.freeze([
|
|
34405
|
+
...USER_FACING_KIND_SET
|
|
34406
|
+
]);
|
|
34407
|
+
var HIDDEN_NOTICE_KINDS = Object.freeze(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "agent").map(([kind]) => kind));
|
|
34310
34408
|
|
|
34311
34409
|
// ../core/dist/direct-chat/cursor-advance.js
|
|
34312
34410
|
var CURSOR_ADVANCE_NON_SHORTFALL_KEYS = ["advanced", "advanced_unreported", "failed"];
|
|
@@ -34991,6 +35089,12 @@ var WAITING_KINDS = [
|
|
|
34991
35089
|
];
|
|
34992
35090
|
var WAITING_KIND_SET = new Set(WAITING_KINDS);
|
|
34993
35091
|
|
|
35092
|
+
// ../core/dist/alerts/age.js
|
|
35093
|
+
var MINUTE_MS = 6e4;
|
|
35094
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
35095
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
35096
|
+
var ALERT_AGE_SEVERITY_FLOORS = [{ afterMs: 24 * HOUR_MS, floor: "critical" }];
|
|
35097
|
+
|
|
34994
35098
|
// ../core/dist/conversations/metrics.js
|
|
34995
35099
|
var PERIOD_CONFIG = {
|
|
34996
35100
|
"24h": { windowMs: 24 * 60 * 60 * 1e3, bucket: "hour" },
|
|
@@ -36418,6 +36522,25 @@ var FLAG_REGISTRY = [
|
|
|
36418
36522
|
// deliberate, audited per-org flip (ADR-0022 §4).
|
|
36419
36523
|
sensitive: true
|
|
36420
36524
|
},
|
|
36525
|
+
{
|
|
36526
|
+
key: "email-require-approval-enforcement",
|
|
36527
|
+
description: 'Enforcement gate for the `email.require_approval` guardrail (ENG-9611). That guardrail has been `default_for_new_orgs` since ~2026-05-03 and its display text promises "Require human approval before sending any email", but nothing ever read it: its only runtime path was toGuardrailForPrompt, i.e. a line in the agent CLAUDE.md. When ON for an org, a DISPATCHING email send (never a draft-create, ENG-7980) is held and routed to Human Approval regardless of recipient domain \u2014 which is what "any email" means, and is what distinguishes it from email-guard-require-approval-enabled, whose require_approval stage only intercepts a would-be DOMAIN block. Deliberately separate from the guardrail row: roughly four months of orgs already carry an inert `enforce`-level row, so reading the row alone would arm a blocking control across all of them on deploy. New orgs are armed by an org-scoped override written at org creation; existing orgs stay off until an operator flips them. Evaluated per-org. Ships dark.',
|
|
36528
|
+
flagType: "boolean",
|
|
36529
|
+
// Declared safe value is `false` (no hold). A flag-DB read error degrades here, so a flags
|
|
36530
|
+
// outage can never silently start holding real customer email — the same fail-OPEN posture
|
|
36531
|
+
// enforceEmailDomainGuard already takes, and the opposite of the enforcement resolver's
|
|
36532
|
+
// fail-CLOSED, deliberately: a control that cannot verify itself must not block mail.
|
|
36533
|
+
// No envVar: net-new control with no pre-flags env gate to migrate (ADR-0022).
|
|
36534
|
+
defaultValue: false,
|
|
36535
|
+
// Turning it on holds real customer email pending a human tap, so it is a deliberate,
|
|
36536
|
+
// audited per-org flip (ADR-0022 §4).
|
|
36537
|
+
sensitive: true,
|
|
36538
|
+
// ENG-9629: NEW orgs are armed on. Declared here rather than hardcoded in the
|
|
36539
|
+
// seeding code, so `listNewOrgFlagOverrides()` is the one answer to "which flags
|
|
36540
|
+
// does a new org get". `defaultValue` stays false so the ~4 months of orgs already
|
|
36541
|
+
// carrying an inert enforce-level email.require_approval row are NOT armed on deploy.
|
|
36542
|
+
newOrgOverride: true
|
|
36543
|
+
},
|
|
36421
36544
|
{
|
|
36422
36545
|
key: "email-guard-require-approval-enabled",
|
|
36423
36546
|
description: "Platform enable-gate for the email-domain guardrail REQUIRE_APPROVAL stage (ENG-7939). When ON for an org, a scope at email_guard_stage=require_approval routes a send to a non-allowed domain into Human Approval (an Approve/Deny card) instead of a hard block: the rollout UI unlocks the option and the write routes accept require_approval. When OFF (default) the write routes reject require_approval and the UI shows it as not yet available, so no scope can select it. Structurally also depends on hitl-approval-routing being on (the approval broker fails closed to a hard block when routing is off). Evaluated per-org. Ships dark.",
|
package/dist/mcp/index.js
CHANGED
|
@@ -41723,6 +41723,104 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
|
|
|
41723
41723
|
"waiting_on_agent"
|
|
41724
41724
|
];
|
|
41725
41725
|
var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
|
|
41726
|
+
var NOTICE_KIND_AUDIENCE = {
|
|
41727
|
+
// ---- USER -------------------------------------------------------------
|
|
41728
|
+
// An integration broke and only the customer can reconnect it. Carries the
|
|
41729
|
+
// ENG-7652 deep link and renders as the ENG-9256 card — the one notice kind
|
|
41730
|
+
// that already earned a bespoke renderer.
|
|
41731
|
+
integration_failure: "user",
|
|
41732
|
+
// The other half of that pair: the thing you were asked to reconnect is working
|
|
41733
|
+
// again. Kept visible even though it needs no ACTION, because it closes a loop
|
|
41734
|
+
// the customer was explicitly pulled into — hiding it would leave the reconnect
|
|
41735
|
+
// card as the last word on a problem that is now fixed.
|
|
41736
|
+
//
|
|
41737
|
+
// ENG-9592 left a wart here and recorded it: two of the three recovery arms
|
|
41738
|
+
// were written in the second person to the AGENT ("mention it to your owner",
|
|
41739
|
+
// "your session will pick it up"), which reads as nonsense to the customer now
|
|
41740
|
+
// seeing the same string. ENG-9609 rewrote all three to be true for both
|
|
41741
|
+
// readers and pinned it in `eng-9609-recovery-copy-dual-audience.test.ts`.
|
|
41742
|
+
// The note is deleted rather than updated: a deferral that outlives the thing
|
|
41743
|
+
// it defers is just a false claim about the code.
|
|
41744
|
+
integration_recovered: "user",
|
|
41745
|
+
// The form itself. `direct-chat-form.ts` calls it "the agent→user render
|
|
41746
|
+
// message"; hiding it would remove the control the user is meant to fill in.
|
|
41747
|
+
form_request_render: "user",
|
|
41748
|
+
// ENG-9592: the outcome chip for a button the user just pressed — "already
|
|
41749
|
+
// resolved", "only the manager can approve", the re-prompt. Its producer says
|
|
41750
|
+
// it exists so the click does not "look like it did nothing", which is exactly
|
|
41751
|
+
// an answer owed to a person. See the note on the stamped payload below.
|
|
41752
|
+
approval_outcome: "user",
|
|
41753
|
+
// ---- AGENT ------------------------------------------------------------
|
|
41754
|
+
// The ENG-9592 report's headline kind: parked-card pickup instructions, in the
|
|
41755
|
+
// second person, ending in an order not to reply in direct-chat.
|
|
41756
|
+
waiting_response: "agent",
|
|
41757
|
+
// Already agent-directed before this change; each is summarised above and its
|
|
41758
|
+
// reasoning lives beside its entry in AGENT_DIRECTED_NOTICE_KINDS.
|
|
41759
|
+
scheduled_task_nudge: "agent",
|
|
41760
|
+
kanban_check: "agent",
|
|
41761
|
+
manager_feedback: "agent",
|
|
41762
|
+
form_timeout: "agent",
|
|
41763
|
+
integration_connected: "agent",
|
|
41764
|
+
offer_result: "agent",
|
|
41765
|
+
waiting_on_agent: "agent",
|
|
41766
|
+
// "The user submitted your form … Use payload.values to continue the user's
|
|
41767
|
+
// task" — a delivery mechanism, with a raw request uuid. The user submitted it;
|
|
41768
|
+
// they do not need to be told they did.
|
|
41769
|
+
form_result: "agent",
|
|
41770
|
+
// Same shape for a tapped button: "The user tapped X on your button prompt
|
|
41771
|
+
// (request `<uuid>`)". They tapped it.
|
|
41772
|
+
button_click: "agent",
|
|
41773
|
+
// ENG-9397: tells the agent a question was answered AFTER it stopped listening
|
|
41774
|
+
// so it does not report the person as silent. The person's own answer goes
|
|
41775
|
+
// back on the channel they tapped in, not here.
|
|
41776
|
+
late_button_click: "agent",
|
|
41777
|
+
// Broker grant resolutions. Second person to the agent, and each carries the
|
|
41778
|
+
// grant uuid the tool contracts explicitly forbid showing a user ("NEVER paste
|
|
41779
|
+
// the grant UUID into user-facing prose"). Two of these are in the report.
|
|
41780
|
+
supabase_grant_resolved: "agent",
|
|
41781
|
+
supabase_grant_denied: "agent",
|
|
41782
|
+
aws_grant_resolved: "agent",
|
|
41783
|
+
aws_grant_denied: "agent",
|
|
41784
|
+
gcp_grant_resolved: "agent",
|
|
41785
|
+
gcp_grant_denied: "agent",
|
|
41786
|
+
// HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
|
|
41787
|
+
// action happened, and do NOT poll".
|
|
41788
|
+
integration_invoke_resolved: "agent",
|
|
41789
|
+
integration_invoke_denied: "agent",
|
|
41790
|
+
// Support/recruit approvals — same shape, agent resumes the provisioning.
|
|
41791
|
+
recruit_resolved: "agent",
|
|
41792
|
+
recruit_denied: "agent",
|
|
41793
|
+
// "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
|
|
41794
|
+
// uuid and all.
|
|
41795
|
+
approval_expired: "agent",
|
|
41796
|
+
// A routine fired; the agent picks the work up.
|
|
41797
|
+
routine_firing_result: "agent",
|
|
41798
|
+
// Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
|
|
41799
|
+
// call addressed to the machine.
|
|
41800
|
+
live_advisor_escalation: "agent",
|
|
41801
|
+
live_advisor_session_open: "agent",
|
|
41802
|
+
// The assigner reopened a card and the agent must work it again.
|
|
41803
|
+
assigner_reopen: "agent",
|
|
41804
|
+
// An inbound trigger event delivered onto the rail for the agent to handle.
|
|
41805
|
+
// Named `trigger_event` by `triggerDeliveryPayload` — NOT `trigger_delivery`,
|
|
41806
|
+
// which is what the producing module is called. Read from the builder.
|
|
41807
|
+
trigger_event: "agent",
|
|
41808
|
+
// Operational degradation routed into the agent's chat by the alert bridge.
|
|
41809
|
+
degradation_alert: "agent",
|
|
41810
|
+
// ENG-9592: probes and synthetic prompts, previously carrying NO payload at
|
|
41811
|
+
// all and therefore unclassifiable. Stamped at their producers so the verdict
|
|
41812
|
+
// is recorded rather than inherited from the default. `agent_probe` covers
|
|
41813
|
+
// both probe kinds (liveness and the board nudge); the specific one is
|
|
41814
|
+
// `payload.probe_kind`, so a new probe kind needs no entry here.
|
|
41815
|
+
agent_probe: "agent",
|
|
41816
|
+
agent_question_probe: "agent",
|
|
41817
|
+
kanban_confirm_prompt: "agent"
|
|
41818
|
+
};
|
|
41819
|
+
var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
|
|
41820
|
+
var USER_FACING_NOTICE_KINDS = Object.freeze([
|
|
41821
|
+
...USER_FACING_KIND_SET
|
|
41822
|
+
]);
|
|
41823
|
+
var HIDDEN_NOTICE_KINDS = Object.freeze(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "agent").map(([kind]) => kind));
|
|
41726
41824
|
|
|
41727
41825
|
// ../core/dist/direct-chat/cursor-advance.js
|
|
41728
41826
|
var CURSOR_ADVANCE_NON_SHORTFALL_KEYS = ["advanced", "advanced_unreported", "failed"];
|
|
@@ -41968,6 +42066,12 @@ function describeReportsToOutcome(resolved) {
|
|
|
41968
42066
|
}
|
|
41969
42067
|
}
|
|
41970
42068
|
|
|
42069
|
+
// ../core/dist/alerts/age.js
|
|
42070
|
+
var MINUTE_MS = 6e4;
|
|
42071
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
42072
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
42073
|
+
var ALERT_AGE_SEVERITY_FLOORS = [{ afterMs: 24 * HOUR_MS, floor: "critical" }];
|
|
42074
|
+
|
|
41971
42075
|
// ../core/dist/conversations/metrics.js
|
|
41972
42076
|
var PERIOD_CONFIG = {
|
|
41973
42077
|
"24h": { windowMs: 24 * 60 * 60 * 1e3, bucket: "hour" },
|
|
@@ -43395,6 +43499,25 @@ var FLAG_REGISTRY = [
|
|
|
43395
43499
|
// deliberate, audited per-org flip (ADR-0022 §4).
|
|
43396
43500
|
sensitive: true
|
|
43397
43501
|
},
|
|
43502
|
+
{
|
|
43503
|
+
key: "email-require-approval-enforcement",
|
|
43504
|
+
description: 'Enforcement gate for the `email.require_approval` guardrail (ENG-9611). That guardrail has been `default_for_new_orgs` since ~2026-05-03 and its display text promises "Require human approval before sending any email", but nothing ever read it: its only runtime path was toGuardrailForPrompt, i.e. a line in the agent CLAUDE.md. When ON for an org, a DISPATCHING email send (never a draft-create, ENG-7980) is held and routed to Human Approval regardless of recipient domain \u2014 which is what "any email" means, and is what distinguishes it from email-guard-require-approval-enabled, whose require_approval stage only intercepts a would-be DOMAIN block. Deliberately separate from the guardrail row: roughly four months of orgs already carry an inert `enforce`-level row, so reading the row alone would arm a blocking control across all of them on deploy. New orgs are armed by an org-scoped override written at org creation; existing orgs stay off until an operator flips them. Evaluated per-org. Ships dark.',
|
|
43505
|
+
flagType: "boolean",
|
|
43506
|
+
// Declared safe value is `false` (no hold). A flag-DB read error degrades here, so a flags
|
|
43507
|
+
// outage can never silently start holding real customer email — the same fail-OPEN posture
|
|
43508
|
+
// enforceEmailDomainGuard already takes, and the opposite of the enforcement resolver's
|
|
43509
|
+
// fail-CLOSED, deliberately: a control that cannot verify itself must not block mail.
|
|
43510
|
+
// No envVar: net-new control with no pre-flags env gate to migrate (ADR-0022).
|
|
43511
|
+
defaultValue: false,
|
|
43512
|
+
// Turning it on holds real customer email pending a human tap, so it is a deliberate,
|
|
43513
|
+
// audited per-org flip (ADR-0022 §4).
|
|
43514
|
+
sensitive: true,
|
|
43515
|
+
// ENG-9629: NEW orgs are armed on. Declared here rather than hardcoded in the
|
|
43516
|
+
// seeding code, so `listNewOrgFlagOverrides()` is the one answer to "which flags
|
|
43517
|
+
// does a new org get". `defaultValue` stays false so the ~4 months of orgs already
|
|
43518
|
+
// carrying an inert enforce-level email.require_approval row are NOT armed on deploy.
|
|
43519
|
+
newOrgOverride: true
|
|
43520
|
+
},
|
|
43398
43521
|
{
|
|
43399
43522
|
key: "email-guard-require-approval-enabled",
|
|
43400
43523
|
description: "Platform enable-gate for the email-domain guardrail REQUIRE_APPROVAL stage (ENG-7939). When ON for an org, a scope at email_guard_stage=require_approval routes a send to a non-allowed domain into Human Approval (an Approve/Deny card) instead of a hard block: the rollout UI unlocks the option and the write routes accept require_approval. When OFF (default) the write routes reject require_approval and the UI shows it as not yet available, so no scope can select it. Structurally also depends on hitl-approval-routing being on (the approval broker fails closed to a hard block when routing is off). Evaluated per-org. Ships dark.",
|
package/dist/mcp/origami.js
CHANGED
|
@@ -40515,6 +40515,104 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
|
|
|
40515
40515
|
"waiting_on_agent"
|
|
40516
40516
|
];
|
|
40517
40517
|
var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
|
|
40518
|
+
var NOTICE_KIND_AUDIENCE = {
|
|
40519
|
+
// ---- USER -------------------------------------------------------------
|
|
40520
|
+
// An integration broke and only the customer can reconnect it. Carries the
|
|
40521
|
+
// ENG-7652 deep link and renders as the ENG-9256 card — the one notice kind
|
|
40522
|
+
// that already earned a bespoke renderer.
|
|
40523
|
+
integration_failure: "user",
|
|
40524
|
+
// The other half of that pair: the thing you were asked to reconnect is working
|
|
40525
|
+
// again. Kept visible even though it needs no ACTION, because it closes a loop
|
|
40526
|
+
// the customer was explicitly pulled into — hiding it would leave the reconnect
|
|
40527
|
+
// card as the last word on a problem that is now fixed.
|
|
40528
|
+
//
|
|
40529
|
+
// ENG-9592 left a wart here and recorded it: two of the three recovery arms
|
|
40530
|
+
// were written in the second person to the AGENT ("mention it to your owner",
|
|
40531
|
+
// "your session will pick it up"), which reads as nonsense to the customer now
|
|
40532
|
+
// seeing the same string. ENG-9609 rewrote all three to be true for both
|
|
40533
|
+
// readers and pinned it in `eng-9609-recovery-copy-dual-audience.test.ts`.
|
|
40534
|
+
// The note is deleted rather than updated: a deferral that outlives the thing
|
|
40535
|
+
// it defers is just a false claim about the code.
|
|
40536
|
+
integration_recovered: "user",
|
|
40537
|
+
// The form itself. `direct-chat-form.ts` calls it "the agent→user render
|
|
40538
|
+
// message"; hiding it would remove the control the user is meant to fill in.
|
|
40539
|
+
form_request_render: "user",
|
|
40540
|
+
// ENG-9592: the outcome chip for a button the user just pressed — "already
|
|
40541
|
+
// resolved", "only the manager can approve", the re-prompt. Its producer says
|
|
40542
|
+
// it exists so the click does not "look like it did nothing", which is exactly
|
|
40543
|
+
// an answer owed to a person. See the note on the stamped payload below.
|
|
40544
|
+
approval_outcome: "user",
|
|
40545
|
+
// ---- AGENT ------------------------------------------------------------
|
|
40546
|
+
// The ENG-9592 report's headline kind: parked-card pickup instructions, in the
|
|
40547
|
+
// second person, ending in an order not to reply in direct-chat.
|
|
40548
|
+
waiting_response: "agent",
|
|
40549
|
+
// Already agent-directed before this change; each is summarised above and its
|
|
40550
|
+
// reasoning lives beside its entry in AGENT_DIRECTED_NOTICE_KINDS.
|
|
40551
|
+
scheduled_task_nudge: "agent",
|
|
40552
|
+
kanban_check: "agent",
|
|
40553
|
+
manager_feedback: "agent",
|
|
40554
|
+
form_timeout: "agent",
|
|
40555
|
+
integration_connected: "agent",
|
|
40556
|
+
offer_result: "agent",
|
|
40557
|
+
waiting_on_agent: "agent",
|
|
40558
|
+
// "The user submitted your form … Use payload.values to continue the user's
|
|
40559
|
+
// task" — a delivery mechanism, with a raw request uuid. The user submitted it;
|
|
40560
|
+
// they do not need to be told they did.
|
|
40561
|
+
form_result: "agent",
|
|
40562
|
+
// Same shape for a tapped button: "The user tapped X on your button prompt
|
|
40563
|
+
// (request `<uuid>`)". They tapped it.
|
|
40564
|
+
button_click: "agent",
|
|
40565
|
+
// ENG-9397: tells the agent a question was answered AFTER it stopped listening
|
|
40566
|
+
// so it does not report the person as silent. The person's own answer goes
|
|
40567
|
+
// back on the channel they tapped in, not here.
|
|
40568
|
+
late_button_click: "agent",
|
|
40569
|
+
// Broker grant resolutions. Second person to the agent, and each carries the
|
|
40570
|
+
// grant uuid the tool contracts explicitly forbid showing a user ("NEVER paste
|
|
40571
|
+
// the grant UUID into user-facing prose"). Two of these are in the report.
|
|
40572
|
+
supabase_grant_resolved: "agent",
|
|
40573
|
+
supabase_grant_denied: "agent",
|
|
40574
|
+
aws_grant_resolved: "agent",
|
|
40575
|
+
aws_grant_denied: "agent",
|
|
40576
|
+
gcp_grant_resolved: "agent",
|
|
40577
|
+
gcp_grant_denied: "agent",
|
|
40578
|
+
// HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
|
|
40579
|
+
// action happened, and do NOT poll".
|
|
40580
|
+
integration_invoke_resolved: "agent",
|
|
40581
|
+
integration_invoke_denied: "agent",
|
|
40582
|
+
// Support/recruit approvals — same shape, agent resumes the provisioning.
|
|
40583
|
+
recruit_resolved: "agent",
|
|
40584
|
+
recruit_denied: "agent",
|
|
40585
|
+
// "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
|
|
40586
|
+
// uuid and all.
|
|
40587
|
+
approval_expired: "agent",
|
|
40588
|
+
// A routine fired; the agent picks the work up.
|
|
40589
|
+
routine_firing_result: "agent",
|
|
40590
|
+
// Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
|
|
40591
|
+
// call addressed to the machine.
|
|
40592
|
+
live_advisor_escalation: "agent",
|
|
40593
|
+
live_advisor_session_open: "agent",
|
|
40594
|
+
// The assigner reopened a card and the agent must work it again.
|
|
40595
|
+
assigner_reopen: "agent",
|
|
40596
|
+
// An inbound trigger event delivered onto the rail for the agent to handle.
|
|
40597
|
+
// Named `trigger_event` by `triggerDeliveryPayload` — NOT `trigger_delivery`,
|
|
40598
|
+
// which is what the producing module is called. Read from the builder.
|
|
40599
|
+
trigger_event: "agent",
|
|
40600
|
+
// Operational degradation routed into the agent's chat by the alert bridge.
|
|
40601
|
+
degradation_alert: "agent",
|
|
40602
|
+
// ENG-9592: probes and synthetic prompts, previously carrying NO payload at
|
|
40603
|
+
// all and therefore unclassifiable. Stamped at their producers so the verdict
|
|
40604
|
+
// is recorded rather than inherited from the default. `agent_probe` covers
|
|
40605
|
+
// both probe kinds (liveness and the board nudge); the specific one is
|
|
40606
|
+
// `payload.probe_kind`, so a new probe kind needs no entry here.
|
|
40607
|
+
agent_probe: "agent",
|
|
40608
|
+
agent_question_probe: "agent",
|
|
40609
|
+
kanban_confirm_prompt: "agent"
|
|
40610
|
+
};
|
|
40611
|
+
var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
|
|
40612
|
+
var USER_FACING_NOTICE_KINDS = Object.freeze([
|
|
40613
|
+
...USER_FACING_KIND_SET
|
|
40614
|
+
]);
|
|
40615
|
+
var HIDDEN_NOTICE_KINDS = Object.freeze(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "agent").map(([kind]) => kind));
|
|
40518
40616
|
|
|
40519
40617
|
// ../core/dist/direct-chat/cursor-advance.js
|
|
40520
40618
|
var CURSOR_ADVANCE_NON_SHORTFALL_KEYS = ["advanced", "advanced_unreported", "failed"];
|
|
@@ -40739,6 +40837,12 @@ var WAITING_KINDS = [
|
|
|
40739
40837
|
];
|
|
40740
40838
|
var WAITING_KIND_SET = new Set(WAITING_KINDS);
|
|
40741
40839
|
|
|
40840
|
+
// ../core/dist/alerts/age.js
|
|
40841
|
+
var MINUTE_MS = 6e4;
|
|
40842
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
40843
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
40844
|
+
var ALERT_AGE_SEVERITY_FLOORS = [{ afterMs: 24 * HOUR_MS, floor: "critical" }];
|
|
40845
|
+
|
|
40742
40846
|
// ../core/dist/conversations/metrics.js
|
|
40743
40847
|
var PERIOD_CONFIG = {
|
|
40744
40848
|
"24h": { windowMs: 24 * 60 * 60 * 1e3, bucket: "hour" },
|
|
@@ -42166,6 +42270,25 @@ var FLAG_REGISTRY = [
|
|
|
42166
42270
|
// deliberate, audited per-org flip (ADR-0022 §4).
|
|
42167
42271
|
sensitive: true
|
|
42168
42272
|
},
|
|
42273
|
+
{
|
|
42274
|
+
key: "email-require-approval-enforcement",
|
|
42275
|
+
description: 'Enforcement gate for the `email.require_approval` guardrail (ENG-9611). That guardrail has been `default_for_new_orgs` since ~2026-05-03 and its display text promises "Require human approval before sending any email", but nothing ever read it: its only runtime path was toGuardrailForPrompt, i.e. a line in the agent CLAUDE.md. When ON for an org, a DISPATCHING email send (never a draft-create, ENG-7980) is held and routed to Human Approval regardless of recipient domain \u2014 which is what "any email" means, and is what distinguishes it from email-guard-require-approval-enabled, whose require_approval stage only intercepts a would-be DOMAIN block. Deliberately separate from the guardrail row: roughly four months of orgs already carry an inert `enforce`-level row, so reading the row alone would arm a blocking control across all of them on deploy. New orgs are armed by an org-scoped override written at org creation; existing orgs stay off until an operator flips them. Evaluated per-org. Ships dark.',
|
|
42276
|
+
flagType: "boolean",
|
|
42277
|
+
// Declared safe value is `false` (no hold). A flag-DB read error degrades here, so a flags
|
|
42278
|
+
// outage can never silently start holding real customer email — the same fail-OPEN posture
|
|
42279
|
+
// enforceEmailDomainGuard already takes, and the opposite of the enforcement resolver's
|
|
42280
|
+
// fail-CLOSED, deliberately: a control that cannot verify itself must not block mail.
|
|
42281
|
+
// No envVar: net-new control with no pre-flags env gate to migrate (ADR-0022).
|
|
42282
|
+
defaultValue: false,
|
|
42283
|
+
// Turning it on holds real customer email pending a human tap, so it is a deliberate,
|
|
42284
|
+
// audited per-org flip (ADR-0022 §4).
|
|
42285
|
+
sensitive: true,
|
|
42286
|
+
// ENG-9629: NEW orgs are armed on. Declared here rather than hardcoded in the
|
|
42287
|
+
// seeding code, so `listNewOrgFlagOverrides()` is the one answer to "which flags
|
|
42288
|
+
// does a new org get". `defaultValue` stays false so the ~4 months of orgs already
|
|
42289
|
+
// carrying an inert enforce-level email.require_approval row are NOT armed on deploy.
|
|
42290
|
+
newOrgOverride: true
|
|
42291
|
+
},
|
|
42169
42292
|
{
|
|
42170
42293
|
key: "email-guard-require-approval-enabled",
|
|
42171
42294
|
description: "Platform enable-gate for the email-domain guardrail REQUIRE_APPROVAL stage (ENG-7939). When ON for an org, a scope at email_guard_stage=require_approval routes a send to a non-allowed domain into Human Approval (an Approve/Deny card) instead of a hard block: the rollout UI unlocks the option and the write routes accept require_approval. When OFF (default) the write routes reject require_approval and the UI shows it as not yet available, so no scope can select it. Structurally also depends on hitl-approval-routing being on (the approval broker fails closed to a hard block when routing is off). Evaluated per-org. Ships dark.",
|
|
@@ -34628,6 +34628,104 @@ var AGENT_DIRECTED_NOTICE_KINDS = [
|
|
|
34628
34628
|
"waiting_on_agent"
|
|
34629
34629
|
];
|
|
34630
34630
|
var AGENT_DIRECTED_KIND_SET = new Set(AGENT_DIRECTED_NOTICE_KINDS);
|
|
34631
|
+
var NOTICE_KIND_AUDIENCE = {
|
|
34632
|
+
// ---- USER -------------------------------------------------------------
|
|
34633
|
+
// An integration broke and only the customer can reconnect it. Carries the
|
|
34634
|
+
// ENG-7652 deep link and renders as the ENG-9256 card — the one notice kind
|
|
34635
|
+
// that already earned a bespoke renderer.
|
|
34636
|
+
integration_failure: "user",
|
|
34637
|
+
// The other half of that pair: the thing you were asked to reconnect is working
|
|
34638
|
+
// again. Kept visible even though it needs no ACTION, because it closes a loop
|
|
34639
|
+
// the customer was explicitly pulled into — hiding it would leave the reconnect
|
|
34640
|
+
// card as the last word on a problem that is now fixed.
|
|
34641
|
+
//
|
|
34642
|
+
// ENG-9592 left a wart here and recorded it: two of the three recovery arms
|
|
34643
|
+
// were written in the second person to the AGENT ("mention it to your owner",
|
|
34644
|
+
// "your session will pick it up"), which reads as nonsense to the customer now
|
|
34645
|
+
// seeing the same string. ENG-9609 rewrote all three to be true for both
|
|
34646
|
+
// readers and pinned it in `eng-9609-recovery-copy-dual-audience.test.ts`.
|
|
34647
|
+
// The note is deleted rather than updated: a deferral that outlives the thing
|
|
34648
|
+
// it defers is just a false claim about the code.
|
|
34649
|
+
integration_recovered: "user",
|
|
34650
|
+
// The form itself. `direct-chat-form.ts` calls it "the agent→user render
|
|
34651
|
+
// message"; hiding it would remove the control the user is meant to fill in.
|
|
34652
|
+
form_request_render: "user",
|
|
34653
|
+
// ENG-9592: the outcome chip for a button the user just pressed — "already
|
|
34654
|
+
// resolved", "only the manager can approve", the re-prompt. Its producer says
|
|
34655
|
+
// it exists so the click does not "look like it did nothing", which is exactly
|
|
34656
|
+
// an answer owed to a person. See the note on the stamped payload below.
|
|
34657
|
+
approval_outcome: "user",
|
|
34658
|
+
// ---- AGENT ------------------------------------------------------------
|
|
34659
|
+
// The ENG-9592 report's headline kind: parked-card pickup instructions, in the
|
|
34660
|
+
// second person, ending in an order not to reply in direct-chat.
|
|
34661
|
+
waiting_response: "agent",
|
|
34662
|
+
// Already agent-directed before this change; each is summarised above and its
|
|
34663
|
+
// reasoning lives beside its entry in AGENT_DIRECTED_NOTICE_KINDS.
|
|
34664
|
+
scheduled_task_nudge: "agent",
|
|
34665
|
+
kanban_check: "agent",
|
|
34666
|
+
manager_feedback: "agent",
|
|
34667
|
+
form_timeout: "agent",
|
|
34668
|
+
integration_connected: "agent",
|
|
34669
|
+
offer_result: "agent",
|
|
34670
|
+
waiting_on_agent: "agent",
|
|
34671
|
+
// "The user submitted your form … Use payload.values to continue the user's
|
|
34672
|
+
// task" — a delivery mechanism, with a raw request uuid. The user submitted it;
|
|
34673
|
+
// they do not need to be told they did.
|
|
34674
|
+
form_result: "agent",
|
|
34675
|
+
// Same shape for a tapped button: "The user tapped X on your button prompt
|
|
34676
|
+
// (request `<uuid>`)". They tapped it.
|
|
34677
|
+
button_click: "agent",
|
|
34678
|
+
// ENG-9397: tells the agent a question was answered AFTER it stopped listening
|
|
34679
|
+
// so it does not report the person as silent. The person's own answer goes
|
|
34680
|
+
// back on the channel they tapped in, not here.
|
|
34681
|
+
late_button_click: "agent",
|
|
34682
|
+
// Broker grant resolutions. Second person to the agent, and each carries the
|
|
34683
|
+
// grant uuid the tool contracts explicitly forbid showing a user ("NEVER paste
|
|
34684
|
+
// the grant UUID into user-facing prose"). Two of these are in the report.
|
|
34685
|
+
supabase_grant_resolved: "agent",
|
|
34686
|
+
supabase_grant_denied: "agent",
|
|
34687
|
+
aws_grant_resolved: "agent",
|
|
34688
|
+
aws_grant_denied: "agent",
|
|
34689
|
+
gcp_grant_resolved: "agent",
|
|
34690
|
+
gcp_grant_denied: "agent",
|
|
34691
|
+
// HITL tool-call approvals: "Do NOT call this tool again, do NOT claim the
|
|
34692
|
+
// action happened, and do NOT poll".
|
|
34693
|
+
integration_invoke_resolved: "agent",
|
|
34694
|
+
integration_invoke_denied: "agent",
|
|
34695
|
+
// Support/recruit approvals — same shape, agent resumes the provisioning.
|
|
34696
|
+
recruit_resolved: "agent",
|
|
34697
|
+
recruit_denied: "agent",
|
|
34698
|
+
// "Your `<verb>` approval request (`<uuid>`) EXPIRED at …" — in the report,
|
|
34699
|
+
// uuid and all.
|
|
34700
|
+
approval_expired: "agent",
|
|
34701
|
+
// A routine fired; the agent picks the work up.
|
|
34702
|
+
routine_firing_result: "agent",
|
|
34703
|
+
// Live-advisor wake: "Call `live_read` with escalation_id …" — a literal tool
|
|
34704
|
+
// call addressed to the machine.
|
|
34705
|
+
live_advisor_escalation: "agent",
|
|
34706
|
+
live_advisor_session_open: "agent",
|
|
34707
|
+
// The assigner reopened a card and the agent must work it again.
|
|
34708
|
+
assigner_reopen: "agent",
|
|
34709
|
+
// An inbound trigger event delivered onto the rail for the agent to handle.
|
|
34710
|
+
// Named `trigger_event` by `triggerDeliveryPayload` — NOT `trigger_delivery`,
|
|
34711
|
+
// which is what the producing module is called. Read from the builder.
|
|
34712
|
+
trigger_event: "agent",
|
|
34713
|
+
// Operational degradation routed into the agent's chat by the alert bridge.
|
|
34714
|
+
degradation_alert: "agent",
|
|
34715
|
+
// ENG-9592: probes and synthetic prompts, previously carrying NO payload at
|
|
34716
|
+
// all and therefore unclassifiable. Stamped at their producers so the verdict
|
|
34717
|
+
// is recorded rather than inherited from the default. `agent_probe` covers
|
|
34718
|
+
// both probe kinds (liveness and the board nudge); the specific one is
|
|
34719
|
+
// `payload.probe_kind`, so a new probe kind needs no entry here.
|
|
34720
|
+
agent_probe: "agent",
|
|
34721
|
+
agent_question_probe: "agent",
|
|
34722
|
+
kanban_confirm_prompt: "agent"
|
|
34723
|
+
};
|
|
34724
|
+
var USER_FACING_KIND_SET = new Set(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "user").map(([kind]) => kind));
|
|
34725
|
+
var USER_FACING_NOTICE_KINDS = Object.freeze([
|
|
34726
|
+
...USER_FACING_KIND_SET
|
|
34727
|
+
]);
|
|
34728
|
+
var HIDDEN_NOTICE_KINDS = Object.freeze(Object.entries(NOTICE_KIND_AUDIENCE).filter(([, audience]) => audience === "agent").map(([kind]) => kind));
|
|
34631
34729
|
|
|
34632
34730
|
// ../core/dist/direct-chat/cursor-advance.js
|
|
34633
34731
|
var CURSOR_ADVANCE_NON_SHORTFALL_KEYS = ["advanced", "advanced_unreported", "failed"];
|
|
@@ -35259,6 +35357,12 @@ var WAITING_KIND_SET = new Set(WAITING_KINDS);
|
|
|
35259
35357
|
// ../core/dist/alerts/index.js
|
|
35260
35358
|
init_snooze();
|
|
35261
35359
|
|
|
35360
|
+
// ../core/dist/alerts/age.js
|
|
35361
|
+
var MINUTE_MS = 6e4;
|
|
35362
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
35363
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
35364
|
+
var ALERT_AGE_SEVERITY_FLOORS = [{ afterMs: 24 * HOUR_MS, floor: "critical" }];
|
|
35365
|
+
|
|
35262
35366
|
// ../core/dist/conversations/metrics.js
|
|
35263
35367
|
var PERIOD_CONFIG = {
|
|
35264
35368
|
"24h": { windowMs: 24 * 60 * 60 * 1e3, bucket: "hour" },
|
|
@@ -36686,6 +36790,25 @@ var FLAG_REGISTRY = [
|
|
|
36686
36790
|
// deliberate, audited per-org flip (ADR-0022 §4).
|
|
36687
36791
|
sensitive: true
|
|
36688
36792
|
},
|
|
36793
|
+
{
|
|
36794
|
+
key: "email-require-approval-enforcement",
|
|
36795
|
+
description: 'Enforcement gate for the `email.require_approval` guardrail (ENG-9611). That guardrail has been `default_for_new_orgs` since ~2026-05-03 and its display text promises "Require human approval before sending any email", but nothing ever read it: its only runtime path was toGuardrailForPrompt, i.e. a line in the agent CLAUDE.md. When ON for an org, a DISPATCHING email send (never a draft-create, ENG-7980) is held and routed to Human Approval regardless of recipient domain \u2014 which is what "any email" means, and is what distinguishes it from email-guard-require-approval-enabled, whose require_approval stage only intercepts a would-be DOMAIN block. Deliberately separate from the guardrail row: roughly four months of orgs already carry an inert `enforce`-level row, so reading the row alone would arm a blocking control across all of them on deploy. New orgs are armed by an org-scoped override written at org creation; existing orgs stay off until an operator flips them. Evaluated per-org. Ships dark.',
|
|
36796
|
+
flagType: "boolean",
|
|
36797
|
+
// Declared safe value is `false` (no hold). A flag-DB read error degrades here, so a flags
|
|
36798
|
+
// outage can never silently start holding real customer email — the same fail-OPEN posture
|
|
36799
|
+
// enforceEmailDomainGuard already takes, and the opposite of the enforcement resolver's
|
|
36800
|
+
// fail-CLOSED, deliberately: a control that cannot verify itself must not block mail.
|
|
36801
|
+
// No envVar: net-new control with no pre-flags env gate to migrate (ADR-0022).
|
|
36802
|
+
defaultValue: false,
|
|
36803
|
+
// Turning it on holds real customer email pending a human tap, so it is a deliberate,
|
|
36804
|
+
// audited per-org flip (ADR-0022 §4).
|
|
36805
|
+
sensitive: true,
|
|
36806
|
+
// ENG-9629: NEW orgs are armed on. Declared here rather than hardcoded in the
|
|
36807
|
+
// seeding code, so `listNewOrgFlagOverrides()` is the one answer to "which flags
|
|
36808
|
+
// does a new org get". `defaultValue` stays false so the ~4 months of orgs already
|
|
36809
|
+
// carrying an inert enforce-level email.require_approval row are NOT armed on deploy.
|
|
36810
|
+
newOrgOverride: true
|
|
36811
|
+
},
|
|
36689
36812
|
{
|
|
36690
36813
|
key: "email-guard-require-approval-enabled",
|
|
36691
36814
|
description: "Platform enable-gate for the email-domain guardrail REQUIRE_APPROVAL stage (ENG-7939). When ON for an org, a scope at email_guard_stage=require_approval routes a send to a non-allowed domain into Human Approval (an Approve/Deny card) instead of a hard block: the rollout UI unlocks the option and the write routes accept require_approval. When OFF (default) the write routes reject require_approval and the UI shows it as not yet available, so no scope can select it. Structurally also depends on hitl-approval-routing being on (the approval broker fails closed to a hard block when routing is off). Evaluated per-org. Ships dark.",
|