@sema-agent/core 5.36.0 → 5.38.0

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 (56) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/dist/agents/subagent.d.ts +10 -0
  3. package/dist/agents/subagent.js +6 -0
  4. package/dist/agents/teacher.js +3 -0
  5. package/dist/agents/team.d.ts +7 -1
  6. package/dist/agents/team.js +11 -9
  7. package/dist/agents/verify.js +3 -0
  8. package/dist/core/auto-mode-prompt-assets.d.ts +5 -3
  9. package/dist/core/auto-mode-prompt-assets.js +1 -1
  10. package/dist/core/checkpoint-store.d.ts +26 -1
  11. package/dist/core/governance-codes.js +4 -0
  12. package/dist/core/hooks.d.ts +129 -2
  13. package/dist/core/hooks.js +20 -3
  14. package/dist/core/memory-engine/engine.d.ts +142 -0
  15. package/dist/core/memory-engine/engine.js +264 -2
  16. package/dist/core/memory-engine/file-backend.d.ts +490 -16
  17. package/dist/core/memory-engine/file-backend.js +1099 -36
  18. package/dist/core/memory-engine/index.d.ts +2 -2
  19. package/dist/core/memory-engine/index.js +1 -1
  20. package/dist/core/memory-engine/layout.d.ts +42 -2
  21. package/dist/core/memory-engine/layout.js +76 -12
  22. package/dist/core/memory-engine/memory-backend-contract.d.ts +13 -0
  23. package/dist/core/memory-engine/memory-backend-contract.js +89 -0
  24. package/dist/core/protocol-table.d.ts +4 -4
  25. package/dist/core/runner/assemble-result.d.ts +5 -0
  26. package/dist/core/runner/assemble-result.js +1 -1
  27. package/dist/core/runner/prepare-config-doors.d.ts +17 -0
  28. package/dist/core/runner/prepare-config-doors.js +33 -2
  29. package/dist/core/runner/prepare-memory.d.ts +11 -1
  30. package/dist/core/runner/prepare-memory.js +48 -2
  31. package/dist/core/runner/prepare-task.d.ts +22 -2
  32. package/dist/core/runner/prepare-task.js +125 -42
  33. package/dist/core/runner/runtask.js +50 -11
  34. package/dist/core/tool-model-gate.d.ts +125 -0
  35. package/dist/core/tool-model-gate.js +303 -0
  36. package/dist/core/tool-policy.d.ts +1 -1
  37. package/dist/core/types.d.ts +284 -1
  38. package/dist/core/types.js +21 -0
  39. package/dist/core/untrusted-text.d.ts +1 -1
  40. package/dist/index.d.ts +5 -4
  41. package/dist/index.js +3 -2
  42. package/dist/orchestration/builtin-workflows.d.ts +68 -6
  43. package/dist/orchestration/builtin-workflows.js +26 -9
  44. package/dist/orchestration/run-workflow-tool.d.ts +10 -1
  45. package/dist/orchestration/run-workflow-tool.js +70 -27
  46. package/dist/orchestration/workflow-script-store.d.ts +8 -3
  47. package/dist/prompts/coordinator.d.ts +4 -1
  48. package/dist/prompts/coordinator.js +8 -0
  49. package/dist/prompts/default.d.ts +14 -4
  50. package/dist/prompts/default.js +2 -1
  51. package/dist/scenarios/full-body.d.ts +5 -0
  52. package/dist/scenarios/full-body.js +8 -4
  53. package/dist/tools/fs/fs-shared.d.ts +3 -2
  54. package/dist/tools/fs/fs-shared.js +19 -9
  55. package/package.json +1 -1
  56. package/test/export-surface.snapshot.json +24 -1
