@rosthq/cli 0.7.111 → 0.7.113
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/forge-workspace.d.ts +3 -1
- package/dist/forge-workspace.d.ts.map +1 -1
- package/dist/index.js +164 -19
- package/dist/index.js.map +3 -3
- package/dist/runner-sandbox.d.ts +1 -1
- package/dist/runner-sandbox.d.ts.map +1 -1
- package/dist/runner-serve.d.ts +1 -0
- package/dist/runner-serve.d.ts.map +1 -1
- package/package.json +1 -1
- package/prompts/how-tos/human-confirmations.md +1 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type StepLedger } from "./step-ledger.js";
|
|
2
2
|
export declare const MODEL_SPAWN_ENV_ALLOWLIST: readonly ["PATH", "HOME", "USER", "LANG", "LC_ALL", "TMPDIR", "SHELL", "NODE_OPTIONS"];
|
|
3
|
-
export declare function buildModelSpawnEnv(base: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
3
|
+
export declare function buildModelSpawnEnv(base: NodeJS.ProcessEnv, claudeConfigDir?: string): NodeJS.ProcessEnv;
|
|
4
|
+
export declare function resolveSourceClaudeConfigDir(base: NodeJS.ProcessEnv): string;
|
|
5
|
+
export declare function provisionIsolatedClaudeConfigDir(base: NodeJS.ProcessEnv, configDir: string): Promise<string>;
|
|
4
6
|
export type ForgeCredential = {
|
|
5
7
|
token: string;
|
|
6
8
|
expiresAt: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forge-workspace.d.ts","sourceRoot":"","sources":["../src/forge-workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"forge-workspace.d.ts","sourceRoot":"","sources":["../src/forge-workspace.ts"],"names":[],"mappings":"AA4CA,OAAO,EAAqB,KAAK,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AASrF,eAAO,MAAM,yBAAyB,wFAc5B,CAAC;AAEX,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,CAAC,UAAU,EAOvB,eAAe,CAAC,EAAE,MAAM,GACvB,MAAM,CAAC,UAAU,CAiBnB;AAcD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAQ5E;AAOD,wBAAsB,gCAAgC,CACpD,IAAI,EAAE,MAAM,CAAC,UAAU,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAejB;AAID,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAG3B,QAAQ,EAAE,MAAM,CAAC;IAGjB,WAAW,EAAE,MAAM,CAAC;IAGpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAKlB,OAAO,EAAE,MAAM,CAAC;IAIhB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvD,MAAM,MAAM,4BAA4B,GAAG;IAEzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1D,OAAO,EAAE,qBAAqB,CAAC;IAE/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,UAAU,EAAE,eAAe,CAAC;IAI5B,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAyOF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB5E;AAqJD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,cAAc,CAAC,CAiB1G;AASD,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,UAAU,EAAE,eAAe,CAAC;IAE5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,cAAc,CAAC,CA0C1G;AAiDD,wBAAsB,aAAa,CACjC,EAAE,EAAE,cAAc,EAClB,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,UAAU,GAClB,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA4BvC;AAsBD,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiC/E;AAcD,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAE9D,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,eAAe,CAAC;IAG5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAGzB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAE7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IAGf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AA+GF,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAE1G;AA4CD,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IAEf,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IAE1B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAIF,MAAM,MAAM,mBAAmB,GAC3B,gBAAgB,GAChB,WAAW,GACX,YAAY,GACZ,OAAO,GACP,SAAS,GACT,QAAQ,GACR,SAAS,CAAC;AAEd,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,mBAAmB,CA4BxF;AAsBD,MAAM,MAAM,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAI5D,wBAAsB,qBAAqB,CAAC,OAAO,EAAE;IACnD,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAajC;AAED,MAAM,MAAM,iBAAiB,GAEzB;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAE9C;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAQzB,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,qBAAqB,CAAC;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwC7B;AAID,wBAAsB,0BAA0B,CAAC,OAAO,EAAE;IACxD,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBhB;AAgBD,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA0BxH;AAiBD,wBAAsB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvE"}
|
package/dist/index.js
CHANGED
|
@@ -38746,6 +38746,7 @@ var catalogEntries = CATALOG_ENTRIES.map(enrichCatalogEntry);
|
|
|
38746
38746
|
var catalogById = new Map(catalogEntries.map((entry) => [entry.id, entry]));
|
|
38747
38747
|
|
|
38748
38748
|
// ../../packages/protocol/src/skills.ts
|
|
38749
|
+
var SKILL_DESCRIPTION_MAX_CHARS = 500;
|
|
38749
38750
|
var skillVisibilitySchema = external_exports.enum(["private", "seat", "tenant"]);
|
|
38750
38751
|
var skillStatusSchema = external_exports.enum(["draft", "pending_review", "published", "archived"]);
|
|
38751
38752
|
var skillSourceTypeSchema = external_exports.enum([
|
|
@@ -38762,12 +38763,14 @@ var skillCatalogTierSchema = external_exports.enum(["free", "pro", "enterprise",
|
|
|
38762
38763
|
var skillLocalClientSchema = external_exports.enum(["claude-code", "codex", "cursor"]);
|
|
38763
38764
|
var skillSlugSchema = external_exports.string().regex(/^[a-z0-9][a-z0-9-]{1,80}$/);
|
|
38764
38765
|
var skillNameSchema = external_exports.string().trim().min(1).max(120);
|
|
38765
|
-
var
|
|
38766
|
+
var skillApplicationShape = {
|
|
38766
38767
|
domain: external_exports.string().trim().min(1).max(80).optional(),
|
|
38767
38768
|
summary: external_exports.string().trim().min(1).max(500),
|
|
38768
38769
|
best_for: external_exports.array(external_exports.string().trim().min(1).max(160)).max(20).default([]),
|
|
38769
38770
|
not_for: external_exports.array(external_exports.string().trim().min(1).max(160)).max(20).default([])
|
|
38770
|
-
}
|
|
38771
|
+
};
|
|
38772
|
+
var skillApplicationSchema = external_exports.object(skillApplicationShape).strict();
|
|
38773
|
+
var skillApplicationInputSchema = external_exports.object(skillApplicationShape);
|
|
38771
38774
|
var skillToolDependencySchema = external_exports.object({
|
|
38772
38775
|
tool: external_exports.string().trim().min(1).max(120),
|
|
38773
38776
|
min_scope_tier: toolScopeTierSchema,
|
|
@@ -38787,7 +38790,7 @@ var skillValidationIssueSchema = external_exports.object({
|
|
|
38787
38790
|
var normalizedSkillPackageSchema = external_exports.object({
|
|
38788
38791
|
slug: skillSlugSchema,
|
|
38789
38792
|
name: skillNameSchema,
|
|
38790
|
-
description: external_exports.string().trim().min(1).max(
|
|
38793
|
+
description: external_exports.string().trim().min(1).max(SKILL_DESCRIPTION_MAX_CHARS),
|
|
38791
38794
|
visibility: skillVisibilitySchema,
|
|
38792
38795
|
application: skillApplicationSchema,
|
|
38793
38796
|
frontmatter: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
@@ -40689,7 +40692,7 @@ var aicosPulseSnapshotSchema = external_exports.object({
|
|
|
40689
40692
|
// ../../packages/protocol/src/command-introspection.ts
|
|
40690
40693
|
var requiredScopeSchema = external_exports.enum(["tenant_admin", "tenant", "seat", "user"]);
|
|
40691
40694
|
var confirmationSchema = external_exports.enum(["none", "human_required", "credential_flow", "dangerous"]);
|
|
40692
|
-
var trustedExecutionModeSchema = external_exports.enum(["eligible", "always_human", "not_applicable"]);
|
|
40695
|
+
var trustedExecutionModeSchema = external_exports.enum(["eligible", "eligible_bounded", "always_human", "not_applicable"]);
|
|
40693
40696
|
var trustedExecutionRiskFlagSchema = external_exports.enum([
|
|
40694
40697
|
"admin",
|
|
40695
40698
|
"credential",
|
|
@@ -48239,7 +48242,7 @@ Drafting can be assisted by agents. Activation is a human decision. When authori
|
|
|
48239
48242
|
order: 40,
|
|
48240
48243
|
title: "Agent staffing playbook",
|
|
48241
48244
|
summary: "How to decide whether a seat should be human, agent, or hybrid, and how to go live safely.",
|
|
48242
|
-
version: "2026-07-
|
|
48245
|
+
version: "2026-07-20.1",
|
|
48243
48246
|
public: true,
|
|
48244
48247
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
48245
48248
|
stages: ["staffing"],
|
|
@@ -48297,7 +48300,7 @@ Two creation paths, both draft-first. Read the stock-agents guide for templates
|
|
|
48297
48300
|
- 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
48301
|
- 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
48302
|
- 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.
|
|
48303
|
+
- 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
48304
|
- 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
48305
|
|
|
48303
48306
|
## Review readiness before go-live
|
|
@@ -48312,7 +48315,7 @@ The lane a live agent runs on \u2014 cloud (the {{brand}}-managed runtime), a pa
|
|
|
48312
48315
|
|
|
48313
48316
|
## When to stop for confirmation
|
|
48314
48317
|
|
|
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
|
|
48318
|
+
\`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
48319
|
|
|
48317
48320
|
## Non-negotiables
|
|
48318
48321
|
|
|
@@ -50009,7 +50012,7 @@ Set \`ROST_SKILL_INSTALL_ROOT\` only for a sandbox or CI override. Local copies
|
|
|
50009
50012
|
order: 55,
|
|
50010
50013
|
title: "Agent reference map",
|
|
50011
50014
|
summary: "Where CLI sessions, MCP clients, and in-app agents should retrieve {{brand}} guidance before recommending setup changes.",
|
|
50012
|
-
version: "2026-07-
|
|
50015
|
+
version: "2026-07-20.1",
|
|
50013
50016
|
public: true,
|
|
50014
50017
|
audiences: ["cli", "mcp", "in_app_agent"],
|
|
50015
50018
|
stages: ["company_setup", "graph_design", "charter_design", "staffing", "operating_rhythm"],
|
|
@@ -50123,6 +50126,7 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
50123
50126
|
- Run the weekly Sync (compile, run, complete, assign): sync-rhythm-playbook.
|
|
50124
50127
|
- Operate local runners and work orders: runner-guide.
|
|
50125
50128
|
- Approve or reject a pending confirmation (human only): confirmations-guide.
|
|
50129
|
+
- 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
50130
|
- Manage members, settings, and notifications: settings-guide, settings-members-and-invites-guide, notifications-guide.
|
|
50127
50131
|
- Explain company-wide billing, payment, invoices, or usage true-ups: billing-and-pricing-guide, then settings-guide.
|
|
50128
50132
|
- Diagnose a failure on any surface: troubleshooting-guide, then security-model-guide.
|
|
@@ -50133,7 +50137,7 @@ Read the listed guide before recommending or running each workflow. Every workfl
|
|
|
50133
50137
|
- Graph design: responsibility-graph-playbook
|
|
50134
50138
|
- Charter design: charter-design-playbook, charter-authoring-deep-dive
|
|
50135
50139
|
- 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
|
|
50140
|
+
- 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
50141
|
- Local agents and runners: mcp-and-cli-guide, runner-guide, agent-reference-map
|
|
50138
50142
|
- Security and troubleshooting: ai-model-data-handling-guide, security-model-guide, troubleshooting-guide
|
|
50139
50143
|
|
|
@@ -50708,6 +50712,86 @@ The billing area in Settings answers:
|
|
|
50708
50712
|
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
50713
|
|
|
50710
50714
|
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.`
|
|
50715
|
+
},
|
|
50716
|
+
{
|
|
50717
|
+
slug: "governed-command-capability-matrix",
|
|
50718
|
+
order: 72,
|
|
50719
|
+
title: "Governed command capability matrix",
|
|
50720
|
+
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.",
|
|
50721
|
+
version: "2026-07-20.1",
|
|
50722
|
+
public: true,
|
|
50723
|
+
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
50724
|
+
stages: ["charter_design", "staffing", "operating_rhythm"],
|
|
50725
|
+
relatedCommandIds: [
|
|
50726
|
+
"command.list",
|
|
50727
|
+
"command.describe",
|
|
50728
|
+
"agent.update_schedule",
|
|
50729
|
+
"goal.bind_measurable",
|
|
50730
|
+
"skill.assign_to_seat",
|
|
50731
|
+
"friction.resolve",
|
|
50732
|
+
"agent.run_now",
|
|
50733
|
+
"agent.trust.create",
|
|
50734
|
+
"confirmation.approve"
|
|
50735
|
+
],
|
|
50736
|
+
legal: {
|
|
50737
|
+
publicRisk: "low",
|
|
50738
|
+
notes: [
|
|
50739
|
+
"Describes {{brand}}-native command governance classification; no third-party or proprietary content."
|
|
50740
|
+
]
|
|
50741
|
+
},
|
|
50742
|
+
sources: [
|
|
50743
|
+
{
|
|
50744
|
+
label: "Governed command capability matrix (generated)",
|
|
50745
|
+
internalPath: "docs/reference/governed-command-capability-matrix.md",
|
|
50746
|
+
note: "Authoritative, command-by-command capability table regenerated from the command registry (`pnpm generate:capability-matrix`) and kept in sync by a drift test."
|
|
50747
|
+
}
|
|
50748
|
+
],
|
|
50749
|
+
body: `# Governed command capability matrix
|
|
50750
|
+
|
|
50751
|
+
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.
|
|
50752
|
+
|
|
50753
|
+
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.
|
|
50754
|
+
|
|
50755
|
+
## The four confirmation classes
|
|
50756
|
+
|
|
50757
|
+
Every command declares one of four confirmation classes:
|
|
50758
|
+
|
|
50759
|
+
- **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).
|
|
50760
|
+
- **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).
|
|
50761
|
+
- **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.
|
|
50762
|
+
- **Dangerous** \u2014 an irreversible or high-blast-radius action (for example decommissioning an agent) that always asks, with extra confirmation friction.
|
|
50763
|
+
|
|
50764
|
+
## The Trusted-eligibility classes
|
|
50765
|
+
|
|
50766
|
+
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:
|
|
50767
|
+
|
|
50768
|
+
- **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.
|
|
50769
|
+
- **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.
|
|
50770
|
+
- **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.
|
|
50771
|
+
- **Not applicable** \u2014 a discovery or read command with no durable action to automate.
|
|
50772
|
+
|
|
50773
|
+
## The five-command auto band
|
|
50774
|
+
|
|
50775
|
+
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:
|
|
50776
|
+
|
|
50777
|
+
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.
|
|
50778
|
+
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.
|
|
50779
|
+
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.
|
|
50780
|
+
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.
|
|
50781
|
+
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.
|
|
50782
|
+
|
|
50783
|
+
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.
|
|
50784
|
+
|
|
50785
|
+
## The always-human floor
|
|
50786
|
+
|
|
50787
|
+
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.
|
|
50788
|
+
|
|
50789
|
+
## Where to look up a specific command
|
|
50790
|
+
|
|
50791
|
+
- 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.
|
|
50792
|
+
- A single command's exact schema and classification: {{cli}} command schema <id> (CLI) or rost_describe_command (MCP).
|
|
50793
|
+
- How pending confirmations are approved or rejected: confirmations-guide.
|
|
50794
|
+
- How Trusted grants are created, inspected, and revoked: agent-staffing-playbook.`
|
|
50711
50795
|
},
|
|
50712
50796
|
{
|
|
50713
50797
|
slug: "settings-guide",
|
|
@@ -50920,7 +51004,7 @@ Every notification should include the seat, cause, evidence, and requested decis
|
|
|
50920
51004
|
order: 75,
|
|
50921
51005
|
title: "Local runner guide",
|
|
50922
51006
|
summary: "How local agent sessions and runner surfaces should operate through {{brand}} without bypassing Charters or audit.",
|
|
50923
|
-
version: "2026-07-20.
|
|
51007
|
+
version: "2026-07-20.2",
|
|
50924
51008
|
public: true,
|
|
50925
51009
|
audiences: ["human", "cli", "mcp", "in_app_agent"],
|
|
50926
51010
|
stages: ["staffing", "operating_rhythm"],
|
|
@@ -51016,7 +51100,7 @@ Use this flow when a headless or desktop runner cannot use the interactive web c
|
|
|
51016
51100
|
|
|
51017
51101
|
## When to stop for confirmation
|
|
51018
51102
|
|
|
51019
|
-
\`runner.pairing.start
|
|
51103
|
+
\`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
51104
|
|
|
51021
51105
|
## Guardrails
|
|
51022
51106
|
|
|
@@ -52916,7 +53000,7 @@ var COMMAND_MANIFEST = [
|
|
|
52916
53000
|
{ "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
53001
|
{ "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
53002
|
{ "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": "
|
|
53003
|
+
{ "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
53004
|
{ "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
53005
|
{ "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
53006
|
{ "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." },
|
|
@@ -55723,7 +55807,8 @@ var RUNNER_ASKPASS_DIR = path4.join(tmpdir(), "rost-runner-askpass");
|
|
|
55723
55807
|
var RUNNER_TEMP_PREFIXES = [
|
|
55724
55808
|
"rost-runner-mcp-",
|
|
55725
55809
|
"rost-runner-sandbox-",
|
|
55726
|
-
"rost-runner-askpass-"
|
|
55810
|
+
"rost-runner-askpass-",
|
|
55811
|
+
"rost-runner-claude-config-"
|
|
55727
55812
|
];
|
|
55728
55813
|
var RUNNER_TEMP_STARTUP_SWEEP_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
55729
55814
|
var RUNNER_TEMP_TURN_SWEEP_MAX_AGE_MS = 45 * 60 * 1e3;
|
|
@@ -56820,7 +56905,7 @@ function parseSemver2(value) {
|
|
|
56820
56905
|
import { execFile as execFileCallback5, spawn } from "node:child_process";
|
|
56821
56906
|
import { createHash as createHash2 } from "node:crypto";
|
|
56822
56907
|
import { constants as fsConstants2 } from "node:fs";
|
|
56823
|
-
import { access as access3, chmod as chmod2, mkdir as mkdir5, readFile as
|
|
56908
|
+
import { access as access3, chmod as chmod2, mkdir as mkdir5, readFile as readFile6, rename, rm as rm5, statfs, writeFile as writeFile5 } from "node:fs/promises";
|
|
56824
56909
|
import { cpus, homedir as homedir4, hostname as hostname3, platform, totalmem, tmpdir as tmpdir2 } from "node:os";
|
|
56825
56910
|
import path7 from "node:path";
|
|
56826
56911
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
@@ -56829,7 +56914,8 @@ import { promisify as promisify5 } from "node:util";
|
|
|
56829
56914
|
// src/forge-workspace.ts
|
|
56830
56915
|
import { execFile as execFileCallback4 } from "node:child_process";
|
|
56831
56916
|
import { createHash } from "node:crypto";
|
|
56832
|
-
import { chmod, lstat, mkdir as mkdir4, mkdtemp, realpath, rm as rm4, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
56917
|
+
import { chmod, lstat, mkdir as mkdir4, mkdtemp, readFile as readFile5, realpath, rm as rm4, stat as stat3, writeFile as writeFile4 } from "node:fs/promises";
|
|
56918
|
+
import os2 from "node:os";
|
|
56833
56919
|
import path6 from "node:path";
|
|
56834
56920
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
56835
56921
|
import { promisify as promisify4 } from "node:util";
|
|
@@ -56908,7 +56994,7 @@ var MODEL_SPAWN_ENV_ALLOWLIST = [
|
|
|
56908
56994
|
"SHELL",
|
|
56909
56995
|
"NODE_OPTIONS"
|
|
56910
56996
|
];
|
|
56911
|
-
function buildModelSpawnEnv(base) {
|
|
56997
|
+
function buildModelSpawnEnv(base, claudeConfigDir) {
|
|
56912
56998
|
const out = {};
|
|
56913
56999
|
for (const key of MODEL_SPAWN_ENV_ALLOWLIST) {
|
|
56914
57000
|
const value = base[key];
|
|
@@ -56916,8 +57002,36 @@ function buildModelSpawnEnv(base) {
|
|
|
56916
57002
|
out[key] = value;
|
|
56917
57003
|
}
|
|
56918
57004
|
}
|
|
57005
|
+
if (typeof claudeConfigDir === "string" && claudeConfigDir.length > 0) {
|
|
57006
|
+
out.CLAUDE_CONFIG_DIR = claudeConfigDir;
|
|
57007
|
+
}
|
|
56919
57008
|
return out;
|
|
56920
57009
|
}
|
|
57010
|
+
var CLAUDE_CONFIG_AUTH_FILES = [".credentials.json", ".claude.json"];
|
|
57011
|
+
function resolveSourceClaudeConfigDir(base) {
|
|
57012
|
+
const explicit = base.CLAUDE_CONFIG_DIR;
|
|
57013
|
+
if (typeof explicit === "string" && explicit.length > 0) {
|
|
57014
|
+
return explicit;
|
|
57015
|
+
}
|
|
57016
|
+
const home = base.HOME;
|
|
57017
|
+
const homeDir = typeof home === "string" && home.length > 0 ? home : os2.homedir();
|
|
57018
|
+
return path6.join(homeDir, ".claude");
|
|
57019
|
+
}
|
|
57020
|
+
async function provisionIsolatedClaudeConfigDir(base, configDir) {
|
|
57021
|
+
await mkdir4(configDir, { recursive: true, mode: 448 });
|
|
57022
|
+
await chmod(configDir, 448);
|
|
57023
|
+
const source = resolveSourceClaudeConfigDir(base);
|
|
57024
|
+
for (const file2 of CLAUDE_CONFIG_AUTH_FILES) {
|
|
57025
|
+
try {
|
|
57026
|
+
const data = await readFile5(path6.join(source, file2));
|
|
57027
|
+
const dest = path6.join(configDir, file2);
|
|
57028
|
+
await writeFile4(dest, data, { mode: 384 });
|
|
57029
|
+
await chmod(dest, 384);
|
|
57030
|
+
} catch {
|
|
57031
|
+
}
|
|
57032
|
+
}
|
|
57033
|
+
return configDir;
|
|
57034
|
+
}
|
|
56921
57035
|
var GIT_HARDENING_ARGS = [
|
|
56922
57036
|
"-c",
|
|
56923
57037
|
"core.hooksPath=/dev/null",
|
|
@@ -58111,7 +58225,7 @@ async function pairIfNeeded(client, fetchImpl, appUrl2, config2, io) {
|
|
|
58111
58225
|
}
|
|
58112
58226
|
async function loadState(filePath, expectedTenantId) {
|
|
58113
58227
|
try {
|
|
58114
|
-
const parsed = JSON.parse(await
|
|
58228
|
+
const parsed = JSON.parse(await readFile6(filePath, "utf8"));
|
|
58115
58229
|
if (typeof parsed.runner_id === "string" && typeof parsed.runner_secret === "string") {
|
|
58116
58230
|
if (expectedTenantId && parsed.tenant_id !== expectedTenantId) {
|
|
58117
58231
|
return null;
|
|
@@ -58578,6 +58692,9 @@ function resolveTurnPlan(input) {
|
|
|
58578
58692
|
return {
|
|
58579
58693
|
profile: "read_status",
|
|
58580
58694
|
claudeAllowedTools: [...input.kind === "turn_execution" ? RUNNER_AICOS_TURN_TOOLS : RUNNER_WORK_ORDER_TOOLS],
|
|
58695
|
+
// DER-2104: the read stub is MCP-only — no local built-ins. `--tools ""` now enforces
|
|
58696
|
+
// that (previously nothing did, so a stub turn silently inherited full local access).
|
|
58697
|
+
localBuiltinTools: [],
|
|
58581
58698
|
codexSandbox: "read-only",
|
|
58582
58699
|
outputFormat: input.kind === "turn_execution" ? "json" : "text",
|
|
58583
58700
|
repoDir: null,
|
|
@@ -58592,6 +58709,9 @@ function resolveTurnPlan(input) {
|
|
|
58592
58709
|
...execution.allowed_mcp_tools.map(claudeMcpToolName),
|
|
58593
58710
|
...claudeLocalToolsFor(execution.local_tools)
|
|
58594
58711
|
],
|
|
58712
|
+
// DER-2104: the same built-in set, but as the `--tools` HARD whitelist (not the
|
|
58713
|
+
// auto-approve list). `none` → `[]` → `--tools ""` → zero built-ins for a seat_work turn.
|
|
58714
|
+
localBuiltinTools: claudeLocalToolsFor(execution.local_tools),
|
|
58595
58715
|
codexSandbox: execution.local_tools === "workspace_write" ? "workspace-write" : "read-only",
|
|
58596
58716
|
// Forge build/review turns emit a structured JSON envelope (reusing the AICOS
|
|
58597
58717
|
// --output-format json pattern) so their summary is a real contract, not a stdout slice.
|
|
@@ -58641,8 +58761,19 @@ function buildTurnCommand(input) {
|
|
|
58641
58761
|
"--mcp-config",
|
|
58642
58762
|
configPath,
|
|
58643
58763
|
"--strict-mcp-config",
|
|
58764
|
+
// DER-2104: --tools is the HARD built-in whitelist. `--tools ""` (empty join for
|
|
58765
|
+
// local_tools "none") removes Bash/Read/Write/Edit/… entirely, and the operator's
|
|
58766
|
+
// settings.json cannot widen it — the real enforcement of `local_tools`. --allowedTools
|
|
58767
|
+
// stays as the auto-approve list for the governed MCP + any declared local built-ins.
|
|
58768
|
+
"--tools",
|
|
58769
|
+
plan.localBuiltinTools.join(","),
|
|
58644
58770
|
"--allowedTools",
|
|
58645
58771
|
plan.claudeAllowedTools.join(","),
|
|
58772
|
+
// DER-2104: unattended turns must never wait on a prompt — dontAsk auto-denies any tool
|
|
58773
|
+
// call that would otherwise prompt. Governed MCP tools and the declared local built-ins
|
|
58774
|
+
// are in --allowedTools (auto-approved, never prompt), so this only denies the unexpected.
|
|
58775
|
+
"--permission-mode",
|
|
58776
|
+
"dontAsk",
|
|
58646
58777
|
"--output-format",
|
|
58647
58778
|
plan.outputFormat,
|
|
58648
58779
|
// DER-1397: turn off Claude Code's own nested Bash sandbox when the outer seatbelt confines
|
|
@@ -58894,6 +59025,10 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
|
|
|
58894
59025
|
await writeFile5(configPath, `${mcpConfig}
|
|
58895
59026
|
`, { mode: 384 });
|
|
58896
59027
|
await chmod2(configPath, 384);
|
|
59028
|
+
const claudeConfigDir = runtime === "claude" ? await provisionIsolatedClaudeConfigDir(
|
|
59029
|
+
process.env,
|
|
59030
|
+
path7.join(tmpdir2(), `rost-runner-claude-config-${createHash2("sha256").update(`${configPath}:cfg`).digest("hex").slice(0, 16)}`)
|
|
59031
|
+
) : null;
|
|
58897
59032
|
const resumeSessionId = runtime === "claude" ? getClaudeResumeSessionId(ctx.state, workOrder) : void 0;
|
|
58898
59033
|
const built = buildTurnCommand({
|
|
58899
59034
|
runtime,
|
|
@@ -58922,7 +59057,7 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
|
|
|
58922
59057
|
// A Forge turn's cwd is its worktree; every other turn stays in tmpdir.
|
|
58923
59058
|
cwd: plan.repoDir ?? tmpdir2(),
|
|
58924
59059
|
timeoutMs: plan.timeoutMs,
|
|
58925
|
-
env: buildModelSpawnEnv(process.env),
|
|
59060
|
+
env: buildModelSpawnEnv(process.env, claudeConfigDir ?? void 0),
|
|
58926
59061
|
expectSessionEnvelope,
|
|
58927
59062
|
resumeSessionId,
|
|
58928
59063
|
// T1.6: only Forge turns carry a structured evidence contract worth parsing.
|
|
@@ -58951,6 +59086,9 @@ async function spawnRunnerTurn(ctx, workOrder, runtime, kind) {
|
|
|
58951
59086
|
if (sandboxProfilePath) {
|
|
58952
59087
|
void rm5(sandboxProfilePath, { force: true });
|
|
58953
59088
|
}
|
|
59089
|
+
if (claudeConfigDir) {
|
|
59090
|
+
void rm5(claudeConfigDir, { recursive: true, force: true });
|
|
59091
|
+
}
|
|
58954
59092
|
void sweepOrphanedTurnTempFiles();
|
|
58955
59093
|
if (forgePrep) {
|
|
58956
59094
|
if (plan.profile === "forge_build" && result.ok && forgePrep.credential.canPush) {
|
|
@@ -59098,6 +59236,10 @@ async function spawnMergeConflictModel(ctx, input) {
|
|
|
59098
59236
|
await writeFile5(configPath, `${mcpConfig}
|
|
59099
59237
|
`, { mode: 384 });
|
|
59100
59238
|
await chmod2(configPath, 384);
|
|
59239
|
+
const claudeConfigDir = input.runtime === "claude" ? await provisionIsolatedClaudeConfigDir(
|
|
59240
|
+
process.env,
|
|
59241
|
+
path7.join(tmpdir2(), `rost-runner-claude-config-${createHash2("sha256").update(`${configPath}:cfg`).digest("hex").slice(0, 16)}`)
|
|
59242
|
+
) : null;
|
|
59101
59243
|
const plan = resolveTurnPlan({ kind: "work_order", execution: input.execution, repoDir: input.workspace.worktreeDir });
|
|
59102
59244
|
const prompt = [
|
|
59103
59245
|
"You are resolving a merge conflict on a pull request branch so it can merge into the base branch.",
|
|
@@ -59127,7 +59269,7 @@ async function spawnMergeConflictModel(ctx, input) {
|
|
|
59127
59269
|
cwd: input.workspace.worktreeDir,
|
|
59128
59270
|
timeoutMs: plan.timeoutMs,
|
|
59129
59271
|
// The model gets the EXPLICIT allowlist env — never the merge token, GIT_ASKPASS, or the bearer.
|
|
59130
|
-
env: buildModelSpawnEnv(process.env),
|
|
59272
|
+
env: buildModelSpawnEnv(process.env, claudeConfigDir ?? void 0),
|
|
59131
59273
|
expectSessionEnvelope: false
|
|
59132
59274
|
});
|
|
59133
59275
|
const exitClass = classifyModelExit(result);
|
|
@@ -59143,6 +59285,9 @@ async function spawnMergeConflictModel(ctx, input) {
|
|
|
59143
59285
|
if (sandboxProfilePath) {
|
|
59144
59286
|
void rm5(sandboxProfilePath, { force: true });
|
|
59145
59287
|
}
|
|
59288
|
+
if (claudeConfigDir) {
|
|
59289
|
+
void rm5(claudeConfigDir, { recursive: true, force: true });
|
|
59290
|
+
}
|
|
59146
59291
|
void sweepOrphanedTurnTempFiles();
|
|
59147
59292
|
return result;
|
|
59148
59293
|
}
|