@sema-agent/core 7.6.0 → 7.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/agents/agent-transcript-tool.d.ts +2 -2
  3. package/dist/agents/cascade.d.ts +2 -3
  4. package/dist/agents/repair-loop.d.ts +2 -2
  5. package/dist/agents/retain-ledger.d.ts +2 -3
  6. package/dist/agents/send-message-tool.d.ts +2 -2
  7. package/dist/agents/session-util.d.ts +2 -2
  8. package/dist/agents/subagent.d.ts +3 -4
  9. package/dist/agents/teacher.d.ts +2 -2
  10. package/dist/agents/team.d.ts +2 -2
  11. package/dist/agents/verify.d.ts +5 -6
  12. package/dist/core/agent-definition.d.ts +172 -0
  13. package/dist/core/agent-definition.js +1 -0
  14. package/dist/core/delegation-frames.d.ts +298 -0
  15. package/dist/core/delegation-frames.js +21 -0
  16. package/dist/core/engine-notice.d.ts +555 -0
  17. package/dist/core/engine-notice.js +55 -0
  18. package/dist/core/gate-fold.d.ts +12 -0
  19. package/dist/core/gate-fold.js +158 -0
  20. package/dist/core/gate-lanes.d.ts +93 -0
  21. package/dist/core/gate-lanes.js +626 -0
  22. package/dist/core/hands-band.d.ts +134 -0
  23. package/dist/core/hands-band.js +1 -0
  24. package/dist/core/hooks.d.ts +20 -101
  25. package/dist/core/hooks.js +53 -854
  26. package/dist/core/mcp-failure.d.ts +43 -5
  27. package/dist/core/mcp-failure.js +31 -14
  28. package/dist/core/mcp-server-spec.d.ts +217 -0
  29. package/dist/core/mcp-server-spec.js +1 -0
  30. package/dist/core/model-seat.d.ts +99 -0
  31. package/dist/core/model-seat.js +1 -0
  32. package/dist/core/reminder-mint.d.ts +10 -0
  33. package/dist/core/reminder-mint.js +3 -0
  34. package/dist/core/runner/contracts.d.ts +382 -6
  35. package/dist/core/runner/gate-exit.d.ts +177 -9
  36. package/dist/core/runner/gate-exit.js +70 -1
  37. package/dist/core/runner/prepare-caps-and-workflow.d.ts +2 -7
  38. package/dist/core/runner/prepare-delegation-surface.d.ts +2 -7
  39. package/dist/core/runner/prepare-task.d.ts +2 -2
  40. package/dist/core/runner/runtask.d.ts +4 -71
  41. package/dist/core/runner/runtask.js +14 -5
  42. package/dist/core/runner-deps.d.ts +1416 -0
  43. package/dist/core/runner-deps.js +1 -0
  44. package/dist/core/runtime-caps.d.ts +164 -0
  45. package/dist/core/runtime-caps.js +1 -0
  46. package/dist/core/task-event.d.ts +910 -0
  47. package/dist/core/task-event.js +1 -0
  48. package/dist/core/task-limits.d.ts +110 -0
  49. package/dist/core/task-limits.js +1 -0
  50. package/dist/core/task-result.d.ts +809 -0
  51. package/dist/core/task-result.js +1 -0
  52. package/dist/core/task-spec.d.ts +1370 -0
  53. package/dist/core/task-spec.js +1 -0
  54. package/dist/core/task-stream.d.ts +382 -0
  55. package/dist/core/task-stream.js +1 -0
  56. package/dist/core/tool-spec.d.ts +1174 -0
  57. package/dist/core/tool-spec.js +1 -0
  58. package/dist/core/types.d.ts +26 -7691
  59. package/dist/core/types.js +2 -76
  60. package/dist/core/warm-resume.d.ts +2 -2
  61. package/dist/index.d.ts +2 -1
  62. package/dist/index.js +1 -1
  63. package/dist/orchestration/goal.d.ts +2 -2
  64. package/dist/orchestration/run-spec.d.ts +2 -2
  65. package/dist/orchestration/run-workflow-tool.d.ts +3 -3
  66. package/dist/orchestration/workflow.d.ts +4 -4
  67. package/dist/scenarios/scenario-registry.d.ts +3 -3
  68. package/dist/scenarios/teacher-quickstart.d.ts +2 -2
  69. package/dist/server/http.d.ts +2 -2
  70. package/dist/stores/file/fs-atomic.d.ts +88 -12
  71. package/dist/stores/file/fs-atomic.js +184 -55
  72. package/dist/stores/file/index.d.ts +1 -0
  73. package/dist/stores/file/index.js +1 -0
  74. package/package.json +1 -1
  75. package/test/export-surface.snapshot.json +9 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 7.6.1 — 2026-09-07