@@ -381,6 +381,25 @@ export interface ToolSpec<TParams extends TSchema = TSchema> {
381
381
  * Exclusion still wins ({@link TaskSpec.excludeTools} unmounts — nothing left to keep inline).
382
382
  */
383
383
  alwaysLoad?: boolean;
384
+ /**
385
+ * design/277 — model-gate CLASS tag (open vocabulary; the built-in table is
386
+ * {@link import("./tool-model-gate.js").TOOL_MODEL_GATE_CLASSES}, v1 vocabulary =
387
+ * `"task-scaffold"`). A tagged entry declares "I am a default-mounted scaffold of this class":
388
+ * at prepare, when the task's RESOLVED model id matches the class's rule, THIS entry is dropped
389
+ * from the roster (true unmount, entry-level — a same-name untagged entry is untouched; the
390
+ * removed entry stops occupying its name on every downstream surface). Untagged = never gated.
391
+ * The default-bundle assemblers stamp their default arms only; an EXPLICITLY composed tool is
392
+ * not tagged (user asked ⇒ user gets) — so don't stamp hand-mounted factories. FAIL-OPEN: an id
393
+ * the merged table knows nothing about is never gated (BYOM open set — the table encodes
394
+ * positive knowledge only), and a tag naming an unknown class is inert + announced
395
+ * (`config.tool_model_gate_unknown_class`). Restore channels: explicit composition (no tag),
396
+ * {@link TaskSpec.restoreGatedTools}, env `SEMA_TOOL_MODEL_GATE=off`,
397
+ * `RunnerDeps.toolModelGate: false`; {@link TaskSpec.excludeTools} always wins regardless.
398
+ * The materialized `AgentTool` face does NOT carry this field (`defineTool` is a whitelist
399
+ * constructor) — the decision completes on the ToolSpec face inside `prepareConfigDoors`,
400
+ * before any conversion.
401
+ */
402
+ modelGate?: string;
384
403
  /**
385
404
  * Tool contract identity (campaign S2, prompt-assembly protocol §7): declares the EXECUTION
386
405
  * CONTRACT this tool implements, independent of its presentation text. `defineTool` attaches it
@@ -751,6 +770,13 @@ export interface ToolExecuteContext {
751
770
  * X arrives deferred, the exemption having been dropped in transit — which is the one outcome the
752
771
  * parent explicitly ruled out. Children merge this with their own spec value. */
753
772
  alwaysLoadTools?: readonly string[];
773
+ /** design/277 — the model-gate restore selector ({@link TaskSpec.restoreGatedTools}), inherited
774
+ * down the delegation tree on the same trusted seat as the three tool-face controls above
775
+ * (Runner-filled, read-only, frozen snapshot). Restoration is a TASK-TREE intent ("this work
776
+ * wants the scaffold back") and each child re-judges the gate under its OWN resolved model —
777
+ * dropping the selector in transit would trim a same-model child's roster in a way nobody
778
+ * chose (the gate is a default, not a policy; there is no tighten-only axis to protect). */
779
+ restoreGatedTools?: readonly string[] | true;
754
780
  /** R2 双形轴 — the parent's resolved prompt profile, inherited down the delegation tree like the
755
781
  * tool-face controls (Runner-filled): a classic-profile parent's children speak classic too
756
782
  * unless the child spec says otherwise (child spec wins — profile is presentation, not policy). */
@@ -1867,6 +1893,24 @@ export interface TaskSpec {
1867
1893
  * wins — an unmounted tool has no schema to keep inline).
1868
1894
  */
1869
1895
  alwaysLoadTools?: string[];
1896
+ /**
1897
+ * design/277 — per-task restore valve for the tool-registration MODEL GATE. The gate trims
1898
+ * default-mounted scaffold entries (tagged via {@link ToolSpec.modelGate}) from the roster when
1899
+ * the task's resolved model id matches the gate table — this valve opts the task (and its whole
1900
+ * delegation tree — the selector inherits down like `excludeTools`) back in:
1901
+ * · an ARRAY of wire names — naming ANY tagged tool restores that tool's WHOLE class for this
1902
+ * task (CC parity: opting into any member of the family restores the family). Judged against
1903
+ * the full stamp set, so a name that `excludeTools` also lists still works as a class
1904
+ * SELECTOR — while the exclusion itself still wins for that name (exclusion is the final
1905
+ * valve; no restore channel resurrects an excluded name). Unknown names are inert (a
1906
+ * center-distributed list may be a superset), same posture as `excludeTools`.
1907
+ * · literal `true` — every gate class restored for this task (the shortest "this task wants
1908
+ * all its scaffolding" spelling for center-distributed specs).
1909
+ * A malformed value refuses at prepare (`config.tool_model_gate_invalid`, #123) — garbage must
1910
+ * not silently read as "restore nothing" in the trimming direction. Absent = the gate's verdict
1911
+ * stands. Explicit composition needs no valve: a hand-mounted (untagged) tool is never gated.
1912
+ */
1913
+ restoreGatedTools?: string[] | true;
1870
1914
  /**
1871
1915
  * RB-403 — whether a schema-VALID call on a still-deferred tool runs the real tool directly
1872
1916
  * (activating it as a side effect). Default `true`, matching the upstream posture where the
@@ -2713,6 +2757,79 @@ export interface RemoteEnvFailureNote {
2713
2757
  message: string;
2714
2758
  }
2715
2759
  /** Result returned when a task finishes or gets stuck. Designed to be machine-readable for an external AI. */
2760
+ /**
2761
+ * design/178 v2 §2.3 (件①) — the value of {@link TaskResult.effectiveMemoryScopes}: the memory
2762
+ * visibility face a leg ACTUALLY ran under, as a DISCRIMINATED three-state union (deliberately no
2763
+ * `"partial"` state — the engine session is built only after every plane materialized, so a
2764
+ * half-mounted scene is a fail-open `memoryless` with residue, never a served half-face):
2765
+ *
2766
+ * - `"mounted"` — the memory engine session mounted. `scopes` is the EFFECTIVE VISIBILITY set in
2767
+ * the effective serving order, both exactly as the engine mounted them: per plane, the
2768
+ * admission-projected read layering PLUS a distinct write-only scope where one exists (the
2769
+ * engine registers the write scope's dir and its entries ride the injected index — a write-only
2770
+ * scope IS visible; the common writeScope∈scopes form dedups to the plain layering), project
2771
+ * plane first on a dual root. Each row carries its admission ORIGIN (`"deployment"` = the
2772
+ * operator's own declared set; `"request"` = the caller's spec — the two trust planes of the
2773
+ * org admission door). `writeScope` is the effective write face as granted (an org writeScope
2774
+ * not explicitly granted reads `null` here, exactly as it ran). `contract` names the
2775
+ * scope-identity contract in force (`"v2"` typed keys / `"legacy"` opaque strings).
2776
+ * SCOPE OF THE CLAIM (stated precisely): the rows are the MEMORY-ENGINE scope set this leg
2777
+ * mounted — the dirs the engine registered and indexed. They deliberately do NOT cover the
2778
+ * separate memory-adjacent faces (the shared-memory store pair, the project-context memory
2779
+ * layer — each its own surface with its own disclosure), and two REGISTERED engine-plane
2780
+ * channels can carry another scope's bytes without a row here: a root-owning scope's non-empty
2781
+ * on-disk index is served verbatim to a later mount of that root ("live file wins"),
2782
+ * and control-plane announcements carry no producing scope and drain plane-wide. Both are
2783
+ * engine mount semantics under their own tickets, disclosed here so this face is never read as
2784
+ * a complete cross-face visibility proof.
2785
+ * - `"memoryless"` — memory was configured but did not mount. `reason: "mount-failed"` = the
2786
+ * fail-open mount arm caught a fault anywhere in the mount phase (directory resolution through
2787
+ * materialize — named for the whole captured span, not one step); `reason: "no-backend"` = the
2788
+ * spec enables memory but no `RunnerDeps.memoryBackend` is configured. `materializedResidue`
2789
+ * (mount-failed only) lists plane scopes whose PHYSICAL materialize had already completed when
2790
+ * the fault hit — a LOWER bound (a plane that threw mid-materialize is not listed; on-disk
2791
+ * residue is ≥ this list), and explicitly NOT a visibility face: an auditor must never read
2792
+ * residue as mounted scopes, which is why it is a separate seat from the always-empty `scopes`.
2793
+ * - `"none"` — memory was not in play at all: `"no-spec"` = the task carries no usable memory
2794
+ * spec; `"disabled"` = a spec is present with `enabled: false`.
2795
+ *
2796
+ * Deliberate-refusal configurations (`config.memory_*` codes) fail the whole prepare and produce
2797
+ * NO observation — this union never dresses a refusal as a state. Honesty note (design r7): the
2798
+ * `?: never` members forbid non-`undefined` values at the type level; the repo does not compile
2799
+ * with `exactOptionalPropertyTypes`, so explicit-`undefined` presence is a wire-validator concern,
2800
+ * not a type-level one.
2801
+ */
2802
+ export type EffectiveMemoryScopes = {
2803
+ state: "mounted";
2804
+ reason?: never;
2805
+ contract: "v2" | "legacy";
2806
+ scopes: Array<{
2807
+ scope: string;
2808
+ origin: "deployment" | "request";
2809
+ }>;
2810
+ writeScope: string | null;
2811
+ materializedResidue?: never;
2812
+ } | {
2813
+ state: "memoryless";
2814
+ reason: "mount-failed";
2815
+ contract?: "v2" | "legacy";
2816
+ scopes: [];
2817
+ writeScope: null;
2818
+ materializedResidue?: string[];
2819
+ } | {
2820
+ state: "memoryless";
2821
+ reason: "no-backend";
2822
+ contract?: "v2" | "legacy";
2823
+ scopes: [];
2824
+ writeScope: null;
2825
+ } | {
2826
+ state: "none";
2827
+ reason: "no-spec" | "disabled";
2828
+ contract?: never;
2829
+ scopes: [];
2830
+ writeScope: null;
2831
+ materializedResidue?: never;
2832
+ };
2716
2833
  export interface TaskResult {
2717
2834
  taskId: string;
2718
2835
  /** Use this to continue the same conversation on the next call. */
@@ -2972,6 +3089,28 @@ export interface TaskResult {
2972
3089
  * governing the WORK, never the contents of any checkpoint row.
2973
3090
  */
2974
3091
  effectiveReadDenyPatterns?: readonly import("../tools/fs/read-deny.js").NormalizedReadDenyEntry[];
3092
+ /**
3093
+ * design/178 v2 §2.3 (件①) — the memory VISIBILITY face this leg actually ran under, as an
3094
+ * engine-filled OBSERVATION (never a knob: writing it on a spec does nothing). This is the
3095
+ * EFFECTIVE face, not the requested one: a refused request never reaches a terminal at all (the
3096
+ * whole prepare fails with its governance code), so what this seat answers is "what was actually
3097
+ * given" — the delta against the request is directly readable (an org writeScope not explicitly
3098
+ * granted collapses to `null` here as it did in the run; a fail-open mount failure reads
3099
+ * `memoryless`, never a dressed-up mount).
3100
+ *
3101
+ * **In-presence condition** (same law as {@link effectiveReadFace}): present on every terminal of
3102
+ * a leg that COMPLETED prepare — the memory-less states are answered as their own values
3103
+ * (`none` / `memoryless`), so consumers must never read ABSENCE as "no memory"; absence means
3104
+ * only "prepare never completed". Delegated children mint their own on their own legs (their
3105
+ * request plane can only narrow the parent's frozen org verdict); a resume leg's value is the
3106
+ * re-adjudication at resume time (admission runs in every prepare — the current-policy reading,
3107
+ * same axis as the read-face seats).
3108
+ *
3109
+ * Minted AFTER the materialize outcome, not after the admission verdict — the fail-open mount
3110
+ * arm sits between the two, and stamping earlier would report a mount that never happened.
3111
+ * See {@link EffectiveMemoryScopes} for the per-state field law.
3112
+ */
3113
+ effectiveMemoryScopes?: EffectiveMemoryScopes;
2975
3114
  /**
2976
3115
  * `turns`/`tokens`/`costMicroUsd` are this task's OWN model usage. `nested` is the summed usage of any
2977
3116
  * delegated sub-runs (sub-agents) it spawned — present only when it delegated. The true total
@@ -4345,6 +4484,93 @@ export interface BackgroundChildEvent {
4345
4484
  costMicroUsd?: number;
4346
4485
  };
4347
4486
  }
4487
+ /**
4488
+ * #281 件B — one lifecycle phase of a DELEGATED child leg, delivered to the process-level
4489
+ * {@link RunnerDeps.onDelegationLifecycle} observer: the public, deps-level home of the delegation
4490
+ * lifecycle that previously lived only on the trusted RunInternals third parameter
4491
+ * (`onSubagentSpawn` — sync lane, a steer handle whose `settled` is a void promise) and on the
4492
+ * background-lane-only {@link BackgroundChildEvent}. A deployment wired ONLY through `RunnerDeps`
4493
+ * now sees every delegation lane through one seat.
4494
+ *
4495
+ * EMISSION CHOKEPOINT (the reason this seat covers every lane at once): frames are minted by the
4496
+ * RUNNER at the child LEG itself — spawn right after the leg's `wiring_manifest` (prepared, nothing
4497
+ * run yet), terminal when the leg's `TaskResult` assembles — not by the individual spawn lanes. Every
4498
+ * delegation lane (sync/steer/background/fork/revive, workflow-spawned agents) runs its child through
4499
+ * this chokepoint, so none of them needs its own emission and none can drift.
4500
+ *
4501
+ * PER-LEG semantics, deliberately: a durable park + resume, or a retained child's revive, is a NEW
4502
+ * leg — each emits its own spawn/terminal pair, and `identity.legKind` (`"resume"`) says which cycle
4503
+ * a frame belongs to. Consumers correlate legs of one delegation by `identity.taskId` /
4504
+ * `identity.parentToolCallId` (stable across cycles).
4505
+ *
4506
+ * HONEST ABSENCES (recorded, not gaps to fix silently):
4507
+ * · a child whose PREPARE throws emits neither frame (there is no leg identity to report);
4508
+ * · the ROOT leg emits nothing here — the deployment called `runTask` itself and holds the result;
4509
+ * this seat is the delegation observer, not a run observer;
4510
+ * · a deps-only resume (`resume(token, outcome, config)` — no trusted internals re-supplied) of a
4511
+ * checkpoint minted BEFORE the delegation axis was persisted
4512
+ * ({@link import("./checkpoint-store.js").CheckpointState.isDelegatedChild}) emits neither frame:
4513
+ * the row carries no evidence the parked leg was a delegated child, and fabricating the axis
4514
+ * would stamp delegation frames onto host-resumed root tasks. Rows minted WITH the axis resume
4515
+ * with their spawn/terminal pair even deps-only; a resume that re-supplies trusted internals
4516
+ * (every in-engine lane does) was never affected.
4517
+ * PAIRING (codex r2-D2 closed the one hole): a spawn frame is always closed by a terminal frame —
4518
+ * the ordinary path emits it where the `TaskResult` assembles, and a POST-SPAWN throw that the
4519
+ * stream layer converts into a synthesized failed result (e.g. `resume.tool_unavailable` re-thrown
4520
+ * past the run tail) emits the failed terminal from that backstop, gated on a carrier that is set
4521
+ * only after the spawn emission and cleared by the ordinary terminal (so the two sites can never
4522
+ * both fire for one leg). A leg whose PROCESS dies mid-flight is the only unpaired spawn.
4523
+ *
4524
+ * OBSERVATION ONLY (matrix §5.2 Q3: frame-rate lifecycle facts ride an observer seat, never
4525
+ * onNotice): no return capability, and delivery can never alter the child run —
4526
+ * {@link deliverDelegationLifecycle} contains a throwing sink and an async sink's rejection alike.
4527
+ *
4528
+ * FRAME OBJECT SHAPE (consumer contract, not an implementation detail): every delivered frame is
4529
+ * FROZEN and carries a NULL PROTOTYPE — re-minted at the one delivery point so a forged member
4530
+ * cannot ride a frame through a writable `Object.prototype`, the same rule (and the same trade) as
4531
+ * the {@link import("./hooks.js").HookInvocationIdentity} envelope inside it. `Object.keys`, spread,
4532
+ * JSON serialization and direct member reads (`frame.status`) all behave normally, but
4533
+ * `frame instanceof Object` is `false` and inherited methods are ABSENT — probe optional members
4534
+ * with `Object.hasOwn(frame, "errorCode")` or `"errorCode" in frame`, never
4535
+ * `frame.hasOwnProperty(...)` (throws) or implicit string coercion (`` `${frame}` `` throws).
4536
+ */
4537
+ export type DelegationLifecycleEvent = {
4538
+ phase: "spawn";
4539
+ /** The child LEG's identity envelope (#281 件A — the same frozen object that leg's own hook
4540
+ * invocations carry). `isDelegatedChild` is `true` by construction on every frame here. */
4541
+ identity: import("./hooks.js").HookInvocationIdentity;
4542
+ } | {
4543
+ phase: "terminal";
4544
+ /** Same envelope as the leg's spawn frame (one mint per leg). */
4545
+ identity: import("./hooks.js").HookInvocationIdentity;
4546
+ /** The leg's settled status — the `TaskResult.status` the spawning lane receives, verbatim
4547
+ * (the sync lane's previously-void `settled` payload, made public). `"suspended"` means a
4548
+ * durable park: expect a later `"resume"`-leg spawn/terminal pair if it is redeemed. */
4549
+ status: TaskResult["status"];
4550
+ /** Turns the leg completed. */
4551
+ turns: number;
4552
+ /** The leg's `TaskResult.errorCode`, when one was stamped. */
4553
+ errorCode?: string;
4554
+ };
4555
+ /** Test seam (mirrors `__resetMalformedNoticeSeatAnnouncement`): never called by production code. */
4556
+ export declare function __resetMalformedDelegationSeatAnnouncement(): void;
4557
+ /**
4558
+ * The ONE delivery form behind every {@link RunnerDeps.onDelegationLifecycle} emission point (both
4559
+ * runner stations — spawn and terminal — call this; a second spelling of the swallow/announce rules
4560
+ * would be the #170 triplication reborn). Contract:
4561
+ * · a FUNCTION seat is invoked with the frame FROZEN (a mutating observer must not rewrite what a
4562
+ * later frame consumer — or the shared identity envelope's other readers — see), contained in the
4563
+ * caller's {@link SafeNotifier} against BOTH failure shapes the void-typed seat admits: a
4564
+ * synchronous throw ({@link SafeNotifier.notify}) and an async sink's rejected promise
4565
+ * ({@link observeThenableRejection} routes it back through the same notifier/site — the #253
4566
+ * three-station form). A broken observer never faults the child run.
4567
+ * · a PRESENT NON-function seat is a bad deployment value; #123 forbids folding it to silence. There
4568
+ * is no per-frame console fallback (this is a frame-rate observer stream, not an announcement
4569
+ * channel — an unwired seat means UNOBSERVED, and echoing every spawn to stderr would flood), so
4570
+ * the loud exit is the seat DEFECT itself: announced via `console.warn` once per process.
4571
+ * · an ABSENT seat is a plain no-op (the deployment chose not to observe).
4572
+ */
4573
+ export declare function deliverDelegationLifecycle(seat: RunnerDeps["onDelegationLifecycle"], event: DelegationLifecycleEvent, notifier: import("./safe-notify.js").SafeNotifier, site: string): void;
4348
4574
  /**
4349
4575
  * parity-204 — structured `RunnerDeps.loadProjectMemory` return (backward-compatible: a bare
4350
4576
  * `string | null` keeps its exact historical meaning). Adds the CC 2.1.204 `seededFromContext`
@@ -4424,6 +4650,24 @@ export interface EngineNotice {
4424
4650
  * a library-direct `createHandsToolkit` mount announces at toolkit creation (one per mount,
4425
4651
  * through the band-local `HandsToolkitOptions.onNotice` seat, absent ⇒ `console.warn`);
4426
4652
  * `detail: { seat, declared, inForce, cause }`.
4653
+ * - `"config.tool_model_gate_removed"` (design/277) — the model gate trimmed default-mounted
4654
+ * scaffold entries from a task's roster. One notice per (model, class), de-duplicated once per
4655
+ * `onNotice` SINK on the (modelId, class, canonical sorted removed-name set) line (same unit
4656
+ * as `config.read_face_deployment_clamped`: two deployments hosted in one process each hear
4657
+ * their own trim; unwired console arm once per process) — same class with a different removal
4658
+ * shape is a distinct fact and announces again;
4659
+ * `detail: { modelId, gateClass, removed, restore }` (`restore` names the three valves).
4660
+ * - `"config.tool_model_gate_unknown_class"` (design/277) — a `ToolSpec.modelGate` tag names a
4661
+ * class the merged gate table has no row for: the tag is inert (fail-open — the tool stays
4662
+ * mounted) and this is its loud half (a tag typo must not silently become "never gated" with
4663
+ * nobody told). Once per `onNotice` sink per class (console arm once per process);
4664
+ * `detail: { gateClass }`.
4665
+ * - `"config.tool_model_gate_env_invalid"` (design/277, the NOTICE dialect of the same fact the
4666
+ * refusal code carries) — `SEMA_TOOL_MODEL_GATE` holds a value outside `on|1|true|off|0|false`
4667
+ * in a seat where it is NOT in force (nothing this prepare would gate): announced once per
4668
+ * `onNotice` sink per value (console arm once per process) instead of lying in wait; where the
4669
+ * value IS in force the prepare refuses with the same code as `TaskResult.errorCode` (one
4670
+ * fact, one code, two loudness dialects); `detail: { raw }`.
4427
4671
  *
4428
4672
  * Deliberately NOT a notice family: brain retry/reconnect liveness (a rate limit, a 5xx, a
4429
4673
  * transient network failure being retried). Those are per-attempt liveness frames with their own
@@ -4779,6 +5023,23 @@ export interface RunnerDeps {
4779
5023
  * completion pushes from it. Observability only — a throwing observer is swallowed, never faults a run.
4780
5024
  */
4781
5025
  onBackgroundChildEvent?: (event: BackgroundChildEvent) => void;
5026
+ /**
5027
+ * #281 件B — PROCESS-level observer for EVERY delegated child leg's lifecycle (`spawn`/`terminal`),
5028
+ * all delegation lanes at once: synchronous and steer-handle delegations (whose spawn/settle
5029
+ * previously reached only the trusted `RunInternals.onSubagentSpawn` third parameter — and whose
5030
+ * `settled` is a void promise), background/fork/revive children (whose {@link BackgroundChildEvent}
5031
+ * family this seat complements, not replaces — BCE stays the fleet-row lane with registry `a*`
5032
+ * handles and ticks; this seat is the leg-identity lane), and workflow-spawned agents. Frames are
5033
+ * minted at the child leg's own runner chokepoint and carry the #281 件A identity envelope plus a
5034
+ * terminal status summary — see {@link DelegationLifecycleEvent} for the emission points, the
5035
+ * per-leg semantics and the recorded honest absences. Wire it once at Runner construction; a
5036
+ * deployment needs NO RunInternals access to observe delegation any more. Observation only — a
5037
+ * throwing or rejecting observer is contained ({@link deliverDelegationLifecycle}) and never
5038
+ * faults the child run; a PRESENT non-function value here is announced once per process and the
5039
+ * frames are simply not delivered (#123 — a bad seat must be loud, and this stream's loud exit is
5040
+ * the seat defect, not a per-frame console flood).
5041
+ */
5042
+ onDelegationLifecycle?: (event: DelegationLifecycleEvent) => void;
4782
5043
  /**
4783
5044
  * design/98 (S8) — the HARD sandbox seam for LLM-AUTHORED workflow scripts (`TaskSpec.selfOrchestration`).
4784
5045
  * A deployment supplies an isolated-vm / separate-process runner whose `safeForUntrustedScripts === true`;
@@ -4866,7 +5127,7 @@ export interface RunnerDeps {
4866
5127
  * resolves a saved workflow, and a registration's `defaultArgs` merge under the call-time args. Opt-in
4867
5128
  * (absent ⇒ inline `script` + built-in names only). */
4868
5129
  workflowScriptStore?: import("../orchestration/workflow-script-store.js").WorkflowScriptStore;
4869
- /** design/140 §6 1c — `false` removes the BUILT-IN named workflows (`team-discussion`, …) from the
5130
+ /** design/140 §6 1c — `false` removes the BUILT-IN named workflows (`discussion`, …) from the
4870
5131
  * auto-mounted run_workflow tool (the `builtinAgents:false` analog; default ON). A deployment
4871
5132
  * `workflowScriptStore` registration of the same name shadows a built-in regardless. */
4872
5133
  builtinWorkflows?: boolean;
@@ -5047,6 +5308,28 @@ export interface RunnerDeps {
5047
5308
  mcpImageResizer?: import("./mcp.js").McpImageResizer;
5048
5309
  /** Default tool-call gate for all tasks (a task's own `toolPolicy` overrides this). */
5049
5310
  toolPolicy?: import("./tool-policy.js").ToolPolicy;
5311
+ /**
5312
+ * design/277 — the deployment seat of the tool-registration MODEL GATE (default ON; the gate
5313
+ * itself only ever touches entries tagged via {@link ToolSpec.modelGate}, so an untagged roster
5314
+ * is byte-identical under any value here):
5315
+ * · `false` — deployment kill switch: the gate never trims anything.
5316
+ * · `{ classes }` — per-class rule rows merged into the built-in table
5317
+ * ({@link import("./tool-model-gate.js").TOOL_MODEL_GATE_CLASSES}) PER AXIS: a present
5318
+ * `floors`/`modelIds` axis REPLACES that axis, an absent axis INHERITS the built-in one — so
5319
+ * a row adding only `modelIds` (the BYOM channel for gating a deployment's own strong model)
5320
+ * keeps the built-in claude floors armed. `floors: []` / `modelIds: []` are the EXPLICIT
5321
+ * per-axis clears; a class whose merged rule has both axes empty gates nothing (legal
5322
+ * per-class off). New class names extend the open vocabulary for deployment-authored tags.
5323
+ * The legality set is CLOSED (#123): any other shape — array/null/true seat, unknown keys at
5324
+ * either level, malformed floors/modelIds rows, families that can never match the canonical id
5325
+ * grammar, duplicate families/ids, `/`-prefixed ids — refuses the prepare loudly
5326
+ * (`config.tool_model_gate_invalid`), never folds to a guess. Process-level counterpart: env
5327
+ * `SEMA_TOOL_MODEL_GATE=off`. Removals are announced per (model, class) through `onNotice`
5328
+ * (`config.tool_model_gate_removed`) — a silent default-face trim is forbidden (#237).
5329
+ */
5330
+ toolModelGate?: false | {
5331
+ classes?: Record<string, import("./tool-model-gate.js").ToolModelGateRule>;
5332
+ };
5050
5333
  /** Deployment default for {@link TaskSpec.basePolicyForResumeEdit} (#93 / F-012 L3): the resume-edit
5051
5334
  * re-adjudication override. Resolution: `spec.basePolicyForResumeEdit ?? THIS ?? (spec.toolPolicy ??
5052
5335
  * deps.toolPolicy)` — absence falls back to the caller policy, never to a silent skip. */
@@ -1,3 +1,24 @@
1
+ import { observeThenableRejection } from "./safe-notify.js";
2
+ let malformedDelegationSeatAnnounced = false;
3
+ export function __resetMalformedDelegationSeatAnnouncement() {
4
+ malformedDelegationSeatAnnounced = false;
5
+ }
6
+ export function deliverDelegationLifecycle(seat, event, notifier, site) {
7
+ if (typeof seat === "function") {
8
+ const frame = Object.freeze(Object.assign(Object.create(null), event));
9
+ notifier.notify(() => observeThenableRejection(seat(frame), notifier, site), site);
10
+ return;
11
+ }
12
+ if (seat !== undefined && !malformedDelegationSeatAnnounced) {
13
+ malformedDelegationSeatAnnounced = true;
14
+ try {
15
+ console.warn(`The delegation-lifecycle sink (RunnerDeps.onDelegationLifecycle) holds ${seat === null ? "null" : typeof seat} — not a ` +
16
+ `function. Delegation spawn/terminal frames are NOT delivered until the wiring is fixed (omit the key, or wire a function).`);
17
+ }
18
+ catch {
19
+ }
20
+ }
21
+ }
1
22
  let malformedNoticeSeatAnnounced = false;
2
23
  export function __resetMalformedNoticeSeatAnnouncement() {
3
24
  malformedNoticeSeatAnnounced = false;
@@ -21,7 +21,7 @@
21
21
  * model-facing instructions. Always neutralizes `<system-reminder>` / `</system-reminder>` (the codebase's
22
22
  * elevated-authority wrapper) by inserting a zero-width space after the leading `<`. Pass `extraTags` to also
23
23
  * neutralize a CALLER's own data-framing tags — e.g. `team.ts` embeds member output inside `<statement>` /
24
- * `<team-discussion>`, so an untrusted member could emit `</statement>` to break out (search [46] BUG2);
24
+ * `<discussion>`, so an untrusted member could emit `</statement>` to break out (search [46] BUG2);
25
25
  * the caller passes those tag names. Tag names must be literal (alphanumeric/hyphen) — they are code-supplied
26
26
  * wrapper names, never untrusted input. Idempotent for prompt assembly (a defused tag no longer matches).
27
27
  */
package/dist/index.d.ts CHANGED
@@ -21,6 +21,7 @@ export { createWebFetchTool, webFetchToolSpec, htmlToText, type WebFetchConfig,
21
21
  export { createTodoWriteTool } from "./tools/todo.js";
22
22
  export { createTaskListTools, createMemoryTaskListStore, assertJsonMetadata, type TaskListItem, type TaskListStore } from "./tools/task-list.js";
23
23
  export { assembleCodeTools, type CodeToolsConfig, CODE_ROLE } from "./scenarios/full-body.js";
24
+ export { TOOL_MODEL_GATE_CLASSES, isModelGatedForClass, type ToolModelGateRule } from "./core/tool-model-gate.js";
24
25
  export { capAggregateToolResults, AGGREGATE_TOOL_RESULT_BUDGET_CHARS, DEFAULT_BUDGET_EXEMPT_TOOLS, type AggregateBudgetOptions, } from "./core/tool-result-budget.js";
25
26
  export { capAggregateMediaBytes, AGGREGATE_MEDIA_BUDGET_BYTES, type MediaStripInfo } from "./core/media-byte-cap.js";
26
27
  export { createAskUserQuestionTool, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, isQuestionUnavailable, type OnQuestionOutcome, type QuestionUnavailable, type OnQuestion, type AskQuestion, type AskQuestionOption, type AskQuestionRequest, type QuestionAnswer, type QuestionAnswerItem, type AskQuestionCardDetails, type AskUserQuestionToolOptions, type AskAnswerContinuationSource, type SyntheticContinuationReason, } from "./core/ask-question.js";
@@ -162,9 +163,9 @@ export { FilePermissionRuleStoreProvider } from "./stores/file/permission-rule-s
162
163
  export { adoptFilePermissionRuleStore, type AdoptFileRuleStoreResult } from "./stores/file/permission-rule-adopt.js";
163
164
  export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootAdoptionFile, ROOT_ADOPTION_FILE, type AdoptionErrorCode, type AdoptionSource, type AdoptionReport, type AdoptionReceipt, type AdoptionLegReport, type AffectedDeploymentConfig, type RootAdoptionFile, } from "./stores/file/adoption/marker.js";
164
165
  export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, type AdoptionStatus, type AdoptLocalDataRootOptions, type AdoptLocalDataRootResult, type AdoptionCarriageLeg, type AdoptionCarriageLegContext, type AdoptionConfigWitnessReceipt, } from "./stores/file/adoption/adopt.js";
165
- export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, type PersistedRuleHit, type PersistedRuleUnreadable, type PersistedRuleAnswer, normalizePersistedRuleHit, type Hooks, type HookToolContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, type PermissionDeniedSource, } from "./core/hooks.js";
166
+ export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, type PersistedRuleHit, type PersistedRuleUnreadable, type PersistedRuleAnswer, normalizePersistedRuleHit, type Hooks, type HookToolContext, type HookInvocationIdentity, type UserPromptSubmitContext, type PostToolBatchContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, type PermissionDeniedSource, } from "./core/hooks.js";
166
167
  export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
167
- export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
168
+ export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type MemoryGetDetails, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type EntryProvenanceAccount, type TransferEvidence, type CommittedBinding, type CommittedEntrySnapshot, type CommittedScopeSnapshots, type EntryCustodyReport, erasureSelectHash, type EraseMemoryEntriesInput, type ErasureSelect, type ErasedBinding, type MemoryErasureAttestation, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
168
169
  export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, type SharedMemoryStoreProvider, type SharedMemoryStoreReader, type SharedMemoryPagedList, type SharedMemoryStoreInfo, type SharedMemoryDocumentEntry, type SharedMemorySnapshot, type SharedMemoryRequestContext, type MemoryListDetails, type MemoryReadDetails, } from "./core/shared-memory/types.js";
169
170
  export { sharedMemoryStoreContract, type SharedMemoryFixture, type SharedMemoryStoreContractHooks, } from "./core/shared-memory/contract.js";
170
171
  export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
@@ -201,7 +202,7 @@ export { assertWorkflowSandboxConformance, assertWorkflowPrimitivesWiring, asser
201
202
  export { WorkflowModelNotAllowedError, type WorkflowAgentSpec } from "./orchestration/workflow-governance.js";
202
203
  export { WorkflowMaxAgentsError, WorkflowResultTooLargeError } from "./orchestration/workflow.js";
203
204
  export { createFileWorkflowScriptStore, mergeWorkflowArgs, type WorkflowScriptStore, type NamedWorkflowResolution, type NamedWorkflowListing, } from "./orchestration/workflow-script-store.js";
204
- export { TEAM_DISCUSSION_WORKFLOW_NAME, TEAM_DISCUSSION_SCRIPT, builtinWorkflowDefinitions, builtinWorkflowListings, resolveBuiltinWorkflow, type BuiltinWorkflowDefinition, } from "./orchestration/builtin-workflows.js";
205
+ export { DISCUSSION_WORKFLOW_NAME, DISCUSSION_SCRIPT, TEAM_DISCUSSION_WORKFLOW_NAME, TEAM_DISCUSSION_SCRIPT, canonicalWorkflowName, retiredWorkflowNameAliases, builtinWorkflowDefinitions, builtinWorkflowListings, resolveBuiltinWorkflow, type BuiltinWorkflowDefinition, } from "./orchestration/builtin-workflows.js";
205
206
  export { WORKFLOW_AGENT_STALL_MS, WORKFLOW_AGENT_MAX_RETRIES, WORKFLOW_AGENT_THROTTLE_BACKOFF_MS } from "./orchestration/workflow.js";
206
207
  export { createRunWorkflowTool, RUN_WORKFLOW_TOOL_NAME, workflowWhenToUseText, renderNamedWorkflowListing, type WorkflowCompletionNotifier, type WorkflowLimits, type RunWorkflowToolDeps, } from "./orchestration/run-workflow-tool.js";
207
208
  export { runSideQuery, type SideQuerySpec, type SideQueryResult, type SideQueryToolDef, type SideQueryDeps, type SideQueryMessage } from "./core/side-query.js";
@@ -254,7 +255,7 @@ export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
254
255
  export { type BrainTimeoutConfig } from "./brain/timeout.js";
255
256
  export { createAssistantMessageEventStream } from "./internal/llm.js";
256
257
  export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
257
- export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, EngineNotice, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
258
+ export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, BrainRetryErrClass, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, A2aServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, EngineNotice, RuntimeCaps, BackgroundChildEvent, DelegationLifecycleEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskLimits, StaleToolResultOffloadOptions, TaskResult, EffectiveMemoryScopes, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ReversibilityVerdict, ToolEffect, ToolContentOrigin, WorkflowGovernanceBaseline, DelegationTaskType, } from "./core/types.js";
258
259
  export { Type } from "typebox";
259
260
  export type { TSchema, Static } from "typebox";
260
261
  export { explainPromptAssembly, describeDefaultPack, type DefaultPackDescription, type ExplainInput } from "./prompt-assembly/explain.js";
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { createWebFetchTool, webFetchToolSpec, htmlToText, createWebSearchTool,
10
10
  export { createTodoWriteTool } from "./tools/todo.js";
11
11
  export { createTaskListTools, createMemoryTaskListStore, assertJsonMetadata } from "./tools/task-list.js";
12
12
  export { assembleCodeTools, CODE_ROLE } from "./scenarios/full-body.js";
13
+ export { TOOL_MODEL_GATE_CLASSES, isModelGatedForClass } from "./core/tool-model-gate.js";
13
14
  export { capAggregateToolResults, AGGREGATE_TOOL_RESULT_BUDGET_CHARS, DEFAULT_BUDGET_EXEMPT_TOOLS, } from "./core/tool-result-budget.js";
14
15
  export { capAggregateMediaBytes, AGGREGATE_MEDIA_BUDGET_BYTES } from "./core/media-byte-cap.js";
15
16
  export { createAskUserQuestionTool, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, isQuestionUnavailable, } from "./core/ask-question.js";
@@ -126,7 +127,7 @@ export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootA
126
127
  export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, } from "./stores/file/adoption/adopt.js";
127
128
  export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, normalizePersistedRuleHit, } from "./core/hooks.js";
