@integrity-labs/agt-cli 0.28.528 → 0.28.529

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.
@@ -33484,6 +33484,45 @@ var INTEGRATION_REGISTRY = [
33484
33484
  { id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
33485
33485
  ]
33486
33486
  },
33487
+ {
33488
+ // ENG-8332: the Augmented Team HELP knowledge base, split out of
33489
+ // `augmented-support` so an agent can be given the docs WITHOUT also being
33490
+ // given a ticket-filing button, an agent-proposal button, and org-wide read
33491
+ // of agents, hosts, integrations, alerts, flags and the audit log. That
33492
+ // bundling was why "just give everyone augmented-support" was the wrong
33493
+ // answer, and the cost was agents answering platform questions from
33494
+ // inference instead of documentation (the CS-1529/CS-1530 case).
33495
+ //
33496
+ // Provisions the @integrity-labs/augmented-help-kb-mcp stdio broker, a
33497
+ // read-only client over /host/kb - the single enumerated carve-out from the
33498
+ // ADR-0032 org-lock invariant (ENG-7119). KB content is platform-curated
33499
+ // and org-neutral, so this grants NO view of any org's state; the client
33500
+ // has no POST transport at all, so writes are structurally impossible
33501
+ // rather than merely unregistered.
33502
+ //
33503
+ // auth `none` - no end-user OAuth, the host JWT is the credential. `beta`
33504
+ // while distribution widens. NOT in the Add Integration picker (no
33505
+ // `installable`): granted deliberately, like its two siblings.
33506
+ //
33507
+ // NAMING (ENG-7281): this is the "help knowledge base" - shared, published,
33508
+ // org-neutral PRODUCT help. It is NOT the org knowledge store that
33509
+ // `knowledge_search` / `context_search` read. Keep the two distinct in every
33510
+ // surface that names them.
33511
+ id: "augmented-help-kb",
33512
+ name: "Augmented Help KB",
33513
+ category: "knowledge",
33514
+ description: "The Augmented Team help knowledge base: search and read the shared, published product documentation (how-tos, common fixes, FAQs). Identical for every organization and org-neutral by design - it grants no view of your org's own state, and cannot file tickets or propose changes. Distinct from your organization's own knowledge store.",
33515
+ supported_auth_types: ["none"],
33516
+ beta: true,
33517
+ capabilities: [
33518
+ {
33519
+ id: "augmented-help-kb:read",
33520
+ name: "Read Help Docs",
33521
+ description: "Search and read published Augmented Team help articles (org-neutral product documentation). Read-only; no ticket filing, no agent proposals, no org-state reads.",
33522
+ access: "read"
33523
+ }
33524
+ ]
33525
+ },
33487
33526
  {
33488
33527
  id: "firecrawl",
33489
33528
  name: "Firecrawl",
@@ -34363,10 +34402,21 @@ function parseAccountEnforcementMarker(raw) {
34363
34402
  const level = parsed.level;
34364
34403
  if (level !== "warn" && level !== "mute")
34365
34404
  return null;
34366
- return { version: ACCOUNT_ENFORCEMENT_MARKER_VERSION, level };
34405
+ const rawText = parsed.text;
34406
+ const text = typeof rawText === "string" && rawText.trim() ? rawText.trim() : void 0;
34407
+ return {
34408
+ version: ACCOUNT_ENFORCEMENT_MARKER_VERSION,
34409
+ level,
34410
+ ...text ? { text } : {}
34411
+ };
34367
34412
  }
34368
- function buildAccountIssueReplyText() {
34369
- return "There is an issue with your account, please contact support@augmented.team.";
34413
+ var DEFAULT_ACCOUNT_ENFORCEMENT_COPY = {
34414
+ warn: "Heads-up: there's an issue with your account that needs attention. Please contact support@augmented.team so I can keep helping you.",
34415
+ mute: "There is an issue with your account, please contact support@augmented.team."
34416
+ };
34417
+ function buildAccountIssueReplyText(level, override) {
34418
+ const trimmed = typeof override === "string" ? override.trim() : "";
34419
+ return trimmed || DEFAULT_ACCOUNT_ENFORCEMENT_COPY[level];
34370
34420
  }
34371
34421
 
34372
34422
  // ../core/dist/kanban/state-machine.js
@@ -35459,6 +35509,32 @@ var FLAG_REGISTRY = [
35459
35509
  // Best-effort reach estimate only; not part of the schema fingerprint.
35460
35510
  since: "0.28.504"
35461
35511
  },
35512
+ {
35513
+ key: "utilization-occupancy-qualifier",
35514
+ description: "Utilization busy-minutes gate (ENG-8465): shadow = report every measured bucket exactly as before while COUNTING how many a transcript qualifier would drop; enforce = drop measured buckets that have no qualifying assistant turn (>= 25 output tokens, non-synthetic) within \xB1120s. The qualifier is the merged @augmented/core primitive (extractQualifyingTurns / isBucketQualified); the host reads a bounded transcript tail incl. <sessionId>/subagents/ at drain time and FAILS OPEN (credits ungated) when a transcript cannot be read. Read host-side via hostFlagStore (getString) in the manager; consumer ships in this PR's agt-cli auto-publish bump. Both modes emit the OccupancyQualificationClassifications shadow metric (qualified positive-control + unqualified_dropped signal + unreadable), so per-agent impact is measured before the flip.",
35515
+ flagType: "enum",
35516
+ allowedValues: ["shadow", "enforce"],
35517
+ // Declared safe value is `shadow`: it reproduces pre-flag billing exactly, so
35518
+ // rollout changes no agent's minutes while the shadow metric accrues the
35519
+ // enforce-flip evidence. `enforce` lowers a billing-adjacent number, so it is a
35520
+ // deliberate, audited flip — never a flag-DB-read-error default.
35521
+ defaultValue: "shadow",
35522
+ // Operator per-host override (ADR-0022 highest precedence). No _ENABLED/_DISABLED/
35523
+ // _MODE suffix, and read via hostFlagStore not a raw process.env gate, so not a
35524
+ // new env gate under ENG-6252. Never pinned in sst.config.ts (ENG-8303).
35525
+ envVar: "AGT_UTILIZATION_OCCUPANCY_QUALIFIER",
35526
+ // enforce lowers a billing-adjacent number, so flipping/weakening it is guarded
35527
+ // like the other enforcement-mode flags.
35528
+ sensitive: true,
35529
+ // Reach threshold (ENG-8465): the host reader (occupancyQualifierMode in
35530
+ // manager-worker.ts) lands in this PR's agt-cli auto-publish patch bump, which
35531
+ // is the first published version to contain it (through 0.28.528 does not). An
35532
+ // UNSET `since` makes classifyHostReach report `honors` (full coverage), which
35533
+ // would greenlight an `enforce` flip while older hosts silently stay `shadow`.
35534
+ // Best-effort estimate (like docker-hygiene's), in the safe direction — a
35535
+ // not-yet-published version reports 0% honor until hosts update. (CodeRabbit)
35536
+ since: "0.28.529"
35537
+ },
35462
35538
  {
35463
35539
  key: "composio-hitl-mode",
35464
35540
  description: "Composio managed-toolkits HITL gate (ENG-6027): off = kill switch, shadow = resolve + audit the tier decision but never block, enforce = block write_high_risk+ calls and route them to Human Approval (an Approve/Deny card). Since ENG-7828 enforce ALWAYS routes to a Human Approval card by default; set hitl-approval-routing=off to make enforce a hard block with no approval instead. Per-org rollout from the admin Feature Flags page; ENG-7672 migrated this off the fleet-wide COMPOSIO_HITL_MODE env var.",
@@ -35865,6 +35941,15 @@ var FLAG_REGISTRY = [
35865
35941
  // runbook gates on it. Leaving the placeholder in place is safe (nothing
35866
35942
  // flips); shipping a guessed number is not.
35867
35943
  since: "0.29.0"
35944
+ },
35945
+ {
35946
+ key: "help-kb-auto-grant",
35947
+ 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).",
35948
+ flagType: "boolean",
35949
+ // Declared safe value is `false` = grant nothing. A flag-store outage must
35950
+ // never auto-attach an integration nobody asked for, and both ENG-8332
35951
+ // prerequisites above are still open.
35952
+ defaultValue: false
35868
35953
  }
35869
35954
  ];
35870
35955
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
@@ -36826,7 +36911,7 @@ function accountEnforcementMarkerPath(codeName) {
36826
36911
  if (!codeName) return null;
36827
36912
  return join12(homedir3(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
36828
36913
  }
36829
- function readAccountEnforcementLevel(opts) {
36914
+ function readAccountEnforcementMarker(opts) {
36830
36915
  const path = opts.filePath ?? accountEnforcementMarkerPath(opts.codeName);
36831
36916
  if (!path) return null;
36832
36917
  let raw;
@@ -36835,7 +36920,14 @@ function readAccountEnforcementLevel(opts) {
36835
36920
  } catch {
36836
36921
  return null;
36837
36922
  }
36838
- return parseAccountEnforcementMarker(raw)?.level ?? null;
36923
+ return parseAccountEnforcementMarker(raw);
36924
+ }
36925
+ function readAccountEnforcementLevel(opts) {
36926
+ return readAccountEnforcementMarker(opts)?.level ?? null;
36927
+ }
36928
+ function resolveAccountIssueReplyText(level, opts) {
36929
+ const marker = readAccountEnforcementMarker(opts);
36930
+ return buildAccountIssueReplyText(level, marker?.level === level ? marker.text : void 0);
36839
36931
  }
36840
36932
  function shouldSendAccountWarn(opts) {
36841
36933
  if (readAccountEnforcementLevel({ codeName: opts.codeName, filePath: opts.filePath }) !== "warn") {
@@ -37206,7 +37298,7 @@ async function maybeSendDirectChatAccountWarn(sessionId) {
37206
37298
  const res = await apiPost("/host/direct-chat/reply", {
37207
37299
  agent_id: AGT_AGENT_ID,
37208
37300
  session_id: sessionId,
37209
- content: buildAccountIssueReplyText(),
37301
+ content: resolveAccountIssueReplyText("warn", { codeName: AGT_AGENT_CODE_NAME ?? null }),
37210
37302
  // The L1 warn nag is an extra message alongside the agent's real reply,
37211
37303
  // which has already advanced the cursor.
37212
37304
  // cursor-advance-allow: deliberately EMPTY — nothing to advance, no count to read.
@@ -37866,7 +37958,7 @@ async function pollForMessages(sinceMs) {
37866
37958
  now: Date.now()
37867
37959
  });
37868
37960
  const route = throttle.reply ? "/host/direct-chat/reply" : "/host/direct-chat/consume";
37869
- const body = throttle.reply ? { agent_id: AGT_AGENT_ID, session_id: msg.session_id, content: buildAccountIssueReplyText(), message_ids: [msg.id], kind: "notice" } : { agent_id: AGT_AGENT_ID, session_id: msg.session_id, message_ids: [msg.id] };
37961
+ const body = throttle.reply ? { agent_id: AGT_AGENT_ID, session_id: msg.session_id, content: resolveAccountIssueReplyText("mute", { codeName: AGT_AGENT_CODE_NAME ?? null }), message_ids: [msg.id], kind: "notice" } : { agent_id: AGT_AGENT_ID, session_id: msg.session_id, message_ids: [msg.id] };
37870
37962
  try {
37871
37963
  const res2 = await apiPost(route, body);
37872
37964
  const { body: data2, httpOk, statusText } = await readCursorAdvanceBody(res2);
@@ -39822,6 +39822,45 @@ var INTEGRATION_REGISTRY = [
39822
39822
  { id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
39823
39823
  ]
39824
39824
  },
39825
+ {
39826
+ // ENG-8332: the Augmented Team HELP knowledge base, split out of
39827
+ // `augmented-support` so an agent can be given the docs WITHOUT also being
39828
+ // given a ticket-filing button, an agent-proposal button, and org-wide read
39829
+ // of agents, hosts, integrations, alerts, flags and the audit log. That
39830
+ // bundling was why "just give everyone augmented-support" was the wrong
39831
+ // answer, and the cost was agents answering platform questions from
39832
+ // inference instead of documentation (the CS-1529/CS-1530 case).
39833
+ //
39834
+ // Provisions the @integrity-labs/augmented-help-kb-mcp stdio broker, a
39835
+ // read-only client over /host/kb - the single enumerated carve-out from the
39836
+ // ADR-0032 org-lock invariant (ENG-7119). KB content is platform-curated
39837
+ // and org-neutral, so this grants NO view of any org's state; the client
39838
+ // has no POST transport at all, so writes are structurally impossible
39839
+ // rather than merely unregistered.
39840
+ //
39841
+ // auth `none` - no end-user OAuth, the host JWT is the credential. `beta`
39842
+ // while distribution widens. NOT in the Add Integration picker (no
39843
+ // `installable`): granted deliberately, like its two siblings.
39844
+ //
39845
+ // NAMING (ENG-7281): this is the "help knowledge base" - shared, published,
39846
+ // org-neutral PRODUCT help. It is NOT the org knowledge store that
39847
+ // `knowledge_search` / `context_search` read. Keep the two distinct in every
39848
+ // surface that names them.
39849
+ id: "augmented-help-kb",
39850
+ name: "Augmented Help KB",
39851
+ category: "knowledge",
39852
+ description: "The Augmented Team help knowledge base: search and read the shared, published product documentation (how-tos, common fixes, FAQs). Identical for every organization and org-neutral by design - it grants no view of your org's own state, and cannot file tickets or propose changes. Distinct from your organization's own knowledge store.",
39853
+ supported_auth_types: ["none"],
39854
+ beta: true,
39855
+ capabilities: [
39856
+ {
39857
+ id: "augmented-help-kb:read",
39858
+ name: "Read Help Docs",
39859
+ description: "Search and read published Augmented Team help articles (org-neutral product documentation). Read-only; no ticket filing, no agent proposals, no org-state reads.",
39860
+ access: "read"
39861
+ }
39862
+ ]
39863
+ },
39825
39864
  {
39826
39865
  id: "firecrawl",
39827
39866
  name: "Firecrawl",
@@ -41361,6 +41400,32 @@ var FLAG_REGISTRY = [
41361
41400
  // Best-effort reach estimate only; not part of the schema fingerprint.
41362
41401
  since: "0.28.504"
41363
41402
  },
41403
+ {
41404
+ key: "utilization-occupancy-qualifier",
41405
+ description: "Utilization busy-minutes gate (ENG-8465): shadow = report every measured bucket exactly as before while COUNTING how many a transcript qualifier would drop; enforce = drop measured buckets that have no qualifying assistant turn (>= 25 output tokens, non-synthetic) within \xB1120s. The qualifier is the merged @augmented/core primitive (extractQualifyingTurns / isBucketQualified); the host reads a bounded transcript tail incl. <sessionId>/subagents/ at drain time and FAILS OPEN (credits ungated) when a transcript cannot be read. Read host-side via hostFlagStore (getString) in the manager; consumer ships in this PR's agt-cli auto-publish bump. Both modes emit the OccupancyQualificationClassifications shadow metric (qualified positive-control + unqualified_dropped signal + unreadable), so per-agent impact is measured before the flip.",
41406
+ flagType: "enum",
41407
+ allowedValues: ["shadow", "enforce"],
41408
+ // Declared safe value is `shadow`: it reproduces pre-flag billing exactly, so
41409
+ // rollout changes no agent's minutes while the shadow metric accrues the
41410
+ // enforce-flip evidence. `enforce` lowers a billing-adjacent number, so it is a
41411
+ // deliberate, audited flip — never a flag-DB-read-error default.
41412
+ defaultValue: "shadow",
41413
+ // Operator per-host override (ADR-0022 highest precedence). No _ENABLED/_DISABLED/
41414
+ // _MODE suffix, and read via hostFlagStore not a raw process.env gate, so not a
41415
+ // new env gate under ENG-6252. Never pinned in sst.config.ts (ENG-8303).
41416
+ envVar: "AGT_UTILIZATION_OCCUPANCY_QUALIFIER",
41417
+ // enforce lowers a billing-adjacent number, so flipping/weakening it is guarded
41418
+ // like the other enforcement-mode flags.
41419
+ sensitive: true,
41420
+ // Reach threshold (ENG-8465): the host reader (occupancyQualifierMode in
41421
+ // manager-worker.ts) lands in this PR's agt-cli auto-publish patch bump, which
41422
+ // is the first published version to contain it (through 0.28.528 does not). An
41423
+ // UNSET `since` makes classifyHostReach report `honors` (full coverage), which
41424
+ // would greenlight an `enforce` flip while older hosts silently stay `shadow`.
41425
+ // Best-effort estimate (like docker-hygiene's), in the safe direction — a
41426
+ // not-yet-published version reports 0% honor until hosts update. (CodeRabbit)
41427
+ since: "0.28.529"
41428
+ },
41364
41429
  {
41365
41430
  key: "composio-hitl-mode",
41366
41431
  description: "Composio managed-toolkits HITL gate (ENG-6027): off = kill switch, shadow = resolve + audit the tier decision but never block, enforce = block write_high_risk+ calls and route them to Human Approval (an Approve/Deny card). Since ENG-7828 enforce ALWAYS routes to a Human Approval card by default; set hitl-approval-routing=off to make enforce a hard block with no approval instead. Per-org rollout from the admin Feature Flags page; ENG-7672 migrated this off the fleet-wide COMPOSIO_HITL_MODE env var.",
@@ -41767,6 +41832,15 @@ var FLAG_REGISTRY = [
41767
41832
  // runbook gates on it. Leaving the placeholder in place is safe (nothing
41768
41833
  // flips); shipping a guessed number is not.
41769
41834
  since: "0.29.0"
41835
+ },
41836
+ {
41837
+ key: "help-kb-auto-grant",
41838
+ 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).",
41839
+ flagType: "boolean",
41840
+ // Declared safe value is `false` = grant nothing. A flag-store outage must
41841
+ // never auto-attach an integration nobody asked for, and both ENG-8332
41842
+ // prerequisites above are still open.
41843
+ defaultValue: false
41770
41844
  }
41771
41845
  ];
41772
41846
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
@@ -33711,6 +33711,45 @@ var INTEGRATION_REGISTRY = [
33711
33711
  { id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
33712
33712
  ]
33713
33713
  },
33714
+ {
33715
+ // ENG-8332: the Augmented Team HELP knowledge base, split out of
33716
+ // `augmented-support` so an agent can be given the docs WITHOUT also being
33717
+ // given a ticket-filing button, an agent-proposal button, and org-wide read
33718
+ // of agents, hosts, integrations, alerts, flags and the audit log. That
33719
+ // bundling was why "just give everyone augmented-support" was the wrong
33720
+ // answer, and the cost was agents answering platform questions from
33721
+ // inference instead of documentation (the CS-1529/CS-1530 case).
33722
+ //
33723
+ // Provisions the @integrity-labs/augmented-help-kb-mcp stdio broker, a
33724
+ // read-only client over /host/kb - the single enumerated carve-out from the
33725
+ // ADR-0032 org-lock invariant (ENG-7119). KB content is platform-curated
33726
+ // and org-neutral, so this grants NO view of any org's state; the client
33727
+ // has no POST transport at all, so writes are structurally impossible
33728
+ // rather than merely unregistered.
33729
+ //
33730
+ // auth `none` - no end-user OAuth, the host JWT is the credential. `beta`
33731
+ // while distribution widens. NOT in the Add Integration picker (no
33732
+ // `installable`): granted deliberately, like its two siblings.
33733
+ //
33734
+ // NAMING (ENG-7281): this is the "help knowledge base" - shared, published,
33735
+ // org-neutral PRODUCT help. It is NOT the org knowledge store that
33736
+ // `knowledge_search` / `context_search` read. Keep the two distinct in every
33737
+ // surface that names them.
33738
+ id: "augmented-help-kb",
33739
+ name: "Augmented Help KB",
33740
+ category: "knowledge",
33741
+ description: "The Augmented Team help knowledge base: search and read the shared, published product documentation (how-tos, common fixes, FAQs). Identical for every organization and org-neutral by design - it grants no view of your org's own state, and cannot file tickets or propose changes. Distinct from your organization's own knowledge store.",
33742
+ supported_auth_types: ["none"],
33743
+ beta: true,
33744
+ capabilities: [
33745
+ {
33746
+ id: "augmented-help-kb:read",
33747
+ name: "Read Help Docs",
33748
+ description: "Search and read published Augmented Team help articles (org-neutral product documentation). Read-only; no ticket filing, no agent proposals, no org-state reads.",
33749
+ access: "read"
33750
+ }
33751
+ ]
33752
+ },
33714
33753
  {
33715
33754
  id: "firecrawl",
33716
33755
  name: "Firecrawl",
@@ -34534,10 +34573,21 @@ function parseAccountEnforcementMarker(raw) {
34534
34573
  const level = parsed.level;
34535
34574
  if (level !== "warn" && level !== "mute")
34536
34575
  return null;
34537
- return { version: ACCOUNT_ENFORCEMENT_MARKER_VERSION, level };
34576
+ const rawText = parsed.text;
34577
+ const text = typeof rawText === "string" && rawText.trim() ? rawText.trim() : void 0;
34578
+ return {
34579
+ version: ACCOUNT_ENFORCEMENT_MARKER_VERSION,
34580
+ level,
34581
+ ...text ? { text } : {}
34582
+ };
34538
34583
  }
34539
- function buildAccountIssueReplyText() {
34540
- return "There is an issue with your account, please contact support@augmented.team.";
34584
+ var DEFAULT_ACCOUNT_ENFORCEMENT_COPY = {
34585
+ warn: "Heads-up: there's an issue with your account that needs attention. Please contact support@augmented.team so I can keep helping you.",
34586
+ mute: "There is an issue with your account, please contact support@augmented.team."
34587
+ };
34588
+ function buildAccountIssueReplyText(level, override) {
34589
+ const trimmed = typeof override === "string" ? override.trim() : "";
34590
+ return trimmed || DEFAULT_ACCOUNT_ENFORCEMENT_COPY[level];
34541
34591
  }
34542
34592
 
34543
34593
  // ../core/dist/kanban/state-machine.js
@@ -35633,6 +35683,32 @@ var FLAG_REGISTRY = [
35633
35683
  // Best-effort reach estimate only; not part of the schema fingerprint.
35634
35684
  since: "0.28.504"
35635
35685
  },
35686
+ {
35687
+ key: "utilization-occupancy-qualifier",
35688
+ description: "Utilization busy-minutes gate (ENG-8465): shadow = report every measured bucket exactly as before while COUNTING how many a transcript qualifier would drop; enforce = drop measured buckets that have no qualifying assistant turn (>= 25 output tokens, non-synthetic) within \xB1120s. The qualifier is the merged @augmented/core primitive (extractQualifyingTurns / isBucketQualified); the host reads a bounded transcript tail incl. <sessionId>/subagents/ at drain time and FAILS OPEN (credits ungated) when a transcript cannot be read. Read host-side via hostFlagStore (getString) in the manager; consumer ships in this PR's agt-cli auto-publish bump. Both modes emit the OccupancyQualificationClassifications shadow metric (qualified positive-control + unqualified_dropped signal + unreadable), so per-agent impact is measured before the flip.",
35689
+ flagType: "enum",
35690
+ allowedValues: ["shadow", "enforce"],
35691
+ // Declared safe value is `shadow`: it reproduces pre-flag billing exactly, so
35692
+ // rollout changes no agent's minutes while the shadow metric accrues the
35693
+ // enforce-flip evidence. `enforce` lowers a billing-adjacent number, so it is a
35694
+ // deliberate, audited flip — never a flag-DB-read-error default.
35695
+ defaultValue: "shadow",
35696
+ // Operator per-host override (ADR-0022 highest precedence). No _ENABLED/_DISABLED/
35697
+ // _MODE suffix, and read via hostFlagStore not a raw process.env gate, so not a
35698
+ // new env gate under ENG-6252. Never pinned in sst.config.ts (ENG-8303).
35699
+ envVar: "AGT_UTILIZATION_OCCUPANCY_QUALIFIER",
35700
+ // enforce lowers a billing-adjacent number, so flipping/weakening it is guarded
35701
+ // like the other enforcement-mode flags.
35702
+ sensitive: true,
35703
+ // Reach threshold (ENG-8465): the host reader (occupancyQualifierMode in
35704
+ // manager-worker.ts) lands in this PR's agt-cli auto-publish patch bump, which
35705
+ // is the first published version to contain it (through 0.28.528 does not). An
35706
+ // UNSET `since` makes classifyHostReach report `honors` (full coverage), which
35707
+ // would greenlight an `enforce` flip while older hosts silently stay `shadow`.
35708
+ // Best-effort estimate (like docker-hygiene's), in the safe direction — a
35709
+ // not-yet-published version reports 0% honor until hosts update. (CodeRabbit)
35710
+ since: "0.28.529"
35711
+ },
35636
35712
  {
35637
35713
  key: "composio-hitl-mode",
35638
35714
  description: "Composio managed-toolkits HITL gate (ENG-6027): off = kill switch, shadow = resolve + audit the tier decision but never block, enforce = block write_high_risk+ calls and route them to Human Approval (an Approve/Deny card). Since ENG-7828 enforce ALWAYS routes to a Human Approval card by default; set hitl-approval-routing=off to make enforce a hard block with no approval instead. Per-org rollout from the admin Feature Flags page; ENG-7672 migrated this off the fleet-wide COMPOSIO_HITL_MODE env var.",
@@ -36039,6 +36115,15 @@ var FLAG_REGISTRY = [
36039
36115
  // runbook gates on it. Leaving the placeholder in place is safe (nothing
36040
36116
  // flips); shipping a guessed number is not.
36041
36117
  since: "0.29.0"
36118
+ },
36119
+ {
36120
+ key: "help-kb-auto-grant",
36121
+ 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).",
36122
+ flagType: "boolean",
36123
+ // Declared safe value is `false` = grant nothing. A flag-store outage must
36124
+ // never auto-attach an integration nobody asked for, and both ENG-8332
36125
+ // prerequisites above are still open.
36126
+ defaultValue: false
36042
36127
  }
36043
36128
  ];
36044
36129
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
@@ -36091,7 +36176,7 @@ function accountEnforcementMarkerPath(codeName) {
36091
36176
  if (!codeName) return null;
36092
36177
  return join2(homedir2(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
36093
36178
  }
36094
- function readAccountEnforcementLevel(opts) {
36179
+ function readAccountEnforcementMarker(opts) {
36095
36180
  const path = opts.filePath ?? accountEnforcementMarkerPath(opts.codeName);
36096
36181
  if (!path) return null;
36097
36182
  let raw;
@@ -36100,7 +36185,14 @@ function readAccountEnforcementLevel(opts) {
36100
36185
  } catch {
36101
36186
  return null;
36102
36187
  }
36103
- return parseAccountEnforcementMarker(raw)?.level ?? null;
36188
+ return parseAccountEnforcementMarker(raw);
36189
+ }
36190
+ function readAccountEnforcementLevel(opts) {
36191
+ return readAccountEnforcementMarker(opts)?.level ?? null;
36192
+ }
36193
+ function resolveAccountIssueReplyText(level, opts) {
36194
+ const marker = readAccountEnforcementMarker(opts);
36195
+ return buildAccountIssueReplyText(level, marker?.level === level ? marker.text : void 0);
36104
36196
  }
36105
36197
  function shouldSendAccountWarn(opts) {
36106
36198
  if (readAccountEnforcementLevel({ codeName: opts.codeName, filePath: opts.filePath }) !== "warn") {
@@ -40649,7 +40741,7 @@ async function maybeSendAccountMuteNotice(args) {
40649
40741
  },
40650
40742
  body: JSON.stringify({
40651
40743
  channel: args.channel,
40652
- text: buildAccountIssueReplyText(),
40744
+ text: resolveAccountIssueReplyText("mute", { codeName: AGENT_CODE_NAME }),
40653
40745
  ...args.threadTs ? { thread_ts: args.threadTs } : {}
40654
40746
  })
40655
40747
  });
@@ -40697,7 +40789,7 @@ async function maybeSendSlackAccountWarn(args) {
40697
40789
  },
40698
40790
  body: JSON.stringify({
40699
40791
  channel: args.channel,
40700
- text: buildAccountIssueReplyText(),
40792
+ text: resolveAccountIssueReplyText("warn", { codeName: AGENT_CODE_NAME }),
40701
40793
  ...args.threadTs ? { thread_ts: args.threadTs } : {}
40702
40794
  })
40703
40795
  });
@@ -34032,6 +34032,45 @@ var INTEGRATION_REGISTRY = [
34032
34032
  { id: "augmented-support:propose-writes", name: "Propose Self-Remediation", description: "Propose creating an agent in your own org; executed only after a human approves a server-rendered diff.", access: "write" }
34033
34033
  ]
34034
34034
  },
34035
+ {
34036
+ // ENG-8332: the Augmented Team HELP knowledge base, split out of
34037
+ // `augmented-support` so an agent can be given the docs WITHOUT also being
34038
+ // given a ticket-filing button, an agent-proposal button, and org-wide read
34039
+ // of agents, hosts, integrations, alerts, flags and the audit log. That
34040
+ // bundling was why "just give everyone augmented-support" was the wrong
34041
+ // answer, and the cost was agents answering platform questions from
34042
+ // inference instead of documentation (the CS-1529/CS-1530 case).
34043
+ //
34044
+ // Provisions the @integrity-labs/augmented-help-kb-mcp stdio broker, a
34045
+ // read-only client over /host/kb - the single enumerated carve-out from the
34046
+ // ADR-0032 org-lock invariant (ENG-7119). KB content is platform-curated
34047
+ // and org-neutral, so this grants NO view of any org's state; the client
34048
+ // has no POST transport at all, so writes are structurally impossible
34049
+ // rather than merely unregistered.
34050
+ //
34051
+ // auth `none` - no end-user OAuth, the host JWT is the credential. `beta`
34052
+ // while distribution widens. NOT in the Add Integration picker (no
34053
+ // `installable`): granted deliberately, like its two siblings.
34054
+ //
34055
+ // NAMING (ENG-7281): this is the "help knowledge base" - shared, published,
34056
+ // org-neutral PRODUCT help. It is NOT the org knowledge store that
34057
+ // `knowledge_search` / `context_search` read. Keep the two distinct in every
34058
+ // surface that names them.
34059
+ id: "augmented-help-kb",
34060
+ name: "Augmented Help KB",
34061
+ category: "knowledge",
34062
+ description: "The Augmented Team help knowledge base: search and read the shared, published product documentation (how-tos, common fixes, FAQs). Identical for every organization and org-neutral by design - it grants no view of your org's own state, and cannot file tickets or propose changes. Distinct from your organization's own knowledge store.",
34063
+ supported_auth_types: ["none"],
34064
+ beta: true,
34065
+ capabilities: [
34066
+ {
34067
+ id: "augmented-help-kb:read",
34068
+ name: "Read Help Docs",
34069
+ description: "Search and read published Augmented Team help articles (org-neutral product documentation). Read-only; no ticket filing, no agent proposals, no org-state reads.",
34070
+ access: "read"
34071
+ }
34072
+ ]
34073
+ },
34035
34074
  {
34036
34075
  id: "firecrawl",
34037
34076
  name: "Firecrawl",
@@ -34855,10 +34894,21 @@ function parseAccountEnforcementMarker(raw) {
34855
34894
  const level = parsed.level;
34856
34895
  if (level !== "warn" && level !== "mute")
34857
34896
  return null;
34858
- return { version: ACCOUNT_ENFORCEMENT_MARKER_VERSION, level };
34897
+ const rawText = parsed.text;
34898
+ const text = typeof rawText === "string" && rawText.trim() ? rawText.trim() : void 0;
34899
+ return {
34900
+ version: ACCOUNT_ENFORCEMENT_MARKER_VERSION,
34901
+ level,
34902
+ ...text ? { text } : {}
34903
+ };
34859
34904
  }
34860
- function buildAccountIssueReplyText() {
34861
- return "There is an issue with your account, please contact support@augmented.team.";
34905
+ var DEFAULT_ACCOUNT_ENFORCEMENT_COPY = {
34906
+ warn: "Heads-up: there's an issue with your account that needs attention. Please contact support@augmented.team so I can keep helping you.",
34907
+ mute: "There is an issue with your account, please contact support@augmented.team."
34908
+ };
34909
+ function buildAccountIssueReplyText(level, override) {
34910
+ const trimmed = typeof override === "string" ? override.trim() : "";
34911
+ return trimmed || DEFAULT_ACCOUNT_ENFORCEMENT_COPY[level];
34862
34912
  }
34863
34913
 
34864
34914
  // ../core/dist/kanban/state-machine.js
@@ -35954,6 +36004,32 @@ var FLAG_REGISTRY = [
35954
36004
  // Best-effort reach estimate only; not part of the schema fingerprint.
35955
36005
  since: "0.28.504"
35956
36006
  },
36007
+ {
36008
+ key: "utilization-occupancy-qualifier",
36009
+ description: "Utilization busy-minutes gate (ENG-8465): shadow = report every measured bucket exactly as before while COUNTING how many a transcript qualifier would drop; enforce = drop measured buckets that have no qualifying assistant turn (>= 25 output tokens, non-synthetic) within \xB1120s. The qualifier is the merged @augmented/core primitive (extractQualifyingTurns / isBucketQualified); the host reads a bounded transcript tail incl. <sessionId>/subagents/ at drain time and FAILS OPEN (credits ungated) when a transcript cannot be read. Read host-side via hostFlagStore (getString) in the manager; consumer ships in this PR's agt-cli auto-publish bump. Both modes emit the OccupancyQualificationClassifications shadow metric (qualified positive-control + unqualified_dropped signal + unreadable), so per-agent impact is measured before the flip.",
36010
+ flagType: "enum",
36011
+ allowedValues: ["shadow", "enforce"],
36012
+ // Declared safe value is `shadow`: it reproduces pre-flag billing exactly, so
36013
+ // rollout changes no agent's minutes while the shadow metric accrues the
36014
+ // enforce-flip evidence. `enforce` lowers a billing-adjacent number, so it is a
36015
+ // deliberate, audited flip — never a flag-DB-read-error default.
36016
+ defaultValue: "shadow",
36017
+ // Operator per-host override (ADR-0022 highest precedence). No _ENABLED/_DISABLED/
36018
+ // _MODE suffix, and read via hostFlagStore not a raw process.env gate, so not a
36019
+ // new env gate under ENG-6252. Never pinned in sst.config.ts (ENG-8303).
36020
+ envVar: "AGT_UTILIZATION_OCCUPANCY_QUALIFIER",
36021
+ // enforce lowers a billing-adjacent number, so flipping/weakening it is guarded
36022
+ // like the other enforcement-mode flags.
36023
+ sensitive: true,
36024
+ // Reach threshold (ENG-8465): the host reader (occupancyQualifierMode in
36025
+ // manager-worker.ts) lands in this PR's agt-cli auto-publish patch bump, which
36026
+ // is the first published version to contain it (through 0.28.528 does not). An
36027
+ // UNSET `since` makes classifyHostReach report `honors` (full coverage), which
36028
+ // would greenlight an `enforce` flip while older hosts silently stay `shadow`.
36029
+ // Best-effort estimate (like docker-hygiene's), in the safe direction — a
36030
+ // not-yet-published version reports 0% honor until hosts update. (CodeRabbit)
36031
+ since: "0.28.529"
36032
+ },
35957
36033
  {
35958
36034
  key: "composio-hitl-mode",
35959
36035
  description: "Composio managed-toolkits HITL gate (ENG-6027): off = kill switch, shadow = resolve + audit the tier decision but never block, enforce = block write_high_risk+ calls and route them to Human Approval (an Approve/Deny card). Since ENG-7828 enforce ALWAYS routes to a Human Approval card by default; set hitl-approval-routing=off to make enforce a hard block with no approval instead. Per-org rollout from the admin Feature Flags page; ENG-7672 migrated this off the fleet-wide COMPOSIO_HITL_MODE env var.",
@@ -36360,6 +36436,15 @@ var FLAG_REGISTRY = [
36360
36436
  // runbook gates on it. Leaving the placeholder in place is safe (nothing
36361
36437
  // flips); shipping a guessed number is not.
36362
36438
  since: "0.29.0"
36439
+ },
36440
+ {
36441
+ key: "help-kb-auto-grant",
36442
+ 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).",
36443
+ flagType: "boolean",
36444
+ // Declared safe value is `false` = grant nothing. A flag-store outage must
36445
+ // never auto-attach an integration nobody asked for, and both ENG-8332
36446
+ // prerequisites above are still open.
36447
+ defaultValue: false
36363
36448
  }
36364
36449
  ];
36365
36450
  var REGISTRY_BY_KEY = new Map(FLAG_REGISTRY.map((definition) => [definition.key, definition]));
@@ -36412,7 +36497,7 @@ function accountEnforcementMarkerPath(codeName) {
36412
36497
  if (!codeName) return null;
36413
36498
  return join3(homedir3(), ".augmented", codeName, ACCOUNT_ENFORCEMENT_MARKER_FILENAME);
36414
36499
  }
36415
- function readAccountEnforcementLevel(opts) {
36500
+ function readAccountEnforcementMarker(opts) {
36416
36501
  const path = opts.filePath ?? accountEnforcementMarkerPath(opts.codeName);
36417
36502
  if (!path) return null;
36418
36503
  let raw;
@@ -36421,7 +36506,14 @@ function readAccountEnforcementLevel(opts) {
36421
36506
  } catch {
36422
36507
  return null;
36423
36508
  }
36424
- return parseAccountEnforcementMarker(raw)?.level ?? null;
36509
+ return parseAccountEnforcementMarker(raw);
36510
+ }
36511
+ function readAccountEnforcementLevel(opts) {
36512
+ return readAccountEnforcementMarker(opts)?.level ?? null;
36513
+ }
36514
+ function resolveAccountIssueReplyText(level, opts) {
36515
+ const marker = readAccountEnforcementMarker(opts);
36516
+ return buildAccountIssueReplyText(level, marker?.level === level ? marker.text : void 0);
36425
36517
  }
36426
36518
  function shouldSendAccountWarn(opts) {
36427
36519
  if (readAccountEnforcementLevel({ codeName: opts.codeName, filePath: opts.filePath }) !== "warn") {
@@ -39677,7 +39769,7 @@ async function maybeSendTelegramAccountMuteNotice(args) {
39677
39769
  "sendMessage",
39678
39770
  {
39679
39771
  chat_id: args.chatId,
39680
- text: buildAccountIssueReplyText(),
39772
+ text: resolveAccountIssueReplyText("mute", { codeName: AGENT_CODE_NAME }),
39681
39773
  ...args.messageThreadId != null ? { message_thread_id: args.messageThreadId } : {}
39682
39774
  },
39683
39775
  1e4
@@ -39714,7 +39806,7 @@ async function maybeSendTelegramAccountWarn(args) {
39714
39806
  return;
39715
39807
  }
39716
39808
  try {
39717
- const resp = await telegramApiCall("sendMessage", { chat_id: args.chatId, text: buildAccountIssueReplyText() }, 1e4);
39809
+ const resp = await telegramApiCall("sendMessage", { chat_id: args.chatId, text: resolveAccountIssueReplyText("warn", { codeName: AGENT_CODE_NAME }) }, 1e4);
39718
39810
  if (!resp.ok) {
39719
39811
  TELEGRAM_ACCOUNT_WARN_NOTICE_CACHE.delete(key2);
39720
39812
  process.stderr.write(
@@ -37,7 +37,7 @@ import {
37
37
  writeDirectChatSessionState,
38
38
  writeEgressAllowlist,
39
39
  writePersistentClaudeWrapper
40
- } from "./chunk-PR3QSOLI.js";
40
+ } from "./chunk-Q4XGKOHZ.js";
41
41
  import "./chunk-XWVM4KPK.js";
42
42
  export {
43
43
  EGRESS_BASELINE_DOMAINS,
@@ -79,4 +79,4 @@ export {
79
79
  writeEgressAllowlist,
80
80
  writePersistentClaudeWrapper
81
81
  };
82
- //# sourceMappingURL=persistent-session-KAHG73SM.js.map
82
+ //# sourceMappingURL=persistent-session-T4IY7AJU.js.map