4
+
5
+ Patch: three bug fixes from the 7.6.0 field and black-box rounds (#608 P1, #609, #610) and the first refactor wave (design/393 S0, #594, #598), all byte-invariant on the runtime except where named. One public d.ts narrowing is called out below.
6
+
7
+ ### Fixed
8
+ - **#608 (P1)** — the file store's single-writer directory lock judged its owner by pid number alone, so a dead holder's pid recycled to an unrelated process kept the lock "in use" and every engine start failed with `store.dir_in_use` until an operator deleted the lock by hand (the cli production shape: two LOCK files reading `79814`, no trailing newline). The lock record now carries a process fingerprint `{pid, startedAtMs, startedSinceBootMs, host, v: 2}`; liveness is "pid alive AND not falsified by BOTH clocks" (a wall-clock start and an uptime-relative start — each unreliable exactly where the other is sound); a record from another host, or one without a comparable measure, keeps the pre-fingerprint verdict (a false "dead" reclaims a working writer's directory; a false "live" costs one refusal an operator can act on); a reboot the host has outlived is the uptime measure's second way of saying gone. Bare-pid locks are read by pid and rewritten on reclaim. What the guards cannot see (a same-boot backward clock correction hiding a genuine reuse; a reboot the machine has since outlived with no comparable measure) falls back to the pre-existing refusal, never a wrong reclaim — a boot-scoped kernel start token is the design-level fix (#612).
9
+ - **#609** — a resume of a parked policy ask that still spells the retired decision facts (`settledBy` / `approver` as top-level keys) is refused before the CAS with a coded error naming the `hostDecision` shape, instead of having the keys silently ignored (found by the 7.6.0 black-box round, G2.b).
10
+ - **#610** — every connect-phase MCP failure reports `delivered: "no"` — the dial has dispatched nothing of the caller's, so the verdict is a fact, not the in-flight guess; the two kinds a server itself answered (`protocol`, `http_status`) keep the table verdict. One verdict table (`DELIVERED_BY_KIND`, fenced over the closed set) replaces the per-row spellings. A stdio child that exits before the handshake is now `connection_closed / no` (was `unknown`); a 401 endpoint stays `http_status / unknown`; the request phase is unchanged. The dial's `no` promises that no call of the caller's was dispatched — it does not promise that no user data crossed the line during the handshake's elicitation (#611).
11
+ - **#594-b** — the #594 station relocation had put one microtask between the fold and the lanes (and one more inside the screening wrapper), so an org rule cleared on that tick was read as absent and a call 7.6.0 denied was let through; the three station-group seams (screening→fold, fold→lanes, lanes→exit) are back to the one-body form's await boundaries — the next group runs inside the previous group's continuation via a `GatePass.afterFold` seat. Five boundary pins record the microtask counts against the 7.6.0 tree.
12
+ - 7.6.0 carry-over disclosure: the D-8 refusal text `Resume it via checkpointToken` became `Resume it via the pause's token` (wording only).
13
+
14
+ ### BREAKING (d.ts face only — runtime unchanged)
15
+ - Option types and orchestration entry points that used to name the `Runner` CLASS for their `runner` member / parameter (`TaskServerOptions`, `SubagentToolOptions`, `SendMessageToolOptions`, `RunWorkflowToolDeps`, `warmResume`, `runGoal`, `runCascade`, `runRepairLoop`, `verify*`, `runWithTeacher`, `startWorkflow`, `runWorkflow`) now name **`RunnerSelfSeat`** — the one seat the Runner implements and every consumer names (`sessions`, `runTask`, `runTaskStream`, `resume`, `resumeStream`, `agentCatalog`, `emitTaskOutcome`, `gateBaseline`). A host that read `opts.runner.swapModels` or `opts.runner.sideQuery` THROUGH an option type no longer type-checks; call them on the Runner instance it constructed. No shipped consumer does (server calls `swapModels` on its own instances). Passing a `Runner` where a seat is expected still compiles.
16
+
17
+ ### Changed (refactor wave 1 — byte-invariant on the runtime)
18
+ - **design/393 S0** — the run loop's seven contract declarations move down to `contracts.ts`; runtask.ts takes its contracts from their declaring modules (orchestrator contract edges 2→0; G2 exemptions 3→1); the G5 phase-api gate is driven by a `PHASE_FAMILIES` table; LAYERING gains the "run lanes" stratum. runtask.ts 12 215 → 11 946 lines. dist `runtask.js` differs only in import lines.
19
+ - **#594** — the 23 gate stations (+4 exits) leave hooks.ts for the three-layer shape: `gate-fold.ts` (L1, the policy fold), `gate-lanes.ts` (L1, the org + ask-resolution lanes), `runner/gate-exit.ts` (L0, the exits + the one mint); hooks.ts keeps only the hook machinery and a six-call dispatch; `GatePass` is the one record the three read and write. hooks.ts 4 047 → 2 291 lines. Station-file closed-set pin + wiring pin. Words, order, deny layers, settlement kinds: unchanged and pinned.
20
+ - **#598** — the 7 721-line public type hub `types.ts` becomes a 54-line re-export hub over fourteen layer-0 domain modules (`model-seat`, `task-spec`, `tool-spec`, `hands-band`, `agent-definition`, `mcp-server-spec`, `task-limits`, `task-result`, `task-event`, `task-stream`, `runtime-caps`, `delegation-frames`, `runner-deps`, `engine-notice`); every import path and the public export surface are byte-identical; a re-export closed-set pin refuses a declaration re-appearing in the hub.
21
+
22
+ ### Added
23
+ - `processFingerprint(pid?)`, `isProcessLive(record)`, `type ProcessFingerprint` — the file store's process-identity pair, exported for a host's own liveness arm.
24
+ - `type RunnerSelfSeat`.
25
+
26
+ ### Unchanged and pinned
27
+ - Public export surface: 7.6.0's 2 098 names plus the four above, zero removed. Wire frames, the durable park row, the 23 gate stations, `TaskResult.terminal`, the MCP failure record's kinds: unchanged.
28
+
3
29
  ## 7.6.0 — 2026-09-07
4
30
 
5
31
  **BREAKING.** design/390 S6 (three slices, merged): the tool gate's settlement/origin words become ONE `GateOutcome` record, `TaskResult` becomes ONE terminal record, MCP failures become ONE structural record with a delivery verdict, and the durable off switch becomes a word. Every consumer that read the retired keys must migrate (server 7.64.0, cli/client-core, web-admin, desktop — the criteria post lists the frames old→new).
@@ -1,10 +1,10 @@
1
1
  import { Type } from "typebox";
2
- import type { Runner } from "../core/runner/runtask.js";
2
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
3
3
  /** Model-facing name of the child-transcript read tool (residual lane C). */
4
4
  export declare const AGENT_TRANSCRIPT_TOOL_NAME = "AgentTranscript";
5
5
  export interface AgentTranscriptToolOptions {
6
6
  /** Runner whose `sessions` store holds the child's persisted history. */
7
- runner: Runner;
7
+ runner: RunnerSelfSeat;
8
8
  /** The unified registry the background Agent lane registered its a* handles in (scopes reads to lineage). */
9
9
  registry: import("../core/task-registry.js").TaskRegistry;
10
10
  /** design/151 S1b: the durable ledger — when the live row/retain entry is gone (restart, terminal GC,
@@ -1,5 +1,4 @@
1
- import type { Runner } from "../core/runner/runtask.js";
2
- import type { RunInternals } from "../core/runner/prepare-task.js";
1
+ import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
3
2
  import type { ModelRef, TaskResult, TaskSpec, TaskStatus } from "../core/types.js";
4
3
  /**
5
4
  * Quality-gate cascade (design/27). Run the SAME task across a ladder of models (cheapest → strongest);
@@ -154,7 +153,7 @@ export interface CascadeRunResult extends TaskResult {
154
153
  * (`effect: "write"`), those execute once PER rung — ensure idempotency, or gate before the side effect
155
154
  * (e.g. a structured-output gate). `TaskSpec` never guaranteed idempotency; cascade makes it explicit.
156
155
  */
157
- export declare function runCascade(runner: Runner, spec: TaskSpec, config: CascadeConfig,
156
+ export declare function runCascade(runner: RunnerSelfSeat, spec: TaskSpec, config: CascadeConfig,
158
157
  /**
159
158
  * The TRUSTED, run-scoped internals channel — the same object `Runner.runTask` takes as its second
160
159
  * argument — forwarded to EVERY rung under the composition forward contract (identity, with the one
@@ -1,4 +1,4 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  import type { TaskSpec } from "../core/types.js";
3
3
  import type { ExecutionEnv } from "../internal/harness-types.js";
4
4
  import type { VerificationResult } from "./verify.js";
@@ -278,4 +278,4 @@ export declare function terminalForTier(oracle: OracleResult): RepairTerminal |
278
278
  * SAFE-tier: the projection caps every PASS at `candidate_only` — this NEVER auto-accepts. `runRepairLoop` is a
279
279
  * SIBLING of {@link verifyCompleted}: it composes over `runner.runTask` and never touches the Runner core.
280
280
  */
281
- export declare function runRepairLoop(runner: Runner, implSpec: TaskSpec, config: RepairLoopConfig): Promise<RepairResult>;
281
+ export declare function runRepairLoop(runner: RunnerSelfSeat, implSpec: TaskSpec, config: RepairLoopConfig): Promise<RepairResult>;
@@ -1,6 +1,5 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  import type { TaskSpec } from "../core/types.js";
3
- import type { RunInternals } from "../core/runner/prepare-task.js";
4
3
  /** design/122 D2 — per-child resume cap (default 8): a child can be revived at most this many times. */
5
4
  export declare const SUBAGENT_RESUME_CAP = 8;
6
5
  /**
@@ -25,7 +24,7 @@ export interface SubagentRetainEntry {
25
24
  * resume.evicted, the 1.283 ruling). Lifetime: the entry's `release` closure already captures the same
26
25
  * runner, so this adds no new retention class.
27
26
  */
28
- runner?: Runner;
27
+ runner?: RunnerSelfSeat;
29
28
  agentName?: string;
30
29
  /** fix-C5: PER-ENTRY retain TTL override (ms). A SESSION-scoped ledger is shared by two purposes with
31
30
  * different windows (failure-evidence retain = FAILED_SESSION_RETAIN_TTL_MS vs a session-scoped bg
@@ -1,5 +1,5 @@
1
1
  import { Type } from "typebox";
2
- import type { Runner } from "../core/runner/runtask.js";
2
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
3
3
  import type { TaskNotificationPayload } from "../core/task-notification.js";
4
4
  import { type ToolCtxEnricher } from "../core/tools.js";
5
5
  import { type TaskAccess } from "../core/task-registry.js";
@@ -12,7 +12,7 @@ import { type PeerAdmissionConfig, type PeerInboundChainRef, type PeerSelfRef }
12
12
  export declare const SEND_MESSAGE_TOOL_NAME = "SendMessage";
13
13
  export interface SendMessageToolOptions {
14
14
  /** Runner used to execute the resumed child run (the design/122 resume face's delegation runner). */
15
- runner: Runner;
15
+ runner: RunnerSelfSeat;
16
16
  /** The unified task registry the background Agent lane registered its a* handles in. */
17
17
  registry: import("../core/task-registry.js").TaskRegistry;
18
18
  /** design/122 D1 — the parent run's retain ledger (present only when `TaskSpec.retainSubagentSessions`
@@ -1,7 +1,7 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  /**
3
3
  * Release a throwaway session, swallowing errors — best-effort cleanup for the verifier/cascade-rung
4
4
  * sessions that agents spin up and discard. Always call this in a `finally` so a throwing `runTask`
5
5
  * result handler or caller hook (`onRung`/`onRound`) can't leak the session.
6
6
  */
7
- export declare function releaseSession(runner: Runner, sessionId: string): Promise<void>;
7
+ export declare function releaseSession(runner: RunnerSelfSeat, sessionId: string): Promise<void>;
@@ -1,7 +1,6 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  import type { AgentDefinition, Model, ModelRef, TaskLimits, TerminalCause, ToolSpec } from "../core/types.js";
3
3
  import { type ExecutionEnv } from "../internal/harness.js";
4
- import type { RunInternals } from "../core/runner/prepare-task.js";
5
4
  import type { TaskNotificationPayload } from "../core/task-notification.js";
6
5
  import { RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX } from "../config/defaults.js";
7
6
  /**
@@ -433,7 +432,7 @@ export declare function markerFragment(): string;
433
432
  export declare function createSubagentResume(deps: {
434
433
  ledger: SubagentRetainLedger | undefined;
435
434
  parentToolCallId: string;
436
- runner: Runner;
435
+ runner: RunnerSelfSeat;
437
436
  notify?: (n: TaskNotificationPayload, opts?: {
438
437
  priority?: "now" | "next" | "later";
439
438
  }) => void;
@@ -616,7 +615,7 @@ export interface SubagentToolOptions {
616
615
  * .jsonl` + a `.meta.json` sidecar), so "the child conversation is readable afterwards" is a
617
616
  * property CC never makes conditional on a store tier.
618
617
  */
619
- runner: Runner;
618
+ runner: RunnerSelfSeat;
620
619
  /**
621
620
  * design/115 P3 — background sub-agents (CC `run_in_background`). When set, the tool exposes the
622
621
  * `run_in_background` parameter: the call returns an `a*` task_id immediately, the child runs
@@ -1,4 +1,4 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  import { type StrategyOrigin, type StrategyStore, type StrategyStoreIncident } from "../core/strategy-store.js";
3
3
  import type { ModelRef, TaskResult, TaskSpec } from "../core/types.js";
4
4
  /**
@@ -156,4 +156,4 @@ export declare function parseTeacherAdvice(text: string): TeacherAdvice;
156
156
  * completed output (catches "passes but semantically wrong"). Correction-then-takeover, with hard
157
157
  * cost guards (escalation cap, teacher-spend ratio, bounded teacher turns).
158
158
  */
159
- export declare function runWithTeacher(runner: Runner, studentSpec: TaskSpec, teacher?: TeacherConfig): Promise<TeacherRunResult>;
159
+ export declare function runWithTeacher(runner: RunnerSelfSeat, studentSpec: TaskSpec, teacher?: TeacherConfig): Promise<TeacherRunResult>;
@@ -1,4 +1,4 @@
1
- import type { Runner } from "../core/runner/runtask.js";
1
+ import type { RunnerSelfSeat } from "../core/runner/contracts.js";
2
2
  import type { McpServerSpec, ModelRef, ModelRole, TaskSpec, ToolSpec } from "../core/types.js";
3
3
  import type { CheckpointGate, CheckpointToken } from "../core/checkpoint-store.js";
4
4
  export interface TeamMember {
@@ -59,7 +59,7 @@ export type TeamEvent = {
59
59
  type: "done";
60
60
  };
61
61
  export interface TeamDiscussionOptions {
62
- runner: Runner;
62
+ runner: RunnerSelfSeat;
63
63
  /** Default model for members / synthesizer without their own. If omitted, members resolve the
64
64
  * `team` role and the synthesizer the `synthesize` role (both fall back to `default`). */
65
65
  model?: ModelRef;
@@ -1,6 +1,5 @@
1
1
  import { Type, type Static } from "typebox";
2
- import type { Runner, ResumeTaskConfig } from "../core/runner/runtask.js";
3
- import type { RunInternals } from "../core/runner/prepare-task.js";
2
+ import type { ResumeTaskConfig, RunInternals, RunnerSelfSeat } from "../core/runner/contracts.js";
4
3
  import type { CheckpointGate, CheckpointToken, ResumeOutcome } from "../core/checkpoint-store.js";
5
4
  import type { ModelRef, TaskResult, TaskSpec, TaskStatus, ToolSpec } from "../core/types.js";
6
5
  /**
@@ -242,7 +241,7 @@ export interface VerificationResult extends TaskResult {
242
241
  * override is given, the verifier uses {@link STATIC_VERIFICATION_PROMPT} (read the diff/results; don't try
243
242
  * to execute — that was L2's job), avoiding the "PARTIAL on everything" failure in a read-only sandbox.
244
243
  */
245
- export declare function verifyCompleted(runner: Runner, result: TaskResult, specBase: ResumeTaskConfig, objective: string, config: VerifyConfig,
244
+ export declare function verifyCompleted(runner: RunnerSelfSeat, result: TaskResult, specBase: ResumeTaskConfig, objective: string, config: VerifyConfig,
246
245
  /**
247
246
  * The TRUSTED, run-scoped internals channel — the same object `Runner.runTask` takes as its second
248
247
  * argument — forwarded to EVERY leg this gate drives under the composition forward contract (identity,
@@ -303,7 +302,7 @@ internals?: RunInternals): Promise<VerificationResult>;
303
302
  * failed-with-token (verdict `unverified`); the caller approves and calls {@link resumeWithVerification}
304
303
  * to resume AND verify (design/51 P1-b: the durable + HITL + verify integration).
305
304
  */
306
- export declare function runWithVerification(runner: Runner, implSpec: TaskSpec, config?: VerifyConfig,
305
+ export declare function runWithVerification(runner: RunnerSelfSeat, implSpec: TaskSpec, config?: VerifyConfig,
307
306
  /** The trusted run-scoped internals channel, forwarded UNCHANGED to every leg this entry drives —
308
307
  * the implementation run, then (on completion) the verifier + fix legs of the gate. Full contract,
309
308
  * including the attribution and forwarded-whole rules, on {@link verifyCompleted}. Absent ⇒ every
@@ -324,7 +323,7 @@ internals?: RunInternals): Promise<VerificationResult>;
324
323
  * after approval, so a pre-suspend diff would grade stale code. The verifier already verifies the current working
325
324
  * tree (verifierObjective), so dropping the stale diff closes the timing window.
326
325
  */
327
- export declare function resumeWithVerification(runner: Runner, token: CheckpointToken, outcome: ResumeOutcome, taskConfig: ResumeTaskConfig, objective: string, config?: VerifyConfig,
326
+ export declare function resumeWithVerification(runner: RunnerSelfSeat, token: CheckpointToken, outcome: ResumeOutcome, taskConfig: ResumeTaskConfig, objective: string, config?: VerifyConfig,
328
327
  /** The trusted run-scoped internals channel, forwarded UNCHANGED to every leg this entry drives —
329
328
  * `Runner.resume`'s own internals argument for the RESUMED implementation leg, then (on completion)
330
329
  * the verifier + fix legs of the gate. Note that this seat carries the resume-path duty of the same
@@ -344,7 +343,7 @@ export interface DeveloperTaskConfig extends VerifyConfig {
344
343
  * Pair with a role map that gives a strong implementation model and cheaper helper/verifier models for
345
344
  * "auto model selection" (design/28 §3.2): `roles: { default: strong, subagent: cheap, verifier: strong }`.
346
345
  */
347
- export declare function runDeveloperTask(runner: Runner, spec: TaskSpec, config?: DeveloperTaskConfig,
346
+ export declare function runDeveloperTask(runner: RunnerSelfSeat, spec: TaskSpec, config?: DeveloperTaskConfig,
348
347
  /** The trusted run-scoped internals channel, forwarded UNCHANGED to every leg this entry drives — in
349
348
  * BOTH arms: the lone implementation run when `verify: false`, and the whole gate otherwise. The two
350
349
  * arms differ in ONE respect: the gate's door refusal of `isolation` (see {@link verifyCompleted})
@@ -0,0 +1,172 @@
1
+ /**
2
+ * A delegated AGENT's definition and the skills it may mount: `AgentDefinition` (the agent a subagent
3
+ * tool spawns), `SkillManifest` (a skill's on-disk front matter) and `SkillSpec` (the wired form the
4
+ * runner mounts). Layer 0 vocabulary; `types.ts` re-exports the three, so no consumer's import changes.
5
+ */
6
+ import type { ThinkingLevel } from "../internal/harness.js";
7
+ import type { ModelRef } from "./model-seat.js";
8
+ import type { TaskSpec } from "./task-spec.js";
9
+ /**
10
+ * A declarative, reusable named sub-agent (design/38 1B). Hand a set to {@link createSubagentTool} and the
11
+ * model picks one (by `whenToUse`) to delegate to; the chosen definition's config builds the child task.
12
+ *
13
+ * **Deployment-side config, NOT user input** — `systemPrompt`/`allowTools` shape what the sub-agent can do
14
+ * and see, so they must be set by the deployment, never taken from an end-user message.
15
+ */
16
+ export interface AgentDefinition {
17
+ /** Stable identifier + the value the delegation tool's `agent` parameter selects. Must be unique. */
18
+ name: string;
19
+ /** Guidance shown to the model for WHEN to pick this agent (listed in the delegation tool's description). */
20
+ whenToUse?: string;
21
+ /**
22
+ * F4 (CC 2.1.198 parity, `whenToUseLean` — 锚 pretty.js:409174 `rbm` + selection `tIl` :453029
23
+ * `(lean && e.whenToUseLean) || e.whenToUse`): a SHORT variant of {@link whenToUse} preferred on
24
+ * lean-prompt surfaces. sema posture: the engine runs the CC lean-prompt arm wholesale (web.ts
25
+ * lean-card precedent), so roster listings/descriptions prefer this text whenever present;
26
+ * {@link whenToUse} remains the fallback. Optional — a single-text agent behaves exactly as before.
27
+ */
28
+ whenToUseLean?: string;
29
+ /** Tool allowlist over the delegation pool (`["*"]` = all). Replaces (does not merge with) the tool's
30
+ * own `allowTools`/`denyTools` when this agent is selected. F1 (CC parity): unlike the TOOL-level
31
+ * allow/deny (which never filters the nested delegation tool — that stays `maxDepth`-governed), a
32
+ * PER-AGENT allow/deny ALSO governs the nested delegation tool: an agent whose allow/deny excludes
33
+ * the delegation tool's name cannot re-delegate (CC Explore/Plan `disallowedTools` include Agent,
34
+ * pretty.js:409189/486948). */
35
+ allowTools?: string[];
36
+ /** Tool denylist (a deny always wins). See {@link allowTools} for the per-agent delegation-tool note. */
37
+ denyTools?: string[];
38
+ /**
39
+ * F7 (CC 2.1.198 parity, per-agent `skills` — 锚 pretty.js:422126 `e.skills ?? []`, GA/ungated in 198:
40
+ * CC preloads each named skill's prompt content into the child's opening messages, warning on misses).
41
+ * sema shape: full {@link SkillSpec} objects (sema has no ambient skill registry to resolve bare names
42
+ * against) threaded into the chosen child's `TaskSpec.skills` — disclosed in its `<skills>` block +
43
+ * invocable via the `skill` tool. Deployment-trusted, same trust tier as `systemPrompt`.
44
+ */
45
+ skills?: SkillSpec[];
46
+ /**
47
+ * F7 (CC 2.1.198 parity, per-agent `background` — 锚 pretty.js:453611 `H.background===!0` OR-ed into
48
+ * the background predicate, GA/ungated): `true` = this agent ALWAYS launches on the background lane
49
+ * (an omitted `run_in_background` no longer means sync, and the per-call parameter cannot force sync —
50
+ * CC-same OR semantics). Requires the delegation tool's `background` surface; without one the child
51
+ * runs synchronously (CC-same quiet fallback — CC's env kill-switch arm, :453611 `&& !sJt`).
52
+ */
53
+ background?: boolean;
54
+ /**
55
+ * F7 (CC 2.1.198 parity, per-agent `isolation` — 锚 pretty.js:453599 `z = a ?? H.isolation`, GA):
56
+ * default isolation for this agent; an explicit per-call `isolation` argument wins. sema supports
57
+ * `"worktree"` (CC's `"remote"` arm is a claude.ai-session concern, not ported).
58
+ */
59
+ isolation?: "worktree";
60
+ /** Model for this agent. **Omit to INHERIT the caller's current model** (design/38 1B finding 7) — the
61
+ * recommended default; a concrete `ModelRef` pins it instead. */
62
+ model?: ModelRef;
63
+ /** Thinking level for this agent. **Omit to INHERIT the caller's current thinking level** (the model
64
+ * companion above — a mid-run degrade/boost on the parent carries into new children); a concrete
65
+ * level pins it instead. */
66
+ thinking?: ThinkingLevel;
67
+ /** System prompt / persona for this agent. Falls back to the delegation tool's `systemPrompt`. */
68
+ systemPrompt?: string;
69
+ /** Per-agent turn cap. Falls back to the delegation tool's `limits.maxTurns`. Must be POSITIVE: a
70
+ * non-positive/non-finite value is ignored (CLS-A-3) rather than folded in, because downstream an
71
+ * explicit `0` DISABLES the turn cap — the opposite of the tightening this field expresses. */
72
+ maxTurns?: number;
73
+ /** Long-term memory scope for this agent (same shape as {@link TaskSpec.memory}). */
74
+ memory?: TaskSpec["memory"];
75
+ /**
76
+ * This agent's own {@link TaskSpec.memoryPersistenceCapable} declaration — the same three-state
77
+ * statement, made per definition: an agent whose closure tools persist memory declares `true`
78
+ * (suppressing the read-only-memory disclosure no roster inference can clear), one whose roster
79
+ * looks write-capable but reaches no durable store declares `false` (forcing the disclosure).
80
+ * Arbitration with the spawning run's declaration: a parent's explicit `false` is a FLOOR and wins
81
+ * over a definition `true` (the disclosure is about the deployment's storage, which choosing this
82
+ * agent does not change); otherwise a declared definition value wins over the parent's; absent
83
+ * both, the child spec carries no value and the child's own roster inference decides.
84
+ * On the workflow lane (`agent(…, {agentType})`) the definition value fills an ABSENT governed-spec
85
+ * value only — a base/spec declaration of either polarity wins (the lane's spec-pinned-fields rule).
86
+ */
87
+ memoryPersistenceCapable?: boolean;
88
+ /**
89
+ * Observer agents (CC 2.1.206 parity — 逐字锚 docs/CC206-OBSERVER-ANCHORS-2026-07-11.md, schema
90
+ * 面 C @28385708): "Agent type auto-spawned as a background observer whenever this agent runs.
91
+ * The observer receives read-only activity digests and reports via the ObserverReport tool; it
92
+ * never participates in the task." Resolution is warn-and-unobserved on an unknown type and
93
+ * refuses chaining (an observer's own `observer` declaration is ignored). Gated by
94
+ * {@link RuntimeCaps.allowObservers} — EXPLICIT opt-in, default OFF (the sema seat of CC's
95
+ * default-unset env `CLAUDE_CODE_EXPERIMENTAL_OBSERVER_AGENTS` + default-true statsig pair).
96
+ */
97
+ observer?: string;
98
+ /**
99
+ * CC 面 C: "Supplemental postamble appended (after the harness-owned default) to each activity
100
+ * digest sent to the observer. Blank values are ignored."
101
+ */
102
+ observerMessage?: string;
103
+ }
104
+ /**
105
+ * A per-skill runtime capability manifest (design/77 §3 Gate-3). When present, loading the skill
106
+ * SCOPES the rest of the invocation to ONLY these tools/paths via runtime deny-narrowing: a tool call
107
+ * not in `allowTools` (intersected across nested skill frames) is DENIED, and a write whose canonical
108
+ * target falls outside `allowPaths` is DENIED — regardless of how permissive the task policy is.
109
+ *
110
+ * 🔴 **Safe-by-construction:** a manifest can only SUBTRACT capability. The narrowing composes via the
111
+ * `deny > ask > allow` fold (`combinePolicies`) where `deny` short-circuits, so a manifest can never
112
+ * *grant* a tool the task policy withheld — whoever sets a manifest can only restrict further.
113
+ * Worst case (the model never pops the frame) = no narrowing, never widening — still ⊆ task policy.
114
+ *
115
+ * The manifest is CALLER-provided here (same trust level as the rest of `SkillSpec`); deriving it
116
+ * automatically (the auto-promote pipeline) is a separate, deferred concern (design/77 §5).
117
+ */
118
+ export interface SkillManifest {
119
+ /** The ONLY tool names the invocation may call while this skill's frame is active. */
120
+ allowTools: string[];
121
+ /**
122
+ * Optional path allowlist for WRITE tools (`write_file`/`edit_file`): a write whose canonicalized
123
+ * target is not inside one of these (path-segment-aware) prefixes is DENIED. Omit = no path narrowing
124
+ * (only `allowTools` applies). Reads are never path-narrowed (this gate restricts capability, not visibility).
125
+ *
126
+ * 🔴 **Fail-closed (MAJOR-2):** `allowPaths` can only confine tools whose write target is a parseable `path`
127
+ * argument (`write_file`/`edit_file`). While an `allowPaths` constraint is active, any OTHER mutating
128
+ * (effect:write/idempotent) allowlisted tool — notably `bash`, whose command can write anywhere — is DENIED
129
+ * outright, because its target cannot be path-confined. So a manifest that lists `bash` together with
130
+ * `allowPaths` does NOT let bash write/egress anywhere: bash is denied while the path constraint is active.
131
+ * Confine writes to specific paths via `write_file`/`edit_file` only.
132
+ */
133
+ allowPaths?: string[];
134
+ /** Reserved (design/77 §3): whether egress is permitted under this manifest. Carried through; v1 does
135
+ * not act on it beyond the allowTools intersection (egress tools must also be in `allowTools`). */
136
+ egress?: boolean;
137
+ /** Stable lineage id of the artifact this manifest came from — used in deny reasons + as the scope key. */
138
+ lineageId: string;
139
+ }
140
+ /** A skill made available to this task (passed as an object; not loaded from disk). */
141
+ export interface SkillSpec {
142
+ name: string;
143
+ description: string;
144
+ content: string;
145
+ /** Optional Gate-3 runtime capability manifest (design/77 §3) — see {@link SkillManifest}. */
146
+ manifest?: SkillManifest;
147
+ /**
148
+ * Optional attachments bundled with the skill (additive) — the CC bundled-skill shape (a SKILL.md whose
149
+ * body references sibling files by relative path) translated to sema's brain-outside posture, where the
150
+ * ruling is: **core never writes to disk.** CC extracts a bundle and lets the body reference files on
151
+ * the filesystem; sema core has no filesystem authority of its own, so materializing attachments into a
152
+ * working directory (making `Read`-by-path work) is the DEPLOYMENT's half. What core owns is exactly two
153
+ * faces, both bounded:
154
+ * 1. **disclosure** — each attachment's relative `path` is listed on the skill's `<skills>`-block line
155
+ * (metadata only, capped like the rest of the block), so the model knows the material exists before
156
+ * it loads the skill;
157
+ * 2. **delivery** — a `Skill` invoke appends an `## Attachments` section after the body (which is
158
+ * itself delivered untruncated): each file as `### <path>` + its content, under a SEPARATE total
159
+ * cap (`SKILL_ATTACHMENTS_MAX_CHARS`, 50k chars — an attachments-face budget; truncation/omission
160
+ * is always disclosed in-band). Without deployment-side materialization this inline delivery is the
161
+ * attachment's ONLY reachable face — that is the deliberate minimal shape, not an oversight.
162
+ *
163
+ * `path` is a relative, display-oriented identifier (how the body refers to the file); core never
164
+ * resolves it against a filesystem. `content` carries the SAME trust contract as {@link content}: skill
165
+ * material is CALLER-trusted instructions by design (see the skills module note) — a caller forwarding
166
+ * end-user skills is responsible for vetting attachments exactly like the body.
167
+ */
168
+ files?: Array<{
169
+ path: string;
170
+ content: string;
171
+ }>;
172
+ }
@@ -0,0 +1 @@
1
+ export {};