128
129
  export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, } from "./core/memory.js";
129
- export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
130
+ export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, readV2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, erasureSelectHash, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
130
131
  export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, } from "./core/shared-memory/types.js";
131
132
  export { sharedMemoryStoreContract, } from "./core/shared-memory/contract.js";
132
133
  export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
@@ -162,7 +163,7 @@ export { assertWorkflowSandboxConformance, assertWorkflowPrimitivesWiring, asser
162
163
  export { WorkflowModelNotAllowedError } from "./orchestration/workflow-governance.js";
163
164
  export { WorkflowMaxAgentsError, WorkflowResultTooLargeError } from "./orchestration/workflow.js";
164
165
  export { createFileWorkflowScriptStore, mergeWorkflowArgs, } from "./orchestration/workflow-script-store.js";
165
- export { TEAM_DISCUSSION_WORKFLOW_NAME, TEAM_DISCUSSION_SCRIPT, builtinWorkflowDefinitions, builtinWorkflowListings, resolveBuiltinWorkflow, } from "./orchestration/builtin-workflows.js";
166
+ export { DISCUSSION_WORKFLOW_NAME, DISCUSSION_SCRIPT, TEAM_DISCUSSION_WORKFLOW_NAME, TEAM_DISCUSSION_SCRIPT, canonicalWorkflowName, retiredWorkflowNameAliases, builtinWorkflowDefinitions, builtinWorkflowListings, resolveBuiltinWorkflow, } from "./orchestration/builtin-workflows.js";
166
167
  export { WORKFLOW_AGENT_STALL_MS, WORKFLOW_AGENT_MAX_RETRIES, WORKFLOW_AGENT_THROTTLE_BACKOFF_MS } from "./orchestration/workflow.js";
167
168
  export { createRunWorkflowTool, RUN_WORKFLOW_TOOL_NAME, workflowWhenToUseText, renderNamedWorkflowListing, } from "./orchestration/run-workflow-tool.js";
168
169
  export { runSideQuery } from "./core/side-query.js";