@sema-agent/core 7.49.5 → 7.50.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.
- package/CHANGELOG.md +157 -0
- package/dist/agents/observer.js +3 -10
- package/dist/agents/subagent-steps.d.ts +6 -14
- package/dist/agents/subagent-steps.js +3 -17
- package/dist/brain/stream-shared.d.ts +1 -1
- package/dist/core/allow-entry.d.ts +1 -1
- package/dist/core/allow-entry.js +1 -1
- package/dist/core/ask-origin.d.ts +15 -11
- package/dist/core/ask-origin.js +6 -14
- package/dist/core/auto-mode-prompt.js +6 -2
- package/dist/core/checkpoint-store.d.ts +6 -4
- package/dist/core/checkpoint-store.js +1 -1
- package/dist/core/context-edit.d.ts +2 -2
- package/dist/core/decision-receipt.d.ts +2 -2
- package/dist/core/decision-receipt.js +30 -11
- package/dist/core/delegation-frames.d.ts +66 -18
- package/dist/core/delegation-frames.js +22 -0
- package/dist/core/engine-notice.d.ts +7 -5
- package/dist/core/frame-settlement.d.ts +6 -1
- package/dist/core/gate-fold.js +34 -19
- package/dist/core/gate-lanes.js +15 -13
- package/dist/core/gate-outcome.d.ts +2 -2
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +28 -20
- package/dist/core/human-input-projection.js +2 -0
- package/dist/core/lsp-diagnostics.d.ts +3 -0
- package/dist/core/lsp-diagnostics.js +6 -0
- package/dist/core/lsp-session.d.ts +39 -17
- package/dist/core/lsp-session.js +118 -58
- package/dist/core/lsp.d.ts +83 -3
- package/dist/core/lsp.js +146 -16
- package/dist/core/mcp.js +2 -1
- package/dist/core/media-byte-cap.d.ts +14 -0
- package/dist/core/media-byte-cap.js +15 -3
- package/dist/core/memory-engine/consolidation-driver.d.ts +23 -1
- package/dist/core/memory-engine/consolidation-driver.js +54 -6
- package/dist/core/memory-engine/consolidation-write-gate.d.ts +46 -0
- package/dist/core/memory-engine/consolidation-write-gate.js +82 -0
- package/dist/core/memory-engine/consolidation.d.ts +17 -0
- package/dist/core/memory-engine/consolidation.js +1 -0
- package/dist/core/memory-engine/distiller.d.ts +8 -2
- package/dist/core/memory-engine/distiller.js +8 -6
- package/dist/core/memory-engine/engine.d.ts +37 -4
- package/dist/core/memory-engine/engine.js +127 -38
- package/dist/core/memory-engine/file-backend.d.ts +8 -3
- package/dist/core/memory-engine/file-backend.js +44 -16
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/landing-admission.d.ts +65 -0
- package/dist/core/memory-engine/landing-admission.js +68 -0
- package/dist/core/memory-engine/types.d.ts +23 -0
- package/dist/core/mode-policy.d.ts +3 -2
- package/dist/core/mode-policy.js +2 -0
- package/dist/core/permission-rule-model.d.ts +19 -13
- package/dist/core/permission-rule-model.js +7 -4
- package/dist/core/permission-rule-provider.d.ts +11 -0
- package/dist/core/permission-rules.d.ts +1 -1
- package/dist/core/permission-rules.js +5 -2
- package/dist/core/persisted-rule-arms.d.ts +15 -7
- package/dist/core/persisted-rule-arms.js +13 -6
- package/dist/core/reminder-mint.d.ts +5 -0
- package/dist/core/reminder-mint.js +1 -0
- package/dist/core/retired-keys.d.ts +8 -0
- package/dist/core/retired-keys.js +4 -0
- package/dist/core/rule-lane-reads.d.ts +4 -4
- package/dist/core/rule-lane-reads.js +10 -1
- package/dist/core/runner/construction-doors.d.ts +10 -4
- package/dist/core/runner/construction-doors.js +25 -2
- package/dist/core/runner/contracts.d.ts +20 -3
- package/dist/core/runner/env-capability-census.js +1 -1
- package/dist/core/runner/gate-exit.js +2 -1
- package/dist/core/runner/memory-consolidation-driver.d.ts +6 -4
- package/dist/core/runner/memory-consolidation-driver.js +5 -2
- package/dist/core/runner/memory-consolidation-write-judge.d.ts +17 -0
- package/dist/core/runner/memory-consolidation-write-judge.js +14 -0
- package/dist/core/runner/permission-rule-lanes.d.ts +16 -22
- package/dist/core/runner/permission-rule-lanes.js +13 -43
- package/dist/core/runner/person-path-rows.d.ts +244 -0
- package/dist/core/runner/person-path-rows.js +387 -0
- package/dist/core/runner/policy-throw.d.ts +34 -0
- package/dist/core/runner/policy-throw.js +25 -0
- package/dist/core/runner/prepare-acquire-reconcile.js +8 -1
- package/dist/core/runner/prepare-artifact.d.ts +5 -3
- package/dist/core/runner/prepare-artifact.js +2 -8
- package/dist/core/runner/prepare-ask-lane.d.ts +2 -1
- package/dist/core/runner/prepare-ask-lane.js +14 -16
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +4 -3
- package/dist/core/runner/prepare-caps-and-workflow.js +1 -1
- package/dist/core/runner/prepare-context-lane.js +2 -2
- package/dist/core/runner/prepare-gate-stations.d.ts +3 -3
- package/dist/core/runner/prepare-gate-stations.js +1 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +19 -10
- package/dist/core/runner/prepare-hands-readface.js +57 -43
- package/dist/core/runner/prepare-lsp.d.ts +15 -13
- package/dist/core/runner/prepare-lsp.js +11 -11
- package/dist/core/runner/prepare-policy-chain.d.ts +8 -4
- package/dist/core/runner/prepare-policy-chain.js +11 -10
- package/dist/core/runner/prepare-run-refs.js +1 -1
- package/dist/core/runner/prepare-task.js +24 -16
- package/dist/core/runner/prepare-turn-wiring.d.ts +13 -6
- package/dist/core/runner/prepare-turn-wiring.js +19 -8
- package/dist/core/runner/read-root-grant.d.ts +1 -25
- package/dist/core/runner/read-root-grant.js +1 -17
- package/dist/core/runner/retired-runner-deps.d.ts +2 -2
- package/dist/core/runner/run-brain-sinks.d.ts +1 -5
- package/dist/core/runner/run-brain-sinks.js +2 -4
- package/dist/core/runner/run-harness-handlers.js +5 -4
- package/dist/core/runner/run-identity-wiring.d.ts +4 -4
- package/dist/core/runner/run-identity-wiring.js +10 -1
- package/dist/core/runner/run-leg.d.ts +1 -1
- package/dist/core/runner/run-leg.js +22 -9
- package/dist/core/runner/run-settle-and-teardown.d.ts +0 -4
- package/dist/core/runner/run-settle-and-teardown.js +7 -4
- package/dist/core/runner/run-terminal-adoption.d.ts +1 -1
- package/dist/core/runner/run-terminal-adoption.js +1 -1
- package/dist/core/runner/run-turn-boundary.js +2 -2
- package/dist/core/runner/runtask.js +8 -8
- package/dist/core/runner/session-file-state-replay.d.ts +14 -4
- package/dist/core/runner/session-file-state-replay.js +8 -0
- package/dist/core/runner/stream-steer-verb.js +3 -0
- package/dist/core/runner/tool-end-body.d.ts +5 -4
- package/dist/core/runner/tool-end-body.js +4 -4
- package/dist/core/runner/tool-output-projection.d.ts +6 -4
- package/dist/core/runner/tool-output-projection.js +66 -47
- package/dist/core/runner-deps.d.ts +6 -3
- package/dist/core/shared-memory/types.d.ts +2 -2
- package/dist/core/shell-read-silence.d.ts +23 -0
- package/dist/core/shell-read-silence.js +18 -0
- package/dist/core/synthetic-read-verdict.d.ts +80 -21
- package/dist/core/synthetic-read-verdict.js +89 -18
- package/dist/core/task-event.d.ts +113 -25
- package/dist/core/task-spec.d.ts +44 -0
- package/dist/core/task-tool-shape.d.ts +1 -1
- package/dist/core/tool-catalog-entries.js +16 -2
- package/dist/core/tool-policy.d.ts +25 -15
- package/dist/core/tool-policy.js +9 -13
- package/dist/core/trace.d.ts +3 -2
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +2 -2
- package/dist/core/user-attachment.d.ts +164 -0
- package/dist/core/user-attachment.js +437 -0
- package/dist/engine/compaction/compaction.js +10 -3
- package/dist/engine/compaction/utils.js +6 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -1
- package/dist/engine/execution-env/node-execution-env.js +125 -0
- package/dist/engine/harness/agent-harness.d.ts +12 -2
- package/dist/engine/harness/agent-harness.js +15 -3
- package/dist/engine/harness/types.d.ts +21 -0
- package/dist/engine/llm/content-block-render.d.ts +15 -0
- package/dist/engine/llm/content-block-render.js +10 -0
- package/dist/engine/llm/index.d.ts +1 -0
- package/dist/engine/llm/index.js +1 -0
- package/dist/engine/llm/types.d.ts +80 -4
- package/dist/engine/llm/types.js +43 -1
- package/dist/engine/session/import-validate.js +2 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +2 -1
- package/dist/internal/harness-types.d.ts +1 -1
- package/dist/internal/llm.d.ts +2 -2
- package/dist/internal/llm.js +1 -1
- package/dist/orchestration/workflow.d.ts +4 -5
- package/dist/orchestration/workflow.js +2 -2
- package/dist/prompts/default.d.ts +1 -1
- package/dist/tools/artifact/artifact-tool.js +1 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
- package/dist/tools/fs/dir-entries.d.ts +4 -10
- package/dist/tools/fs/dir-entries.js +4 -11
- package/dist/tools/fs/file-read-check.js +3 -3
- package/dist/tools/fs/fs-pdf.js +2 -4
- package/dist/tools/fs/fs-read.d.ts +47 -4
- package/dist/tools/fs/fs-read.js +63 -19
- package/dist/tools/fs/fs-search-tools.d.ts +3 -3
- package/dist/tools/fs/fs-search-tools.js +7 -2
- package/dist/tools/fs/fs-write.d.ts +1 -1
- package/dist/tools/fs/fs-write.js +7 -6
- package/dist/tools/fs/index.d.ts +7 -1
- package/dist/tools/fs/index.js +56 -34
- package/dist/tools/fs/read-deny-home.d.ts +19 -1
- package/dist/tools/fs/read-deny-home.js +32 -22
- package/dist/tools/fs/read-deny.d.ts +14 -0
- package/dist/tools/fs/read-deny.js +8 -0
- package/dist/tools/fs/repo-map.d.ts +3 -2
- package/dist/tools/fs/repo-map.js +11 -3
- package/dist/tools/fs/safety.d.ts +41 -2
- package/dist/tools/fs/safety.js +12 -3
- package/dist/tools/fs/shell-read-check.d.ts +12 -3
- package/dist/tools/fs/shell-read-check.js +44 -24
- package/dist/tools/fs/shell-read-device.d.ts +1 -1
- package/dist/tools/fs/shell-read-face.d.ts +15 -0
- package/dist/tools/fs/shell-read-face.js +5 -0
- package/dist/tools/fs/shell-read-judge.d.ts +9 -4
- package/dist/tools/fs/shell-read-judge.js +1 -1
- package/dist/tools/loop-tick.d.ts +2 -2
- package/package.json +3 -1
- package/test/export-surface.snapshot.json +39 -1
- package/wire-changes/core@7.50.0.json +1699 -0
- package/wire-changes/core@7.50.1.json +65 -0
- package/dist/core/runner/persisted-path-rows.d.ts +0 -88
- package/dist/core/runner/persisted-path-rows.js +0 -108
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* nothing else. Layer 0 vocabulary; `types.ts` re-exports every name below, so no consumer's import
|
|
7
7
|
* changes.
|
|
8
8
|
*/
|
|
9
|
-
import type { ActorAssertion } from "../internal/llm.js";
|
|
9
|
+
import type { ActorAssertion, UserAttachmentKind, UserAttachmentOutcome } from "../internal/llm.js";
|
|
10
10
|
import type { TaskResult } from "./task-result.js";
|
|
11
11
|
import type { TaskNotificationPayload } from "./task-notification.js";
|
|
12
12
|
import type { ProviderCondition, ProviderConditionSource } from "../brain/provider-dialect.js";
|
|
@@ -383,17 +383,28 @@ export type TaskEvent = ({
|
|
|
383
383
|
* (previously dropped here); the internal `details` payload is NOT exposed (e.g. a sub-agent tool's
|
|
384
384
|
* `details` is the entire child `TaskResult`).
|
|
385
385
|
*
|
|
386
|
-
* **Type is `unknown` and intentionally non-uniform** —
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
386
|
+
* **Type is `unknown` and intentionally non-uniform** — a `string` result stays a string (over the core text cap it is
|
|
387
|
+
* cut and ends with the `…[+N chars truncated]` marker); a `(TextContent|ImageContent|DocumentContent)[]` result stays
|
|
388
|
+
* an array whose blocks keep their slots. One rule for the array (see {@link truncated}): its text blocks (each at its
|
|
389
|
+
* text plus whatever else it carries) — with any block that is neither text nor an admitted image/document, at its
|
|
390
|
+
* serialization — are one character stream under the text cap, cut IN
|
|
391
|
+
* PLACE where the cap runs out (that block ends with the marker, the stream's later blocks leave); MEDIA blocks are not
|
|
392
|
+
* measured against the text cap and ride AS-IS while the leg's media budget lasts (`RunnerDeps.mediaByteCapBytes`,
|
|
393
|
+
* default `AGGREGATE_MEDIA_BUDGET_BYTES`: decoded bytes, spent as base64 on the wire — x 4/3 — after the text's
|
|
394
|
+
* serialized size), past which a block becomes `{ type, mimeType?, bytes, truncated: true }` in its slot (never a
|
|
395
|
+
* string; a media type over 255 characters is not echoed), and when not even a descriptor fits, it and every later
|
|
396
|
+
* media block fold into ONE `{ type: "omitted", blocks, bytes, truncated: true }` in its slot, so the media in an event
|
|
397
|
+
* is bounded at any block count. A consumer must handle both shapes.
|
|
390
398
|
*
|
|
391
399
|
* **UNTRUSTED RAW + for OBSERVABILITY ONLY**: it is external tool output (file reads, shell stderr, API
|
|
392
400
|
* bodies) and may carry secrets/paths/PII — core bounds only its SIZE; a consumer MUST redact and MAY
|
|
393
401
|
* further bound before it persists or displays it (same contract as `tool_start.args`). It is for a live
|
|
394
402
|
* UI / trace, NOT for re-feeding to a model: a truncated body would mislead an LLM, and the model already
|
|
395
403
|
* has the full, untruncated result in its own context — build model prompts from the session, never by
|
|
396
|
-
* replaying this field.
|
|
404
|
+
* replaying this field. The engine's two model-facing readers of it, the observer digest and the sub-agent step
|
|
405
|
+
* outcome, render a block through the one block rendering (text as text, any other block as its `[type: mimeType]`
|
|
406
|
+
* marker, never its payload).
|
|
407
|
+
* Absent when the tool produced no content body.
|
|
397
408
|
*/
|
|
398
409
|
output?: unknown;
|
|
399
410
|
/**
|
|
@@ -543,29 +554,31 @@ export type TaskEvent = ({
|
|
|
543
554
|
*/
|
|
544
555
|
notExecuted?: true;
|
|
545
556
|
/**
|
|
546
|
-
* design/99 §E1 — `true` when {@link output}
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
557
|
+
* design/99 §E1 — `true` exactly when {@link output} is not the content the tool returned: text was cut at the cap
|
|
558
|
+
* (the string, or the block at the cut, carries the marker; the stream's later blocks left), a media block was
|
|
559
|
+
* replaced by its descriptor, media folded into the summary, or content that could not be read was replaced by the
|
|
560
|
+
* one `[unserializable tool output]` string. Lets a consumer detect truncation programmatically
|
|
561
|
+
* instead of parsing the marker out of the text; a media block carries `truncated: true` on its own descriptor.
|
|
562
|
+
* Absent/false = `output` IS the returned content, every block in its slot. (The full untruncated result still
|
|
563
|
+
* lives in the model's context / `ToolResultStore`.)
|
|
550
564
|
*/
|
|
551
565
|
truncated?: boolean;
|
|
552
566
|
/**
|
|
553
|
-
* Present iff {@link truncated}: the TRUE original size (characters) of
|
|
554
|
-
* the
|
|
567
|
+
* Present iff {@link truncated} and the content could be read: the TRUE original size (characters) of
|
|
568
|
+
* the value this event's {@link output} was bounded from — for a string result, the string's own
|
|
555
569
|
* length; for a non-string result (a blocks array), the SUM of each block's own true size (a text
|
|
556
|
-
* block's `.text.length
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
570
|
+
* block's `.text.length` plus whatever else it carries at its serialized length; an image/document block's
|
|
571
|
+
* `.data.length`, i.e. its base64 payload, whether the
|
|
572
|
+
* block rode as-is or was replaced by its descriptor; any other block, outside the tool contract, its serialized
|
|
573
|
+
* length) — never `JSON.stringify(content).length`, which is
|
|
574
|
+
* polluted by two different kinds of noise: structural overhead (field-name/punctuation bytes that aren't
|
|
575
|
+
* content at all) AND, for text containing quotes/backslashes/control characters, escape inflation (a
|
|
576
|
+
* real result: 17298 reported vs 13696 true content characters).
|
|
562
577
|
*
|
|
563
|
-
* **Not
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
* `
|
|
567
|
-
* ahead of the cap plus the marker's `N` — and that gap is itself the honest signal that non-text bulk
|
|
568
|
-
* was dropped, not an inconsistency to paper over.
|
|
578
|
+
* **Not arithmetically tied to the marker's own `N`**: the marker counts how much MORE of the shown text
|
|
579
|
+
* exists beyond the cut point; `totalChars` counts the whole ORIGINAL value, media blocks included, so it
|
|
580
|
+
* can run far ahead of the cap plus `N`. Read what was cut from the marker (text) and from the
|
|
581
|
+
* descriptors' own `bytes` (media), not from the gap.
|
|
569
582
|
*/
|
|
570
583
|
totalChars?: number;
|
|
571
584
|
} & TaskEventIdentity) | ({
|
|
@@ -869,6 +882,10 @@ export type TaskEvent = ({
|
|
|
869
882
|
* serving layer replaying the ledger); the core's live emissions precede the commit and
|
|
870
883
|
* omit it — consumers there join via `message_committed` + stream order. */
|
|
871
884
|
entryId?: string;
|
|
885
|
+
/** Present only on the `"applied"` frame of an objective that declared attachments: per attachment, in order, what
|
|
886
|
+
* the engine read for it and will send (`outcome`) — an admission result, not a delivery. Each attachment is
|
|
887
|
+
* delivered as its own message after the objective; its `message_committed` is the delivery. */
|
|
888
|
+
attachments?: readonly HumanInputAttachment[];
|
|
872
889
|
} & TaskEventIdentity) | ({
|
|
873
890
|
/**
|
|
874
891
|
* design/99 §E3/§E10 — a live BRAIN-LAYER status the brain would otherwise absorb
|
|
@@ -897,11 +914,74 @@ export type TaskEvent = ({
|
|
|
897
914
|
* fact, not a default: a pre-373 producer event, or a parked record whose tier was not
|
|
898
915
|
* carried (the terminal sweep's re-pend) — never read absence as `"later"`. */
|
|
899
916
|
priority?: import("./task-notification.js").SystemInjectionPriority;
|
|
917
|
+
} & TaskEventIdentity) | ({
|
|
918
|
+
/**
|
|
919
|
+
* A DELEGATED CHILD STARTED: the one frame that says who the child is, at the beat it starts —
|
|
920
|
+
* before its first model request, so a consumer opens the child's row (a foreground child's panel
|
|
921
|
+
* line, a background child's fleet entry) without waiting a model turn for the first
|
|
922
|
+
* `task_progress`. Mirrors CC's `system/task_started`.
|
|
923
|
+
*
|
|
924
|
+
* ONE MINT PER CYCLE, at the child leg's spawn station, for every delegation lane alike
|
|
925
|
+
* (foreground, background, fork, workflow agent, named teammate): a first spawn mints it, and so
|
|
926
|
+
* does every revival of a completed child (a new cycle — `seq` moves on, the `taskId`/`sessionId`
|
|
927
|
+
* of the revived run say which). A durable RESUME of a parked leg is the same cycle continuing and
|
|
928
|
+
* mints NOTHING; a child whose prepare throws never reaches the station and mints nothing either
|
|
929
|
+
* (its terminal still arrives on the lane that spawned it). Ordered strictly after the leg's
|
|
930
|
+
* `wiring_manifest` and strictly before anything its first turn produces, so on the forward
|
|
931
|
+
* channel it is the child's first frame. Rides the same door as `task_progress` (the child's own
|
|
932
|
+
* stream, and the forward channel to the deployment); the process-level delegation-lifecycle
|
|
933
|
+
* `spawn` frame is a projection of this mint, delivered at the same instant under the same gate.
|
|
934
|
+
*
|
|
935
|
+
* Live and ephemeral like `task_progress`: never persisted, never replayed on resume, absent from
|
|
936
|
+
* checkpoints. Every member below is a value the run already speaks elsewhere — this frame
|
|
937
|
+
* introduces no new reading of any of them.
|
|
938
|
+
*
|
|
939
|
+
* CC mapping: `task_id` → {@link taskId} (run domain; a background child's registry handle rides
|
|
940
|
+
* {@link TaskEventIdentity.bgAgentId}), `tool_use_id` → `parentToolCallId`, `description` →
|
|
941
|
+
* {@link name}, `subagent_type` → {@link agentType}, `task_type`/`is_backgrounded` → {@link taskType}
|
|
942
|
+
* (absent = a foreground child), `run_id` → {@link seq} (the cycle), `parent_task_id` →
|
|
943
|
+
* {@link parentTaskId}, `session_id` → {@link sessionId}. Not carried: `prompt` (a delegated
|
|
944
|
+
* objective can hold a secret — the same reason {@link name} never falls back to it), `awaited`,
|
|
945
|
+
* `spawn_depth` (the nesting is the `parentTaskId` chain), and the shell/monitor-only members.
|
|
946
|
+
*/
|
|
947
|
+
type: "task_started";
|
|
948
|
+
/** The child RUN's id (`spec.taskId ?? sessionId`) — the key its `task_progress` frames carry. */
|
|
949
|
+
taskId: string;
|
|
950
|
+
/** The child run's session id — the handle its transcript is read by. */
|
|
951
|
+
sessionId: string;
|
|
952
|
+
/** The fleet-task kind, exactly as the child's `task_progress.taskType`: ABSENT for a foreground
|
|
953
|
+
* (synchronous) child, which has no fleet row. */
|
|
954
|
+
taskType?: DelegationTaskType;
|
|
955
|
+
/** The registry row's cycle generation, exactly as `task_progress.seq` (absent where the child has no
|
|
956
|
+
* `a*` row). A revived cycle's frame carries the bumped value. */
|
|
957
|
+
seq?: number;
|
|
958
|
+
/** Workflow-lane self-identification, as on `task_progress` (stamped where the workflow forwards). */
|
|
959
|
+
workflowRunId?: string;
|
|
960
|
+
/** The workflow agent's label, riding with {@link workflowRunId}. */
|
|
961
|
+
workflowAgentLabel?: string;
|
|
962
|
+
/** The spawning run's task id, exactly as `task_progress.parentTaskId`. */
|
|
963
|
+
parentTaskId?: string;
|
|
964
|
+
/** The spawning run's session id (the always-on parent linkage). */
|
|
965
|
+
parentSessionId?: string;
|
|
966
|
+
/** The delegation tree's root host session. */
|
|
967
|
+
rootSessionId?: string;
|
|
968
|
+
/** The child's display label, the same bounded single-line value its `task_progress.name` and its
|
|
969
|
+
* hook identity's `agentName` carry. UNTRUSTED display text. */
|
|
970
|
+
name?: string;
|
|
971
|
+
/** The explicit `Agent({name})` spawn identity (the teammate key), when the spawn carried one. */
|
|
972
|
+
spawnName?: string;
|
|
973
|
+
/** The resolved subagent type the child was spawned as (absent on a workflow-lane agent). */
|
|
974
|
+
agentType?: string;
|
|
975
|
+
/** The model the child leg was PREPARED with — the value its `task_progress.model` and
|
|
976
|
+
* `TaskResult.model` carry. */
|
|
977
|
+
model: string;
|
|
978
|
+
/** Epoch ms at the mint. */
|
|
979
|
+
startedAt: number;
|
|
900
980
|
} & TaskEventIdentity) | ({
|
|
901
981
|
/**
|
|
902
982
|
* design/99 MF-10 — a SUBAGENT PROGRESS TICK: the delegated sub-run's usage ACCRUING
|
|
903
983
|
* over time, emitted at each turn boundary WHILE it runs, so a parent UI animates the Task card's rollup
|
|
904
|
-
* (tokens/tool-uses climbing). Emitted ONLY for a
|
|
984
|
+
* (tokens/tool-uses climbing). Emitted ONLY for a delegated leg (the same eligibility as `task_started`); a top-level
|
|
905
985
|
* run's own usage is the consumer's own. `status:"running"` mid-run; the terminal usage is the `done` result.
|
|
906
986
|
* Live/ephemeral — NOT persisted (a resumable trace re-derives usage from the result), like `status`.
|
|
907
987
|
* Maps to CC `SDKTaskProgress` (camelCase here → snake_case `task_id`/`total_tokens`/`tool_uses`/`duration_ms`
|
|
@@ -1075,6 +1155,14 @@ export type TaskEvent = ({
|
|
|
1075
1155
|
export type HumanInputEvent = Extract<TaskEvent, {
|
|
1076
1156
|
type: "human_input";
|
|
1077
1157
|
}>;
|
|
1158
|
+
/** One attachment on a `human_input` frame: its position, the kind the engine found (absent when the read was refused
|
|
1159
|
+
* before the kind was known), what reached the model of its contents, and the path or name it was declared with. */
|
|
1160
|
+
export interface HumanInputAttachment {
|
|
1161
|
+
readonly ordinal: number;
|
|
1162
|
+
readonly kind?: UserAttachmentKind;
|
|
1163
|
+
readonly outcome: UserAttachmentOutcome;
|
|
1164
|
+
readonly label: string;
|
|
1165
|
+
}
|
|
1078
1166
|
/**
|
|
1079
1167
|
* Outcome of a manual {@link TaskStream.compact} request (the enum names align with
|
|
1080
1168
|
* the diagnosis decision tree's drain exits, so a consumer can tell "202 processed" states apart):
|
package/dist/core/task-spec.d.ts
CHANGED
|
@@ -31,6 +31,39 @@ export type ImageInput = {
|
|
|
31
31
|
/** URL the runner will fetch and inline as base64 before sending to the model. */
|
|
32
32
|
url: string;
|
|
33
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* One file the user attached to the objective, by WHO HOLDS ITS BYTES (never by what kind of file it is — the engine
|
|
36
|
+
* finds that out and reports it):
|
|
37
|
+
* - `{ path, lines? }` — a file or directory the engine can reach in its workspace: the engine reads it through the
|
|
38
|
+
* Read tool's own read and admission (read-deny table, roots, the run's deny rules), as if the model had read it,
|
|
39
|
+
* minus the questions — the user's declaration is the answer to an ordinary ask; a read some layer would put to a
|
|
40
|
+
* person other than the asker (an organization rule, a deployment-authored or real-approval ask) is not attached.
|
|
41
|
+
* `lines` reads a line range (1-based, `end` inclusive).
|
|
42
|
+
* - `{ name, text, startLine? }` — text the host holds (a local file a remote engine cannot reach, an unsaved buffer):
|
|
43
|
+
* delivered as given, line-numbered from `startLine` (default 1). It opens nothing an objective could not carry,
|
|
44
|
+
* and records no read state.
|
|
45
|
+
* - `{ name, image: { data, mimeType } }` — an image file the host holds (base64), admitted like an image the Read tool
|
|
46
|
+
* serves.
|
|
47
|
+
* Each attachment reaches the model as its own message right after the objective, marked as the engine's: two
|
|
48
|
+
* marked sentences around the data, the name or path only in the data. See `USER_ATTACHMENT_SEAT` for the limits.
|
|
49
|
+
*/
|
|
50
|
+
export type UserAttachment = {
|
|
51
|
+
readonly path: string;
|
|
52
|
+
readonly lines?: {
|
|
53
|
+
readonly start: number;
|
|
54
|
+
readonly end?: number;
|
|
55
|
+
};
|
|
56
|
+
} | {
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly text: string;
|
|
59
|
+
readonly startLine?: number;
|
|
60
|
+
} | {
|
|
61
|
+
readonly name: string;
|
|
62
|
+
readonly image: {
|
|
63
|
+
readonly data: string;
|
|
64
|
+
readonly mimeType: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
34
67
|
/** A single self-contained task with its full configuration. */
|
|
35
68
|
/** The shell-gate FLOOR vocabulary — {@link TaskSpec.shellGate}'s value set, the word the engine persists on a
|
|
36
69
|
* shell-gated ask (`RiskDescriptor.shellGateDoctrine`) and carries down a delegation chain. One value: `"always"`
|
|
@@ -133,6 +166,17 @@ export interface TaskSpec {
|
|
|
133
166
|
interactiveQuestionFallback?: boolean;
|
|
134
167
|
/** Optional images attached to this turn's user message (model must support vision). */
|
|
135
168
|
images?: ImageInput[];
|
|
169
|
+
/**
|
|
170
|
+
* Files the user attached to this objective ({@link UserAttachment}): at most 20, delivered after the
|
|
171
|
+
* UserPromptSubmit hook lets the objective through (a hook that blocks it reads nothing), each as its own
|
|
172
|
+
* engine-minted message right after the objective. A path entry needs a workspace (hands on). A malformed entry,
|
|
173
|
+
* a text entry over the Read limit (100 000 rendered characters), an image the API would not accept, a path entry
|
|
174
|
+
* on a run without a workspace, or any entry on a durable resume leg is refused at the door:
|
|
175
|
+
* `config.user_attachment_invalid`, the message opening with the field path (`TaskSpec.userAttachments[2].text: …`).
|
|
176
|
+
* A file the engine may not read is not refused: its message says it was not attached and why, and the
|
|
177
|
+
* `human_input` event's `attachments[]` reports each outcome.
|
|
178
|
+
*/
|
|
179
|
+
userAttachments?: readonly UserAttachment[];
|
|
136
180
|
/** Reuse an existing in-memory session for chat continuity; omit to start fresh. */
|
|
137
181
|
sessionId?: string;
|
|
138
182
|
/**
|
|
@@ -44,7 +44,7 @@ export interface TaskToolCapabilities {
|
|
|
44
44
|
/** TaskStop accepts a background agent's spawn NAME as task_id (registry name resolution only). */
|
|
45
45
|
nameAddressing: boolean;
|
|
46
46
|
}
|
|
47
|
-
/** Full-capability profile = the registry-backed mount with notifications wired (CC
|
|
47
|
+
/** Full-capability profile = the registry-backed mount with notifications wired (CC 209 verbatim form). */
|
|
48
48
|
export declare const REGISTRY_TASK_TOOL_CAPS: TaskToolCapabilities;
|
|
49
49
|
/** The env-direct thin-shell profile: cursor polling over a background shell, nothing else. */
|
|
50
50
|
export declare const ENV_DIRECT_TASK_TOOL_CAPS: TaskToolCapabilities;
|
|
@@ -97,8 +97,22 @@ export const TOOL_CATALOG_ENTRIES = [
|
|
|
97
97
|
compactable: true,
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
|
-
{
|
|
101
|
-
|
|
100
|
+
{
|
|
101
|
+
id: "repo-map", name: "RepoMap", source: "builtin", definedIn: "src/tools/fs/repo-map.ts", mountedBy: ["hands"], cards: ["repo-map"],
|
|
102
|
+
face: {
|
|
103
|
+
family: "search", effect: "read", contract: c("core.repo_map@1"),
|
|
104
|
+
pathTarget: { param: "path", access: "read", base: "root", absent: "base" },
|
|
105
|
+
ruleFace: { params: ["path", "max_chars", "max_files"] },
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: "lsp", name: "LSP", source: "builtin", definedIn: "src/core/lsp.ts", mountedBy: ["hands"], cards: [],
|
|
110
|
+
face: {
|
|
111
|
+
family: "search", effect: "read", contract: c("core.lsp@1"),
|
|
112
|
+
pathTarget: { param: "filePath", access: "read", base: "cwd", absent: "none" },
|
|
113
|
+
ruleFace: { params: ["operation", "filePath", "line", "character", "query"] },
|
|
114
|
+
},
|
|
115
|
+
},
|
|
102
116
|
{
|
|
103
117
|
id: "artifact", name: ARTIFACT_TOOL_NAME, source: "builtin", definedIn: "src/tools/artifact/artifact-tool.ts", mountedBy: ["optional"], cards: ["artifact"],
|
|
104
118
|
face: { family: "other", effect: "write", contract: c("core.artifact@1"), ruleFace: { primaryParams: ["action"] }, renderHints: { summaryParams: ["action", "file_path", "url"] } },
|
|
@@ -234,6 +234,9 @@ export interface EngineAttestation {
|
|
|
234
234
|
readonly unresolvableCause?: import("./ask-unresolvable-notice.js").AskUnresolvableCause;
|
|
235
235
|
/** The classes of the asks a policy fold collapsed — the proof behind a decision's `foldedAskClasses`. */
|
|
236
236
|
readonly foldedClasses?: readonly import("./ask-origin.js").AskClass[];
|
|
237
|
+
/** Where a path deny row refused the call — the row, the view of the target it met, the face the call is on. The gate's
|
|
238
|
+
* exit mints the refusal's card from it; the judge that found the row is its only writer. */
|
|
239
|
+
readonly pathDenial?: import("../tools/fs/safety.js").PathDenialEvidence;
|
|
237
240
|
}
|
|
238
241
|
/** The members a station attests — everything but the call binding. */
|
|
239
242
|
export type AttestationMembers = Omit<EngineAttestation, "toolCallId" | "toolName">;
|
|
@@ -302,6 +305,8 @@ export declare function screenApproverAttribution(v: unknown): {
|
|
|
302
305
|
approver?: string;
|
|
303
306
|
defect?: string;
|
|
304
307
|
};
|
|
308
|
+
/** An integrity guard an ask stands on ({@link PermissionResult}'s `guards`). */
|
|
309
|
+
export type AskGuard = "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "artifact_shared_read";
|
|
305
310
|
/**
|
|
306
311
|
* A three-state permission decision for a tool call (design/37). Upgrades the old two-state
|
|
307
312
|
* `{allow|deny}`:
|
|
@@ -327,11 +332,13 @@ export declare function screenApproverAttribution(v: unknown): {
|
|
|
327
332
|
* record ({@link EngineAttestation}) the receipt refuses in any other form, and the gate's exit mints the one
|
|
328
333
|
* settlement record ({@link import("./gate-outcome.js").GateOutcome}) from it; a policy that puts a `settledBy`
|
|
329
334
|
* or `approver` member on its verdict is putting an unread property on it.
|
|
330
|
-
* RB-479-B① (ruled 2026-08-02): the legacy `reason` field is REMOVED — one name for one thing.
|
|
335
|
+
* RB-479-B① (ruled 2026-08-02): the legacy `reason` field is REMOVED — one name for one thing. The ask arm's one-word
|
|
336
|
+
* `guard` is retired the same way, for `guards`.
|
|
331
337
|
*
|
|
332
338
|
* The TYPE carries that retirement only where a decision is a literal in an annotated position; an inferred `check`
|
|
333
|
-
* return compiles green with a stray `reason`, so the enforcement is at RUNTIME — every point that consumes a
|
|
334
|
-
* refuses one
|
|
339
|
+
* return compiles green with a stray `reason` or `guard`, so the enforcement is at RUNTIME — every point that consumes a
|
|
340
|
+
* decision refuses one that carries a retired member ({@link RETIRED_DECISION_MEMBERS}), fail-closed
|
|
341
|
+
* ({@link refuseOutOfContractDecision}).
|
|
335
342
|
*/
|
|
336
343
|
export type PermissionResult = {
|
|
337
344
|
action: "allow";
|
|
@@ -454,18 +461,21 @@ export type PermissionResult = {
|
|
|
454
461
|
/** The ask's whole class set, in {@link import("./ask-origin.js").ASK_CLASSES} order (see
|
|
455
462
|
* {@link AskRequest.classes}). Stamped beside {@link askClass}, under the same rule. */
|
|
456
463
|
classes?: readonly import("./ask-origin.js").AskClass[];
|
|
457
|
-
/** WHICH integrity
|
|
458
|
-
* shell text the engine cannot read or
|
|
459
|
-
*
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
|
|
464
|
+
/** WHICH integrity guards stand behind this ask — a removal of a protected location, an unverifiable recursive delete,
|
|
465
|
+
* shell text the engine cannot read (or an environment that did not answer the read station), the session-transcript
|
|
466
|
+
* write. A set: one ask may stand on several, and each keeps its class. ENGINE-STAMPED by the guard policies and the
|
|
467
|
+
* gate fold; a fold-internal fact the class derivation reads ({@link import("./ask-origin.js").classifyAsk}) so the
|
|
468
|
+
* guards, which mint the same `requiresRealApproval` ask, are told apart by a fact and not by their prose. Never
|
|
469
|
+
* copied onto the approval request or the park row. Replaces the one-word `guard`, which a decision no longer carries:
|
|
470
|
+
* a decision that still does is refused by name ({@link RETIRED_DECISION_MEMBERS}). */
|
|
471
|
+
guards?: readonly AskGuard[];
|
|
463
472
|
/** The call could not be READ against a rule that may reach it — a content-form deny row, a content-form
|
|
464
|
-
* ask row,
|
|
465
|
-
*
|
|
473
|
+
* ask row, a persisted-rule row (the lexer's word), or rows the shell read station's boundary stands on that
|
|
474
|
+
* could not be read (`persisted_rows`). ENGINE-STAMPED at the four unreadable mint sites;
|
|
475
|
+
* the class derivation reads it as `rule_unreadable` (no mode releases it, a person may clear it, no
|
|
466
476
|
* automatic lane may). It replaces the former practice of stamping `matchedAskRule` on an unreadable
|
|
467
477
|
* read: a rule that COULD NOT be matched is not a rule that matched. Fold-internal; not on the request. */
|
|
468
|
-
ruleUnreadable?: "content_deny" | "content_ask" | "persisted_call";
|
|
478
|
+
ruleUnreadable?: "content_deny" | "content_ask" | "persisted_call" | "persisted_rows";
|
|
469
479
|
/** The ask was authored by the DEPLOYMENT's own governance (an operator's must-ask list, a managed command
|
|
470
480
|
* policy's default ask) — a fact a host's policy states on its own ask so the class derivation reads it
|
|
471
481
|
* as `operator_forced`: a permission mode releases nothing an operator mandated (`dontAsk` refuses it like
|
|
@@ -853,8 +863,8 @@ export declare const DECISION_MEMBERS: readonly DecisionMember[];
|
|
|
853
863
|
* taken off the carrier's own descriptor (a member outside the contract is neither read nor carried — a policy's self-declared
|
|
854
864
|
* record on another name finds no reader); any other spelling refused by name — an accessor (never invoked), a member the
|
|
855
865
|
* prototype or a non-enumerable property supplies unless that descriptor spells absence (an `undefined` data value) — judged by
|
|
856
|
-
* descriptor, never read; (3)
|
|
857
|
-
*
|
|
866
|
+
* descriptor, never read; (3) a retired member ({@link RETIRED_DECISION_MEMBERS}: `reason`, `guard`) carried by the same presence law as a contract
|
|
867
|
+
* member — own, held by an accessor, or supplied by the prototype — judged without a read (ignoring it silently dropped the policy's text or the ask's guard); (4) the VALUES, off the engine's
|
|
858
868
|
* one-read record, never a second read of the caller's object — the retired window absent, `action` in
|
|
859
869
|
* its closed set (`screenContractValues`, decision-receipt.ts — every closed-set member is held to its set there; a consumer ranks a decision by testing two of its words, so any other value used to rank as an
|
|
860
870
|
* allow; a `canUseTool` result outside its set is a failure in CC) and `decisionReason` in {@link DECISION_REASONS} when
|
|
@@ -1085,7 +1095,7 @@ export declare function createCoarseCommandNamePolicy(opts: {
|
|
|
1085
1095
|
tools?: string[];
|
|
1086
1096
|
}): ToolPolicy;
|
|
1087
1097
|
/**
|
|
1088
|
-
* CC 220 "Unverifiable Deletion Target" parity (auto-mode rule): ASK on a recursive+forced delete whose
|
|
1098
|
+
* CC 220 "Unverifiable Deletion Target" parity (auto-mode rule; its text is in 220–245, gone from 2.1.250 on): ASK on a recursive+forced delete whose
|
|
1089
1099
|
* target is a variable / substitution that cannot be resolved from the command itself — fail-closed in the
|
|
1090
1100
|
* sense that with no live classifier/approver the ask degrades to deny (see {@link PermissionResult}'s
|
|
1091
1101
|
* `ask` doc), never to allow. The guard reads ONE plan, the read station's (`removalReadingOf`,
|
package/dist/core/tool-policy.js
CHANGED
|
@@ -16,7 +16,7 @@ import { boundInputHashOf } from "./canonical-json.js";
|
|
|
16
16
|
import { delimitUntrusted, inlineUntrusted, REVIEWER_NOTE_MAX_BODY } from "./untrusted-text.js";
|
|
17
17
|
import { describeRejectedValue } from "./tool-search-setting.js";
|
|
18
18
|
import { thrownText } from "./thrown-value.js";
|
|
19
|
-
import { assertNoRetiredToolPolicyKeys } from "./retired-keys.js";
|
|
19
|
+
import { assertNoRetiredToolPolicyKeys, RETIRED_DECISION_MEMBERS } from "./retired-keys.js";
|
|
20
20
|
import { isEngineRefusal, nestedRecordsOf, receiveContract, receiveNestedRecords, refusedOutOfContract, screenContractValues } from "./decision-receipt.js";
|
|
21
21
|
export { isEngineRefusal } from "./decision-receipt.js";
|
|
22
22
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers, parsePermissionRule } from "./permission-rules.js";
|
|
@@ -43,6 +43,7 @@ const ATTESTATION_GROUP_OF = {
|
|
|
43
43
|
classifierRound: "classifierRound",
|
|
44
44
|
unresolvableCause: "unresolvableCause",
|
|
45
45
|
foldedClasses: "foldedClasses",
|
|
46
|
+
pathDenial: "pathDenial",
|
|
46
47
|
};
|
|
47
48
|
const ATTESTATION_MEMBERS = Object.keys(ATTESTATION_GROUP_OF);
|
|
48
49
|
const groupLead = (g) => ATTESTATION_MEMBERS.find((k) => ATTESTATION_GROUP_OF[k] === g);
|
|
@@ -238,18 +239,15 @@ export function constraintChainDigest(chain) {
|
|
|
238
239
|
}
|
|
239
240
|
const ALLOW = Object.freeze({ action: "allow" });
|
|
240
241
|
const ALLOW_BY_RULE = Object.freeze({ action: "allow", decisionReason: "rule" });
|
|
241
|
-
const RETIRED_TEXT_FIELD = "reason";
|
|
242
242
|
export const DECISION_MEMBERS = Object.keys({
|
|
243
243
|
action: 0, updatedInput: 0, message: 0, decisionReason: 0, requiresRealApproval: 0, denialLimitFallback: 0, classifierNoRuling: 0, allowRuleShadowed: 0, probeReason: 0,
|
|
244
244
|
probeCause: 0, probeMandated: 0, mandated: 0, mandate: 0, probeReadRootCandidate: 0, matchedAskRule: 0, ruleEvidence: 0, segmentCoverage: 0,
|
|
245
|
-
origin: 0, askClass: 0, classes: 0,
|
|
245
|
+
origin: 0, askClass: 0, classes: 0, guards: 0, ruleUnreadable: 0, authoredBy: 0, foldedAskClasses: 0, attestation: 0,
|
|
246
246
|
});
|
|
247
247
|
const HOOK_RESULT_MEMBERS = [...DECISION_MEMBERS, "additionalContext"];
|
|
248
248
|
const HOOK_SEAM_UNREAD = new Set(["decisionReason"]);
|
|
249
249
|
const HOOK_SEAM_OPTIONAL = new Set(["action"]);
|
|
250
250
|
const HOOK_RECEIPTS = new WeakSet();
|
|
251
|
-
const RETIRED_TEXT_FIELD_DENY_MESSAGE = `a permission decision carries the retired "${RETIRED_TEXT_FIELD}" field — rename it to "message" (the one text field ` +
|
|
252
|
-
`a decision carries); denied fail-closed rather than executing a decision whose text this layer cannot read`;
|
|
253
251
|
const ENGINE_RECEIPTS = new WeakSet();
|
|
254
252
|
export function refuseOutOfContractDecision(d, opts) {
|
|
255
253
|
const hookSeam = opts?.reasonIsNonInput === true;
|
|
@@ -260,11 +258,9 @@ export function refuseOutOfContractDecision(d, opts) {
|
|
|
260
258
|
}
|
|
261
259
|
if ((hookSeam ? HOOK_RECEIPTS : ENGINE_RECEIPTS).has(d) || isEngineRefusal(d))
|
|
262
260
|
return d;
|
|
263
|
-
const decision = receiveContract(d, hookSeam ? HOOK_RESULT_MEMBERS : DECISION_MEMBERS, "");
|
|
261
|
+
const decision = receiveContract(d, hookSeam ? HOOK_RESULT_MEMBERS : DECISION_MEMBERS, "", RETIRED_DECISION_MEMBERS);
|
|
264
262
|
if (decision.kind === "refused")
|
|
265
263
|
return decision.refused;
|
|
266
|
-
if (Object.prototype.hasOwnProperty.call(d, RETIRED_TEXT_FIELD))
|
|
267
|
-
return refusedOutOfContract(RETIRED_TEXT_FIELD_DENY_MESSAGE);
|
|
268
264
|
const contract = decision.held;
|
|
269
265
|
const refused = receiveNestedRecords(contract) ?? screenContractValues(contract, hookSeam ? { skip: HOOK_SEAM_UNREAD, optional: HOOK_SEAM_OPTIONAL } : undefined);
|
|
270
266
|
if (refused !== undefined)
|
|
@@ -293,9 +289,9 @@ export function refuseOutOfContractDecision(d, opts) {
|
|
|
293
289
|
`the engine keeps its own copy of what it read; denied fail-closed`);
|
|
294
290
|
}
|
|
295
291
|
const receipt = Object.freeze(attestation !== undefined ? { ...detached.value, attestation } : detached.value);
|
|
296
|
-
for (const
|
|
297
|
-
if (
|
|
298
|
-
Object.freeze(
|
|
292
|
+
for (const v of Object.values(receipt))
|
|
293
|
+
if (Array.isArray(v))
|
|
294
|
+
Object.freeze(v);
|
|
299
295
|
for (const record of nestedRecordsOf(receipt)) {
|
|
300
296
|
for (const v of Object.values(record))
|
|
301
297
|
if (Array.isArray(v))
|
|
@@ -711,7 +707,7 @@ function removalAsk(guard, text) {
|
|
|
711
707
|
unverifiable_delete: `Unverifiable recursive delete (fail-closed unless cleared): ${text}. Re-run the delete with the resolved literal path written into the command itself (or assign the variable a literal path in the same command, e.g. \`DIR=/exact/path; rm -rf "$DIR"\`) so the target can be verified.`,
|
|
712
708
|
unverifiable_shell_text: `Unverifiable shell text (fail-closed unless cleared): ${text}. Write the text into the command itself (a \`-c\` string, a here-document or a here-string) and the engine reads it as it reads any command.`,
|
|
713
709
|
};
|
|
714
|
-
return { action: "ask", decisionReason: "safety", requiresRealApproval: true, guard, message: messages[guard] };
|
|
710
|
+
return { action: "ask", decisionReason: "safety", requiresRealApproval: true, guards: [guard], message: messages[guard] };
|
|
715
711
|
}
|
|
716
712
|
function pathSegments(p) {
|
|
717
713
|
return p.split(/[\\/]/).filter(Boolean);
|
|
@@ -784,7 +780,7 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
784
780
|
action: "ask",
|
|
785
781
|
decisionReason: "safety",
|
|
786
782
|
requiresRealApproval: true,
|
|
787
|
-
|
|
783
|
+
guards: ["transcript_write"],
|
|
788
784
|
message: `Session-transcript write (fail-closed unless cleared): ${what}. Session transcripts (the .jsonl files ` +
|
|
789
785
|
`under the agent data dir's sessions/ directory) are harness-written session state, not agent working ` +
|
|
790
786
|
`files — modifying or deleting them tampers with the run's own audit trail. Reading them (ls/cat/grep ` +
|
package/dist/core/trace.d.ts
CHANGED
|
@@ -475,8 +475,9 @@ export type TraceEvent = {
|
|
|
475
475
|
} | {
|
|
476
476
|
/**
|
|
477
477
|
* design/179 — the person's persisted rule store could not be read (at prepare, or for one call), so
|
|
478
|
-
* that read's rows took no part:
|
|
479
|
-
* per-read record; the person hears it once per run
|
|
478
|
+
* that read's rows took no part: a call it served was judged without them — and, at a call, asks a person (the
|
|
479
|
+
* rows could hold a deny). The operator's per-read record; the person hears it once per run
|
|
480
|
+
* (`permission.rule_store_unavailable`).
|
|
480
481
|
*/
|
|
481
482
|
kind: "permission.rule_store_unreadable";
|
|
482
483
|
version: 1;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type { AgentTool, ThinkingLevel, ToolInputValidationContext, ToolInputVer
|
|
|
13
13
|
import type { Model, StreamFn } from "../internal/llm.js";
|
|
14
14
|
export type { ModelRef, ModelRole, RoleSpec, ModelRoles, Brain } from "./model-seat.js";
|
|
15
15
|
export { MODEL_ROLES } from "./model-seat.js";
|
|
16
|
-
export type { StaleToolResultOffloadOptions, ImageInput, TaskSpec, ShellGateDoctrine } from "./task-spec.js";
|
|
16
|
+
export type { StaleToolResultOffloadOptions, ImageInput, TaskSpec, ShellGateDoctrine, UserAttachment } from "./task-spec.js";
|
|
17
17
|
export type { PermissionMode } from "./ask-origin.js";
|
|
18
18
|
export type { ToolEffect, ToolContentOrigin, ReversibilityVerdict, ReadRootGrantCandidate, ToolSpec, ToolReturn, NestedUsage, NestedUsageAccum, ToolExecuteContext } from "./tool-spec.js";
|
|
19
19
|
export type { BeforeWriteRequest, BeforeWriteResult, BeforeWriteHook, TrackEditRequest, TrackEditResult, TrackFileEditHook, FileEditedNotice, FileEditedHook, HandsBandOptions } from "./hands-band.js";
|
|
@@ -22,12 +22,12 @@ export type { McpServerSpec, A2aServerSpec, McpElicitRequest, McpElicitResponse,
|
|
|
22
22
|
export type { TaskLimits } from "./task-limits.js";
|
|
23
23
|
export type { TaskStatus, RemoteEnvFailureNote, EffectiveMemoryScopes, TaskResult, HumanReviewGateRow } from "./task-result.js";
|
|
24
24
|
export type { TerminalCause, PausedCause } from "./terminal-cause.js";
|
|
25
|
-
export type { TaskEventIdentity, BrainStatusPhase, BrainRetryErrClass, BrainStatus, ToolActivity, HumanInputSource, HumanInputDelivery, DelegationTaskType, TaskEvent, HumanInputEvent, CompactOutcome } from "./task-event.js";
|
|
25
|
+
export type { TaskEventIdentity, BrainStatusPhase, BrainRetryErrClass, BrainStatus, ToolActivity, HumanInputSource, HumanInputDelivery, DelegationTaskType, TaskEvent, HumanInputEvent, HumanInputAttachment, CompactOutcome } from "./task-event.js";
|
|
26
26
|
export type { TaskStream } from "./task-stream.js";
|
|
27
27
|
export type { WorkflowGovernanceBaseline, RuntimeCaps, AutoModeDenySource } from "./runtime-caps.js";
|
|
28
28
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
29
29
|
export type { BackgroundChildEvent, DelegationLifecycleEvent } from "./delegation-frames.js";
|
|
30
|
-
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
30
|
+
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle, emitsChildRowFrames, taskStartedFrame } from "./delegation-frames.js";
|
|
31
31
|
export type { ProjectMemoryLoad, ResumePreflightInfo, ResumePreflightVerdict, RunnerDeps } from "./runner-deps.js";
|
|
32
32
|
export type { EngineNotice, OwedUserInputAccount, UserInputUndrainedCause } from "./engine-notice.js";
|
|
33
33
|
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, parentLegIds, settleOwedUserInput, undrainedUserInputNotices, USER_INPUT_UNDRAINED_CAUSES, USER_INPUT_UNDRAINED_FAMILIES } from "./engine-notice.js";
|
package/dist/core/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { MODEL_ROLES } from "./model-seat.js";
|
|
2
2
|
export { AUTO_MODE_DENY_SOURCES, isAutoModeDenySource } from "./runtime-caps.js";
|
|
3
|
-
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle } from "./delegation-frames.js";
|
|
3
|
+
export { __resetMalformedDelegationSeatAnnouncement, deliverDelegationLifecycle, emitsChildRowFrames, taskStartedFrame } from "./delegation-frames.js";
|
|
4
4
|
export { __resetMalformedNoticeSeatAnnouncement, deliverEngineNotice, owedUserInputCounts, parentLegIds, settleOwedUserInput, undrainedUserInputNotices, USER_INPUT_UNDRAINED_CAUSES, USER_INPUT_UNDRAINED_FAMILIES } from "./engine-notice.js";
|
|
@@ -330,8 +330,8 @@ export declare function cutEngineSegments(text: string, segments: unknown): {
|
|
|
330
330
|
* offsets are DEFINED: a user-lane message qualifies only when its content is a plain string or a
|
|
331
331
|
* SINGLE text block (whose text is that same string). Multi-block / image-bearing content returns
|
|
332
332
|
* `undefined` and consumers render the message VERBATIM with their own local flatten — the two
|
|
333
|
-
* projection sides flatten blocks DIFFERENTLY (the auto-mode window joins with `\n` + `[image]`
|
|
334
|
-
*
|
|
333
|
+
* projection sides flatten blocks DIFFERENTLY (the auto-mode window joins with `\n` + `[image: …]`
|
|
334
|
+
* block markers; the compaction serializer drops non-text blocks and joins with no separator), so a
|
|
335
335
|
* single `[start, end)` range would point at different characters on each side. The restriction
|
|
336
336
|
* costs nothing real: every engine-assembled prefixed/segmented message (first-frame objective
|
|
337
337
|
* concatenation, resume continuation) is minted from ONE plain string — the sole exception is a
|