@rosthq/cli 0.7.110 → 0.7.112
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/index.js +126 -18
- package/dist/index.js.map +3 -3
- package/dist/runner-serve.d.ts +4 -0
- package/dist/runner-serve.d.ts.map +1 -1
- package/package.json +1 -1
- package/prompts/how-tos/human-confirmations.md +1 -0
package/dist/index.js
CHANGED
|
@@ -40689,7 +40689,7 @@ var aicosPulseSnapshotSchema = external_exports.object({
|
|
|
40689
40689
|
// ../../packages/protocol/src/command-introspection.ts
|
|
40690
40690
|
var requiredScopeSchema = external_exports.enum(["tenant_admin", "tenant", "seat", "user"]);
|
|
40691
40691
|
var confirmationSchema = external_exports.enum(["none", "human_required", "credential_flow", "dangerous"]);
|
|
40692
|
-
var trustedExecutionModeSchema = external_exports.enum(["eligible", "always_human", "not_applicable"]);
|
|
40692
|
+
var trustedExecutionModeSchema = external_exports.enum(["eligible", "eligible_bounded", "always_human", "not_applicable"]);
|
|
40693
40693
|
var trustedExecutionRiskFlagSchema = external_exports.enum([
|
|
40694
40694
|
"admin",
|
|
40695
40695
|
"credential",
|
|
@@ -48239,7 +48239,7 @@ Drafting can be assisted by agents. Activation is a human decision. When authori
|
|
|
48239
48239
|
order: 40,
|
|
48240
48240
|
title: "Agent staffing playbook",
|
|
48241
48241
|
summary: "How to decide whether a seat should be human, agent, or hybrid, and how to go live safely.",
|
|
48242
|
-
version: "2026-07-
|
|
48242
|
+
version: "2026-07-20.1",
|
|
48243
48243
|
public: true,
|
|
48244
48244
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
48245
48245
|
stages: ["staffing"],
|
|
@@ -48297,7 +48297,7 @@ Two creation paths, both draft-first. Read the stock-agents guide for templates
|
|
|
48297
48297
|
- From a template: list with \`agent_template.list\` / \`rost_list_agent_templates\`, then \`agent.create_from_template\` / \`rost_create_agent_from_template\` with \`seat_id\` and \`template_slug\`. Returns a draft agent and draft Charter only.
|
|
48298
48298
|
- Custom: \`agent_setup.start\` / \`rost_start_agent_setup\` (returns a \`setup_id\`), iterate with \`agent_setup.get\` and \`agent_setup.update\`, then \`agent.create_custom\` / \`rost_create_custom_agent\`. Stage tools with \`agent.configure_tools\` (vault refs only) and sandbox with \`agent.run_dry_run\`.
|
|
48299
48299
|
- Inspect runtime: \`agent.status\` / \`rost_get_agent_status\` with \`{"seat_id":"<seat-id>"}\` returns lane, live state, steward chain, dry-run result, and Runner availability.
|
|
48300
|
-
- Run on demand: \`{{cli}} agent run-now --seat-id <seat-id>\` / \`agent.run_now\` / \`rost_run_agent_now\` queues an immediate live run without changing the saved schedule. Cloud agents dispatch to the Inngest executor; runner agents queue work for the paired runner.
|
|
48300
|
+
- Run on demand: \`{{cli}} agent run-now --seat-id <seat-id>\` / \`agent.run_now\` / \`rost_run_agent_now\` queues an immediate live run without changing the saved schedule. Cloud agents dispatch to the Inngest executor; runner agents queue work for the paired runner. It is \`human_required\` (DER-1766/DER-2081): a human requesting a run acts directly, an agent re-running its OWN seat (same-seat) may auto-execute under a standing Trusted grant, and a cross-seat dispatch (one seat running a different seat's agent) always asks a human. It still requires a live staffed agent and passes the normal server-side tool guard.
|
|
48301
48301
|
- Audit what an agent did (Trust Card): \`{{cli}} command agent.list_runs --json '{"seat_id":"<seat-id>"}'\` / \`rost_list_agent_runs\` returns the seat's run history with per-run Skill activation counts plus tool-call, guard-denied, and guard-held counts; \`{{cli}} agent get-run --seat-id <seat-id> --run-id <run-id>\` / \`agent.get_run\` / \`rost_get_agent_run_diagnostics\` reads one run's transcript reference, token/cost usage, outcome, product-visible run errors, and any Skill versions/files loaded for that run. Pass \`--transcript\` (\`{"transcript":true}\`) to also return the persisted, secret-scrubbed session transcript for that run when one exists \u2014 cloud-lane and runner turns persist a bounded transcript at turn end. Final run outcomes are no longer chopped to a short summary; the full report survives. Loaded Skill file hashes and sizes identify the immutable source package; the runtime may still bound or truncate prompt text before sending it to the model. \`{{cli}} command agent.list_tool_calls --json '{"seat_id":"<seat-id>"}'\` / \`rost_list_agent_tool_calls\` returns the tool-call ledger with each call's guard result. Both list commands include \`denied_tool_call_count\` and \`held_tool_call_count\` rollups: hard guard denials stay separate from actions escalated for review. Pass \`{"seat_id":"<seat-id>","held_only":true}\` to \`agent.list_tool_calls\` for only the held calls. The web seat page shows the same facts as a Trust Card, and its Activity tab additionally renders the full persisted transcript and artifacts rail for a selected session inline (no \`--transcript\` flag needed there) alongside the business-activity ledger (\`work.record\`/\`work.list\`) \u2014 counter tiles and a run-grouped feed with each record's verb, object, outcome, evidence, and \`template_ref\` when one was used.
|
|
48302
48302
|
|
|
48303
48303
|
## Review readiness before go-live
|
|
@@ -48312,7 +48312,7 @@ The lane a live agent runs on \u2014 cloud (the {{brand}}-managed runtime), a pa
|
|
|
48312
48312
|
|
|
48313
48313
|
## When to stop for confirmation
|
|
48314
48314
|
|
|
48315
|
-
\`agent.create_from_template\`, \`agent.create_custom\`, \`staffing.assign_user\`, \`agent.go_live\`, \`agent.update_schedule\`, \`agent_setup.relane\`, and \`mcp_token.create\` are \`human_required\`; \`agent.configure_tools\` and \`credential.ingress\` are \`credential_flow\` (both gate through the vault-backed credential path with human approval; \`agent.configure_tools\` stages the request and only \`credential.ingress\` takes the raw secret, as a vault reference); \`agent.decommission\` is \`dangerous\`. \`agent.run_now\` is
|
|
48315
|
+
\`agent.create_from_template\`, \`agent.create_custom\`, \`staffing.assign_user\`, \`agent.go_live\`, \`agent.update_schedule\`, \`agent_setup.relane\`, and \`mcp_token.create\` are \`human_required\`; \`agent.configure_tools\` and \`credential.ingress\` are \`credential_flow\` (both gate through the vault-backed credential path with human approval; \`agent.configure_tools\` stages the request and only \`credential.ingress\` takes the raw secret, as a vault reference); \`agent.decommission\` is \`dangerous\`. \`agent.run_now\` is \`human_required\` (DER-1766/DER-2081): a cross-seat run always asks, while a same-seat re-run of the acting seat's own live agent may auto-execute only under a standing Trusted grant. An agent may draft, configure (with vault refs), dry-run, and request an on-demand run; the human approves go-live, credentials, schedule changes, and decommission. \`run_dry_run\` is ungated by human approval, but it is **precondition-gated**: the seat's permission manifest must be signed first (\`charter.sign_manifest\`). Attempting a dry run before sign-off returns a clean \`COMMAND_PRECONDITION_FAILED\` naming \`charter.sign_manifest\`, not a generic failure. Go-live after a passed dry run is \`human_required\`. See the confirmations guide.
|
|
48316
48316
|
|
|
48317
48317
|
## Non-negotiables
|
|
48318
48318
|
|
|
@@ -50009,7 +50009,7 @@ Set \`ROST_SKILL_INSTALL_ROOT\` only for a sandbox or CI override. Local copies
|
|
|
50009
50009
|
order: 55,
|
|
50010
50010
|
title: "Agent reference map",
|
|
50011
50011
|
summary: "Where CLI sessions, MCP clients, and in-app agents should retrieve {{brand}} guidance before recommending setup changes.",
|
|
50012
|
-
version: "2026-07-
|
|
50012
|
+
version: "2026-07-20.1",
|
|
50013
50013
|
public: true,
|
|
50014
50014
|
audiences: ["cli", "mcp", "in_app_agent"],
|
|
50015
50015
|
stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
|
|
@@ -50123,6 +50123,7 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
50123
50123
|
- Run the weekly Sync (compile, run, complete, assign): sync-rhythm-playbook.
|
|
50124
50124
|
- Operate local runners and work orders: runner-guide.
|
|
50125
50125
|
- Approve or reject a pending confirmation (human only): confirmations-guide.
|
|
50126
|
+
- Explain what a command or agent can do automatically versus what always asks a human, or how Trusted mode and the auto band work: governed-command-capability-matrix, then confirmations-guide.
|
|
50126
50127
|
- Manage members, settings, and notifications: settings-guide, settings-members-and-invites-guide, notifications-guide.
|
|
50127
50128
|
- Explain company-wide billing, payment, invoices, or usage true-ups: billing-and-pricing-guide, then settings-guide.
|
|
50128
50129
|
- Diagnose a failure on any surface: troubleshooting-guide, then security-model-guide.
|
|
@@ -50133,7 +50134,7 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
50133
50134
|
- Graph design: responsibility-graph-playbook
|
|
50134
50135
|
- Charter design: charter-design-playbook, charter-authoring-deep-dive
|
|
50135
50136
|
- Staffing: agent-staffing-playbook, add-agents-guide, custom-agents-guide, agent-builder-guide, agent-definition-import-guide, how-agents-work, tool-access-and-vault, available-tools-guide, skill-builder-guide, agent-skill-authoring-guide, agent-skill-setup-guide, mcp-and-cli-guide, stock-agents-guide
|
|
50136
|
-
- Operating rhythm: aicos-chat-guide, cascade-guide, signal-guide, friction-guide, confirmations-guide, steward-queue-guide, sync-rhythm-playbook, notifications-guide
|
|
50137
|
+
- Operating rhythm: aicos-chat-guide, cascade-guide, signal-guide, friction-guide, confirmations-guide, governed-command-capability-matrix, steward-queue-guide, sync-rhythm-playbook, notifications-guide
|
|
50137
50138
|
- Local agents and runners: mcp-and-cli-guide, runner-guide, agent-reference-map
|
|
50138
50139
|
- Security and troubleshooting: ai-model-data-handling-guide, security-model-guide, troubleshooting-guide
|
|
50139
50140
|
|
|
@@ -50253,7 +50254,7 @@ Agents can suggest commitments and report progress. They should not create a new
|
|
|
50253
50254
|
order: 61,
|
|
50254
50255
|
title: "Signal guide",
|
|
50255
50256
|
summary: "How to define and read measurables so the company runs on evidence instead of status theater.",
|
|
50256
|
-
version: "2026-07-20.
|
|
50257
|
+
version: "2026-07-20.2",
|
|
50257
50258
|
public: true,
|
|
50258
50259
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
50259
50260
|
stages: ["operating_rhythm"],
|
|
@@ -50312,7 +50313,7 @@ Avoid vanity numbers, manual-only status fields, and metrics nobody can act on.
|
|
|
50312
50313
|
- Add a measurable: \`measurable.create\` (scope: seat) defines a measurable a seat owns \u2014 name, unit, direction, target, cadence. The seat owns it; readings attach to it afterward.
|
|
50313
50314
|
- Record a reading: \`{{cli}} status record --measurable-id <id> --value <n>\` (\`status.record\`, scope: seat) writes a status event with the reading. This is not gated. An agent's \`status.record\` never downgrades a human-confirmed reading: a routine agent read that lands on a period a human already confirmed leaves the confirmed value and its confirmation intact (invariants #7/#8 \u2014 agents recommend; humans decide).
|
|
50314
50315
|
- Confirm a reading: \`{{cli}} signal confirm\` / \`signal.confirm_reading\` / \`rost_confirm_signal_reading\` marks a reading human-verified. \`signal.correct_reading\` / \`rost_correct_signal_reading\` overwrites a reading with a human-confirmed value.
|
|
50315
|
-
- Draft first readings from a connected source: \`signal.draft_first_readings\` pulls a measurable's bound source once (read-only, SSRF-guarded \u2014 the same pull path as \`signal.preview\`) and lands the value as a DRAFT reading for the current period, for a human to confirm. It is for a measurable that has a connected source but
|
|
50316
|
+
- Draft first readings from a connected source: \`signal.draft_first_readings\` pulls a measurable's bound source once (read-only, SSRF-guarded \u2014 the same pull path as \`signal.preview\`) and lands the value as a DRAFT reading for the current period, for a human to confirm. It is strictly for a measurable that has a connected source but has never had a confirmed reading \u2014 in ANY period, not just the current one. A measurable that already carries a confirmed reading (even an older one) is rejected with an "already has readings" outcome and no pull happens, so the first-reading flow can never be repurposed as an ongoing draft source; use \`signal.report\` to add a current-period datapoint or \`signal.correct_reading\` to change a confirmed value instead. The Signal page shows a "Draft first readings" button on the eligible (never-measured) rows so the row stops being a permanent blank. Nothing is published \u2014 a human clears the draft with \`signal.confirm_reading\` (invariant #7) \u2014 and it never fabricates a value: a non-numeric or blocked pull drafts nothing and says so.
|
|
50316
50317
|
|
|
50317
50318
|
## Run Signal without an agent
|
|
50318
50319
|
|
|
@@ -50708,6 +50709,86 @@ The billing area in Settings answers:
|
|
|
50708
50709
|
Settings labels subscription usage separately from the setup model allowance and the inference hard cap. Payment methods and invoice payment stay in Stripe. {{brand}} renders subscription ids/status and invoice summaries only; it does not store card, bank, payment-method, or invoice-payment details.
|
|
50709
50710
|
|
|
50710
50711
|
Do not claim that a live charge happened unless Stripe test/live evidence proves it. For internal or design-partner validation, use Stripe test mode only unless a human owner explicitly completes a real live-payment step.`
|
|
50712
|
+
},
|
|
50713
|
+
{
|
|
50714
|
+
slug: "governed-command-capability-matrix",
|
|
50715
|
+
order: 72,
|
|
50716
|
+
title: "Governed command capability matrix",
|
|
50717
|
+
summary: "How to read {{brand}}'s command capability classification: the four confirmation classes, the Trusted-eligibility classes, the five-command auto band, and the always-human floor.",
|
|
50718
|
+
version: "2026-07-20.1",
|
|
50719
|
+
public: true,
|
|
50720
|
+
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
50721
|
+
stages: ["charter_design", "staffing", "operating_rhythm"],
|
|
50722
|
+
relatedCommandIds: [
|
|
50723
|
+
"command.list",
|
|
50724
|
+
"command.describe",
|
|
50725
|
+
"agent.update_schedule",
|
|
50726
|
+
"goal.bind_measurable",
|
|
50727
|
+
"skill.assign_to_seat",
|
|
50728
|
+
"friction.resolve",
|
|
50729
|
+
"agent.run_now",
|
|
50730
|
+
"agent.trust.create",
|
|
50731
|
+
"confirmation.approve"
|
|
50732
|
+
],
|
|
50733
|
+
legal: {
|
|
50734
|
+
publicRisk: "low",
|
|
50735
|
+
notes: [
|
|
50736
|
+
"Describes {{brand}}-native command governance classification; no third-party or proprietary content."
|
|
50737
|
+
]
|
|
50738
|
+
},
|
|
50739
|
+
sources: [
|
|
50740
|
+
{
|
|
50741
|
+
label: "Governed command capability matrix (generated)",
|
|
50742
|
+
internalPath: "docs/reference/governed-command-capability-matrix.md",
|
|
50743
|
+
note: "Authoritative, command-by-command capability table regenerated from the command registry (`pnpm generate:capability-matrix`) and kept in sync by a drift test."
|
|
50744
|
+
}
|
|
50745
|
+
],
|
|
50746
|
+
body: `# Governed command capability matrix
|
|
50747
|
+
|
|
50748
|
+
Every {{brand}} command that changes state \u2014 through the human app, the CLI, an MCP client, or the in-app AI Chief of Staff \u2014 carries the same registry-derived governance classification. This guide answers the question every agent and every human operator eventually asks: what can my agents do right now, and how do I change that? Which commands ask a human every time, which can automate under Trusted mode, and which stay off-limits to automation no matter what.
|
|
50749
|
+
|
|
50750
|
+
The full command-by-command table is generated directly from the command registry and lives at \`docs/reference/governed-command-capability-matrix.md\`. A drift test keeps it honest: it fails CI the moment the registry changes without the table being regenerated, so the table can never quietly go stale. This guide is the curated companion \u2014 read it first to understand the classification scheme, then open the generated table to look up any specific command's exact row.
|
|
50751
|
+
|
|
50752
|
+
## The four confirmation classes
|
|
50753
|
+
|
|
50754
|
+
Every command declares one of four confirmation classes:
|
|
50755
|
+
|
|
50756
|
+
- **None** \u2014 no human gate at all. The command runs immediately (for example a status update, a work log entry, or a task creation the acting seat already owns).
|
|
50757
|
+
- **Human required** \u2014 the durable-change default. The command mints a pending confirmation a human must approve before it takes effect, unless it qualifies for Trusted auto-band execution (below).
|
|
50758
|
+
- **Credential flow** \u2014 the command routes through the vault-backed credential flow. A raw secret never appears in a prompt, a log, or a CLI argument.
|
|
50759
|
+
- **Dangerous** \u2014 an irreversible or high-blast-radius action (for example decommissioning an agent) that always asks, with extra confirmation friction.
|
|
50760
|
+
|
|
50761
|
+
## The Trusted-eligibility classes
|
|
50762
|
+
|
|
50763
|
+
Turning on Trusted mode for a seat does not change a command's confirmation class. It changes whether that seat may execute a \`human_required\` command's proposal automatically, under a standing authorization a human deliberately established. Every action taken this way is still recorded as its own human-authorized decision \u2014 Trusted mode automates the button-press, not the accountability. Every command falls into one of four Trusted-eligibility classes:
|
|
50764
|
+
|
|
50765
|
+
- **Auto** \u2014 a small, confirmation-free allowlist of low-risk worker actions (status updates, task creation, work logging, and similar) that already run without a human gate and are safe for a Trusted agent to keep doing unattended.
|
|
50766
|
+
- **Auto-bounded** \u2014 a \`human_required\` command that may auto-execute under Trusted, but only for a narrow, founder-approved bounded sub-case of its input (the five-command auto band, below). Every other input on the same command still mints a normal human confirmation.
|
|
50767
|
+
- **Always ask** \u2014 a command carrying a protected risk category (credential, spend, external send, production/go-live, destructive, self-approval, or admin) or otherwise gated. Trusted mode never changes this; it always asks a human.
|
|
50768
|
+
- **Not applicable** \u2014 a discovery or read command with no durable action to automate.
|
|
50769
|
+
|
|
50770
|
+
## The five-command auto band
|
|
50771
|
+
|
|
50772
|
+
Exactly five commands carry an auto band today \u2014 a founder-approved, narrow bounded sub-case where a \`human_required\` command may auto-execute under a standing Trusted grant on a human-initiated turn. Any input outside the described bound still mints a human confirmation:
|
|
50773
|
+
|
|
50774
|
+
1. **\`agent.update_schedule\`** (schedule set) \u2014 setting or changing a seat's routine schedule. Clearing a schedule is out of band and still asks.
|
|
50775
|
+
2. **\`goal.bind_measurable\`** (informs Signal bind) \u2014 binding a Signal in the conservative "informs" role, which never drives goal status. A "drives status" binding is out of band and still asks.
|
|
50776
|
+
3. **\`skill.assign_to_seat\`** (published skill assign) \u2014 assigning an already-published, immutable skill version to a seat. A proposed (non-approved) assignment, or a version that does not resolve to a published skill, is out of band and still asks.
|
|
50777
|
+
4. **\`friction.resolve\`** (routine Friction resolve) \u2014 resolving a Friction the acting seat already owns within its own member-seat subtree. A Friction outside that subtree, or a turn with no identifiable human initiator, is out of band and still asks.
|
|
50778
|
+
5. **\`agent.run_now\`** (same-seat run now) \u2014 re-running the acting seat's own live agent. A cross-seat dispatch, where one seat runs a different seat's agent, is out of band and still asks.
|
|
50779
|
+
|
|
50780
|
+
Widening this set, or adding a sixth command, is a deliberate founder decision \u2014 not something a code change alone can slip in. The registry enforces it: a command cannot carry an auto band unless it is one of these five ids.
|
|
50781
|
+
|
|
50782
|
+
## The always-human floor
|
|
50783
|
+
|
|
50784
|
+
A command carrying any of these risk categories always asks a human, even under Trusted mode: credential handling, spend or billing changes, external sends (invitations, outbound messages), production or go-live actions, destructive actions, self-approval of your own confirmation, or an admin-scope change. No autonomy setting removes this floor. It is a deliberate, conservative-by-default boundary \u2014 see confirmations-guide for how human gates work end to end.
|
|
50785
|
+
|
|
50786
|
+
## Where to look up a specific command
|
|
50787
|
+
|
|
50788
|
+
- The generated, authoritative table: \`docs/reference/governed-command-capability-matrix.md\` \u2014 one row per command with its required scope, confirmation class, Trusted mode, autonomy class, auto-band class (when it has one), MCP exposure, CLI availability, and whether the AI Chief of Staff can reach it as a governed tool call.
|
|
50789
|
+
- A single command's exact schema and classification: {{cli}} command schema <id> (CLI) or rost_describe_command (MCP).
|
|
50790
|
+
- How pending confirmations are approved or rejected: confirmations-guide.
|
|
50791
|
+
- How Trusted grants are created, inspected, and revoked: agent-staffing-playbook.`
|
|
50711
50792
|
},
|
|
50712
50793
|
{
|
|
50713
50794
|
slug: "settings-guide",
|
|
@@ -50920,7 +51001,7 @@ Every notification should include the seat, cause, evidence, and requested decis
|
|
|
50920
51001
|
order: 75,
|
|
50921
51002
|
title: "Local runner guide",
|
|
50922
51003
|
summary: "How local agent sessions and runner surfaces should operate through {{brand}} without bypassing Charters or audit.",
|
|
50923
|
-
version: "2026-07-20.
|
|
51004
|
+
version: "2026-07-20.2",
|
|
50924
51005
|
public: true,
|
|
50925
51006
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
50926
51007
|
stages: ["staffing", "operating_rhythm"],
|
|
@@ -51016,7 +51097,7 @@ Use this flow when a headless or desktop runner cannot use the interactive web c
|
|
|
51016
51097
|
|
|
51017
51098
|
## When to stop for confirmation
|
|
51018
51099
|
|
|
51019
|
-
\`runner.pairing.start
|
|
51100
|
+
\`runner.pairing.start\` and \`work_order.enqueue\` are \`none\`, so they do not create a separate pending confirmation, but \`runner.pairing.start\` is still owner/admin-only at the command authorization layer. \`runner.revoke\`, \`work_order.cancel\`, and \`agent.run_now\` are \`human_required\` (DER-1766/DER-2081): a cross-seat run always asks, and a same-seat re-run of the acting seat's own agent may auto-execute only under a standing Trusted grant. List and status reads are not gated. Revoking a runner or cancelling work is the human-approved act. An agent inspects runner state and proposes the action.
|
|
51020
51101
|
|
|
51021
51102
|
## Guardrails
|
|
51022
51103
|
|
|
@@ -52916,7 +52997,7 @@ var COMMAND_MANIFEST = [
|
|
|
52916
52997
|
{ "id": "agent.resume", "namespace": "agent", "action": "resume", "title": "Resume agent", "description": "Resume a paused agent back to live. Blocks if the steward chain no longer resolves to a human.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "reason", "flag": "reason", "type": "string", "required": false }], "hasComplexInput": false, "help": "Resume a paused agent back to live; the no-orphan guard blocks a resume whose steward chain no longer resolves to a human." },
|
|
52917
52998
|
{ "id": "agent.run_dry_run", "namespace": "agent", "action": "run_dry_run", "title": "Run agent dry run", "description": "Run the sandbox dry run for a draft agent. Durable and idempotent per Charter version; a passed result is reused, never re-run.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "charter_version_id", "flag": "charter-version-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Run the sandbox dry run for a draft agent after the manifest is signed; the result is durable and idempotent per Charter version, and a passed run is reused.", "example": { "seat_id": "0190aaaa-aaaa-7aaa-8aaa-aaaaaaaaaaaa", "charter_version_id": "0190cccc-cccc-7ccc-8ccc-cccccccccccc" } },
|
|
52918
52999
|
{ "id": "agent.run_heartbeats", "namespace": "agent", "action": "run_heartbeats", "title": "Get run heartbeats", "description": "Reads the per-seat run-heartbeat roll-up (quiet-but-healthy vs stalled) for long-running agent programs.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_ids", "flag": "seat-ids", "type": "array", "required": false, "itemType": "string" }], "hasComplexInput": false, "help": "Read the per-seat run-heartbeat roll-up to tell a quiet-but-healthy long-running agent program apart from a stalled one." },
|
|
52919
|
-
{ "id": "agent.run_now", "namespace": "agent", "action": "run_now", "title": "Run agent now", "description": "Queue and dispatch an immediate work order for a live cloud or runner agent on a seat. task_id is cloud-lane only; a runner-lane agent rejects it.", "requiredScope": "tenant", "confirmation": "
|
|
53000
|
+
{ "id": "agent.run_now", "namespace": "agent", "action": "run_now", "title": "Run agent now", "description": "Queue and dispatch an immediate work order for a live cloud or runner agent on a seat. task_id is cloud-lane only; a runner-lane agent rejects it.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }, { "name": "task_id", "flag": "task-id", "type": "string", "required": false }], "hasComplexInput": false, "help": "Queue and dispatch an immediate live agent run without changing the agent's saved schedule. task_id is cloud-lane only; a runner-lane agent rejects it (run task-linked runner work as an interactive agent turn)." },
|
|
52920
53001
|
{ "id": "agent.show_markdown", "namespace": "agent", "action": "show_markdown", "title": "Show agent setup as markdown", "description": "Compose a seat's agent setup, steward, model, tools, and Charter into a clean, human-skimmable markdown card for review.", "requiredScope": "tenant", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Render a seat's agent setup, model, steward, tools, and Charter as a clean markdown card to show your human a quick review." },
|
|
52921
53002
|
{ "id": "agent.status", "namespace": "agent", "action": "status", "title": "Get agent status", "description": "Return the agent occupancy, lane, schedule, live/offline state, steward chain, dry-run result, and Runner availability for a seat.", "requiredScope": "seat", "confirmation": "none", "exposeOverMcp": true, "fields": [{ "name": "seat_id", "flag": "seat-id", "type": "string", "required": true }], "hasComplexInput": false, "help": "Check an agent's lane, live state, steward chain, dry-run result, and Runner availability before relying on it." },
|
|
52922
53003
|
{ "id": "agent.trust.create", "namespace": "agent", "action": "trust.create", "title": "Create agent Trusted grant", "description": "Create a bounded Trusted execution grant for a live agent after a human steward/admin signs the current activation receipt digest.", "requiredScope": "tenant", "confirmation": "human_required", "exposeOverMcp": true, "fields": [{ "name": "agent_id", "flag": "agent-id", "type": "string", "required": true }, { "name": "expected_scope_digest", "flag": "expected-scope-digest", "type": "string", "required": true }, { "name": "budget_cents", "flag": "budget-cents", "type": "integer", "required": true }, { "name": "expires_at", "flag": "expires-at", "type": "string", "required": false }, { "name": "reason", "flag": "reason", "type": "string", "required": false }], "hasComplexInput": false, "help": "Create a bounded Trusted execution grant only after reviewing the activation receipt digest, budget, and always-human boundary. Human steward/admin only." },
|
|
@@ -57737,6 +57818,7 @@ ${usage()}
|
|
|
57737
57818
|
let failed = false;
|
|
57738
57819
|
let activeSessions = 0;
|
|
57739
57820
|
const activeTurnExecutionIds = /* @__PURE__ */ new Set();
|
|
57821
|
+
let serverHeartbeatContractVersion = null;
|
|
57740
57822
|
do {
|
|
57741
57823
|
const detectedCapabilities = await detectCapabilities(cliVersion, env, homeDir, config2.maxSessionsOverride);
|
|
57742
57824
|
const capabilities = capabilitiesForConfiguredRuntime(detectedCapabilities, config2.runtime);
|
|
@@ -57745,7 +57827,8 @@ ${usage()}
|
|
|
57745
57827
|
const heartbeat = await post2(fetchImpl, options.appUrl, "/api/runner/heartbeat", buildHeartbeatBody({
|
|
57746
57828
|
capabilities,
|
|
57747
57829
|
telemetry: detectTelemetry(capabilities, env, activeSessions, cliVersion),
|
|
57748
|
-
activeTurnExecutionIds: [...activeTurnExecutionIds]
|
|
57830
|
+
activeTurnExecutionIds: [...activeTurnExecutionIds],
|
|
57831
|
+
serverContractVersion: serverHeartbeatContractVersion
|
|
57749
57832
|
}), state.runner_secret);
|
|
57750
57833
|
if (heartbeat.status !== 200) {
|
|
57751
57834
|
options.io.stderr.write(`heartbeat ${heartbeat.status}: ${redactForLog(JSON.stringify(heartbeat.json))}
|
|
@@ -57753,6 +57836,10 @@ ${usage()}
|
|
|
57753
57836
|
failed = true;
|
|
57754
57837
|
} else {
|
|
57755
57838
|
heartbeatSucceeded = true;
|
|
57839
|
+
const learnedVersion = readHeartbeatContractVersion(heartbeat.json);
|
|
57840
|
+
if (learnedVersion !== null) {
|
|
57841
|
+
serverHeartbeatContractVersion = learnedVersion;
|
|
57842
|
+
}
|
|
57756
57843
|
options.io.stdout.write(`heartbeat ok #${beat} runner_id=${state.runner_id} claude=${capabilities.claude.installed} codex=${capabilities.codex.installed}
|
|
57757
57844
|
`);
|
|
57758
57845
|
}
|
|
@@ -57766,7 +57853,11 @@ ${usage()}
|
|
|
57766
57853
|
capabilities,
|
|
57767
57854
|
io: options.io,
|
|
57768
57855
|
telemetry: () => detectTelemetry(capabilities, env, activeSessions, cliVersion),
|
|
57769
|
-
activeTurnIds: () => [...activeTurnExecutionIds]
|
|
57856
|
+
activeTurnIds: () => [...activeTurnExecutionIds],
|
|
57857
|
+
serverContractVersion: () => serverHeartbeatContractVersion,
|
|
57858
|
+
recordServerContractVersion: (v) => {
|
|
57859
|
+
serverHeartbeatContractVersion = v;
|
|
57860
|
+
}
|
|
57770
57861
|
});
|
|
57771
57862
|
try {
|
|
57772
57863
|
await claimAndExecute(fetchImpl, options.appUrl, state, config2, options.io, localRuntime, activeTurnExecutionIds);
|
|
@@ -57791,13 +57882,17 @@ ${usage()}
|
|
|
57791
57882
|
localRuntime,
|
|
57792
57883
|
capabilities,
|
|
57793
57884
|
() => detectTelemetry(capabilities, env, activeSessions, cliVersion),
|
|
57794
|
-
activeTurnExecutionIds
|
|
57885
|
+
activeTurnExecutionIds,
|
|
57886
|
+
() => serverHeartbeatContractVersion,
|
|
57887
|
+
(v) => {
|
|
57888
|
+
serverHeartbeatContractVersion = v;
|
|
57889
|
+
}
|
|
57795
57890
|
);
|
|
57796
57891
|
}
|
|
57797
57892
|
} while (!config2.once);
|
|
57798
57893
|
return heartbeatSucceeded && !failed ? 0 : 1;
|
|
57799
57894
|
}
|
|
57800
|
-
async function waitForNextHeartbeat(fetchImpl, appUrl2, state, config2, io, runtime, capabilities, telemetry, activeTurnExecutionIds) {
|
|
57895
|
+
async function waitForNextHeartbeat(fetchImpl, appUrl2, state, config2, io, runtime, capabilities, telemetry, activeTurnExecutionIds, serverContractVersion, recordServerContractVersion) {
|
|
57801
57896
|
const deadline = Date.now() + config2.heartbeatMs;
|
|
57802
57897
|
const stopWait = runtime ? startTurnHeartbeat({
|
|
57803
57898
|
fetchImpl,
|
|
@@ -57807,7 +57902,9 @@ async function waitForNextHeartbeat(fetchImpl, appUrl2, state, config2, io, runt
|
|
|
57807
57902
|
capabilities,
|
|
57808
57903
|
io,
|
|
57809
57904
|
telemetry,
|
|
57810
|
-
activeTurnIds: () => [...activeTurnExecutionIds]
|
|
57905
|
+
activeTurnIds: () => [...activeTurnExecutionIds],
|
|
57906
|
+
serverContractVersion,
|
|
57907
|
+
recordServerContractVersion
|
|
57811
57908
|
}) : null;
|
|
57812
57909
|
try {
|
|
57813
57910
|
while (Date.now() < deadline) {
|
|
@@ -57827,12 +57924,17 @@ async function waitForNextHeartbeat(fetchImpl, appUrl2, state, config2, io, runt
|
|
|
57827
57924
|
stopWait?.();
|
|
57828
57925
|
}
|
|
57829
57926
|
}
|
|
57927
|
+
var HEARTBEAT_ACTIVE_TURN_MIN_CONTRACT_VERSION = 2;
|
|
57928
|
+
function readHeartbeatContractVersion(json2) {
|
|
57929
|
+
const value = json2.heartbeat_contract_version;
|
|
57930
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
57931
|
+
}
|
|
57830
57932
|
function buildHeartbeatBody(input) {
|
|
57831
57933
|
const body = {
|
|
57832
57934
|
capabilities: input.capabilities,
|
|
57833
57935
|
telemetry: input.telemetry
|
|
57834
57936
|
};
|
|
57835
|
-
if (input.activeTurnExecutionIds.length > 0) {
|
|
57937
|
+
if (input.activeTurnExecutionIds.length > 0 && (input.serverContractVersion ?? 0) >= HEARTBEAT_ACTIVE_TURN_MIN_CONTRACT_VERSION) {
|
|
57836
57938
|
body.active_turn_execution_ids = input.activeTurnExecutionIds;
|
|
57837
57939
|
}
|
|
57838
57940
|
return body;
|
|
@@ -57853,11 +57955,17 @@ function startTurnHeartbeat(deps) {
|
|
|
57853
57955
|
const response = await post2(deps.fetchImpl, deps.appUrl, "/api/runner/heartbeat", buildHeartbeatBody({
|
|
57854
57956
|
capabilities: deps.capabilities,
|
|
57855
57957
|
telemetry: deps.telemetry(),
|
|
57856
|
-
activeTurnExecutionIds: deps.activeTurnIds()
|
|
57958
|
+
activeTurnExecutionIds: deps.activeTurnIds(),
|
|
57959
|
+
serverContractVersion: deps.serverContractVersion()
|
|
57857
57960
|
}), deps.secret, controller.signal);
|
|
57858
57961
|
if (!stopped && response.status !== 200) {
|
|
57859
57962
|
deps.io.stderr.write(`turn heartbeat ${response.status}: ${redactForLog(JSON.stringify(response.json))}
|
|
57860
57963
|
`);
|
|
57964
|
+
} else if (!stopped && response.status === 200) {
|
|
57965
|
+
const learnedVersion = readHeartbeatContractVersion(response.json);
|
|
57966
|
+
if (learnedVersion !== null) {
|
|
57967
|
+
deps.recordServerContractVersion(learnedVersion);
|
|
57968
|
+
}
|
|
57861
57969
|
}
|
|
57862
57970
|
} catch (error51) {
|
|
57863
57971
|
if (!stopped) {
|