@themoltnet/agent-daemon 0.42.1 → 0.44.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.
package/dist/cli.js CHANGED
@@ -5,23 +5,23 @@ import { Type } from "typebox";
5
5
  import "multiformats/cid";
6
6
  import "multiformats/codecs/json";
7
7
  import "multiformats/hashes/sha2";
8
- import { Value } from "typebox/value";
8
+ import "typebox/value";
9
9
  import { dirname, join, resolve } from "node:path";
10
10
  import { parseArgs, promisify } from "node:util";
11
- import { AgentRuntime, ApiTaskReporter, ApiTaskSource, PollingApiTaskSource } from "@themoltnet/agent-runtime";
11
+ import { AgentRuntime, ApiTaskReporter, ApiTaskSource, PollingApiTaskSource, createLocalSeedSigner, resolveAgentIdentity, resolveProfileWarmSessionTtlSec, resolveRuntimeProfile, resolveRuntimeProfiles, validateRuntimeProfilePrerequisites } from "@themoltnet/agent-runtime";
12
12
  import { GuestEnvironmentBoundaryError, assertGuestEnvironmentBoundary, createPiRetryTriage, findMainWorktree, isResolvedPathInsideRoot, normalizeRetryTriageResult, redactRetryTriageSecrets } from "@themoltnet/pi-runtime";
13
13
  import { execFile, execFileSync } from "node:child_process";
14
14
  import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, realpathSync, rmSync } from "node:fs";
15
15
  import { AuthenticationError, MoltNetError, connect, createExecutorAttestor, readConfig } from "@themoltnet/sdk";
16
16
  import { createNodeSecretProviderRegistry } from "@themoltnet/sdk/node";
17
17
  import { createHash, randomUUID } from "node:crypto";
18
+ import * as ed from "@noble/ed25519";
19
+ import { createHash as createHash$1, randomBytes } from "crypto";
18
20
  import "multiformats/codecs/raw";
19
21
  import "multiformats/hashes/digest";
20
22
  import "@noble/hashes/sha2";
21
23
  import "multiformats/bases/base32";
22
24
  import { ed25519 } from "@noble/curves/ed25519.js";
23
- import * as ed from "@noble/ed25519";
24
- import { createHash as createHash$1, randomBytes } from "crypto";
25
25
  import "@ipld/dag-cbor";
26
26
  import "@noble/ciphers/chacha";
27
27
  import "@noble/hashes/hkdf";
@@ -41,64 +41,6 @@ import { mkdir, realpath, stat } from "node:fs/promises";
41
41
  import { pipeline } from "node:stream/promises";
42
42
  import { Writable } from "node:stream";
43
43
  import { createGzip } from "node:zlib";
44
- //#region ../../libs/tasks/src/context.ts
45
- /**
46
- * How an executor delivers a context entry to its underlying LLM.
47
- * V1 bindings only; Tier-2 (reference_file, mcp_resource, imported_file,
48
- * tool_response_seed, additional_context_hook) ship in a later slice.
49
- */
50
- var CONTEXT_BINDINGS = [
51
- "skill",
52
- "context_inline",
53
- "prompt_prefix",
54
- "user_inline"
55
- ];
56
- /** Maximum UTF-16 code units accepted in one ContextRef content field. */
57
- var CONTEXT_REF_MAX_CONTENT_LENGTH = 65536;
58
- var ContextBinding = Type.Unsafe(Type.Union(CONTEXT_BINDINGS.map((binding) => Type.Literal(binding)), { $id: "ContextBinding" }));
59
- /**
60
- * One context entry. Bytes are inlined: the proposer chose them, and the
61
- * task's `inputCid` already pins the entire input — including
62
- * `context[]` — so we don't need a separate per-entry hash, fetcher, or
63
- * flagged-content gate. Tasks reference rendered packs (or any other
64
- * external content) by copying their bytes into `content` at task
65
- * creation time.
66
- *
67
- * - `slug` — short identifier the daemon uses to disambiguate
68
- * entries. For `skill` binding it becomes the directory
69
- * name under the runtime's skill discovery path. Must be
70
- * kebab-case-safe (alphanumeric + dashes/underscores).
71
- * - `binding` — how the bytes are delivered to the LLM (see above).
72
- * - `content` — UTF-8 text. Capped at 65,536 UTF-16 code units per
73
- * entry; total per-task context bytes are bounded by the
74
- * soft `maxItems` cap and per-binding daemon limits.
75
- * Raised from 32 KiB in 2026-05 — protocol-heavy operator
76
- * skills (e.g. `.claude/skills/legreffier/SKILL.md`) ship
77
- * at ~35 KiB inline, and the original cap was sized for
78
- * short example skills, not the kind of skill the eval
79
- * substrate is dogfooded on (#943, #823).
80
- */
81
- var ContextRef = Type.Object({
82
- slug: Type.String({
83
- minLength: 1,
84
- maxLength: 64,
85
- pattern: "^[a-zA-Z0-9_-]+$"
86
- }),
87
- binding: ContextBinding,
88
- content: Type.String({
89
- minLength: 1,
90
- maxLength: CONTEXT_REF_MAX_CONTENT_LENGTH
91
- })
92
- }, {
93
- $id: "ContextRef",
94
- additionalProperties: false
95
- });
96
- /** Reusable input fragment for any task type. Soft cap at 5 items. */
97
- var TaskContext = Type.Array(ContextRef, {
98
- $id: "TaskContext",
99
- maxItems: 5
100
- });
101
- //#endregion
102
44
  //#region ../../libs/tasks/src/rubric.ts
103
45
  /**
104
46
  * Rubric — structured acceptance criteria used by judgment tasks.
@@ -201,1893 +143,1973 @@ function validateRubricWeights(rubric) {
201
143
  return null;
202
144
  }
203
145
  //#endregion
204
- //#region ../../libs/tasks/src/runtime-models.ts
146
+ //#region ../../libs/tasks/src/success-criteria.ts
205
147
  /**
206
- * Runtime model catalog: a list of supported provider/model couples that
207
- * MoltNet daemons can target. Backed by the `runtime_models` table.
148
+ * SuccessCriteria — proposer-stated acceptance criteria, evaluated in two
149
+ * complementary places.
208
150
  *
209
- * Scope is intrinsic to the row:
210
- * - `teamId == null` => global entry (MoltNet-seeded, read-only to most callers)
211
- * - `teamId != null` => team-owned custom entry
151
+ * Before this envelope existed, criteria were scattered: a vestigial
152
+ * `criteriaCid` column nobody resolved, free-form prose on
153
+ * `fulfill_brief.input`, and inline `rubric` / `criteria[]` fields on
154
+ * judgment-task inputs. None of those were machine-verifiable
155
+ * end-to-end.
212
156
  *
213
- * The REST API exposes a single shape regardless of scope; the team header
214
- * gates which rows are returned.
157
+ * This module defines a single, content-addressable envelope a proposer
158
+ * attaches to any task type. It has four orthogonal sections — pick
159
+ * whichever apply per task type:
160
+ *
161
+ * - `gates` Promise-level structural/process checks
162
+ * - `assertions` Declarative claims about output JSON
163
+ * - `rubric` Weighted-criteria scoring instrument, reused
164
+ * verbatim from `./rubric.ts`.
165
+ * - `sideEffects` Required process side-effects (e.g. diary entry)
166
+ *
167
+ * ## Two roles, two task types
168
+ *
169
+ * **Producer self-assessment** (fulfillment tasks: `fulfill_brief`,
170
+ * `curate_pack`, `render_pack`). The producer **LLM** evaluates the
171
+ * criteria against its own output and emits a `VerificationRecord`
172
+ * inside `output.verification`. The daemon is pure passthrough — it
173
+ * does not run `evaluateAssertions`, does not inspect the verification
174
+ * record. The REST API is dumb storage; it never re-runs assertions and
175
+ * never runs LLMs. The cross-field rule
176
+ * `requireVerificationWhenCriteriaPresent` enforces "verification
177
+ * required iff successCriteria present" at task-output validation time
178
+ * (server-side schema check). Self-assessment is a truthful self-rating,
179
+ * NOT enforcement — `verification.passed=false` does not block /complete
180
+ * and does not affect `acceptedAttemptN`. See
181
+ * `docs/use/tasks-and-runtime.md` for the full producer/judge flow.
182
+ *
183
+ * **Binding evaluation** (judgment tasks: `assess_brief`, `judge_pack`).
184
+ * A separate task whose IS the application of `successCriteria` to
185
+ * someone else's output. Different agent (enforced at claim time), same
186
+ * envelope. The judge's verdict is binding: this is the *gate* in the
187
+ * MoltNet model. The rubric inside `successCriteria.rubric` IS the job
188
+ * spec for the judge.
189
+ *
190
+ * The clean chain: producer task with `successCriteria` → producer
191
+ * self-assesses honestly → proposer (or automation) creates a downstream
192
+ * judgment task that references the same `successCriteria` (or a
193
+ * stricter rubric) → judgment task delivers the binding verdict.
194
+ *
195
+ * Storage: SuccessCriteria lives inline at `task.input.successCriteria`,
196
+ * pinned via the task's `inputCid`. No separate column or hash. When
197
+ * #881 lands, the `rubric` field can graduate to `{ rubricCid }` lookup
198
+ * without changing this envelope, and producer + judge tasks can pin
199
+ * the SAME rubric across the chain for end-to-end auditability.
215
200
  */
216
- var RuntimeModelProvider = Type.String({
217
- minLength: 1,
218
- maxLength: 100,
219
- pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$"
201
+ var SchemaCheckSpec = Type.Object({ schemaCid: Type.String({ minLength: 1 }) }, { additionalProperties: false });
202
+ var CidEqualsSpec = Type.Object({
203
+ path: Type.String({ minLength: 1 }),
204
+ expected: Type.String({ minLength: 1 })
205
+ }, { additionalProperties: false });
206
+ var SubmitToolCallGate = Type.Object({
207
+ id: Type.String({ minLength: 1 }),
208
+ kind: Type.Literal("submit-tool-call"),
209
+ description: Type.String({ minLength: 1 }),
210
+ required: Type.Boolean()
211
+ }, { additionalProperties: false });
212
+ var Gate = Type.Union([
213
+ SubmitToolCallGate,
214
+ Type.Object({
215
+ id: Type.String({ minLength: 1 }),
216
+ kind: Type.Literal("schema-check"),
217
+ spec: SchemaCheckSpec,
218
+ required: Type.Boolean()
219
+ }, { additionalProperties: false }),
220
+ Type.Object({
221
+ id: Type.String({ minLength: 1 }),
222
+ kind: Type.Literal("cid-equals"),
223
+ spec: CidEqualsSpec,
224
+ required: Type.Boolean()
225
+ }, { additionalProperties: false })
226
+ ], { $id: "Gate" });
227
+ var AssertionOp = Type.Union([
228
+ Type.Literal("exists"),
229
+ Type.Literal("equals"),
230
+ Type.Literal("matches"),
231
+ Type.Literal("in-range"),
232
+ Type.Literal("min-length")
233
+ ], { $id: "AssertionOp" });
234
+ var Assertion = Type.Object({
235
+ id: Type.String({ minLength: 1 }),
236
+ path: Type.String({ minLength: 1 }),
237
+ op: AssertionOp,
238
+ value: Type.Optional(Type.Unknown())
239
+ }, {
240
+ $id: "Assertion",
241
+ additionalProperties: false
220
242
  });
221
- var RuntimeModelName = Type.String({
222
- minLength: 1,
223
- maxLength: 200,
224
- pattern: "^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,199}$"
243
+ var SideEffectsSpec = Type.Object({
244
+ diaryEntryRequired: Type.Optional(Type.Boolean()),
245
+ diaryEntryTags: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
246
+ referencedEntries: Type.Optional(Type.Integer({ minimum: 0 }))
247
+ }, {
248
+ $id: "SideEffectsSpec",
249
+ additionalProperties: false
225
250
  });
226
- var RuntimeModelCapabilities = Type.Record(Type.String({
227
- minLength: 1,
228
- maxLength: 64
229
- }), Type.Union([
230
- Type.Boolean(),
231
- Type.Number(),
232
- Type.String({ maxLength: 256 })
233
- ]));
234
- Type.Object({
235
- id: Type.String({ format: "uuid" }),
236
- teamId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
237
- provider: RuntimeModelProvider,
238
- model: RuntimeModelName,
239
- displayName: Type.Union([Type.String({ maxLength: 200 }), Type.Null()]),
240
- description: Type.Union([Type.String({ maxLength: 4096 }), Type.Null()]),
241
- capabilities: RuntimeModelCapabilities,
242
- isActive: Type.Boolean(),
243
- createdByAgentId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
244
- createdByHumanId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
245
- createdAt: Type.String({ format: "date-time" }),
246
- updatedAt: Type.String({ format: "date-time" })
251
+ var SuccessCriteria = Type.Object({
252
+ version: Type.Literal(1),
253
+ gates: Type.Optional(Type.Array(Gate)),
254
+ assertions: Type.Optional(Type.Array(Assertion)),
255
+ rubric: Type.Optional(Rubric),
256
+ minComposite: Type.Optional(Type.Number({
257
+ minimum: 0,
258
+ maximum: 1
259
+ })),
260
+ sideEffects: Type.Optional(SideEffectsSpec)
247
261
  }, {
248
- $id: "RuntimeModel",
262
+ $id: "SuccessCriteria",
263
+ additionalProperties: false
264
+ });
265
+ var VerificationResultStatus = Type.Union([
266
+ Type.Literal("pass"),
267
+ Type.Literal("fail"),
268
+ Type.Literal("skip")
269
+ ], { $id: "VerificationResultStatus" });
270
+ var VerificationResultKind = Type.Union([
271
+ Type.Literal("gate"),
272
+ Type.Literal("assertion"),
273
+ Type.Literal("rubric"),
274
+ Type.Literal("sideEffect")
275
+ ], { $id: "VerificationResultKind" });
276
+ var VerificationResult = Type.Object({
277
+ id: Type.String({ minLength: 1 }),
278
+ kind: VerificationResultKind,
279
+ status: VerificationResultStatus,
280
+ detail: Type.Optional(Type.String())
281
+ }, {
282
+ $id: "VerificationResult",
283
+ additionalProperties: false
284
+ });
285
+ var VerificationRecord = Type.Object({
286
+ inputCid: Type.String({ minLength: 1 }),
287
+ results: Type.Array(VerificationResult),
288
+ passed: Type.Boolean({ description: "True iff every verification result has status \"pass\" or \"skip\"; false when any result has status \"fail\"." })
289
+ }, {
290
+ $id: "VerificationRecord",
249
291
  additionalProperties: false
250
292
  });
251
293
  //#endregion
252
- //#region ../../libs/tasks/src/runtime-profile-context-recipes.ts
253
- var RUNTIME_PROFILE_CONTEXT_CATALOGUE = {
254
- version: 1,
255
- fragments: {
256
- "artifact-planner-v1": {
257
- binding: "prompt_prefix",
258
- content: "# Bounded artifact planner\n\n- The typed task facts, embedded bounded manifest, exact bound artifact references, registered tools, and runtime capability section are the complete contract. Do not search diaries, inspect a mounted repository, enumerate unrelated tasks or artifacts, modify a checkout, commit, branch, push, or contact GitHub.\n- Read only the exact artifact CIDs named by the task, and only when the embedded manifest does not provide enough evidence. Use the registered task-artifact tools for artifact access; never use shell or CLI wrappers to fetch artifacts, paginate, or discover them speculatively.\n- If the effective runtime exposes a local calculator or shell, use it only inside scratch for coverage accounting, budget arithmetic, and JSON validation. The runtime capability section and policy are authoritative; do not assume a static executable list.\n- Perform semantic classification and planning from supplied content and producer/consumer evidence. Do not substitute filename, directory, language, ecosystem, or repository-specific exclusion rules for evidence.\n- Write and upload exactly the requested versioned plan artifact, then reference its returned metadata through the registered submit-output tool. Do not emit a second prose or JSON representation.",
259
- slug: "artifact-planner-v1"
260
- },
261
- "accountable-delivery-v1": {
262
- binding: "prompt_prefix",
263
- content: "# Accountable delivery\n\n- Pair every commit made during this task with a signed diary entry created by the `moltnet_create_entry` custom tool. Put the returned id in a `MoltNet-Diary: <id>` commit trailer.\n- Keep commit signing enabled; do not bypass the agent git configuration.\n- Push a branch and open or update a pull request only when the task asks for it. For GitHub mutations, use the credential-bound `GH_TOKEN` command form required by the runtime kernel.\n- Keep changes, commits, and any requested pull request coherent enough to review independently.",
264
- slug: "accountable-delivery-v1"
265
- },
266
- "judgment-diary-v1": {
267
- binding: "prompt_prefix",
268
- content: "# Judgment diary discipline\n\n- For an `assess_brief`, `judge_pack`, or `pr_review` task, create a signed diary entry with the `moltnet_create_entry` custom tool before submitting the structured judgment. Capture the rationale and evidence that support the verdict.\n- Add the `judgment` tag and the active task type tag (`assess_brief`, `judge_pack`, or `pr_review`). For `judge_pack`, also add `rubric:<rubricId>` from the task facts.\n- Do not use a shell `moltnet entry` command: task provenance is injected only by the custom tool.",
269
- slug: "judgment-diary-v1"
270
- },
271
- "proactive-memory-v1": {
272
- binding: "prompt_prefix",
273
- content: "# Proactive memory use\n\n- Before non-trivial investigation, debugging, code changes, or review, check the task diary for relevant prior knowledge instead of waiting for a human to ask. Use `moltnet_diary_tags` for cheap reconnaissance, `moltnet_list_entries` when tags or task provenance are known, and `moltnet_search_entries` for semantic similarity. Do not search randomly: pass `taskFilter` for task-local or correlation-local queries, and pass `tags` / `entryTypes` for broader prior-knowledge queries using known tags such as `incident`, `decision`, or `scope:<area>`. Broaden only after constrained searches miss.\n- Before creating an `episodic` incident entry, search for similar incidents using the proposed title, root cause, error text, affected subsystem, and watch-for terms, filtered by `entryTypes: [\"episodic\", \"semantic\"]` and any known `scope:*` or task-provenance tags. If a close prior match exists, do not create an isolated duplicate: reference the prior entry in your response or diary content, update or link it when the new occurrence adds material evidence, or create a new recurrence entry only when the recurrence itself is important signal.\n- When you create a recurrence entry, include the prior matching entry id(s) in the content and explain what is new about this occurrence.",
274
- slug: "proactive-memory-v1"
275
- },
276
- "run-eval-direct-v1": {
277
- binding: "prompt_prefix",
278
- content: "# Direct evaluation run\n\nThe supplied scenario, typed task facts, injected context, and registered submit-output tool are the complete task contract. Do not search diaries, create diary entries, modify a repository, commit, branch, push, or open a pull request unless a task fact explicitly requires it. Submit the agent-authored payload in the first turn; correction turns exist only to recover a rejected or missing submission.",
279
- slug: "run-eval-direct-v1"
280
- },
281
- "task-diary-discipline-v1": {
282
- binding: "prompt_prefix",
283
- content: "# Task diary discipline\n\n- During a daemon task, create diary entries only through the `moltnet_create_entry` custom tool. It binds entries to the current task diary and injects task, type, attempt, and correlation provenance tags.\n- Do not shell out to `moltnet entry create`, `moltnet entry create-signed`, or any other `moltnet entry` subcommand from bash while a task is running. Those paths bypass the custom tool's task-tag injection, so task-filtered diary queries cannot find the entry.\n- You may add useful tags, but do not try to replace task provenance supplied by the runtime.",
284
- slug: "task-diary-discipline-v1"
285
- },
286
- "verification-and-artifacts-v1": {
287
- binding: "prompt_prefix",
288
- content: "# Verification and artifacts\n\n- Run relevant verification before submitting. When task facts include `successCriteria`, assess them honestly in the generated verification contract; a fail or skip with evidence is better than a fabricated pass.\n- The registered submit-output tool owns the exact agent submission schema and validation recovery. Use that schema; do not invent a JSON shape in prose.\n- Upload only task-relevant artifacts, and inspect each before uploading. Never upload secrets, credentials, API keys, auth tokens or headers, .env files, or personal or customer data; redact sensitive values, and prefer minimal, sanitized excerpts over whole logs, bundles, or datasets. Include artifact metadata only where the typed submit contract permits it.\n- If the task depends on prior artifacts, list and download the exact referenced artifact before judging or continuing that work.",
289
- slug: "verification-and-artifacts-v1"
290
- }
291
- },
292
- recipes: {
293
- "artifact-planner@v1": {
294
- description: "Minimal artifact-only context for bounded semantic classification and planning.",
295
- fragments: ["artifact-planner-v1"]
296
- },
297
- "run-eval-direct@v1": {
298
- description: "Minimal direct context for a short, isolated evaluation run.",
299
- fragments: ["run-eval-direct-v1"]
300
- },
301
- "standard-engineering@v1": {
302
- description: "Full opt-in operating guidance for engineering tasks that need diary research, accountable delivery, and verification discipline.",
303
- fragments: [
304
- "proactive-memory-v1",
305
- "task-diary-discipline-v1",
306
- "accountable-delivery-v1",
307
- "judgment-diary-v1",
308
- "verification-and-artifacts-v1"
309
- ]
310
- }
311
- }
312
- };
313
- function deepFreeze(value) {
314
- if (value && typeof value === "object") {
315
- for (const key of Object.keys(value)) deepFreeze(value[key]);
316
- Object.freeze(value);
317
- }
318
- return value;
319
- }
320
- deepFreeze(RUNTIME_PROFILE_CONTEXT_CATALOGUE);
321
- Object.freeze(Object.keys(RUNTIME_PROFILE_CONTEXT_CATALOGUE.recipes));
322
- //#endregion
323
- //#region ../../libs/models/src/credential-scopes.ts
324
- var CREDENTIAL_SCOPES = {
325
- AgentProfile: "agent:profile",
326
- ConnectorInvoke: "connector:invoke",
327
- CryptoSign: "crypto:sign",
328
- DiaryManage: "diary:manage",
329
- DiaryRead: "diary:read",
330
- DiaryWrite: "diary:write",
331
- HumanProfile: "human:profile",
332
- KeyManage: "key:manage",
333
- PackRead: "pack:read",
334
- PackWrite: "pack:write",
335
- RuntimeManage: "runtime:manage",
336
- RuntimeRead: "runtime:read",
337
- TaskClaim: "task:claim",
338
- TaskExecute: "task:execute",
339
- TaskManage: "task:manage",
340
- TaskRead: "task:read",
341
- TeamManage: "team:manage",
342
- TeamRead: "team:read"
343
- };
344
- var ALL_CREDENTIAL_SCOPES = Object.freeze(Object.values(CREDENTIAL_SCOPES));
345
- /**
346
- * Minimum grant for the agent daemon. Task credentials attenuate this further
347
- * to `task:execute` alone.
348
- */
349
- var AGENT_CREDENTIAL_SCOPES = [
350
- CREDENTIAL_SCOPES.AgentProfile,
351
- CREDENTIAL_SCOPES.RuntimeRead,
352
- CREDENTIAL_SCOPES.TaskRead,
353
- CREDENTIAL_SCOPES.TaskClaim,
354
- CREDENTIAL_SCOPES.TaskExecute
355
- ];
356
- Object.freeze(ALL_CREDENTIAL_SCOPES.filter((scope) => scope !== CREDENTIAL_SCOPES.HumanProfile));
357
- [
358
- CREDENTIAL_SCOPES.AgentProfile,
359
- CREDENTIAL_SCOPES.CryptoSign,
360
- CREDENTIAL_SCOPES.DiaryManage,
361
- CREDENTIAL_SCOPES.DiaryRead,
362
- CREDENTIAL_SCOPES.DiaryWrite,
363
- CREDENTIAL_SCOPES.HumanProfile,
364
- CREDENTIAL_SCOPES.PackRead,
365
- CREDENTIAL_SCOPES.PackWrite,
366
- CREDENTIAL_SCOPES.TaskExecute,
367
- CREDENTIAL_SCOPES.TaskManage,
368
- CREDENTIAL_SCOPES.TaskRead,
369
- CREDENTIAL_SCOPES.TeamManage,
370
- CREDENTIAL_SCOPES.TeamRead
371
- ].filter((scope) => scope !== CREDENTIAL_SCOPES.HumanProfile);
372
- //#endregion
373
- //#region ../../libs/models/src/preview-sign.ts
374
- function schemaRef$1(schema, id) {
375
- return Type.Unsafe(Type.Ref(id));
376
- }
377
- var PreviewSignBase64UrlSchema = Type.String({
378
- $id: "PreviewSignBase64Url",
379
- minLength: 1,
380
- maxLength: 5462,
381
- pattern: "^[A-Za-z0-9_-]+$"
294
+ //#region ../../libs/tasks/src/task-artifacts.ts
295
+ var TaskArtifact = Type.Object({
296
+ id: Type.String({ format: "uuid" }),
297
+ teamId: Type.String({ format: "uuid" }),
298
+ taskId: Type.String({ format: "uuid" }),
299
+ attemptN: Type.Union([Type.Integer({ minimum: 1 }), Type.Null()]),
300
+ kind: Type.String({
301
+ minLength: 1,
302
+ maxLength: 100
303
+ }),
304
+ title: Type.String({
305
+ minLength: 1,
306
+ maxLength: 255
307
+ }),
308
+ contentType: Type.String({
309
+ minLength: 1,
310
+ maxLength: 200
311
+ }),
312
+ contentEncoding: Type.Union([Type.String({
313
+ minLength: 1,
314
+ maxLength: 100
315
+ }), Type.Null()]),
316
+ sizeBytes: Type.Integer({ minimum: 0 }),
317
+ cid: Type.String({
318
+ minLength: 1,
319
+ maxLength: 100
320
+ }),
321
+ createdByAgentId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
322
+ expiresAt: Type.Union([Type.String({ format: "date-time" }), Type.Null()]),
323
+ createdAt: Type.String({ format: "date-time" })
324
+ }, { $id: "TaskArtifact" });
325
+ Type.Object({
326
+ artifacts: Type.Array(TaskArtifact),
327
+ nextCursor: Type.Union([Type.String({ minLength: 1 }), Type.Null()])
328
+ }, { $id: "TaskArtifactList" });
329
+ Type.Object({
330
+ limit: Type.Optional(Type.Integer({
331
+ minimum: 1,
332
+ maximum: 100
333
+ })),
334
+ cursor: Type.Optional(Type.String({ minLength: 1 }))
335
+ }, {
336
+ $id: "ListTaskArtifactsQuery",
337
+ additionalProperties: false
382
338
  });
383
- var PreviewSignSha256Base64UrlSchema = Type.String({
384
- $id: "PreviewSignSha256Base64Url",
385
- minLength: 43,
386
- maxLength: 43,
387
- pattern: "^[A-Za-z0-9_-]+$"
339
+ var HeaderSafeContentType = Type.String({
340
+ minLength: 1,
341
+ maxLength: 200,
342
+ pattern: "^[\\x21-\\x7e][\\x20-\\x7e]*$"
388
343
  });
389
- var PreviewSignP256DerSignatureBase64UrlSchema = Type.String({
390
- $id: "PreviewSignP256DerSignatureBase64Url",
391
- minLength: 11,
392
- maxLength: 96,
393
- pattern: "^[A-Za-z0-9_-]+$"
344
+ var HeaderSafeContentEncoding = Type.String({
345
+ minLength: 1,
346
+ maxLength: 100,
347
+ pattern: "^[\\x21-\\x7e][\\x20-\\x7e]*$"
394
348
  });
395
- var PreviewSignEs256PublicKeySchema = Type.Object({
396
- kty: Type.Literal(2),
397
- algorithm: Type.Literal(-7),
398
- curve: Type.Literal(1),
399
- x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
400
- y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
349
+ Type.Object({
350
+ kind: Type.String({
351
+ minLength: 1,
352
+ maxLength: 100
353
+ }),
354
+ title: Type.String({
355
+ minLength: 1,
356
+ maxLength: 255
357
+ }),
358
+ contentType: Type.Optional(HeaderSafeContentType),
359
+ contentEncoding: Type.Optional(HeaderSafeContentEncoding)
401
360
  }, {
402
- $id: "PreviewSignEs256PublicKey",
361
+ $id: "UploadTaskArtifactQuery",
403
362
  additionalProperties: false
404
363
  });
405
- var PreviewSignEcdhEsHkdf256PublicKeySchema = Type.Object({
406
- kty: Type.Literal(2),
407
- algorithm: Type.Literal(-25),
408
- curve: Type.Literal(1),
409
- x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
410
- y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
411
- }, {
412
- $id: "PreviewSignEcdhEsHkdf256PublicKey",
413
- additionalProperties: false
364
+ Type.String({
365
+ $id: "TaskArtifactContent",
366
+ description: "Task artifact content stream.",
367
+ format: "binary"
414
368
  });
415
- var PreviewSignEsp256PublicKeySchema = Type.Object({
416
- kty: Type.Literal(2),
417
- algorithm: Type.Literal(-9),
418
- curve: Type.Literal(1),
419
- x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
420
- y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
421
- }, {
422
- $id: "PreviewSignEsp256PublicKey",
369
+ Type.Object({ taskId: Type.String({ format: "uuid" }) }, {
370
+ $id: "TaskArtifactTaskParams",
423
371
  additionalProperties: false
424
372
  });
425
- var PreviewSignArkgSeedPublicKeySchema = Type.Object({
426
- kty: Type.Literal(-65537),
427
- algorithm: Type.Literal(-65700),
428
- derivedAlgorithm: Type.Literal(-9),
429
- blindingKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
430
- kemKey: schemaRef$1(PreviewSignEcdhEsHkdf256PublicKeySchema, "PreviewSignEcdhEsHkdf256PublicKey")
373
+ Type.Object({
374
+ taskId: Type.String({ format: "uuid" }),
375
+ attemptN: Type.Integer({ minimum: 1 })
431
376
  }, {
432
- $id: "PreviewSignArkgSeedPublicKey",
377
+ $id: "TaskArtifactAttemptParams",
433
378
  additionalProperties: false
434
379
  });
435
- var PreviewSignPublicMaterialSchema = Type.Object({
436
- version: Type.Literal(1),
437
- outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
438
- outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
439
- previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
440
- seedPublicKey: schemaRef$1(PreviewSignArkgSeedPublicKeySchema, "PreviewSignArkgSeedPublicKey")
380
+ Type.Object({
381
+ taskId: Type.String({ format: "uuid" }),
382
+ attemptN: Type.Integer({ minimum: 1 }),
383
+ cid: Type.String({
384
+ minLength: 1,
385
+ maxLength: 100
386
+ })
441
387
  }, {
442
- $id: "PreviewSignPublicMaterial",
388
+ $id: "TaskArtifactContentParams",
443
389
  additionalProperties: false
444
390
  });
445
- var PreviewSignChallengeSchema = Type.Object({
446
- verificationMethod: Type.Literal("human-hardware-previewsign"),
447
- version: Type.Literal(1),
448
- envelope: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
449
- digest: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
450
- additionalArguments: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
451
- outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
452
- outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
453
- previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url")
391
+ Type.Object({
392
+ contentType: Type.Optional(HeaderSafeContentType),
393
+ contentEncoding: Type.Optional(HeaderSafeContentEncoding)
454
394
  }, {
455
- $id: "PreviewSignChallenge",
395
+ $id: "StageTaskArtifactQuery",
456
396
  additionalProperties: false
457
397
  });
458
- var PreviewSignChallengeValueSchema = Type.Object({
459
- verificationMethod: Type.Literal("human-hardware-previewsign"),
460
- value: schemaRef$1(PreviewSignChallengeSchema, "PreviewSignChallenge")
461
- }, {
462
- $id: "PreviewSignChallengeValue",
463
- additionalProperties: false
398
+ Type.Object({
399
+ cid: Type.String({
400
+ minLength: 1,
401
+ maxLength: 100
402
+ }),
403
+ sizeBytes: Type.Integer({ minimum: 0 }),
404
+ contentType: Type.String({
405
+ minLength: 1,
406
+ maxLength: 200
407
+ })
408
+ }, { $id: "StagedTaskArtifact" });
409
+ Type.Object({
410
+ taskId: Type.String({ format: "uuid" }),
411
+ cid: Type.String({
412
+ minLength: 1,
413
+ maxLength: 100
414
+ })
415
+ }, {
416
+ $id: "TaskArtifactTaskContentParams",
417
+ additionalProperties: false
464
418
  });
465
- var PreviewSignChallengeOperationSchema = Type.Union([Type.Literal("credential-registration"), Type.Literal("signing-request")], { $id: "PreviewSignChallengeOperation" });
466
- var PreviewSignReceiptSchema = Type.Object({
467
- version: Type.Literal(1),
468
- signature: schemaRef$1(PreviewSignP256DerSignatureBase64UrlSchema, "PreviewSignP256DerSignatureBase64Url")
419
+ //#endregion
420
+ //#region ../../libs/tasks/src/task-types/assess-brief.ts
421
+ /**
422
+ * `assess_brief` — independently evaluate a fulfilled brief.
423
+ *
424
+ * output_kind: judgment
425
+ * criteria: required (`successCriteria.rubric` — same envelope as
426
+ * `judge_pack`)
427
+ * references: required (must reference the target `fulfill_brief` task)
428
+ *
429
+ * The assessor is a different agent from the producer (enforced by the
430
+ * server / runtime at claim time — not in the wire schema).
431
+ *
432
+ * The rubric in `successCriteria` IS the job spec — the assessor applies
433
+ * it to the target task's output and emits per-criterion scores. Other
434
+ * sections (`assertions`, `gates`, `sideEffects`) MAY be present and are
435
+ * evaluated against the *assessor's output*.
436
+ */
437
+ var ASSESS_BRIEF_TYPE = "assess_brief";
438
+ var AssessBriefInput = Type.Object({
439
+ targetTaskId: Type.String({ format: "uuid" }),
440
+ successCriteria: SuccessCriteria
469
441
  }, {
470
- $id: "PreviewSignReceipt",
442
+ $id: "AssessBriefInput",
471
443
  additionalProperties: false
472
444
  });
473
- var PreviewSignReceiptValueSchema = Type.Object({
474
- verificationMethod: Type.Literal("human-hardware-previewsign"),
475
- value: schemaRef$1(PreviewSignReceiptSchema, "PreviewSignReceipt")
445
+ /** One score line. */
446
+ var AssessBriefScore = Type.Object({
447
+ criterionId: Type.String({ minLength: 1 }),
448
+ score: Type.Number({
449
+ minimum: 0,
450
+ maximum: 1
451
+ }),
452
+ rationale: Type.Optional(Type.String()),
453
+ evidence: Type.Optional(Type.Object({
454
+ commitsVerified: Type.Number(),
455
+ commitsTotal: Type.Number(),
456
+ signatureFailures: Type.Array(Type.String())
457
+ }, { additionalProperties: false }))
476
458
  }, {
477
- $id: "PreviewSignReceiptValue",
459
+ $id: "AssessBriefScore",
460
+ additionalProperties: false
461
+ });
462
+ var AssessBriefOutput = Type.Object({
463
+ scores: Type.Array(AssessBriefScore, { minItems: 1 }),
464
+ composite: Type.Number({
465
+ minimum: 0,
466
+ maximum: 1
467
+ }),
468
+ verdict: Type.String({ minLength: 1 }),
469
+ judgeModel: Type.Optional(Type.String())
470
+ }, {
471
+ $id: "AssessBriefOutput",
478
472
  additionalProperties: false
479
473
  });
480
- var previewSignSchemaContext = {
481
- PreviewSignBase64Url: PreviewSignBase64UrlSchema,
482
- PreviewSignSha256Base64Url: PreviewSignSha256Base64UrlSchema,
483
- PreviewSignP256DerSignatureBase64Url: PreviewSignP256DerSignatureBase64UrlSchema,
484
- PreviewSignEs256PublicKey: PreviewSignEs256PublicKeySchema,
485
- PreviewSignEcdhEsHkdf256PublicKey: PreviewSignEcdhEsHkdf256PublicKeySchema,
486
- PreviewSignEsp256PublicKey: PreviewSignEsp256PublicKeySchema,
487
- PreviewSignArkgSeedPublicKey: PreviewSignArkgSeedPublicKeySchema,
488
- PreviewSignPublicMaterial: PreviewSignPublicMaterialSchema,
489
- PreviewSignChallenge: PreviewSignChallengeSchema,
490
- PreviewSignChallengeValue: PreviewSignChallengeValueSchema,
491
- PreviewSignChallengeOperation: PreviewSignChallengeOperationSchema,
492
- PreviewSignReceipt: PreviewSignReceiptSchema,
493
- PreviewSignReceiptValue: PreviewSignReceiptValueSchema
494
- };
495
- //#endregion
496
- //#region ../../libs/models/src/verification-method.ts
497
474
  /**
498
- * Persisted and wire-level signing verification method identifiers.
475
+ * Async preflight (#1096):
476
+ * - `targetTaskId` resolves to a real task the caller can see.
477
+ * - The target is a `fulfill_brief` (you cannot grade an arbitrary
478
+ * task type as if it were a brief fulfillment).
479
+ * - Unless readiness checks are explicitly deferred, the target is
480
+ * `completed` with an accepted attempt — grading an in-flight or
481
+ * failed task would either race or grade nothing.
499
482
  *
500
- * This vocabulary is append-only. Never rename, remove, or change an existing
501
- * value: PostgreSQL rows, workflow inputs, and API clients persist these exact
502
- * strings. Future signing methods must add a new property and value.
483
+ * Agent-distinctness ("assessor ≠ producer") is a runtime / auth-
484
+ * layer concern and intentionally NOT checked here. It belongs in
485
+ * an auth-aware claim-time check.
503
486
  */
504
- var VERIFICATION_METHOD = {
505
- AgentEd25519: "agent-ed25519",
506
- HumanHardwarePreviewSign: "human-hardware-previewsign"
507
- };
508
- VERIFICATION_METHOD.AgentEd25519, VERIFICATION_METHOD.HumanHardwarePreviewSign;
487
+ async function validateAssessBriefInputAsync(input, ctx) {
488
+ const { targetTaskId } = input;
489
+ const errors = [];
490
+ const target = await ctx.resolveTask(targetTaskId);
491
+ if (!target) {
492
+ errors.push({
493
+ field: "targetTaskId",
494
+ message: `targetTaskId ${targetTaskId} does not resolve to a task you can read`
495
+ });
496
+ return errors;
497
+ }
498
+ if (target.taskType !== "fulfill_brief") errors.push({
499
+ field: "targetTaskId",
500
+ message: `targetTaskId ${targetTaskId} is a ${target.taskType}, not a fulfill_brief`
501
+ });
502
+ if (!ctx.deferReadinessChecks && (target.status !== "completed" || target.acceptedAttemptN === null)) errors.push({
503
+ field: "targetTaskId",
504
+ message: `targetTaskId ${targetTaskId} is not completed with an accepted attempt (status=${target.status}, acceptedAttemptN=${target.acceptedAttemptN})`
505
+ });
506
+ return errors;
507
+ }
509
508
  //#endregion
510
- //#region ../../libs/models/src/schemas.ts
511
- var UuidSchema = Type.String({
512
- format: "uuid",
513
- description: "UUID v4 identifier"
514
- });
515
- var TimestampSchema = Type.String({
516
- format: "date-time",
517
- description: "ISO 8601 timestamp"
518
- });
519
- var verificationMethodLiterals = [Type.Literal(VERIFICATION_METHOD.AgentEd25519), Type.Literal(VERIFICATION_METHOD.HumanHardwarePreviewSign)];
520
- Type.Union(verificationMethodLiterals, { description: "Stable signing verification method identifier" });
521
- var visibilityLiterals = [
522
- Type.Literal("private"),
523
- Type.Literal("moltnet"),
524
- Type.Literal("public")
525
- ];
526
- Type.Union(visibilityLiterals, { description: "Entry visibility level" });
527
- var ENTRY_TYPE_VALUES = [
528
- "episodic",
529
- "semantic",
530
- "procedural",
531
- "reflection"
532
- ];
533
- var entryTypeLiterals = [
509
+ //#region ../../libs/tasks/src/task-types/curate-pack.ts
510
+ /**
511
+ * `curate_pack` — select and rank diary entries into a context pack.
512
+ *
513
+ * output_kind: artifact
514
+ * criteria: not required (rubric-less curation recipe)
515
+ * references: optional (e.g. a prior rendered pack being re-curated)
516
+ *
517
+ * This is step 1 of the three-session attribution loop (#875). The agent
518
+ * runs a structured exploration over a diary — tag inventory, hybrid
519
+ * search, type/tag narrowing — and emits a ranked entry list via
520
+ * `moltnet_pack_create`. The prompt is deterministic given the input
521
+ * (no operator interaction), so two runs with the same input should
522
+ * converge on similar packs.
523
+ *
524
+ * Related: `render_pack`, `judge_pack`.
525
+ */
526
+ var CURATE_PACK_TYPE = "curate_pack";
527
+ var EntryTypeFilter = Type.Union([
534
528
  Type.Literal("episodic"),
535
529
  Type.Literal("semantic"),
536
530
  Type.Literal("procedural"),
537
531
  Type.Literal("reflection")
538
- ];
539
- var EntryTypeSchema = Type.Union(entryTypeLiterals, { description: "Entry memory type" });
540
- /** Regex fragment matching a single entry type value. */
541
- var ENTRY_TYPE_PATTERN = `(${ENTRY_TYPE_VALUES.join("|")})`;
542
- `${ENTRY_TYPE_PATTERN}${ENTRY_TYPE_PATTERN}`, ENTRY_TYPE_VALUES.length - 1;
543
- var PublicKeySchema = Type.String({
544
- pattern: "^ed25519:[A-Za-z0-9+/=]+$",
545
- description: "Ed25519 public key with prefix"
546
- });
547
- var FingerprintSchema = Type.String({
548
- pattern: "^[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}$",
549
- description: "Key fingerprint (A1B2-C3D4-E5F6-G7H8)"
550
- });
551
- Type.Object({
552
- title: Type.Optional(Type.String({ maxLength: 255 })),
553
- content: Type.String({
554
- minLength: 1,
555
- maxLength: 1e5
556
- }),
557
- tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), { maxItems: 20 }))
532
+ ]);
533
+ var CuratePackInput = Type.Object({
534
+ diaryId: Type.String({ format: "uuid" }),
535
+ taskPrompt: Type.String({ minLength: 1 }),
536
+ entryTypes: Type.Optional(Type.Array(EntryTypeFilter, { minItems: 1 })),
537
+ tagFilters: Type.Optional(Type.Object({
538
+ include: Type.Optional(Type.Array(Type.String())),
539
+ exclude: Type.Optional(Type.Array(Type.String())),
540
+ prefix: Type.Optional(Type.String())
541
+ }, { additionalProperties: false })),
542
+ tokenBudget: Type.Optional(Type.Number({ minimum: 500 })),
543
+ recipe: Type.Optional(Type.Union([Type.Literal("topic-focused-v1"), Type.Literal("scope-inventory-v1")])),
544
+ successCriteria: Type.Optional(SuccessCriteria)
545
+ }, {
546
+ $id: "CuratePackInput",
547
+ additionalProperties: false
558
548
  });
559
- Type.Object({
560
- title: Type.Optional(Type.String({ maxLength: 255 })),
561
- content: Type.Optional(Type.String({
562
- minLength: 1,
563
- maxLength: 1e5
564
- })),
565
- tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), { maxItems: 20 }))
549
+ /**
550
+ * Index of the curated pack plus the reasoning trace. The pack itself
551
+ * lives in the database (created via `moltnet_pack_create`); this output
552
+ * is the receipt.
553
+ */
554
+ var CuratePackOutput = Type.Object({
555
+ packId: Type.String({ format: "uuid" }),
556
+ packCid: Type.String({ minLength: 1 }),
557
+ entries: Type.Array(Type.Object({
558
+ entryId: Type.String({ format: "uuid" }),
559
+ rank: Type.Number({ minimum: 1 }),
560
+ rationale: Type.String({ minLength: 1 })
561
+ }, { additionalProperties: false }), { minItems: 1 }),
562
+ recipeParams: Type.Record(Type.String(), Type.Unknown()),
563
+ checkpoints: Type.Optional(Type.Array(Type.Object({
564
+ phase: Type.String({ minLength: 1 }),
565
+ candidateIds: Type.Array(Type.String({ format: "uuid" })),
566
+ droppedIds: Type.Optional(Type.Array(Type.String({ format: "uuid" }))),
567
+ notes: Type.String({ minLength: 1 })
568
+ }, { additionalProperties: false }))),
569
+ summary: Type.String({ minLength: 1 }),
570
+ verification: Type.Optional(VerificationRecord)
571
+ }, {
572
+ $id: "CuratePackOutput",
573
+ additionalProperties: false
566
574
  });
567
- Type.Object({
568
- query: Type.Optional(Type.String({
569
- minLength: 1,
570
- maxLength: 500
571
- })),
572
- tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), {
573
- minItems: 1,
574
- maxItems: 20,
575
- description: "Filter: entry must have ALL specified tags"
576
- })),
577
- limit: Type.Optional(Type.Number({
578
- minimum: 1,
579
- maximum: 100,
580
- default: 20
581
- })),
582
- offset: Type.Optional(Type.Number({
583
- minimum: 0,
584
- default: 0
585
- }))
586
- });
587
- Type.Object({
588
- identityId: UuidSchema,
589
- publicKey: PublicKeySchema,
590
- fingerprint: FingerprintSchema,
591
- createdAt: TimestampSchema
592
- });
593
- Type.Object({
594
- publicKey: PublicKeySchema,
595
- fingerprint: FingerprintSchema
596
- });
597
- Type.Object({ message: Type.String({
598
- minLength: 1,
599
- maxLength: 1e4
600
- }) });
601
- Type.Object({
602
- message: Type.String(),
603
- signature: Type.String({ description: "Base64 encoded Ed25519 signature" }),
604
- publicKey: PublicKeySchema
605
- });
606
- Type.Object({
607
- message: Type.String({
608
- minLength: 1,
609
- maxLength: 1e4
610
- }),
611
- signature: Type.String({ description: "Base64 encoded signature" }),
612
- publicKey: PublicKeySchema
613
- });
614
- Type.Object({
615
- valid: Type.Boolean(),
616
- signer: Type.Optional(Type.Object({ fingerprint: FingerprintSchema }))
617
- });
618
- var BaseAuthContextSchema = Type.Object({
619
- identityId: UuidSchema,
620
- scopes: Type.Array(Type.String()),
621
- subjectType: Type.Union([Type.Literal("agent"), Type.Literal("human")]),
622
- currentTeamId: Type.Union([UuidSchema, Type.Null()])
623
- });
624
- var AgentAuthContextSchema = Type.Intersect([BaseAuthContextSchema, Type.Object({
625
- subjectType: Type.Literal("agent"),
626
- publicKey: PublicKeySchema,
627
- fingerprint: FingerprintSchema,
628
- clientId: Type.String()
629
- })]);
630
- var HumanAuthContextSchema = Type.Intersect([BaseAuthContextSchema, Type.Object({
631
- subjectType: Type.Literal("human"),
632
- clientId: Type.Union([Type.String(), Type.Null()])
633
- })]);
634
- Type.Union([AgentAuthContextSchema, HumanAuthContextSchema]);
635
- Type.Object({
636
- success: Type.Boolean(),
637
- message: Type.Optional(Type.String())
638
- });
639
- Type.Object({ diaryId: UuidSchema });
640
- Type.Object({
641
- diaryId: UuidSchema,
642
- entryId: UuidSchema
643
- });
644
- Type.Object({ entryId: UuidSchema });
645
- Type.Object({ id: UuidSchema });
646
- Type.Object({
647
- publicKey: PublicKeySchema,
648
- fingerprint: FingerprintSchema,
649
- proof: Type.String({
650
- minLength: 1,
651
- maxLength: 256
652
- }),
653
- credentialType: Type.Literal("oauth2"),
654
- agentName: Type.String({
575
+ //#endregion
576
+ //#region ../../libs/runtime-profiles/src/context.ts
577
+ /**
578
+ * How an executor delivers a context entry to its underlying LLM.
579
+ * V1 bindings only; Tier-2 (reference_file, mcp_resource, imported_file,
580
+ * tool_response_seed, additional_context_hook) ship in a later slice.
581
+ */
582
+ var CONTEXT_BINDINGS = [
583
+ "skill",
584
+ "context_inline",
585
+ "prompt_prefix",
586
+ "user_inline"
587
+ ];
588
+ /** Maximum UTF-16 code units accepted in one ContextRef content field. */
589
+ var CONTEXT_REF_MAX_CONTENT_LENGTH = 65536;
590
+ var ContextBinding = Type.Unsafe(Type.Union(CONTEXT_BINDINGS.map((binding) => Type.Literal(binding)), { $id: "ContextBinding" }));
591
+ /**
592
+ * One context entry. Bytes are inlined: the proposer chose them, and the
593
+ * task's `inputCid` already pins the entire input — including
594
+ * `context[]` — so we don't need a separate per-entry hash, fetcher, or
595
+ * flagged-content gate. Tasks reference rendered packs (or any other
596
+ * external content) by copying their bytes into `content` at task
597
+ * creation time.
598
+ *
599
+ * - `slug` — short identifier the daemon uses to disambiguate
600
+ * entries. For `skill` binding it becomes the directory
601
+ * name under the runtime's skill discovery path. Must be
602
+ * kebab-case-safe (alphanumeric + dashes/underscores).
603
+ * - `binding` — how the bytes are delivered to the LLM (see above).
604
+ * - `content` — UTF-8 text. Capped at 65,536 UTF-16 code units per
605
+ * entry; total per-task context bytes are bounded by the
606
+ * soft `maxItems` cap and per-binding daemon limits.
607
+ * Raised from 32 KiB in 2026-05 — protocol-heavy operator
608
+ * skills (e.g. `.claude/skills/legreffier/SKILL.md`) ship
609
+ * at ~35 KiB inline, and the original cap was sized for
610
+ * short example skills, not the kind of skill the eval
611
+ * substrate is dogfooded on (#943, #823).
612
+ */
613
+ var ContextRef = Type.Object({
614
+ slug: Type.String({
655
615
  minLength: 1,
656
- maxLength: 34
616
+ maxLength: 64,
617
+ pattern: "^[a-zA-Z0-9_-]+$"
657
618
  }),
658
- org: Type.Optional(Type.String({
659
- minLength: 1,
660
- maxLength: 39,
661
- pattern: "^[a-zA-Z0-9-]+$",
662
- description: "GitHub organization name. When provided, the GitHub App will be created under this org instead of the personal account."
663
- }))
664
- });
665
- Type.Object({
666
- workflowId: Type.String(),
667
- manifestFormUrl: Type.String()
668
- });
669
- Type.Object({
670
- status: Type.Union([
671
- Type.Literal("awaiting_github"),
672
- Type.Literal("github_code_ready"),
673
- Type.Literal("awaiting_installation"),
674
- Type.Literal("completed"),
675
- Type.Literal("failed")
676
- ]),
677
- githubCode: Type.Optional(Type.String({ description: "GitHub manifest code sealed to the onboarding agent public key." })),
678
- identityId: Type.Optional(Type.String()),
679
- clientId: Type.Optional(Type.String()),
680
- clientSecret: Type.Optional(Type.String({ description: "OAuth2 client secret sealed to the onboarding agent public key." })),
681
- installationId: Type.Optional(Type.String())
682
- });
683
- Type.Object({
684
- wf: Type.String({
619
+ binding: ContextBinding,
620
+ content: Type.String({
685
621
  minLength: 1,
686
- description: "Workflow ID baked into setup_url"
687
- }),
688
- installation_id: Type.String({ minLength: 1 }),
689
- setup_action: Type.Optional(Type.String())
690
- });
691
- Type.Object({ id: UuidSchema });
692
- Type.Object({
693
- id: UuidSchema,
694
- subjectId: UuidSchema
622
+ maxLength: CONTEXT_REF_MAX_CONTENT_LENGTH
623
+ })
624
+ }, {
625
+ $id: "ContextRef",
626
+ additionalProperties: false
695
627
  });
696
- Type.Object({
697
- id: UuidSchema,
698
- inviteId: UuidSchema
628
+ /** Reusable input fragment for any task type. Soft cap at 5 items. */
629
+ var TaskContext = Type.Array(ContextRef, {
630
+ $id: "TaskContext",
631
+ maxItems: 5
699
632
  });
700
- Type.Object({ name: Type.String({
633
+ //#endregion
634
+ //#region ../../libs/runtime-profiles/src/runtime-models.ts
635
+ /**
636
+ * Runtime model catalog: a list of supported provider/model couples that
637
+ * MoltNet daemons can target. Backed by the `runtime_models` table.
638
+ *
639
+ * Scope is intrinsic to the row:
640
+ * - `teamId == null` => global entry (MoltNet-seeded, read-only to most callers)
641
+ * - `teamId != null` => team-owned custom entry
642
+ *
643
+ * The REST API exposes a single shape regardless of scope; the team header
644
+ * gates which rows are returned.
645
+ */
646
+ var RuntimeModelProvider = Type.String({
701
647
  minLength: 1,
702
- maxLength: 255
703
- }) });
704
- Type.Object({
705
- role: Type.Optional(Type.Union([Type.Literal("manager"), Type.Literal("member")])),
706
- maxUses: Type.Optional(Type.Integer({
707
- minimum: 1,
708
- default: 1
709
- })),
710
- expiresInHours: Type.Optional(Type.Integer({
711
- minimum: 1,
712
- maximum: 720,
713
- default: 168
714
- }))
715
- });
716
- Type.Object({ code: Type.String({ minLength: 1 }) });
717
- Type.Object({ role: Type.Union([Type.Literal("manager"), Type.Literal("member")]) });
718
- var TeamRoleSchema = Type.Union([
719
- Type.Literal("owner"),
720
- Type.Literal("manager"),
721
- Type.Literal("member")
722
- ]);
723
- Type.Object({
724
- id: UuidSchema,
725
- name: Type.String()
726
- });
727
- var DateTimeUnsafe = Type.Unsafe(Type.String({ format: "date-time" }));
728
- Type.Object({
729
- id: UuidSchema,
730
- code: Type.String(),
731
- role: Type.Union([Type.Literal("manager"), Type.Literal("member")]),
732
- maxUses: Type.Integer(),
733
- useCount: Type.Integer(),
734
- expiresAt: DateTimeUnsafe,
735
- createdAt: DateTimeUnsafe
736
- });
737
- var TeamMemberSchema = Type.Object({
738
- subjectId: UuidSchema,
739
- subjectType: Type.Union([Type.Literal("agent"), Type.Literal("human")]),
740
- role: TeamRoleSchema,
741
- displayName: Type.String(),
742
- fingerprint: Type.Optional(Type.String()),
743
- email: Type.Optional(Type.String())
744
- });
745
- Type.Object({
746
- id: UuidSchema,
747
- name: Type.String(),
748
- personal: Type.Boolean(),
749
- status: Type.String(),
750
- role: TeamRoleSchema
751
- });
752
- Type.Object({
753
- id: UuidSchema,
754
- name: Type.String(),
755
- status: Type.String(),
756
- personal: Type.Boolean(),
757
- createdAt: DateTimeUnsafe,
758
- updatedAt: DateTimeUnsafe,
759
- members: Type.Array(TeamMemberSchema)
760
- });
761
- Type.Object({
762
- teamId: UuidSchema,
763
- role: Type.Union([Type.Literal("manager"), Type.Literal("member")])
764
- });
765
- Type.Object({
766
- updated: Type.Boolean(),
767
- role: Type.Union([Type.Literal("manager"), Type.Literal("member")])
768
- });
769
- Type.Object({ deleted: Type.Boolean() });
770
- Type.Object({ removed: Type.Boolean() });
771
- var FoundingMemberSchema = Type.Object({
772
- subjectId: UuidSchema,
773
- subjectNs: Type.Union([Type.Literal("Agent"), Type.Literal("Human")]),
774
- role: Type.Union([
775
- Type.Literal("owner"),
776
- Type.Literal("manager"),
777
- Type.Literal("member")
778
- ])
779
- });
780
- Type.Object({
781
- name: Type.String({
782
- minLength: 1,
783
- maxLength: 255
784
- }),
785
- foundingMembers: Type.Optional(Type.Array(FoundingMemberSchema, { minItems: 1 }))
786
- });
787
- Type.Object({
788
- id: UuidSchema,
789
- name: Type.String(),
790
- status: Type.String(),
791
- workflowId: Type.Optional(Type.String())
792
- });
793
- Type.Object({});
794
- Type.Object({
795
- accepted: Type.Boolean(),
796
- teamStatus: Type.String()
648
+ maxLength: 100,
649
+ pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,99}$"
797
650
  });
798
- Type.Object({ destinationTeamId: UuidSchema });
799
- Type.Object({ transferId: UuidSchema });
800
- var TransferResponseSchema = Type.Object({
801
- id: UuidSchema,
802
- diaryId: UuidSchema,
803
- sourceTeamId: UuidSchema,
804
- destinationTeamId: UuidSchema,
805
- status: Type.String(),
806
- initiatedBy: UuidSchema,
807
- expiresAt: Type.Unsafe(Type.String({ format: "date-time" })),
808
- createdAt: Type.Unsafe(Type.String({ format: "date-time" }))
651
+ var RuntimeModelName = Type.String({
652
+ minLength: 1,
653
+ maxLength: 200,
654
+ pattern: "^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,199}$"
809
655
  });
810
- Type.Object({ items: Type.Array(TransferResponseSchema) });
811
- Type.Object({ groupId: UuidSchema });
656
+ var RuntimeModelCapabilities = Type.Record(Type.String({
657
+ minLength: 1,
658
+ maxLength: 64
659
+ }), Type.Union([
660
+ Type.Boolean(),
661
+ Type.Number(),
662
+ Type.String({ maxLength: 256 })
663
+ ]));
812
664
  Type.Object({
813
- groupId: UuidSchema,
814
- subjectId: UuidSchema
665
+ id: Type.String({ format: "uuid" }),
666
+ teamId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
667
+ provider: RuntimeModelProvider,
668
+ model: RuntimeModelName,
669
+ displayName: Type.Union([Type.String({ maxLength: 200 }), Type.Null()]),
670
+ description: Type.Union([Type.String({ maxLength: 4096 }), Type.Null()]),
671
+ capabilities: RuntimeModelCapabilities,
672
+ isActive: Type.Boolean(),
673
+ createdByAgentId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
674
+ createdByHumanId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
675
+ createdAt: Type.String({ format: "date-time" }),
676
+ updatedAt: Type.String({ format: "date-time" })
677
+ }, {
678
+ $id: "RuntimeModel",
679
+ additionalProperties: false
815
680
  });
816
- Type.Object({ name: Type.String({
681
+ //#endregion
682
+ //#region ../../libs/runtime-profiles/src/runtime-profile-context-recipes.ts
683
+ var RUNTIME_PROFILE_CONTEXT_CATALOGUE = {
684
+ version: 1,
685
+ fragments: {
686
+ "artifact-planner-v1": {
687
+ binding: "prompt_prefix",
688
+ content: "# Bounded artifact planner\n\n- The typed task facts, embedded bounded manifest, exact bound artifact references, registered tools, and runtime capability section are the complete contract. Do not search diaries, inspect a mounted repository, enumerate unrelated tasks or artifacts, modify a checkout, commit, branch, push, or contact GitHub.\n- Read only the exact artifact CIDs named by the task, and only when the embedded manifest does not provide enough evidence. Use the registered task-artifact tools for artifact access; never use shell or CLI wrappers to fetch artifacts, paginate, or discover them speculatively.\n- If the effective runtime exposes a local calculator or shell, use it only inside scratch for coverage accounting, budget arithmetic, and JSON validation. The runtime capability section and policy are authoritative; do not assume a static executable list.\n- Perform semantic classification and planning from supplied content and producer/consumer evidence. Do not substitute filename, directory, language, ecosystem, or repository-specific exclusion rules for evidence.\n- Write and upload exactly the requested versioned plan artifact, then reference its returned metadata through the registered submit-output tool. Do not emit a second prose or JSON representation.",
689
+ slug: "artifact-planner-v1"
690
+ },
691
+ "accountable-delivery-v1": {
692
+ binding: "prompt_prefix",
693
+ content: "# Accountable delivery\n\n- Pair every commit made during this task with a task-provenance diary entry created by the `moltnet_create_entry` custom tool. Put the returned id in a `MoltNet-Diary: <id>` commit trailer. The tool does not currently promise a content signature unless you pass `signed: true` while the runtime kernel declares the `agent-signing` host capability; never describe an entry as signed otherwise.\n- When the runtime kernel declares `agent-signing`, sign commits normally with `git commit -S`: the signature is brokered to the trusted host through `SSH_AUTH_SOCK` and no private key exists in the guest. Without that capability commits are unsigned; do not disable signing the runtime provides, and never try to obtain a key from host configuration.\n- Push a branch and open or update a pull request only when the task asks for it. Use a host-brokered GitHub placeholder only when the runtime kernel declares one; if no GitHub credential is active, the authenticated operation is unavailable.\n- Keep changes, commits, and any requested pull request coherent enough to review independently.",
694
+ slug: "accountable-delivery-v1"
695
+ },
696
+ "judgment-diary-v1": {
697
+ binding: "prompt_prefix",
698
+ content: "# Judgment diary discipline\n\n- For an `assess_brief`, `judge_pack`, or `pr_review` task, create a diary entry with the `moltnet_create_entry` custom tool before submitting the structured judgment. Capture the rationale and evidence that support the verdict. Do not claim a content signature unless you created the entry with `signed: true` under a runtime that declares the `agent-signing` host capability.\n- Add the `judgment` tag and the active task type tag (`assess_brief`, `judge_pack`, or `pr_review`). For `judge_pack`, also add `rubric:<rubricId>` from the task facts.\n- Do not use a shell `moltnet entry` command: task provenance is injected only by the custom tool.",
699
+ slug: "judgment-diary-v1"
700
+ },
701
+ "proactive-memory-v1": {
702
+ binding: "prompt_prefix",
703
+ content: "# Proactive memory use\n\n- Before non-trivial investigation, debugging, code changes, or review, check the task diary for relevant prior knowledge instead of waiting for a human to ask. Use `moltnet_diary_tags` for cheap reconnaissance, `moltnet_list_entries` when tags or task provenance are known, and `moltnet_search_entries` for semantic similarity. Do not search randomly: pass `taskFilter` for task-local or correlation-local queries, and pass `tags` / `entryTypes` for broader prior-knowledge queries using known tags such as `incident`, `decision`, or `scope:<area>`. Broaden only after constrained searches miss.\n- Before creating an `episodic` incident entry, search for similar incidents using the proposed title, root cause, error text, affected subsystem, and watch-for terms, filtered by `entryTypes: [\"episodic\", \"semantic\"]` and any known `scope:*` or task-provenance tags. If a close prior match exists, do not create an isolated duplicate: reference the prior entry in your response or diary content, update or link it when the new occurrence adds material evidence, or create a new recurrence entry only when the recurrence itself is important signal.\n- When you create a recurrence entry, include the prior matching entry id(s) in the content and explain what is new about this occurrence.",
704
+ slug: "proactive-memory-v1"
705
+ },
706
+ "run-eval-direct-v1": {
707
+ binding: "prompt_prefix",
708
+ content: "# Direct evaluation run\n\nThe supplied scenario, typed task facts, injected context, and registered submit-output tool are the complete task contract. Do not search diaries, create diary entries, modify a repository, commit, branch, push, or open a pull request unless a task fact explicitly requires it. Submit the agent-authored payload in the first turn; correction turns exist only to recover a rejected or missing submission.",
709
+ slug: "run-eval-direct-v1"
710
+ },
711
+ "task-diary-discipline-v1": {
712
+ binding: "prompt_prefix",
713
+ content: "# Task diary discipline\n\n- During a daemon task, create diary entries only through the `moltnet_create_entry` custom tool. It binds entries to the current task diary and injects task, type, attempt, and correlation provenance tags.\n- Do not shell out to `moltnet entry create`, `moltnet entry create-signed`, or any other `moltnet entry` subcommand from bash while a task is running. For a content-signed entry pass `signed: true` to the custom tool instead; it signs on the trusted host. Those shell paths bypass the custom tool's task-tag injection, so task-filtered diary queries cannot find the entry.\n- You may add useful tags, but do not try to replace task provenance supplied by the runtime.",
714
+ slug: "task-diary-discipline-v1"
715
+ },
716
+ "verification-and-artifacts-v1": {
717
+ binding: "prompt_prefix",
718
+ content: "# Verification and artifacts\n\n- Run relevant verification before submitting. When task facts include `successCriteria`, assess them honestly in the generated verification contract; a fail or skip with evidence is better than a fabricated pass.\n- The registered submit-output tool owns the exact agent submission schema and validation recovery. Use that schema; do not invent a JSON shape in prose.\n- Upload only task-relevant artifacts, and inspect each before uploading. Never upload secrets, credentials, API keys, auth tokens or headers, .env files, or personal or customer data; redact sensitive values, and prefer minimal, sanitized excerpts over whole logs, bundles, or datasets. Include artifact metadata only where the typed submit contract permits it.\n- If the task depends on prior artifacts, list and download the exact referenced artifact before judging or continuing that work.",
719
+ slug: "verification-and-artifacts-v1"
720
+ }
721
+ },
722
+ recipes: {
723
+ "artifact-planner@v1": {
724
+ description: "Minimal artifact-only context for bounded semantic classification and planning.",
725
+ fragments: ["artifact-planner-v1"]
726
+ },
727
+ "run-eval-direct@v1": {
728
+ description: "Minimal direct context for a short, isolated evaluation run.",
729
+ fragments: ["run-eval-direct-v1"]
730
+ },
731
+ "standard-engineering@v1": {
732
+ description: "Full opt-in operating guidance for engineering tasks that need diary research, accountable delivery, and verification discipline.",
733
+ fragments: [
734
+ "proactive-memory-v1",
735
+ "task-diary-discipline-v1",
736
+ "accountable-delivery-v1",
737
+ "judgment-diary-v1",
738
+ "verification-and-artifacts-v1"
739
+ ]
740
+ }
741
+ }
742
+ };
743
+ function deepFreeze(value) {
744
+ if (value && typeof value === "object") {
745
+ for (const key of Object.keys(value)) deepFreeze(value[key]);
746
+ Object.freeze(value);
747
+ }
748
+ return value;
749
+ }
750
+ deepFreeze(RUNTIME_PROFILE_CONTEXT_CATALOGUE);
751
+ Object.freeze(Object.keys(RUNTIME_PROFILE_CONTEXT_CATALOGUE.recipes));
752
+ //#endregion
753
+ //#region ../../libs/models/src/credential-scopes.ts
754
+ var CREDENTIAL_SCOPES = {
755
+ AgentProfile: "agent:profile",
756
+ ConnectorInvoke: "connector:invoke",
757
+ CryptoSign: "crypto:sign",
758
+ DiaryManage: "diary:manage",
759
+ DiaryRead: "diary:read",
760
+ DiaryWrite: "diary:write",
761
+ HumanProfile: "human:profile",
762
+ KeyManage: "key:manage",
763
+ PackRead: "pack:read",
764
+ PackWrite: "pack:write",
765
+ RuntimeManage: "runtime:manage",
766
+ RuntimeRead: "runtime:read",
767
+ TaskClaim: "task:claim",
768
+ TaskExecute: "task:execute",
769
+ TaskManage: "task:manage",
770
+ TaskRead: "task:read",
771
+ TeamManage: "team:manage",
772
+ TeamRead: "team:read"
773
+ };
774
+ var ALL_CREDENTIAL_SCOPES = Object.freeze(Object.values(CREDENTIAL_SCOPES));
775
+ /**
776
+ * Minimum grant for the agent daemon. Task credentials attenuate this further
777
+ * to `task:execute` alone.
778
+ */
779
+ var AGENT_CREDENTIAL_SCOPES = [
780
+ CREDENTIAL_SCOPES.AgentProfile,
781
+ CREDENTIAL_SCOPES.RuntimeRead,
782
+ CREDENTIAL_SCOPES.TaskRead,
783
+ CREDENTIAL_SCOPES.TaskClaim,
784
+ CREDENTIAL_SCOPES.TaskExecute
785
+ ];
786
+ Object.freeze(ALL_CREDENTIAL_SCOPES.filter((scope) => scope !== CREDENTIAL_SCOPES.HumanProfile));
787
+ [
788
+ CREDENTIAL_SCOPES.AgentProfile,
789
+ CREDENTIAL_SCOPES.CryptoSign,
790
+ CREDENTIAL_SCOPES.DiaryManage,
791
+ CREDENTIAL_SCOPES.DiaryRead,
792
+ CREDENTIAL_SCOPES.DiaryWrite,
793
+ CREDENTIAL_SCOPES.HumanProfile,
794
+ CREDENTIAL_SCOPES.PackRead,
795
+ CREDENTIAL_SCOPES.PackWrite,
796
+ CREDENTIAL_SCOPES.TaskExecute,
797
+ CREDENTIAL_SCOPES.TaskManage,
798
+ CREDENTIAL_SCOPES.TaskRead,
799
+ CREDENTIAL_SCOPES.TeamManage,
800
+ CREDENTIAL_SCOPES.TeamRead
801
+ ].filter((scope) => scope !== CREDENTIAL_SCOPES.HumanProfile);
802
+ //#endregion
803
+ //#region ../../libs/models/src/preview-sign.ts
804
+ function schemaRef$1(schema, id) {
805
+ return Type.Unsafe(Type.Ref(id));
806
+ }
807
+ var PreviewSignBase64UrlSchema = Type.String({
808
+ $id: "PreviewSignBase64Url",
817
809
  minLength: 1,
818
- maxLength: 255
819
- }) });
820
- Type.Object({
821
- subjectId: UuidSchema,
822
- subjectNs: Type.Optional(Type.Union([Type.Literal("Agent"), Type.Literal("Human")]))
823
- });
824
- Type.Object({
825
- id: UuidSchema,
826
- name: Type.String(),
827
- teamId: UuidSchema
810
+ maxLength: 5462,
811
+ pattern: "^[A-Za-z0-9_-]+$"
828
812
  });
829
- var GroupMemberResponseSchema = Type.Object({
830
- subjectId: UuidSchema,
831
- subjectNs: Type.String()
813
+ var PreviewSignSha256Base64UrlSchema = Type.String({
814
+ $id: "PreviewSignSha256Base64Url",
815
+ minLength: 43,
816
+ maxLength: 43,
817
+ pattern: "^[A-Za-z0-9_-]+$"
832
818
  });
833
- Type.Object({
834
- id: UuidSchema,
835
- name: Type.String(),
836
- teamId: UuidSchema,
837
- createdAt: DateTimeUnsafe,
838
- members: Type.Array(GroupMemberResponseSchema)
819
+ var PreviewSignP256DerSignatureBase64UrlSchema = Type.String({
820
+ $id: "PreviewSignP256DerSignatureBase64Url",
821
+ minLength: 11,
822
+ maxLength: 96,
823
+ pattern: "^[A-Za-z0-9_-]+$"
839
824
  });
840
- var DiaryGrantRoleSchema = Type.Union([Type.Literal("writer"), Type.Literal("manager")]);
841
- var GrantSubjectNsSchema = Type.Union([
842
- Type.Literal("Agent"),
843
- Type.Literal("Human"),
844
- Type.Literal("Group")
845
- ]);
846
- Type.Object({
847
- subjectId: UuidSchema,
848
- subjectNs: GrantSubjectNsSchema,
849
- role: DiaryGrantRoleSchema
825
+ var PreviewSignEs256PublicKeySchema = Type.Object({
826
+ kty: Type.Literal(2),
827
+ algorithm: Type.Literal(-7),
828
+ curve: Type.Literal(1),
829
+ x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
830
+ y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
831
+ }, {
832
+ $id: "PreviewSignEs256PublicKey",
833
+ additionalProperties: false
850
834
  });
851
- Type.Object({
852
- subjectId: UuidSchema,
853
- subjectNs: GrantSubjectNsSchema,
854
- role: DiaryGrantRoleSchema
835
+ var PreviewSignEcdhEsHkdf256PublicKeySchema = Type.Object({
836
+ kty: Type.Literal(2),
837
+ algorithm: Type.Literal(-25),
838
+ curve: Type.Literal(1),
839
+ x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
840
+ y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
841
+ }, {
842
+ $id: "PreviewSignEcdhEsHkdf256PublicKey",
843
+ additionalProperties: false
855
844
  });
856
- var DiaryGrantResponseSchema = Type.Object({
857
- subjectId: UuidSchema,
858
- subjectNs: GrantSubjectNsSchema,
859
- role: DiaryGrantRoleSchema
845
+ var PreviewSignEsp256PublicKeySchema = Type.Object({
846
+ kty: Type.Literal(2),
847
+ algorithm: Type.Literal(-9),
848
+ curve: Type.Literal(1),
849
+ x: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
850
+ y: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url")
851
+ }, {
852
+ $id: "PreviewSignEsp256PublicKey",
853
+ additionalProperties: false
860
854
  });
861
- Type.Object({ grants: Type.Array(DiaryGrantResponseSchema) });
862
- Type.Object({ revoked: Type.Boolean() });
863
- var TaskGrantRoleSchema = Type.Union([Type.Literal("writer"), Type.Literal("manager")]);
864
- Type.Object({
865
- subjectId: UuidSchema,
866
- subjectNs: GrantSubjectNsSchema,
867
- role: TaskGrantRoleSchema
855
+ var PreviewSignArkgSeedPublicKeySchema = Type.Object({
856
+ kty: Type.Literal(-65537),
857
+ algorithm: Type.Literal(-65700),
858
+ derivedAlgorithm: Type.Literal(-9),
859
+ blindingKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
860
+ kemKey: schemaRef$1(PreviewSignEcdhEsHkdf256PublicKeySchema, "PreviewSignEcdhEsHkdf256PublicKey")
861
+ }, {
862
+ $id: "PreviewSignArkgSeedPublicKey",
863
+ additionalProperties: false
868
864
  });
869
- Type.Object({
870
- subjectId: UuidSchema,
871
- subjectNs: GrantSubjectNsSchema,
872
- role: TaskGrantRoleSchema
865
+ var PreviewSignPublicMaterialSchema = Type.Object({
866
+ version: Type.Literal(1),
867
+ outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
868
+ outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
869
+ previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
870
+ seedPublicKey: schemaRef$1(PreviewSignArkgSeedPublicKeySchema, "PreviewSignArkgSeedPublicKey")
871
+ }, {
872
+ $id: "PreviewSignPublicMaterial",
873
+ additionalProperties: false
873
874
  });
874
- var TaskGrantResponseSchema = Type.Object({
875
- subjectId: UuidSchema,
876
- subjectNs: GrantSubjectNsSchema,
877
- role: TaskGrantRoleSchema
875
+ var PreviewSignChallengeSchema = Type.Object({
876
+ verificationMethod: Type.Literal("human-hardware-previewsign"),
877
+ version: Type.Literal(1),
878
+ envelope: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
879
+ digest: schemaRef$1(PreviewSignSha256Base64UrlSchema, "PreviewSignSha256Base64Url"),
880
+ additionalArguments: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
881
+ outerCredentialId: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url"),
882
+ outerPublicKey: schemaRef$1(PreviewSignEs256PublicKeySchema, "PreviewSignEs256PublicKey"),
883
+ previewKeyHandle: schemaRef$1(PreviewSignBase64UrlSchema, "PreviewSignBase64Url")
884
+ }, {
885
+ $id: "PreviewSignChallenge",
886
+ additionalProperties: false
878
887
  });
879
- Type.Object({ grants: Type.Array(TaskGrantResponseSchema) });
880
- Type.Object({ "x-moltnet-team-id": Type.String({
881
- format: "uuid",
882
- description: "Team ID (UUID) that will own the resource. Required."
883
- }) });
884
- Type.Object({ "x-moltnet-team-id": Type.Optional(Type.String({
885
- format: "uuid",
886
- description: "Team ID (UUID) for scoping the request. Optional."
887
- })) });
888
- Type.Object({
889
- kind: Type.Literal("agent"),
890
- identityId: UuidSchema,
891
- fingerprint: FingerprintSchema,
892
- publicKey: PublicKeySchema
888
+ var PreviewSignChallengeValueSchema = Type.Object({
889
+ verificationMethod: Type.Literal("human-hardware-previewsign"),
890
+ value: schemaRef$1(PreviewSignChallengeSchema, "PreviewSignChallenge")
893
891
  }, {
894
- $id: "AgentPrincipal",
892
+ $id: "PreviewSignChallengeValue",
895
893
  additionalProperties: false
896
894
  });
897
- Type.Object({
898
- kind: Type.Literal("human"),
899
- humanId: UuidSchema,
900
- identityId: Type.Union([UuidSchema, Type.Null()])
895
+ var PreviewSignChallengeOperationSchema = Type.Union([Type.Literal("credential-registration"), Type.Literal("signing-request")], { $id: "PreviewSignChallengeOperation" });
896
+ var PreviewSignReceiptSchema = Type.Object({
897
+ version: Type.Literal(1),
898
+ signature: schemaRef$1(PreviewSignP256DerSignatureBase64UrlSchema, "PreviewSignP256DerSignatureBase64Url")
901
899
  }, {
902
- $id: "HumanPrincipal",
900
+ $id: "PreviewSignReceipt",
903
901
  additionalProperties: false
904
902
  });
905
- var principalUnionVariants = [Type.Object({
906
- kind: Type.Literal("agent"),
907
- identityId: UuidSchema,
908
- fingerprint: FingerprintSchema,
909
- publicKey: PublicKeySchema
910
- }, { additionalProperties: false }), Type.Object({
911
- kind: Type.Literal("human"),
912
- humanId: UuidSchema,
913
- identityId: Type.Union([UuidSchema, Type.Null()])
914
- }, { additionalProperties: false })];
915
- Type.Union(principalUnionVariants, {
916
- $id: "PrincipalIdentity",
917
- discriminator: { propertyName: "kind" }
903
+ var PreviewSignReceiptValueSchema = Type.Object({
904
+ verificationMethod: Type.Literal("human-hardware-previewsign"),
905
+ value: schemaRef$1(PreviewSignReceiptSchema, "PreviewSignReceipt")
906
+ }, {
907
+ $id: "PreviewSignReceiptValue",
908
+ additionalProperties: false
918
909
  });
910
+ var previewSignSchemaContext = {
911
+ PreviewSignBase64Url: PreviewSignBase64UrlSchema,
912
+ PreviewSignSha256Base64Url: PreviewSignSha256Base64UrlSchema,
913
+ PreviewSignP256DerSignatureBase64Url: PreviewSignP256DerSignatureBase64UrlSchema,
914
+ PreviewSignEs256PublicKey: PreviewSignEs256PublicKeySchema,
915
+ PreviewSignEcdhEsHkdf256PublicKey: PreviewSignEcdhEsHkdf256PublicKeySchema,
916
+ PreviewSignEsp256PublicKey: PreviewSignEsp256PublicKeySchema,
917
+ PreviewSignArkgSeedPublicKey: PreviewSignArkgSeedPublicKeySchema,
918
+ PreviewSignPublicMaterial: PreviewSignPublicMaterialSchema,
919
+ PreviewSignChallenge: PreviewSignChallengeSchema,
920
+ PreviewSignChallengeValue: PreviewSignChallengeValueSchema,
921
+ PreviewSignChallengeOperation: PreviewSignChallengeOperationSchema,
922
+ PreviewSignReceipt: PreviewSignReceiptSchema,
923
+ PreviewSignReceiptValue: PreviewSignReceiptValueSchema
924
+ };
925
+ //#endregion
926
+ //#region ../../libs/models/src/verification-method.ts
919
927
  /**
920
- * `$id`-less twin of `PrincipalIdentitySchema`. Required anywhere the
921
- * schema is **embedded** inline into another schema (MCP `outputSchema`
922
- * — every tool that returns a creator-bearing object embeds its own
923
- * copy; provenance-graph node `meta.creator`, etc.). Ajv 8 throws
924
- * `reference "PrincipalIdentity" resolves to more than one schema` if
925
- * the same `$id` appears twice in the same compilation pass, which is
926
- * exactly what happens when the MCP server lists tools and Ajv
927
- * traverses every advertised `outputSchema`.
928
+ * Persisted and wire-level signing verification method identifiers.
928
929
  *
929
- * Structurally identical to `PrincipalIdentitySchema` (they share the
930
- * variants array); change one, change both.
930
+ * This vocabulary is append-only. Never rename, remove, or change an existing
931
+ * value: PostgreSQL rows, workflow inputs, and API clients persist these exact
932
+ * strings. Future signing methods must add a new property and value.
931
933
  */
932
- var PrincipalIdentitySchemaInline = Type.Union(principalUnionVariants, { discriminator: { propertyName: "kind" } });
934
+ var VERIFICATION_METHOD = {
935
+ AgentEd25519: "agent-ed25519",
936
+ HumanHardwarePreviewSign: "human-hardware-previewsign"
937
+ };
938
+ VERIFICATION_METHOD.AgentEd25519, VERIFICATION_METHOD.HumanHardwarePreviewSign;
933
939
  //#endregion
934
- //#region ../../libs/models/src/problem-details.ts
935
- var ProblemCodeSchema = Type.Union([
936
- Type.Literal("UNAUTHORIZED"),
937
- Type.Literal("FORBIDDEN"),
938
- Type.Literal("NOT_FOUND"),
939
- Type.Literal("CONFLICT"),
940
- Type.Literal("UNSUPPORTED_MEDIA_TYPE"),
941
- Type.Literal("VALIDATION_FAILED"),
942
- Type.Literal("INVALID_CHALLENGE"),
943
- Type.Literal("INVALID_SIGNATURE"),
944
- Type.Literal("RATE_LIMIT_EXCEEDED"),
945
- Type.Literal("SERIALIZATION_EXHAUSTED"),
946
- Type.Literal("SIGNING_REQUEST_EXPIRED"),
947
- Type.Literal("SIGNING_REQUEST_ALREADY_COMPLETED"),
948
- Type.Literal("SIGNING_REQUEST_LIMIT_REACHED"),
949
- Type.Literal("REGISTRATION_FAILED"),
950
- Type.Literal("UPSTREAM_ERROR"),
951
- Type.Literal("SERVICE_UNAVAILABLE"),
952
- Type.Literal("INTERNAL_SERVER_ERROR"),
953
- Type.Literal("TEAM_PERSONAL_IMMUTABLE"),
954
- Type.Literal("TEAM_NOT_ACTIVE"),
955
- Type.Literal("INVITE_EXPIRED"),
956
- Type.Literal("INVITE_EXHAUSTED"),
957
- Type.Literal("TEAM_LAST_OWNER"),
958
- Type.Literal("TEAM_ALREADY_ACTIVE"),
959
- Type.Literal("TEAM_NOT_FOUNDING"),
960
- Type.Literal("FOUNDING_ALREADY_ACCEPTED"),
961
- Type.Literal("DIARY_TRANSFER_PENDING"),
962
- Type.Literal("DIARY_TRANSFER_NOT_FOUND"),
963
- Type.Literal("DIARY_TRANSFER_ALREADY_RESOLVED")
964
- ]);
965
- var ProblemDetailsSchema = Type.Object({
966
- type: Type.String({ format: "uri" }),
967
- title: Type.String(),
968
- status: Type.Integer({
969
- minimum: 100,
970
- maximum: 599
940
+ //#region ../../libs/models/src/schemas.ts
941
+ var UuidSchema = Type.String({
942
+ format: "uuid",
943
+ description: "UUID v4 identifier"
944
+ });
945
+ var TimestampSchema = Type.String({
946
+ format: "date-time",
947
+ description: "ISO 8601 timestamp"
948
+ });
949
+ var verificationMethodLiterals = [Type.Literal(VERIFICATION_METHOD.AgentEd25519), Type.Literal(VERIFICATION_METHOD.HumanHardwarePreviewSign)];
950
+ Type.Union(verificationMethodLiterals, { description: "Stable signing verification method identifier" });
951
+ var visibilityLiterals = [
952
+ Type.Literal("private"),
953
+ Type.Literal("moltnet"),
954
+ Type.Literal("public")
955
+ ];
956
+ Type.Union(visibilityLiterals, { description: "Entry visibility level" });
957
+ var ENTRY_TYPE_VALUES = [
958
+ "episodic",
959
+ "semantic",
960
+ "procedural",
961
+ "reflection"
962
+ ];
963
+ var entryTypeLiterals = [
964
+ Type.Literal("episodic"),
965
+ Type.Literal("semantic"),
966
+ Type.Literal("procedural"),
967
+ Type.Literal("reflection")
968
+ ];
969
+ var EntryTypeSchema = Type.Union(entryTypeLiterals, { description: "Entry memory type" });
970
+ /** Regex fragment matching a single entry type value. */
971
+ var ENTRY_TYPE_PATTERN = `(${ENTRY_TYPE_VALUES.join("|")})`;
972
+ `${ENTRY_TYPE_PATTERN}${ENTRY_TYPE_PATTERN}`, ENTRY_TYPE_VALUES.length - 1;
973
+ var PublicKeySchema = Type.String({
974
+ pattern: "^ed25519:[A-Za-z0-9+/=]+$",
975
+ description: "Ed25519 public key with prefix"
976
+ });
977
+ var FingerprintSchema = Type.String({
978
+ pattern: "^[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}$",
979
+ description: "Key fingerprint (A1B2-C3D4-E5F6-G7H8)"
980
+ });
981
+ Type.Object({
982
+ title: Type.Optional(Type.String({ maxLength: 255 })),
983
+ content: Type.String({
984
+ minLength: 1,
985
+ maxLength: 1e5
971
986
  }),
972
- code: ProblemCodeSchema,
973
- detail: Type.Optional(Type.String()),
974
- instance: Type.Optional(Type.String()),
975
- retryAfter: Type.Optional(Type.Integer({
987
+ tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), { maxItems: 20 }))
988
+ });
989
+ Type.Object({
990
+ title: Type.Optional(Type.String({ maxLength: 255 })),
991
+ content: Type.Optional(Type.String({
992
+ minLength: 1,
993
+ maxLength: 1e5
994
+ })),
995
+ tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), { maxItems: 20 }))
996
+ });
997
+ Type.Object({
998
+ query: Type.Optional(Type.String({
999
+ minLength: 1,
1000
+ maxLength: 500
1001
+ })),
1002
+ tags: Type.Optional(Type.Array(Type.String({ maxLength: 128 }), {
1003
+ minItems: 1,
1004
+ maxItems: 20,
1005
+ description: "Filter: entry must have ALL specified tags"
1006
+ })),
1007
+ limit: Type.Optional(Type.Number({
1008
+ minimum: 1,
1009
+ maximum: 100,
1010
+ default: 20
1011
+ })),
1012
+ offset: Type.Optional(Type.Number({
976
1013
  minimum: 0,
977
- description: "Non-negative delay in seconds before retrying, matching the Retry-After response header when present."
1014
+ default: 0
978
1015
  }))
979
- }, {
980
- $id: "ProblemDetails",
981
- additionalProperties: true
982
1016
  });
983
1017
  Type.Object({
984
- field: Type.String(),
985
- message: Type.String(),
986
- code: Type.Optional(Type.String())
987
- }, {
988
- $id: "ValidationError",
989
- additionalProperties: false
1018
+ identityId: UuidSchema,
1019
+ publicKey: PublicKeySchema,
1020
+ fingerprint: FingerprintSchema,
1021
+ createdAt: TimestampSchema
990
1022
  });
991
1023
  Type.Object({
992
- resource: Type.String(),
993
- id: Type.Optional(Type.String({ format: "uuid" })),
994
- keys: Type.Optional(Type.Record(Type.String(), Type.String()))
995
- }, {
996
- $id: "ConflictTarget",
997
- additionalProperties: false
1024
+ publicKey: PublicKeySchema,
1025
+ fingerprint: FingerprintSchema
998
1026
  });
1027
+ Type.Object({ message: Type.String({
1028
+ minLength: 1,
1029
+ maxLength: 1e4
1030
+ }) });
999
1031
  Type.Object({
1000
- constraint: Type.Optional(Type.String()),
1001
- target: Type.Optional(Type.Ref("ConflictTarget"))
1002
- }, {
1003
- $id: "ConflictError",
1004
- additionalProperties: false
1032
+ message: Type.String(),
1033
+ signature: Type.String({ description: "Base64 encoded Ed25519 signature" }),
1034
+ publicKey: PublicKeySchema
1005
1035
  });
1006
- var ConflictProblemDetailsSchema = Type.Intersect([ProblemDetailsSchema, Type.Object({ conflict: Type.Ref("ConflictError") })], { $id: "ConflictProblemDetails" });
1007
1036
  Type.Object({
1008
- type: Type.String(),
1009
- severity: Type.Number(),
1010
- match: Type.String()
1011
- }, {
1012
- $id: "InjectionThreat",
1013
- additionalProperties: false
1014
- });
1015
- Type.Intersect([ConflictProblemDetailsSchema, Type.Object({ flagged: Type.Optional(Type.Array(Type.Object({
1016
- id: Type.String({ format: "uuid" }),
1017
- threats: Type.Array(Type.Ref("InjectionThreat"))
1018
- }, { additionalProperties: false }))) })], { $id: "InjectionConflictProblemDetails" });
1019
- Type.Intersect([ProblemDetailsSchema, Type.Object({ errors: Type.Array(Type.Ref("ValidationError")) })], { $id: "ValidationProblemDetails" });
1020
- Type.Union([
1021
- Type.Literal("pack"),
1022
- Type.Literal("entry"),
1023
- Type.Literal("rendered_pack")
1024
- ]);
1025
- var ProvenanceGraphEdgeKindSchema = Type.Union([
1026
- Type.Literal("includes"),
1027
- Type.Literal("supersedes"),
1028
- Type.Literal("rendered_from")
1029
- ]);
1030
- var ProvenanceGraphPackMetaSchema = Type.Object({
1031
- packId: UuidSchema,
1032
- diaryId: UuidSchema,
1033
- packCid: Type.String(),
1034
- packType: Type.String(),
1035
- packCodec: Type.String(),
1036
- pinned: Type.Boolean(),
1037
- createdAt: TimestampSchema,
1038
- expiresAt: Type.Union([TimestampSchema, Type.Null()]),
1039
- supersedesPackId: Type.Union([UuidSchema, Type.Null()])
1037
+ message: Type.String({
1038
+ minLength: 1,
1039
+ maxLength: 1e4
1040
+ }),
1041
+ signature: Type.String({ description: "Base64 encoded signature" }),
1042
+ publicKey: PublicKeySchema
1040
1043
  });
1041
- /**
1042
- * Discriminated creator embedded inside provenance-node response
1043
- * payloads. Re-uses the shared `PrincipalIdentitySchemaInline` (the
1044
- * `$id`-less twin) — embedding the named `PrincipalIdentitySchema`
1045
- * here would clash with the top-level registration via @fastify/swagger
1046
- * (`reference "PrincipalIdentity" resolves to more than one schema`).
1047
- */
1048
- var ProvenanceGraphCreatorSchema = PrincipalIdentitySchemaInline;
1049
- var ProvenanceGraphEntryMetaSchema = Type.Object({
1050
- entryId: UuidSchema,
1051
- diaryId: UuidSchema,
1052
- entryType: EntryTypeSchema,
1053
- contentHash: Type.Union([Type.String(), Type.Null()]),
1054
- createdAt: TimestampSchema,
1055
- updatedAt: TimestampSchema,
1056
- signed: Type.Boolean(),
1057
- title: Type.Union([Type.String(), Type.Null()]),
1058
- tags: Type.Array(Type.String()),
1059
- creator: Type.Optional(ProvenanceGraphCreatorSchema)
1044
+ Type.Object({
1045
+ valid: Type.Boolean(),
1046
+ signer: Type.Optional(Type.Object({ fingerprint: FingerprintSchema }))
1060
1047
  });
1061
- var ProvenanceGraphPackNodeSchema = Type.Object({
1062
- id: Type.String(),
1063
- kind: Type.Literal("pack"),
1064
- label: Type.String(),
1065
- cid: Type.Union([Type.String(), Type.Null()]),
1066
- meta: Type.Intersect([ProvenanceGraphPackMetaSchema, Type.Object({ creator: Type.Optional(ProvenanceGraphCreatorSchema) })])
1048
+ var BaseAuthContextSchema = Type.Object({
1049
+ identityId: UuidSchema,
1050
+ scopes: Type.Array(Type.String()),
1051
+ subjectType: Type.Union([Type.Literal("agent"), Type.Literal("human")]),
1052
+ currentTeamId: Type.Union([UuidSchema, Type.Null()])
1067
1053
  });
1068
- var ProvenanceGraphEntryNodeSchema = Type.Object({
1069
- id: Type.String(),
1070
- kind: Type.Literal("entry"),
1071
- label: Type.String(),
1072
- cid: Type.Union([Type.String(), Type.Null()]),
1073
- meta: ProvenanceGraphEntryMetaSchema
1054
+ var AgentAuthContextSchema = Type.Intersect([BaseAuthContextSchema, Type.Object({
1055
+ subjectType: Type.Literal("agent"),
1056
+ publicKey: PublicKeySchema,
1057
+ fingerprint: FingerprintSchema,
1058
+ clientId: Type.String()
1059
+ })]);
1060
+ var HumanAuthContextSchema = Type.Intersect([BaseAuthContextSchema, Type.Object({
1061
+ subjectType: Type.Literal("human"),
1062
+ clientId: Type.Union([Type.String(), Type.Null()])
1063
+ })]);
1064
+ Type.Union([AgentAuthContextSchema, HumanAuthContextSchema]);
1065
+ Type.Object({
1066
+ success: Type.Boolean(),
1067
+ message: Type.Optional(Type.String())
1074
1068
  });
1075
- var ProvenanceGraphRenderedPackMetaSchema = Type.Object({
1076
- renderedPackId: UuidSchema,
1077
- sourcePackId: UuidSchema,
1069
+ Type.Object({ diaryId: UuidSchema });
1070
+ Type.Object({
1078
1071
  diaryId: UuidSchema,
1079
- packCid: Type.String(),
1080
- renderMethod: Type.String(),
1081
- totalTokens: Type.Number(),
1082
- pinned: Type.Boolean(),
1083
- createdAt: TimestampSchema,
1084
- expiresAt: Type.Union([TimestampSchema, Type.Null()]),
1085
- creator: Type.Optional(ProvenanceGraphCreatorSchema)
1086
- });
1087
- var ProvenanceGraphRenderedPackNodeSchema = Type.Object({
1088
- id: Type.String(),
1089
- kind: Type.Literal("rendered_pack"),
1090
- label: Type.String(),
1091
- cid: Type.Union([Type.String(), Type.Null()]),
1092
- meta: ProvenanceGraphRenderedPackMetaSchema
1093
- });
1094
- var ProvenanceGraphNodeSchema = Type.Union([
1095
- ProvenanceGraphPackNodeSchema,
1096
- ProvenanceGraphEntryNodeSchema,
1097
- ProvenanceGraphRenderedPackNodeSchema
1098
- ]);
1099
- var ProvenanceGraphEdgeSchema = Type.Object({
1100
- id: Type.String(),
1101
- from: Type.String(),
1102
- to: Type.String(),
1103
- kind: ProvenanceGraphEdgeKindSchema,
1104
- label: Type.Optional(Type.String()),
1105
- meta: Type.Optional(Type.Record(Type.String(), Type.Union([
1106
- Type.String(),
1107
- Type.Number(),
1108
- Type.Boolean(),
1109
- Type.Null()
1110
- ])))
1111
- });
1112
- var ProvenanceGraphMetadataSchema = Type.Object({
1113
- format: Type.Literal("moltnet.provenance-graph/v1"),
1114
- generatedAt: TimestampSchema,
1115
- rootNodeId: Type.String(),
1116
- rootPackId: UuidSchema,
1117
- depth: Type.Number({ minimum: 0 })
1072
+ entryId: UuidSchema
1118
1073
  });
1074
+ Type.Object({ entryId: UuidSchema });
1075
+ Type.Object({ id: UuidSchema });
1119
1076
  Type.Object({
1120
- metadata: ProvenanceGraphMetadataSchema,
1121
- nodes: Type.Array(ProvenanceGraphNodeSchema),
1122
- edges: Type.Array(ProvenanceGraphEdgeSchema)
1123
- }, { $id: "ProvenanceGraph" });
1124
- //#endregion
1125
- //#region ../../libs/models/src/signer-constraint.ts
1126
- var SIGNER_CONSTRAINT_TYPE = {
1127
- Human: "human",
1128
- TeamRole: "team-role",
1129
- Group: "group"
1130
- };
1131
- Type.Union([
1132
- Type.Object({
1133
- type: Type.Literal(SIGNER_CONSTRAINT_TYPE.Human),
1134
- id: Type.String({ format: "uuid" })
1077
+ publicKey: PublicKeySchema,
1078
+ fingerprint: FingerprintSchema,
1079
+ proof: Type.String({
1080
+ minLength: 1,
1081
+ maxLength: 256
1135
1082
  }),
1136
- Type.Object({
1137
- type: Type.Literal(SIGNER_CONSTRAINT_TYPE.TeamRole),
1138
- id: TeamRoleSchema
1083
+ credentialType: Type.Literal("oauth2"),
1084
+ agentName: Type.String({
1085
+ minLength: 1,
1086
+ maxLength: 34
1139
1087
  }),
1140
- Type.Object({
1141
- type: Type.Literal(SIGNER_CONSTRAINT_TYPE.Group),
1142
- id: Type.String({ format: "uuid" })
1143
- })
1144
- ]);
1145
- //#endregion
1146
- //#region ../../libs/models/src/signer-protocol.ts
1147
- function schemaRef(schema) {
1148
- const id = schemaId(schema);
1149
- return Type.Ref(id);
1150
- }
1151
- function schemaId(schema) {
1152
- const id = schema.$id;
1153
- if (typeof id !== "string" || id.length === 0) throw new Error("Signer protocol schemas must have an identifier");
1154
- return id;
1155
- }
1156
- var SignerBase64UrlSchema = PreviewSignBase64UrlSchema;
1157
- var SignerUuidSchema = Type.String({
1158
- $id: "SignerUuid",
1159
- pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
1160
- });
1161
- var SignerOperationSchema = Type.Union([
1162
- Type.Literal("credential-enrollment"),
1163
- Type.Literal("credential-registration"),
1164
- Type.Literal("signing-request")
1165
- ], { $id: "SignerOperation" });
1166
- var SignerChallengeOperationSchema = PreviewSignChallengeOperationSchema;
1167
- var SignerPreviewSignPublicMaterialSchema = PreviewSignPublicMaterialSchema;
1168
- var SignerPreviewSignChallengeValueSchema = PreviewSignChallengeValueSchema;
1169
- var SignerProblemSchema = Type.Object({
1170
- code: Type.String({ minLength: 1 }),
1171
- message: Type.String({ minLength: 1 })
1172
- }, {
1173
- $id: "SignerProblem",
1174
- additionalProperties: false
1088
+ org: Type.Optional(Type.String({
1089
+ minLength: 1,
1090
+ maxLength: 39,
1091
+ pattern: "^[a-zA-Z0-9-]+$",
1092
+ description: "GitHub organization name. When provided, the GitHub App will be created under this org instead of the personal account."
1093
+ }))
1175
1094
  });
1176
- var SignerCeremonyParamsSchema = Type.Object({ ceremonyId: Type.Unsafe(schemaRef(SignerBase64UrlSchema)) }, {
1177
- $id: "SignerCeremonyParams",
1178
- additionalProperties: false
1095
+ Type.Object({
1096
+ workflowId: Type.String(),
1097
+ manifestFormUrl: Type.String()
1179
1098
  });
1180
- var SignerSessionSchema = Type.Object({
1181
- version: Type.Literal(1),
1182
- token: Type.Unsafe(schemaRef(SignerBase64UrlSchema)),
1183
- expiresAt: Type.String()
1184
- }, {
1185
- $id: "SignerSession",
1186
- additionalProperties: false
1099
+ Type.Object({
1100
+ status: Type.Union([
1101
+ Type.Literal("awaiting_github"),
1102
+ Type.Literal("github_code_ready"),
1103
+ Type.Literal("awaiting_installation"),
1104
+ Type.Literal("completed"),
1105
+ Type.Literal("failed")
1106
+ ]),
1107
+ githubCode: Type.Optional(Type.String({ description: "GitHub manifest code sealed to the onboarding agent public key." })),
1108
+ identityId: Type.Optional(Type.String()),
1109
+ clientId: Type.Optional(Type.String()),
1110
+ clientSecret: Type.Optional(Type.String({ description: "OAuth2 client secret sealed to the onboarding agent public key." })),
1111
+ installationId: Type.Optional(Type.String())
1187
1112
  });
1188
- var SignerEnrollmentCeremonyRequestSchema = Type.Object({
1189
- version: Type.Literal(1),
1190
- operation: Type.Literal("credential-enrollment"),
1191
- label: Type.String({
1113
+ Type.Object({
1114
+ wf: Type.String({
1192
1115
  minLength: 1,
1193
- maxLength: 255
1116
+ description: "Workflow ID baked into setup_url"
1194
1117
  }),
1195
- teamId: Type.Unsafe(schemaRef(SignerUuidSchema))
1196
- }, {
1197
- $id: "SignerEnrollmentCeremonyRequest",
1198
- additionalProperties: false
1199
- });
1200
- var SignerChallengeCeremonyRequestSchema = Type.Object({
1201
- version: Type.Literal(1),
1202
- operation: Type.Unsafe(schemaRef(SignerChallengeOperationSchema)),
1203
- resourceId: Type.Unsafe(schemaRef(SignerUuidSchema)),
1204
- challenge: Type.Unsafe(schemaRef(SignerPreviewSignChallengeValueSchema))
1205
- }, {
1206
- $id: "SignerChallengeCeremonyRequest",
1207
- additionalProperties: false
1118
+ installation_id: Type.String({ minLength: 1 }),
1119
+ setup_action: Type.Optional(Type.String())
1208
1120
  });
1209
- var SignerCeremonyRequestSchema = Type.Union([Type.Unsafe(schemaRef(SignerEnrollmentCeremonyRequestSchema)), Type.Unsafe(schemaRef(SignerChallengeCeremonyRequestSchema))], { $id: "SignerCeremonyRequest" });
1210
- var SignerCeremonySchema = Type.Object({
1211
- version: Type.Literal(1),
1212
- id: Type.Unsafe(schemaRef(SignerBase64UrlSchema)),
1213
- operation: Type.Unsafe(schemaRef(SignerOperationSchema)),
1214
- approvalUrl: Type.String(),
1215
- expiresAt: Type.String()
1216
- }, {
1217
- $id: "SignerCeremony",
1218
- additionalProperties: false
1121
+ Type.Object({ id: UuidSchema });
1122
+ Type.Object({
1123
+ id: UuidSchema,
1124
+ subjectId: UuidSchema
1219
1125
  });
1220
- var SignerPendingResultSchema = Type.Object({
1221
- version: Type.Literal(1),
1222
- status: Type.Literal("pending"),
1223
- operation: Type.Unsafe(schemaRef(SignerOperationSchema))
1224
- }, {
1225
- $id: "SignerPendingResult",
1226
- additionalProperties: false
1126
+ Type.Object({
1127
+ id: UuidSchema,
1128
+ inviteId: UuidSchema
1227
1129
  });
1228
- var SignerEnrollmentResultSchema = Type.Object({
1229
- version: Type.Literal(1),
1230
- status: Type.Literal("completed"),
1231
- operation: Type.Literal("credential-enrollment"),
1232
- publicMaterial: Type.Unsafe(schemaRef(SignerPreviewSignPublicMaterialSchema))
1233
- }, {
1234
- $id: "SignerEnrollmentResult",
1235
- additionalProperties: false
1130
+ Type.Object({ name: Type.String({
1131
+ minLength: 1,
1132
+ maxLength: 255
1133
+ }) });
1134
+ Type.Object({
1135
+ role: Type.Optional(Type.Union([
1136
+ Type.Literal("manager"),
1137
+ Type.Literal("executor"),
1138
+ Type.Literal("member")
1139
+ ])),
1140
+ maxUses: Type.Optional(Type.Integer({
1141
+ minimum: 1,
1142
+ default: 1
1143
+ })),
1144
+ expiresInHours: Type.Optional(Type.Integer({
1145
+ minimum: 1,
1146
+ maximum: 720,
1147
+ default: 168
1148
+ }))
1236
1149
  });
1237
- var SignerReceiptSchema = PreviewSignReceiptValueSchema;
1238
- var SignerSignatureResultSchema = Type.Object({
1239
- version: Type.Literal(1),
1240
- status: Type.Literal("completed"),
1241
- operation: Type.Unsafe(schemaRef(SignerChallengeOperationSchema)),
1242
- receipt: Type.Unsafe(schemaRef(SignerReceiptSchema))
1243
- }, {
1244
- $id: "SignerSignatureResult",
1245
- additionalProperties: false
1150
+ Type.Object({ code: Type.String({ minLength: 1 }) });
1151
+ Type.Object({ role: Type.Union([
1152
+ Type.Literal("manager"),
1153
+ Type.Literal("executor"),
1154
+ Type.Literal("member")
1155
+ ]) });
1156
+ var TeamRoleSchema = Type.Union([
1157
+ Type.Literal("owner"),
1158
+ Type.Literal("manager"),
1159
+ Type.Literal("executor"),
1160
+ Type.Literal("member")
1161
+ ]);
1162
+ Type.Object({
1163
+ id: UuidSchema,
1164
+ name: Type.String()
1246
1165
  });
1247
- var SignerFailedResultSchema = Type.Object({
1248
- version: Type.Literal(1),
1249
- status: Type.Literal("failed"),
1250
- operation: Type.Unsafe(schemaRef(SignerOperationSchema)),
1166
+ var DateTimeUnsafe = Type.Unsafe(Type.String({ format: "date-time" }));
1167
+ Type.Object({
1168
+ id: UuidSchema,
1251
1169
  code: Type.String(),
1252
- message: Type.String()
1253
- }, {
1254
- $id: "SignerFailedResult",
1255
- additionalProperties: false
1170
+ role: Type.Union([
1171
+ Type.Literal("manager"),
1172
+ Type.Literal("executor"),
1173
+ Type.Literal("member")
1174
+ ]),
1175
+ maxUses: Type.Integer(),
1176
+ useCount: Type.Integer(),
1177
+ expiresAt: DateTimeUnsafe,
1178
+ createdAt: DateTimeUnsafe
1256
1179
  });
1257
- var SignerCeremonyResultSchema = Type.Union([
1258
- Type.Unsafe(schemaRef(SignerPendingResultSchema)),
1259
- Type.Unsafe(schemaRef(SignerEnrollmentResultSchema)),
1260
- Type.Unsafe(schemaRef(SignerSignatureResultSchema)),
1261
- Type.Unsafe(schemaRef(SignerFailedResultSchema))
1262
- ], { $id: "SignerCeremonyResult" });
1263
- ({ ...previewSignSchemaContext }), schemaId(SignerUuidSchema), schemaId(SignerOperationSchema), schemaId(SignerProblemSchema), schemaId(SignerCeremonyParamsSchema), schemaId(SignerSessionSchema), schemaId(SignerEnrollmentCeremonyRequestSchema), schemaId(SignerChallengeCeremonyRequestSchema), schemaId(SignerCeremonyRequestSchema), schemaId(SignerCeremonySchema), schemaId(SignerPendingResultSchema), schemaId(SignerEnrollmentResultSchema), schemaId(SignerSignatureResultSchema), schemaId(SignerFailedResultSchema), schemaId(SignerCeremonyResultSchema);
1264
- //#endregion
1265
- //#region ../../libs/models/src/tool-enforcement.ts
1266
- var TOOL_ENFORCEMENT_VALUES = [
1267
- "off",
1268
- "watch",
1269
- "enforce"
1270
- ];
1271
- var toolEnforcementLiterals = [
1272
- Type.Literal(TOOL_ENFORCEMENT_VALUES[0]),
1273
- Type.Literal(TOOL_ENFORCEMENT_VALUES[1]),
1274
- Type.Literal(TOOL_ENFORCEMENT_VALUES[2])
1275
- ];
1276
- var ToolEnforcementSchema = Type.Union(toolEnforcementLiterals, { description: "Runtime tool-policy enforcement mode: off (inert), watch (audit only), enforce (block disallowed tools, fail-closed)." });
1277
- //#endregion
1278
- //#region ../../libs/tasks/src/runtime-profiles.ts
1279
- var RuntimeProfileName = Type.String({
1280
- minLength: 1,
1281
- maxLength: 100,
1282
- pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,99}$"
1180
+ var TeamMemberSchema = Type.Object({
1181
+ subjectId: UuidSchema,
1182
+ subjectType: Type.Union([Type.Literal("agent"), Type.Literal("human")]),
1183
+ role: TeamRoleSchema,
1184
+ displayName: Type.String(),
1185
+ fingerprint: Type.Optional(Type.String()),
1186
+ email: Type.Optional(Type.String())
1283
1187
  });
1284
- var RuntimeProfileEnvName = Type.String({
1285
- minLength: 1,
1286
- maxLength: 128,
1287
- pattern: "^[A-Z_][A-Z0-9_]*$"
1188
+ Type.Object({
1189
+ id: UuidSchema,
1190
+ name: Type.String(),
1191
+ personal: Type.Boolean(),
1192
+ status: Type.String(),
1193
+ role: TeamRoleSchema
1194
+ });
1195
+ Type.Object({
1196
+ id: UuidSchema,
1197
+ name: Type.String(),
1198
+ status: Type.String(),
1199
+ personal: Type.Boolean(),
1200
+ createdAt: DateTimeUnsafe,
1201
+ updatedAt: DateTimeUnsafe,
1202
+ members: Type.Array(TeamMemberSchema)
1203
+ });
1204
+ Type.Object({
1205
+ teamId: UuidSchema,
1206
+ role: Type.Union([
1207
+ Type.Literal("manager"),
1208
+ Type.Literal("executor"),
1209
+ Type.Literal("member")
1210
+ ])
1211
+ });
1212
+ Type.Object({
1213
+ updated: Type.Boolean(),
1214
+ role: Type.Union([
1215
+ Type.Literal("manager"),
1216
+ Type.Literal("executor"),
1217
+ Type.Literal("member")
1218
+ ])
1219
+ });
1220
+ Type.Object({ deleted: Type.Boolean() });
1221
+ Type.Object({ removed: Type.Boolean() });
1222
+ var FoundingMemberSchema = Type.Object({
1223
+ subjectId: UuidSchema,
1224
+ subjectNs: Type.Union([Type.Literal("Agent"), Type.Literal("Human")]),
1225
+ role: Type.Union([
1226
+ Type.Literal("owner"),
1227
+ Type.Literal("manager"),
1228
+ Type.Literal("executor"),
1229
+ Type.Literal("member")
1230
+ ])
1288
1231
  });
1289
- var RuntimeProfileToolName = Type.String({
1290
- minLength: 1,
1291
- maxLength: 128,
1292
- pattern: "^[a-zA-Z0-9._/-]+$"
1232
+ Type.Object({
1233
+ name: Type.String({
1234
+ minLength: 1,
1235
+ maxLength: 255
1236
+ }),
1237
+ foundingMembers: Type.Optional(Type.Array(FoundingMemberSchema, { minItems: 1 }))
1293
1238
  });
1294
- var RUNTIME_PROFILE_RUNTIME_KIND_PATTERN = "^[a-z][a-z0-9._-]{0,99}$";
1295
- new RegExp(RUNTIME_PROFILE_RUNTIME_KIND_PATTERN);
1296
- var RuntimeProfileRuntimeKind = Type.String({
1297
- minLength: 1,
1298
- maxLength: 100,
1299
- pattern: RUNTIME_PROFILE_RUNTIME_KIND_PATTERN
1239
+ Type.Object({
1240
+ id: UuidSchema,
1241
+ name: Type.String(),
1242
+ status: Type.String(),
1243
+ workflowId: Type.Optional(Type.String())
1300
1244
  });
1301
- var RuntimeProfileWorkspaceMode = Type.Union([
1302
- Type.Literal("none"),
1303
- Type.Literal("shared_mount"),
1304
- Type.Literal("dedicated_worktree")
1305
- ]);
1306
- /**
1307
- * Tool-policy enforcement mode for the profile's runtime `tool_call` gate:
1308
- * `off` (inert), `watch` (audit only), `enforce` (block disallowed tools,
1309
- * fail-closed). Read by the daemon via `GET /runtime-profiles/:id/allowed-tools`.
1310
- */
1311
- var RuntimeProfileToolEnforcement = ToolEnforcementSchema;
1312
- var RuntimeProfileAllowedWorkspaceModes = Type.Array(RuntimeProfileWorkspaceMode, {
1313
- minItems: 1,
1314
- maxItems: 3,
1315
- uniqueItems: true
1245
+ Type.Object({});
1246
+ Type.Object({
1247
+ accepted: Type.Boolean(),
1248
+ teamStatus: Type.String()
1316
1249
  });
1317
- var RuntimeProfileThinkingLevelOptions = [
1318
- Type.Literal("off"),
1319
- Type.Literal("minimal"),
1320
- Type.Literal("low"),
1321
- Type.Literal("medium"),
1322
- Type.Literal("high"),
1323
- Type.Literal("xhigh")
1324
- ];
1325
- Type.Union([...RuntimeProfileThinkingLevelOptions]);
1326
- var RuntimeProfileNullableThinkingLevel = Type.Union([...RuntimeProfileThinkingLevelOptions, Type.Null()]);
1327
- var RuntimeProfileNullableTemperature = Type.Union([Type.Null(), Type.Number({
1328
- minimum: 0,
1329
- maximum: 2
1330
- })]);
1331
- var RuntimeProfileNullableTopP = Type.Union([Type.Null(), Type.Number({
1332
- minimum: 0,
1333
- maximum: 1
1334
- })]);
1335
- var RuntimeProfileNullableTopK = Type.Union([Type.Integer({
1336
- minimum: 1,
1337
- maximum: 1e4
1338
- }), Type.Null()]);
1339
- var RuntimeProfileNullableMaxOutputTokens = Type.Union([Type.Integer({
1340
- minimum: 1,
1341
- maximum: 1e6
1342
- }), Type.Null()]);
1343
- var RuntimeProfileAllowedHost = Type.String({
1344
- minLength: 1,
1345
- maxLength: 255,
1346
- pattern: "^(?:\\*\\.)?(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)(?:\\.(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?))*$"
1250
+ Type.Object({ destinationTeamId: UuidSchema });
1251
+ Type.Object({ transferId: UuidSchema });
1252
+ var TransferResponseSchema = Type.Object({
1253
+ id: UuidSchema,
1254
+ diaryId: UuidSchema,
1255
+ sourceTeamId: UuidSchema,
1256
+ destinationTeamId: UuidSchema,
1257
+ status: Type.String(),
1258
+ initiatedBy: UuidSchema,
1259
+ expiresAt: Type.Unsafe(Type.String({ format: "date-time" })),
1260
+ createdAt: Type.Unsafe(Type.String({ format: "date-time" }))
1347
1261
  });
1348
- var RuntimeProfileSandbox = Type.Object({
1349
- network: Type.Optional(Type.Object({
1350
- allowedHosts: Type.Optional(Type.Array(RuntimeProfileAllowedHost, { maxItems: 50 })),
1351
- allowedInternalHosts: Type.Optional(Type.Array(RuntimeProfileAllowedHost, { maxItems: 50 }))
1352
- }, { additionalProperties: false })),
1353
- vfs: Type.Optional(Type.Object({
1354
- shadow: Type.Optional(Type.Array(Type.String({
1355
- minLength: 1,
1356
- maxLength: 255
1357
- }), { maxItems: 100 })),
1358
- shadowMode: Type.Optional(Type.Union([Type.Literal("deny"), Type.Literal("tmpfs")]))
1359
- }, { additionalProperties: false })),
1360
- env: Type.Optional(Type.Record(RuntimeProfileEnvName, Type.String({ maxLength: 4096 }))),
1361
- hostExec: Type.Optional(Type.Object({ autoApprove: Type.Optional(Type.Literal(false)) }, { additionalProperties: false })),
1362
- resources: Type.Optional(Type.Object({
1363
- memory: Type.Optional(Type.String({
1364
- minLength: 2,
1365
- maxLength: 16,
1366
- pattern: "^[0-9]+[KMG]?$"
1367
- })),
1368
- cpus: Type.Optional(Type.Integer({
1369
- minimum: 1,
1370
- maximum: 32
1371
- }))
1372
- }, { additionalProperties: false }))
1373
- }, {
1374
- $id: "RuntimeProfileSandbox",
1375
- additionalProperties: false
1262
+ Type.Object({ items: Type.Array(TransferResponseSchema) });
1263
+ Type.Object({ groupId: UuidSchema });
1264
+ Type.Object({
1265
+ groupId: UuidSchema,
1266
+ subjectId: UuidSchema
1376
1267
  });
1377
- var RuntimeProfileContext = Type.Object({
1378
- slug: Type.String({
1379
- minLength: 1,
1380
- maxLength: 64,
1381
- pattern: "^[a-zA-Z0-9_-]+$"
1382
- }),
1383
- binding: Type.Union([
1384
- Type.Literal("skill"),
1385
- Type.Literal("context_inline"),
1386
- Type.Literal("prompt_prefix"),
1387
- Type.Literal("user_inline")
1388
- ]),
1389
- content: Type.String({
1390
- minLength: 1,
1391
- maxLength: 65536
1392
- })
1393
- }, {
1394
- $id: "RuntimeProfileContext",
1395
- additionalProperties: false
1268
+ Type.Object({ name: Type.String({
1269
+ minLength: 1,
1270
+ maxLength: 255
1271
+ }) });
1272
+ Type.Object({
1273
+ subjectId: UuidSchema,
1274
+ subjectNs: Type.Optional(Type.Union([Type.Literal("Agent"), Type.Literal("Human")]))
1396
1275
  });
1397
- var RuntimeProfileRef = Type.Object({ profileId: Type.String({ format: "uuid" }) }, {
1398
- $id: "RuntimeProfileRef",
1399
- additionalProperties: false
1276
+ Type.Object({
1277
+ id: UuidSchema,
1278
+ name: Type.String(),
1279
+ teamId: UuidSchema
1400
1280
  });
1401
- var RuntimeProfileLeaseTtlSec = Type.Integer({
1402
- minimum: 1,
1403
- maximum: 86400
1281
+ var GroupMemberResponseSchema = Type.Object({
1282
+ subjectId: UuidSchema,
1283
+ subjectNs: Type.String()
1404
1284
  });
1405
- var RuntimeProfileHeartbeatIntervalMs = Type.Integer({
1406
- minimum: 0,
1407
- maximum: 36e5
1285
+ Type.Object({
1286
+ id: UuidSchema,
1287
+ name: Type.String(),
1288
+ teamId: UuidSchema,
1289
+ createdAt: DateTimeUnsafe,
1290
+ members: Type.Array(GroupMemberResponseSchema)
1408
1291
  });
1409
- var RuntimeProfileMaxBatchSize = Type.Integer({
1410
- minimum: 1,
1411
- maximum: 1e3
1292
+ var DiaryGrantRoleSchema = Type.Union([Type.Literal("writer"), Type.Literal("manager")]);
1293
+ var GrantSubjectNsSchema = Type.Union([
1294
+ Type.Literal("Agent"),
1295
+ Type.Literal("Human"),
1296
+ Type.Literal("Group")
1297
+ ]);
1298
+ Type.Object({
1299
+ subjectId: UuidSchema,
1300
+ subjectNs: GrantSubjectNsSchema,
1301
+ role: DiaryGrantRoleSchema
1412
1302
  });
1413
- var RuntimeProfileMaxTurns = Type.Integer({
1414
- minimum: 0,
1415
- maximum: 1e4
1303
+ Type.Object({
1304
+ subjectId: UuidSchema,
1305
+ subjectNs: GrantSubjectNsSchema,
1306
+ role: DiaryGrantRoleSchema
1416
1307
  });
1417
- var RuntimeProfileMaxBashTimeouts = Type.Integer({
1418
- minimum: 0,
1419
- maximum: 1e3
1308
+ var DiaryGrantResponseSchema = Type.Object({
1309
+ subjectId: UuidSchema,
1310
+ subjectNs: GrantSubjectNsSchema,
1311
+ role: DiaryGrantRoleSchema
1420
1312
  });
1313
+ Type.Object({ grants: Type.Array(DiaryGrantResponseSchema) });
1314
+ Type.Object({ revoked: Type.Boolean() });
1315
+ var TaskGrantRoleSchema = Type.Union([Type.Literal("writer"), Type.Literal("manager")]);
1421
1316
  Type.Object({
1422
- id: Type.String({ format: "uuid" }),
1423
- teamId: Type.String({ format: "uuid" }),
1424
- name: RuntimeProfileName,
1425
- description: Type.Union([Type.String({ maxLength: 4096 }), Type.Null()]),
1426
- provider: Type.String({
1427
- minLength: 1,
1428
- maxLength: 100
1429
- }),
1430
- model: Type.String({
1431
- minLength: 1,
1432
- maxLength: 200
1433
- }),
1434
- thinkingLevel: RuntimeProfileNullableThinkingLevel,
1435
- temperature: RuntimeProfileNullableTemperature,
1436
- topP: RuntimeProfileNullableTopP,
1437
- topK: RuntimeProfileNullableTopK,
1438
- maxOutputTokens: RuntimeProfileNullableMaxOutputTokens,
1439
- runtimeKind: RuntimeProfileRuntimeKind,
1440
- sandbox: RuntimeProfileSandbox,
1441
- sessionStorageMode: Type.Literal("local"),
1442
- workspaceStorageMode: Type.Literal("local"),
1443
- defaultWorkspaceMode: Type.Union([RuntimeProfileWorkspaceMode, Type.Null()]),
1444
- allowedWorkspaceModes: RuntimeProfileAllowedWorkspaceModes,
1445
- sessionTtlSec: Type.Integer({
1446
- minimum: 1,
1447
- maximum: 86400
1448
- }),
1449
- workspaceTtlSec: Type.Integer({
1450
- minimum: 1,
1451
- maximum: 86400
1452
- }),
1453
- leaseTtlSec: RuntimeProfileLeaseTtlSec,
1454
- heartbeatIntervalMs: RuntimeProfileHeartbeatIntervalMs,
1455
- maxBatchSize: RuntimeProfileMaxBatchSize,
1456
- maxTurns: RuntimeProfileMaxTurns,
1457
- maxBashTimeouts: RuntimeProfileMaxBashTimeouts,
1458
- toolEnforcement: RuntimeProfileToolEnforcement,
1459
- requiredEnv: Type.Array(RuntimeProfileEnvName, { maxItems: 100 }),
1460
- requiredTools: Type.Array(RuntimeProfileToolName, { maxItems: 100 }),
1461
- requiredExecutables: Type.Array(RuntimeProfileToolName, { maxItems: 100 }),
1462
- context: Type.Array(RuntimeProfileContext, { maxItems: 5 }),
1463
- revision: Type.Integer({ minimum: 1 }),
1464
- definitionCid: Type.String({
1465
- minLength: 1,
1466
- maxLength: 100
1467
- }),
1468
- createdByAgentId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1469
- createdByHumanId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1470
- createdAt: Type.String({ format: "date-time" }),
1471
- updatedAt: Type.String({ format: "date-time" })
1472
- }, {
1473
- $id: "RuntimeProfile",
1474
- additionalProperties: false
1317
+ subjectId: UuidSchema,
1318
+ subjectNs: GrantSubjectNsSchema,
1319
+ role: TaskGrantRoleSchema
1475
1320
  });
1476
- //#endregion
1477
- //#region ../../libs/tasks/src/runtime-sessions.ts
1478
- var RuntimeSessionKind = Type.Union([
1479
- Type.Literal("root"),
1480
- Type.Literal("extend"),
1481
- Type.Literal("fork")
1482
- ]);
1483
- var RuntimeSessionCheckpointKind = Type.Union([Type.Literal("attempt_final")]);
1484
1321
  Type.Object({
1485
- id: Type.String({ format: "uuid" }),
1486
- teamId: Type.String({ format: "uuid" }),
1487
- taskId: Type.String({ format: "uuid" }),
1488
- attemptN: Type.Integer({ minimum: 1 }),
1489
- sourceSlotId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1490
- sourceRuntimeProfileId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1491
- sessionKind: RuntimeSessionKind,
1492
- parentSessionId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1493
- contentType: Type.String({
1494
- minLength: 1,
1495
- maxLength: 200
1496
- }),
1497
- contentEncoding: Type.Union([Type.String({
1498
- minLength: 1,
1499
- maxLength: 100
1500
- }), Type.Null()]),
1501
- sizeBytes: Type.Integer({ minimum: 0 }),
1502
- sha256: Type.String({
1503
- minLength: 64,
1504
- maxLength: 64
1505
- }),
1506
- storageClass: Type.String({
1507
- minLength: 1,
1508
- maxLength: 100
1509
- }),
1510
- checkpointKind: RuntimeSessionCheckpointKind,
1511
- uploadedAt: Type.String({ format: "date-time" })
1512
- }, { $id: "RuntimeSession" });
1322
+ subjectId: UuidSchema,
1323
+ subjectNs: GrantSubjectNsSchema,
1324
+ role: TaskGrantRoleSchema
1325
+ });
1326
+ var TaskGrantResponseSchema = Type.Object({
1327
+ subjectId: UuidSchema,
1328
+ subjectNs: GrantSubjectNsSchema,
1329
+ role: TaskGrantRoleSchema
1330
+ });
1331
+ Type.Object({ grants: Type.Array(TaskGrantResponseSchema) });
1332
+ Type.Object({ "x-moltnet-team-id": Type.String({
1333
+ format: "uuid",
1334
+ description: "Team ID (UUID) that will own the resource. Required."
1335
+ }) });
1336
+ Type.Object({ "x-moltnet-team-id": Type.Optional(Type.String({
1337
+ format: "uuid",
1338
+ description: "Team ID (UUID) for scoping the request. Optional."
1339
+ })) });
1513
1340
  Type.Object({
1514
- sourceSlotId: Type.Optional(Type.String({ format: "uuid" })),
1515
- sourceRuntimeProfileId: Type.Optional(Type.String({ format: "uuid" })),
1516
- sessionKind: RuntimeSessionKind,
1517
- parentSessionId: Type.Optional(Type.String({ format: "uuid" }))
1341
+ kind: Type.Literal("agent"),
1342
+ identityId: UuidSchema,
1343
+ fingerprint: FingerprintSchema,
1344
+ publicKey: PublicKeySchema
1518
1345
  }, {
1519
- $id: "UploadRuntimeSessionQuery",
1346
+ $id: "AgentPrincipal",
1520
1347
  additionalProperties: false
1521
1348
  });
1522
- Type.String({
1523
- $id: "RuntimeSessionContent",
1524
- description: "Runtime session content stream.",
1525
- format: "binary"
1526
- });
1527
1349
  Type.Object({
1528
- taskId: Type.String({ format: "uuid" }),
1529
- attemptN: Type.Integer({ minimum: 1 })
1350
+ kind: Type.Literal("human"),
1351
+ humanId: UuidSchema,
1352
+ identityId: Type.Union([UuidSchema, Type.Null()])
1530
1353
  }, {
1531
- $id: "RuntimeSessionAttemptParams",
1354
+ $id: "HumanPrincipal",
1532
1355
  additionalProperties: false
1533
1356
  });
1357
+ var principalUnionVariants = [Type.Object({
1358
+ kind: Type.Literal("agent"),
1359
+ identityId: UuidSchema,
1360
+ fingerprint: FingerprintSchema,
1361
+ publicKey: PublicKeySchema
1362
+ }, { additionalProperties: false }), Type.Object({
1363
+ kind: Type.Literal("human"),
1364
+ humanId: UuidSchema,
1365
+ identityId: Type.Union([UuidSchema, Type.Null()])
1366
+ }, { additionalProperties: false })];
1367
+ Type.Union(principalUnionVariants, {
1368
+ $id: "PrincipalIdentity",
1369
+ discriminator: { propertyName: "kind" }
1370
+ });
1371
+ /**
1372
+ * `$id`-less twin of `PrincipalIdentitySchema`. Required anywhere the
1373
+ * schema is **embedded** inline into another schema (MCP `outputSchema`
1374
+ * — every tool that returns a creator-bearing object embeds its own
1375
+ * copy; provenance-graph node `meta.creator`, etc.). Ajv 8 throws
1376
+ * `reference "PrincipalIdentity" resolves to more than one schema` if
1377
+ * the same `$id` appears twice in the same compilation pass, which is
1378
+ * exactly what happens when the MCP server lists tools and Ajv
1379
+ * traverses every advertised `outputSchema`.
1380
+ *
1381
+ * Structurally identical to `PrincipalIdentitySchema` (they share the
1382
+ * variants array); change one, change both.
1383
+ */
1384
+ var PrincipalIdentitySchemaInline = Type.Union(principalUnionVariants, { discriminator: { propertyName: "kind" } });
1534
1385
  //#endregion
1535
- //#region ../../libs/tasks/src/runtime-slots.ts
1536
- var RuntimeWorkspaceKind = Type.Union([
1537
- Type.Literal("origin"),
1538
- Type.Literal("fork"),
1539
- Type.Literal("scratch")
1386
+ //#region ../../libs/models/src/problem-details.ts
1387
+ var ProblemCodeSchema = Type.Union([
1388
+ Type.Literal("UNAUTHORIZED"),
1389
+ Type.Literal("FORBIDDEN"),
1390
+ Type.Literal("NOT_FOUND"),
1391
+ Type.Literal("CONFLICT"),
1392
+ Type.Literal("UNSUPPORTED_MEDIA_TYPE"),
1393
+ Type.Literal("VALIDATION_FAILED"),
1394
+ Type.Literal("INVALID_CHALLENGE"),
1395
+ Type.Literal("INVALID_SIGNATURE"),
1396
+ Type.Literal("RATE_LIMIT_EXCEEDED"),
1397
+ Type.Literal("SERIALIZATION_EXHAUSTED"),
1398
+ Type.Literal("SIGNING_REQUEST_EXPIRED"),
1399
+ Type.Literal("SIGNING_REQUEST_ALREADY_COMPLETED"),
1400
+ Type.Literal("SIGNING_REQUEST_LIMIT_REACHED"),
1401
+ Type.Literal("REGISTRATION_FAILED"),
1402
+ Type.Literal("UPSTREAM_ERROR"),
1403
+ Type.Literal("SERVICE_UNAVAILABLE"),
1404
+ Type.Literal("INTERNAL_SERVER_ERROR"),
1405
+ Type.Literal("TEAM_PERSONAL_IMMUTABLE"),
1406
+ Type.Literal("TEAM_NOT_ACTIVE"),
1407
+ Type.Literal("INVITE_EXPIRED"),
1408
+ Type.Literal("INVITE_EXHAUSTED"),
1409
+ Type.Literal("TEAM_LAST_OWNER"),
1410
+ Type.Literal("TEAM_ALREADY_ACTIVE"),
1411
+ Type.Literal("TEAM_NOT_FOUNDING"),
1412
+ Type.Literal("FOUNDING_ALREADY_ACCEPTED"),
1413
+ Type.Literal("DIARY_TRANSFER_PENDING"),
1414
+ Type.Literal("DIARY_TRANSFER_NOT_FOUND"),
1415
+ Type.Literal("DIARY_TRANSFER_ALREADY_RESOLVED")
1540
1416
  ]);
1541
- var RuntimeSlotState = Type.Union([Type.Literal("active"), Type.Literal("idle")]);
1542
- var RuntimeWorkspace = Type.Object({
1543
- id: Type.String({ format: "uuid" }),
1544
- teamId: Type.String({ format: "uuid" }),
1545
- workspaceId: Type.String({ minLength: 1 }),
1546
- worktreePath: Type.String({ minLength: 1 }),
1547
- worktreeBranch: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
1548
- kind: RuntimeWorkspaceKind,
1549
- createdAtMs: Type.Integer({ minimum: 0 }),
1550
- lastUsedAtMs: Type.Integer({ minimum: 0 })
1551
- }, { $id: "RuntimeWorkspace" });
1552
- var RuntimeSlot = Type.Object({
1553
- id: Type.String({ format: "uuid" }),
1554
- teamId: Type.String({ format: "uuid" }),
1555
- agentName: Type.String({
1556
- minLength: 1,
1557
- maxLength: 100
1558
- }),
1559
- runtimeProfileId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1560
- provider: Type.String({
1561
- minLength: 1,
1562
- maxLength: 100
1563
- }),
1564
- model: Type.String({
1565
- minLength: 1,
1566
- maxLength: 200
1567
- }),
1568
- slotKey: Type.String({ minLength: 1 }),
1569
- taskType: Type.String({
1570
- minLength: 1,
1571
- maxLength: 100
1417
+ var ProblemDetailsSchema = Type.Object({
1418
+ type: Type.String({ format: "uri" }),
1419
+ title: Type.String(),
1420
+ status: Type.Integer({
1421
+ minimum: 100,
1422
+ maximum: 599
1572
1423
  }),
1573
- state: RuntimeSlotState,
1574
- lastTaskId: Type.String({ format: "uuid" }),
1575
- lastAttemptN: Type.Integer({ minimum: 1 }),
1576
- sessionDir: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
1577
- sessionPath: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
1578
- workspaceRowId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1579
- createdAtMs: Type.Integer({ minimum: 0 }),
1580
- lastUsedAtMs: Type.Integer({ minimum: 0 }),
1581
- expiresAtMs: Type.Integer({ minimum: 0 })
1582
- }, { $id: "RuntimeSlot" });
1583
- var ResolvedRuntimeSlot = Type.Object({
1584
- slot: RuntimeSlot,
1585
- workspace: Type.Union([RuntimeWorkspace, Type.Null()])
1586
- }, { $id: "ResolvedRuntimeSlot" });
1587
- Type.Object({ items: Type.Array(ResolvedRuntimeSlot) }, { $id: "RuntimeSlotListResponse" });
1424
+ code: ProblemCodeSchema,
1425
+ detail: Type.Optional(Type.String()),
1426
+ instance: Type.Optional(Type.String()),
1427
+ retryAfter: Type.Optional(Type.Integer({
1428
+ minimum: 0,
1429
+ description: "Non-negative delay in seconds before retrying, matching the Retry-After response header when present."
1430
+ }))
1431
+ }, {
1432
+ $id: "ProblemDetails",
1433
+ additionalProperties: true
1434
+ });
1588
1435
  Type.Object({
1589
- agentName: Type.String({
1590
- minLength: 1,
1591
- maxLength: 100
1592
- }),
1593
- runtimeProfileId: Type.String({ format: "uuid" }),
1594
- provider: Type.String({
1595
- minLength: 1,
1596
- maxLength: 100
1597
- }),
1598
- model: Type.String({
1599
- minLength: 1,
1600
- maxLength: 200
1601
- }),
1602
- slotKey: Type.String({ minLength: 1 }),
1603
- taskType: Type.String({
1604
- minLength: 1,
1605
- maxLength: 100
1606
- }),
1607
- sessionDir: Type.Optional(Type.String({ minLength: 1 })),
1608
- sessionPath: Type.Optional(Type.String({ minLength: 1 })),
1609
- workspaceId: Type.Optional(Type.String({ minLength: 1 })),
1610
- worktreePath: Type.Optional(Type.String({ minLength: 1 })),
1611
- worktreeBranch: Type.Optional(Type.String({ minLength: 1 })),
1612
- workspaceKind: Type.Optional(RuntimeWorkspaceKind),
1613
- lastTaskId: Type.String({ format: "uuid" }),
1614
- lastAttemptN: Type.Integer({ minimum: 1 })
1436
+ field: Type.String(),
1437
+ message: Type.String(),
1438
+ code: Type.Optional(Type.String())
1615
1439
  }, {
1616
- $id: "BeginRuntimeSlotBody",
1440
+ $id: "ValidationError",
1617
1441
  additionalProperties: false
1618
1442
  });
1619
1443
  Type.Object({
1620
- agentName: Type.String({
1621
- minLength: 1,
1622
- maxLength: 100
1623
- }),
1624
- runtimeProfileId: Type.String({ format: "uuid" }),
1625
- provider: Type.String({
1626
- minLength: 1,
1627
- maxLength: 100
1628
- }),
1629
- model: Type.String({
1630
- minLength: 1,
1631
- maxLength: 200
1632
- }),
1633
- slotKey: Type.String({ minLength: 1 }),
1634
- taskId: Type.String({ format: "uuid" }),
1635
- attemptN: Type.Integer({ minimum: 1 }),
1636
- sessionPath: Type.Optional(Type.String({ minLength: 1 }))
1444
+ resource: Type.String(),
1445
+ id: Type.Optional(Type.String({ format: "uuid" })),
1446
+ keys: Type.Optional(Type.Record(Type.String(), Type.String()))
1637
1447
  }, {
1638
- $id: "FinishRuntimeSlotBody",
1448
+ $id: "ConflictTarget",
1639
1449
  additionalProperties: false
1640
1450
  });
1641
1451
  Type.Object({
1642
- taskId: Type.String({ format: "uuid" }),
1643
- attemptN: Type.Integer({ minimum: 1 })
1452
+ constraint: Type.Optional(Type.String()),
1453
+ target: Type.Optional(Type.Ref("ConflictTarget"))
1644
1454
  }, {
1645
- $id: "FindLatestRuntimeSlotForAttemptQuery",
1455
+ $id: "ConflictError",
1646
1456
  additionalProperties: false
1647
1457
  });
1458
+ var ConflictProblemDetailsSchema = Type.Intersect([ProblemDetailsSchema, Type.Object({ conflict: Type.Ref("ConflictError") })], { $id: "ConflictProblemDetails" });
1648
1459
  Type.Object({
1649
- agentName: Type.Optional(Type.String({
1650
- minLength: 1,
1651
- maxLength: 100
1652
- })),
1653
- runtimeProfileId: Type.Optional(Type.String({ format: "uuid" })),
1654
- state: Type.Optional(RuntimeSlotState),
1655
- limit: Type.Optional(Type.Integer({
1656
- minimum: 1,
1657
- maximum: 200
1658
- }))
1460
+ type: Type.String(),
1461
+ severity: Type.Number(),
1462
+ match: Type.String()
1659
1463
  }, {
1660
- $id: "ListRuntimeSlotsQuery",
1464
+ $id: "InjectionThreat",
1661
1465
  additionalProperties: false
1662
1466
  });
1663
- //#endregion
1664
- //#region ../../libs/tasks/src/success-criteria.ts
1467
+ Type.Intersect([ConflictProblemDetailsSchema, Type.Object({ flagged: Type.Optional(Type.Array(Type.Object({
1468
+ id: Type.String({ format: "uuid" }),
1469
+ threats: Type.Array(Type.Ref("InjectionThreat"))
1470
+ }, { additionalProperties: false }))) })], { $id: "InjectionConflictProblemDetails" });
1471
+ Type.Intersect([ProblemDetailsSchema, Type.Object({ errors: Type.Array(Type.Ref("ValidationError")) })], { $id: "ValidationProblemDetails" });
1472
+ Type.Union([
1473
+ Type.Literal("pack"),
1474
+ Type.Literal("entry"),
1475
+ Type.Literal("rendered_pack")
1476
+ ]);
1477
+ var ProvenanceGraphEdgeKindSchema = Type.Union([
1478
+ Type.Literal("includes"),
1479
+ Type.Literal("supersedes"),
1480
+ Type.Literal("rendered_from")
1481
+ ]);
1482
+ var ProvenanceGraphPackMetaSchema = Type.Object({
1483
+ packId: UuidSchema,
1484
+ diaryId: UuidSchema,
1485
+ packCid: Type.String(),
1486
+ packType: Type.String(),
1487
+ packCodec: Type.String(),
1488
+ pinned: Type.Boolean(),
1489
+ createdAt: TimestampSchema,
1490
+ expiresAt: Type.Union([TimestampSchema, Type.Null()]),
1491
+ supersedesPackId: Type.Union([UuidSchema, Type.Null()])
1492
+ });
1665
1493
  /**
1666
- * SuccessCriteria — proposer-stated acceptance criteria, evaluated in two
1667
- * complementary places.
1668
- *
1669
- * Before this envelope existed, criteria were scattered: a vestigial
1670
- * `criteriaCid` column nobody resolved, free-form prose on
1671
- * `fulfill_brief.input`, and inline `rubric` / `criteria[]` fields on
1672
- * judgment-task inputs. None of those were machine-verifiable
1673
- * end-to-end.
1674
- *
1675
- * This module defines a single, content-addressable envelope a proposer
1676
- * attaches to any task type. It has four orthogonal sections — pick
1677
- * whichever apply per task type:
1678
- *
1679
- * - `gates` Promise-level structural/process checks
1680
- * - `assertions` Declarative claims about output JSON
1681
- * - `rubric` Weighted-criteria scoring instrument, reused
1682
- * verbatim from `./rubric.ts`.
1683
- * - `sideEffects` Required process side-effects (e.g. diary entry)
1684
- *
1685
- * ## Two roles, two task types
1686
- *
1687
- * **Producer self-assessment** (fulfillment tasks: `fulfill_brief`,
1688
- * `curate_pack`, `render_pack`). The producer **LLM** evaluates the
1689
- * criteria against its own output and emits a `VerificationRecord`
1690
- * inside `output.verification`. The daemon is pure passthrough — it
1691
- * does not run `evaluateAssertions`, does not inspect the verification
1692
- * record. The REST API is dumb storage; it never re-runs assertions and
1693
- * never runs LLMs. The cross-field rule
1694
- * `requireVerificationWhenCriteriaPresent` enforces "verification
1695
- * required iff successCriteria present" at task-output validation time
1696
- * (server-side schema check). Self-assessment is a truthful self-rating,
1697
- * NOT enforcement — `verification.passed=false` does not block /complete
1698
- * and does not affect `acceptedAttemptN`. See
1699
- * `docs/use/tasks-and-runtime.md` for the full producer/judge flow.
1700
- *
1701
- * **Binding evaluation** (judgment tasks: `assess_brief`, `judge_pack`).
1702
- * A separate task whose IS the application of `successCriteria` to
1703
- * someone else's output. Different agent (enforced at claim time), same
1704
- * envelope. The judge's verdict is binding: this is the *gate* in the
1705
- * MoltNet model. The rubric inside `successCriteria.rubric` IS the job
1706
- * spec for the judge.
1707
- *
1708
- * The clean chain: producer task with `successCriteria` → producer
1709
- * self-assesses honestly → proposer (or automation) creates a downstream
1710
- * judgment task that references the same `successCriteria` (or a
1711
- * stricter rubric) → judgment task delivers the binding verdict.
1712
- *
1713
- * Storage: SuccessCriteria lives inline at `task.input.successCriteria`,
1714
- * pinned via the task's `inputCid`. No separate column or hash. When
1715
- * #881 lands, the `rubric` field can graduate to `{ rubricCid }` lookup
1716
- * without changing this envelope, and producer + judge tasks can pin
1717
- * the SAME rubric across the chain for end-to-end auditability.
1494
+ * Discriminated creator embedded inside provenance-node response
1495
+ * payloads. Re-uses the shared `PrincipalIdentitySchemaInline` (the
1496
+ * `$id`-less twin) — embedding the named `PrincipalIdentitySchema`
1497
+ * here would clash with the top-level registration via @fastify/swagger
1498
+ * (`reference "PrincipalIdentity" resolves to more than one schema`).
1718
1499
  */
1719
- var SchemaCheckSpec = Type.Object({ schemaCid: Type.String({ minLength: 1 }) }, { additionalProperties: false });
1720
- var CidEqualsSpec = Type.Object({
1721
- path: Type.String({ minLength: 1 }),
1722
- expected: Type.String({ minLength: 1 })
1723
- }, { additionalProperties: false });
1724
- var SubmitToolCallGate = Type.Object({
1725
- id: Type.String({ minLength: 1 }),
1726
- kind: Type.Literal("submit-tool-call"),
1727
- description: Type.String({ minLength: 1 }),
1728
- required: Type.Boolean()
1729
- }, { additionalProperties: false });
1730
- var Gate = Type.Union([
1731
- SubmitToolCallGate,
1500
+ var ProvenanceGraphCreatorSchema = PrincipalIdentitySchemaInline;
1501
+ var ProvenanceGraphEntryMetaSchema = Type.Object({
1502
+ entryId: UuidSchema,
1503
+ diaryId: UuidSchema,
1504
+ entryType: EntryTypeSchema,
1505
+ contentHash: Type.Union([Type.String(), Type.Null()]),
1506
+ createdAt: TimestampSchema,
1507
+ updatedAt: TimestampSchema,
1508
+ signed: Type.Boolean(),
1509
+ title: Type.Union([Type.String(), Type.Null()]),
1510
+ tags: Type.Array(Type.String()),
1511
+ creator: Type.Optional(ProvenanceGraphCreatorSchema)
1512
+ });
1513
+ var ProvenanceGraphPackNodeSchema = Type.Object({
1514
+ id: Type.String(),
1515
+ kind: Type.Literal("pack"),
1516
+ label: Type.String(),
1517
+ cid: Type.Union([Type.String(), Type.Null()]),
1518
+ meta: Type.Intersect([ProvenanceGraphPackMetaSchema, Type.Object({ creator: Type.Optional(ProvenanceGraphCreatorSchema) })])
1519
+ });
1520
+ var ProvenanceGraphEntryNodeSchema = Type.Object({
1521
+ id: Type.String(),
1522
+ kind: Type.Literal("entry"),
1523
+ label: Type.String(),
1524
+ cid: Type.Union([Type.String(), Type.Null()]),
1525
+ meta: ProvenanceGraphEntryMetaSchema
1526
+ });
1527
+ var ProvenanceGraphRenderedPackMetaSchema = Type.Object({
1528
+ renderedPackId: UuidSchema,
1529
+ sourcePackId: UuidSchema,
1530
+ diaryId: UuidSchema,
1531
+ packCid: Type.String(),
1532
+ renderMethod: Type.String(),
1533
+ totalTokens: Type.Number(),
1534
+ pinned: Type.Boolean(),
1535
+ createdAt: TimestampSchema,
1536
+ expiresAt: Type.Union([TimestampSchema, Type.Null()]),
1537
+ creator: Type.Optional(ProvenanceGraphCreatorSchema)
1538
+ });
1539
+ var ProvenanceGraphRenderedPackNodeSchema = Type.Object({
1540
+ id: Type.String(),
1541
+ kind: Type.Literal("rendered_pack"),
1542
+ label: Type.String(),
1543
+ cid: Type.Union([Type.String(), Type.Null()]),
1544
+ meta: ProvenanceGraphRenderedPackMetaSchema
1545
+ });
1546
+ var ProvenanceGraphNodeSchema = Type.Union([
1547
+ ProvenanceGraphPackNodeSchema,
1548
+ ProvenanceGraphEntryNodeSchema,
1549
+ ProvenanceGraphRenderedPackNodeSchema
1550
+ ]);
1551
+ var ProvenanceGraphEdgeSchema = Type.Object({
1552
+ id: Type.String(),
1553
+ from: Type.String(),
1554
+ to: Type.String(),
1555
+ kind: ProvenanceGraphEdgeKindSchema,
1556
+ label: Type.Optional(Type.String()),
1557
+ meta: Type.Optional(Type.Record(Type.String(), Type.Union([
1558
+ Type.String(),
1559
+ Type.Number(),
1560
+ Type.Boolean(),
1561
+ Type.Null()
1562
+ ])))
1563
+ });
1564
+ var ProvenanceGraphMetadataSchema = Type.Object({
1565
+ format: Type.Literal("moltnet.provenance-graph/v1"),
1566
+ generatedAt: TimestampSchema,
1567
+ rootNodeId: Type.String(),
1568
+ rootPackId: UuidSchema,
1569
+ depth: Type.Number({ minimum: 0 })
1570
+ });
1571
+ Type.Object({
1572
+ metadata: ProvenanceGraphMetadataSchema,
1573
+ nodes: Type.Array(ProvenanceGraphNodeSchema),
1574
+ edges: Type.Array(ProvenanceGraphEdgeSchema)
1575
+ }, { $id: "ProvenanceGraph" });
1576
+ //#endregion
1577
+ //#region ../../libs/models/src/signer-constraint.ts
1578
+ var SIGNER_CONSTRAINT_TYPE = {
1579
+ Human: "human",
1580
+ TeamRole: "team-role",
1581
+ Group: "group"
1582
+ };
1583
+ Type.Union([
1732
1584
  Type.Object({
1733
- id: Type.String({ minLength: 1 }),
1734
- kind: Type.Literal("schema-check"),
1735
- spec: SchemaCheckSpec,
1736
- required: Type.Boolean()
1737
- }, { additionalProperties: false }),
1585
+ type: Type.Literal(SIGNER_CONSTRAINT_TYPE.Human),
1586
+ id: Type.String({ format: "uuid" })
1587
+ }),
1738
1588
  Type.Object({
1739
- id: Type.String({ minLength: 1 }),
1740
- kind: Type.Literal("cid-equals"),
1741
- spec: CidEqualsSpec,
1742
- required: Type.Boolean()
1743
- }, { additionalProperties: false })
1744
- ], { $id: "Gate" });
1745
- var AssertionOp = Type.Union([
1746
- Type.Literal("exists"),
1747
- Type.Literal("equals"),
1748
- Type.Literal("matches"),
1749
- Type.Literal("in-range"),
1750
- Type.Literal("min-length")
1751
- ], { $id: "AssertionOp" });
1752
- var Assertion = Type.Object({
1753
- id: Type.String({ minLength: 1 }),
1754
- path: Type.String({ minLength: 1 }),
1755
- op: AssertionOp,
1756
- value: Type.Optional(Type.Unknown())
1589
+ type: Type.Literal(SIGNER_CONSTRAINT_TYPE.TeamRole),
1590
+ id: TeamRoleSchema
1591
+ }),
1592
+ Type.Object({
1593
+ type: Type.Literal(SIGNER_CONSTRAINT_TYPE.Group),
1594
+ id: Type.String({ format: "uuid" })
1595
+ })
1596
+ ]);
1597
+ //#endregion
1598
+ //#region ../../libs/models/src/signer-protocol.ts
1599
+ function schemaRef(schema) {
1600
+ const id = schemaId(schema);
1601
+ return Type.Ref(id);
1602
+ }
1603
+ function schemaId(schema) {
1604
+ const id = schema.$id;
1605
+ if (typeof id !== "string" || id.length === 0) throw new Error("Signer protocol schemas must have an identifier");
1606
+ return id;
1607
+ }
1608
+ var SignerBase64UrlSchema = PreviewSignBase64UrlSchema;
1609
+ var SignerUuidSchema = Type.String({
1610
+ $id: "SignerUuid",
1611
+ pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
1612
+ });
1613
+ var SignerOperationSchema = Type.Union([
1614
+ Type.Literal("credential-enrollment"),
1615
+ Type.Literal("credential-registration"),
1616
+ Type.Literal("signing-request")
1617
+ ], { $id: "SignerOperation" });
1618
+ var SignerChallengeOperationSchema = PreviewSignChallengeOperationSchema;
1619
+ var SignerPreviewSignPublicMaterialSchema = PreviewSignPublicMaterialSchema;
1620
+ var SignerPreviewSignChallengeValueSchema = PreviewSignChallengeValueSchema;
1621
+ var SignerProblemSchema = Type.Object({
1622
+ code: Type.String({ minLength: 1 }),
1623
+ message: Type.String({ minLength: 1 })
1757
1624
  }, {
1758
- $id: "Assertion",
1625
+ $id: "SignerProblem",
1759
1626
  additionalProperties: false
1760
1627
  });
1761
- var SideEffectsSpec = Type.Object({
1762
- diaryEntryRequired: Type.Optional(Type.Boolean()),
1763
- diaryEntryTags: Type.Optional(Type.Array(Type.String({ minLength: 1 }))),
1764
- referencedEntries: Type.Optional(Type.Integer({ minimum: 0 }))
1628
+ var SignerCeremonyParamsSchema = Type.Object({ ceremonyId: Type.Unsafe(schemaRef(SignerBase64UrlSchema)) }, {
1629
+ $id: "SignerCeremonyParams",
1630
+ additionalProperties: false
1631
+ });
1632
+ var SignerSessionSchema = Type.Object({
1633
+ version: Type.Literal(1),
1634
+ token: Type.Unsafe(schemaRef(SignerBase64UrlSchema)),
1635
+ expiresAt: Type.String()
1765
1636
  }, {
1766
- $id: "SideEffectsSpec",
1637
+ $id: "SignerSession",
1767
1638
  additionalProperties: false
1768
1639
  });
1769
- var SuccessCriteria = Type.Object({
1640
+ var SignerEnrollmentCeremonyRequestSchema = Type.Object({
1770
1641
  version: Type.Literal(1),
1771
- gates: Type.Optional(Type.Array(Gate)),
1772
- assertions: Type.Optional(Type.Array(Assertion)),
1773
- rubric: Type.Optional(Rubric),
1774
- minComposite: Type.Optional(Type.Number({
1775
- minimum: 0,
1776
- maximum: 1
1777
- })),
1778
- sideEffects: Type.Optional(SideEffectsSpec)
1642
+ operation: Type.Literal("credential-enrollment"),
1643
+ label: Type.String({
1644
+ minLength: 1,
1645
+ maxLength: 255
1646
+ }),
1647
+ teamId: Type.Unsafe(schemaRef(SignerUuidSchema))
1779
1648
  }, {
1780
- $id: "SuccessCriteria",
1649
+ $id: "SignerEnrollmentCeremonyRequest",
1781
1650
  additionalProperties: false
1782
1651
  });
1783
- var VerificationResultStatus = Type.Union([
1784
- Type.Literal("pass"),
1785
- Type.Literal("fail"),
1786
- Type.Literal("skip")
1787
- ], { $id: "VerificationResultStatus" });
1788
- var VerificationResultKind = Type.Union([
1789
- Type.Literal("gate"),
1790
- Type.Literal("assertion"),
1791
- Type.Literal("rubric"),
1792
- Type.Literal("sideEffect")
1793
- ], { $id: "VerificationResultKind" });
1794
- var VerificationResult = Type.Object({
1795
- id: Type.String({ minLength: 1 }),
1796
- kind: VerificationResultKind,
1797
- status: VerificationResultStatus,
1798
- detail: Type.Optional(Type.String())
1652
+ var SignerChallengeCeremonyRequestSchema = Type.Object({
1653
+ version: Type.Literal(1),
1654
+ operation: Type.Unsafe(schemaRef(SignerChallengeOperationSchema)),
1655
+ resourceId: Type.Unsafe(schemaRef(SignerUuidSchema)),
1656
+ challenge: Type.Unsafe(schemaRef(SignerPreviewSignChallengeValueSchema))
1799
1657
  }, {
1800
- $id: "VerificationResult",
1658
+ $id: "SignerChallengeCeremonyRequest",
1801
1659
  additionalProperties: false
1802
1660
  });
1803
- var VerificationRecord = Type.Object({
1804
- inputCid: Type.String({ minLength: 1 }),
1805
- results: Type.Array(VerificationResult),
1806
- passed: Type.Boolean({ description: "True iff every verification result has status \"pass\" or \"skip\"; false when any result has status \"fail\"." })
1661
+ var SignerCeremonyRequestSchema = Type.Union([Type.Unsafe(schemaRef(SignerEnrollmentCeremonyRequestSchema)), Type.Unsafe(schemaRef(SignerChallengeCeremonyRequestSchema))], { $id: "SignerCeremonyRequest" });
1662
+ var SignerCeremonySchema = Type.Object({
1663
+ version: Type.Literal(1),
1664
+ id: Type.Unsafe(schemaRef(SignerBase64UrlSchema)),
1665
+ operation: Type.Unsafe(schemaRef(SignerOperationSchema)),
1666
+ approvalUrl: Type.String(),
1667
+ expiresAt: Type.String()
1807
1668
  }, {
1808
- $id: "VerificationRecord",
1669
+ $id: "SignerCeremony",
1670
+ additionalProperties: false
1671
+ });
1672
+ var SignerPendingResultSchema = Type.Object({
1673
+ version: Type.Literal(1),
1674
+ status: Type.Literal("pending"),
1675
+ operation: Type.Unsafe(schemaRef(SignerOperationSchema))
1676
+ }, {
1677
+ $id: "SignerPendingResult",
1678
+ additionalProperties: false
1679
+ });
1680
+ var SignerEnrollmentResultSchema = Type.Object({
1681
+ version: Type.Literal(1),
1682
+ status: Type.Literal("completed"),
1683
+ operation: Type.Literal("credential-enrollment"),
1684
+ publicMaterial: Type.Unsafe(schemaRef(SignerPreviewSignPublicMaterialSchema))
1685
+ }, {
1686
+ $id: "SignerEnrollmentResult",
1687
+ additionalProperties: false
1688
+ });
1689
+ var SignerReceiptSchema = PreviewSignReceiptValueSchema;
1690
+ var SignerSignatureResultSchema = Type.Object({
1691
+ version: Type.Literal(1),
1692
+ status: Type.Literal("completed"),
1693
+ operation: Type.Unsafe(schemaRef(SignerChallengeOperationSchema)),
1694
+ receipt: Type.Unsafe(schemaRef(SignerReceiptSchema))
1695
+ }, {
1696
+ $id: "SignerSignatureResult",
1697
+ additionalProperties: false
1698
+ });
1699
+ var SignerFailedResultSchema = Type.Object({
1700
+ version: Type.Literal(1),
1701
+ status: Type.Literal("failed"),
1702
+ operation: Type.Unsafe(schemaRef(SignerOperationSchema)),
1703
+ code: Type.String(),
1704
+ message: Type.String()
1705
+ }, {
1706
+ $id: "SignerFailedResult",
1707
+ additionalProperties: false
1708
+ });
1709
+ var SignerCeremonyResultSchema = Type.Union([
1710
+ Type.Unsafe(schemaRef(SignerPendingResultSchema)),
1711
+ Type.Unsafe(schemaRef(SignerEnrollmentResultSchema)),
1712
+ Type.Unsafe(schemaRef(SignerSignatureResultSchema)),
1713
+ Type.Unsafe(schemaRef(SignerFailedResultSchema))
1714
+ ], { $id: "SignerCeremonyResult" });
1715
+ ({ ...previewSignSchemaContext }), schemaId(SignerUuidSchema), schemaId(SignerOperationSchema), schemaId(SignerProblemSchema), schemaId(SignerCeremonyParamsSchema), schemaId(SignerSessionSchema), schemaId(SignerEnrollmentCeremonyRequestSchema), schemaId(SignerChallengeCeremonyRequestSchema), schemaId(SignerCeremonyRequestSchema), schemaId(SignerCeremonySchema), schemaId(SignerPendingResultSchema), schemaId(SignerEnrollmentResultSchema), schemaId(SignerSignatureResultSchema), schemaId(SignerFailedResultSchema), schemaId(SignerCeremonyResultSchema);
1716
+ //#endregion
1717
+ //#region ../../libs/models/src/tool-enforcement.ts
1718
+ var TOOL_ENFORCEMENT_VALUES = [
1719
+ "off",
1720
+ "watch",
1721
+ "enforce"
1722
+ ];
1723
+ var toolEnforcementLiterals = [
1724
+ Type.Literal(TOOL_ENFORCEMENT_VALUES[0]),
1725
+ Type.Literal(TOOL_ENFORCEMENT_VALUES[1]),
1726
+ Type.Literal(TOOL_ENFORCEMENT_VALUES[2])
1727
+ ];
1728
+ var ToolEnforcementSchema = Type.Union(toolEnforcementLiterals, { description: "Runtime tool-policy enforcement mode: off (inert), watch (audit only), enforce (block disallowed tools, fail-closed)." });
1729
+ //#endregion
1730
+ //#region ../../libs/runtime-profiles/src/runtime-profiles.ts
1731
+ var RuntimeProfileName = Type.String({
1732
+ minLength: 1,
1733
+ maxLength: 100,
1734
+ pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]{0,99}$"
1735
+ });
1736
+ var RuntimeProfileEnvName = Type.String({
1737
+ minLength: 1,
1738
+ maxLength: 128,
1739
+ pattern: "^[A-Z_][A-Z0-9_]*$"
1740
+ });
1741
+ var RuntimeProfileToolName = Type.String({
1742
+ minLength: 1,
1743
+ maxLength: 128,
1744
+ pattern: "^[a-zA-Z0-9._/-]+$"
1745
+ });
1746
+ var RUNTIME_PROFILE_RUNTIME_KIND_PATTERN = "^[a-z][a-z0-9._-]{0,99}$";
1747
+ new RegExp(RUNTIME_PROFILE_RUNTIME_KIND_PATTERN);
1748
+ var RuntimeProfileRuntimeKind = Type.String({
1749
+ minLength: 1,
1750
+ maxLength: 100,
1751
+ pattern: RUNTIME_PROFILE_RUNTIME_KIND_PATTERN
1752
+ });
1753
+ var RuntimeProfileWorkspaceMode = Type.Union([
1754
+ Type.Literal("none"),
1755
+ Type.Literal("shared_mount"),
1756
+ Type.Literal("dedicated_worktree")
1757
+ ]);
1758
+ /**
1759
+ * Tool-policy enforcement mode for the profile's runtime `tool_call` gate:
1760
+ * `off` (inert), `watch` (audit only), `enforce` (block disallowed tools,
1761
+ * fail-closed). Read by the daemon via `GET /runtime-profiles/:id/allowed-tools`.
1762
+ */
1763
+ var RuntimeProfileToolEnforcement = ToolEnforcementSchema;
1764
+ var RuntimeProfileAllowedWorkspaceModes = Type.Array(RuntimeProfileWorkspaceMode, {
1765
+ minItems: 1,
1766
+ maxItems: 3,
1767
+ uniqueItems: true
1768
+ });
1769
+ var RuntimeProfileThinkingLevelOptions = [
1770
+ Type.Literal("off"),
1771
+ Type.Literal("minimal"),
1772
+ Type.Literal("low"),
1773
+ Type.Literal("medium"),
1774
+ Type.Literal("high"),
1775
+ Type.Literal("xhigh")
1776
+ ];
1777
+ Type.Union([...RuntimeProfileThinkingLevelOptions]);
1778
+ var RuntimeProfileNullableThinkingLevel = Type.Union([...RuntimeProfileThinkingLevelOptions, Type.Null()]);
1779
+ var RuntimeProfileNullableTemperature = Type.Union([Type.Null(), Type.Number({
1780
+ minimum: 0,
1781
+ maximum: 2
1782
+ })]);
1783
+ var RuntimeProfileNullableTopP = Type.Union([Type.Null(), Type.Number({
1784
+ minimum: 0,
1785
+ maximum: 1
1786
+ })]);
1787
+ var RuntimeProfileNullableTopK = Type.Union([Type.Integer({
1788
+ minimum: 1,
1789
+ maximum: 1e4
1790
+ }), Type.Null()]);
1791
+ var RuntimeProfileNullableMaxOutputTokens = Type.Union([Type.Integer({
1792
+ minimum: 1,
1793
+ maximum: 1e6
1794
+ }), Type.Null()]);
1795
+ var RuntimeProfileAllowedHost = Type.String({
1796
+ minLength: 1,
1797
+ maxLength: 255,
1798
+ pattern: "^(?:\\*\\.)?(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)(?:\\.(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?))*$"
1799
+ });
1800
+ var RuntimeProfileSandbox = Type.Object({
1801
+ network: Type.Optional(Type.Object({
1802
+ allowedHosts: Type.Optional(Type.Array(RuntimeProfileAllowedHost, { maxItems: 50 })),
1803
+ allowedInternalHosts: Type.Optional(Type.Array(RuntimeProfileAllowedHost, { maxItems: 50 }))
1804
+ }, { additionalProperties: false })),
1805
+ vfs: Type.Optional(Type.Object({
1806
+ shadow: Type.Optional(Type.Array(Type.String({
1807
+ minLength: 1,
1808
+ maxLength: 255
1809
+ }), { maxItems: 100 })),
1810
+ shadowMode: Type.Optional(Type.Union([Type.Literal("deny"), Type.Literal("tmpfs")]))
1811
+ }, { additionalProperties: false })),
1812
+ env: Type.Optional(Type.Record(RuntimeProfileEnvName, Type.String({ maxLength: 4096 }))),
1813
+ hostExec: Type.Optional(Type.Object({ autoApprove: Type.Optional(Type.Literal(false)) }, { additionalProperties: false })),
1814
+ resources: Type.Optional(Type.Object({
1815
+ memory: Type.Optional(Type.String({
1816
+ minLength: 2,
1817
+ maxLength: 16,
1818
+ pattern: "^[0-9]+[KMG]?$"
1819
+ })),
1820
+ cpus: Type.Optional(Type.Integer({
1821
+ minimum: 1,
1822
+ maximum: 32
1823
+ }))
1824
+ }, { additionalProperties: false }))
1825
+ }, {
1826
+ $id: "RuntimeProfileSandbox",
1827
+ additionalProperties: false
1828
+ });
1829
+ var RuntimeProfileContext = Type.Object({
1830
+ slug: Type.String({
1831
+ minLength: 1,
1832
+ maxLength: 64,
1833
+ pattern: "^[a-zA-Z0-9_-]+$"
1834
+ }),
1835
+ binding: Type.Union([
1836
+ Type.Literal("skill"),
1837
+ Type.Literal("context_inline"),
1838
+ Type.Literal("prompt_prefix"),
1839
+ Type.Literal("user_inline")
1840
+ ]),
1841
+ content: Type.String({
1842
+ minLength: 1,
1843
+ maxLength: 65536
1844
+ })
1845
+ }, {
1846
+ $id: "RuntimeProfileContext",
1847
+ additionalProperties: false
1848
+ });
1849
+ var RuntimeProfileRef = Type.Object({ profileId: Type.String({ format: "uuid" }) }, {
1850
+ $id: "RuntimeProfileRef",
1809
1851
  additionalProperties: false
1810
1852
  });
1811
- //#endregion
1812
- //#region ../../libs/tasks/src/task-artifacts.ts
1813
- var TaskArtifact = Type.Object({
1853
+ var RuntimeProfileLeaseTtlSec = Type.Integer({
1854
+ minimum: 1,
1855
+ maximum: 86400
1856
+ });
1857
+ var RuntimeProfileHeartbeatIntervalMs = Type.Integer({
1858
+ minimum: 0,
1859
+ maximum: 36e5
1860
+ });
1861
+ var RuntimeProfileMaxBatchSize = Type.Integer({
1862
+ minimum: 1,
1863
+ maximum: 1e3
1864
+ });
1865
+ var RuntimeProfileMaxTurns = Type.Integer({
1866
+ minimum: 0,
1867
+ maximum: 1e4
1868
+ });
1869
+ var RuntimeProfileMaxBashTimeouts = Type.Integer({
1870
+ minimum: 0,
1871
+ maximum: 1e3
1872
+ });
1873
+ Type.Object({
1814
1874
  id: Type.String({ format: "uuid" }),
1815
1875
  teamId: Type.String({ format: "uuid" }),
1816
- taskId: Type.String({ format: "uuid" }),
1817
- attemptN: Type.Union([Type.Integer({ minimum: 1 }), Type.Null()]),
1818
- kind: Type.String({
1876
+ name: RuntimeProfileName,
1877
+ description: Type.Union([Type.String({ maxLength: 4096 }), Type.Null()]),
1878
+ provider: Type.String({
1819
1879
  minLength: 1,
1820
1880
  maxLength: 100
1821
1881
  }),
1822
- title: Type.String({
1823
- minLength: 1,
1824
- maxLength: 255
1825
- }),
1826
- contentType: Type.String({
1882
+ model: Type.String({
1827
1883
  minLength: 1,
1828
1884
  maxLength: 200
1829
1885
  }),
1830
- contentEncoding: Type.Union([Type.String({
1831
- minLength: 1,
1832
- maxLength: 100
1833
- }), Type.Null()]),
1834
- sizeBytes: Type.Integer({ minimum: 0 }),
1835
- cid: Type.String({
1886
+ thinkingLevel: RuntimeProfileNullableThinkingLevel,
1887
+ temperature: RuntimeProfileNullableTemperature,
1888
+ topP: RuntimeProfileNullableTopP,
1889
+ topK: RuntimeProfileNullableTopK,
1890
+ maxOutputTokens: RuntimeProfileNullableMaxOutputTokens,
1891
+ runtimeKind: RuntimeProfileRuntimeKind,
1892
+ sandbox: RuntimeProfileSandbox,
1893
+ sessionStorageMode: Type.Literal("local"),
1894
+ workspaceStorageMode: Type.Literal("local"),
1895
+ defaultWorkspaceMode: Type.Union([RuntimeProfileWorkspaceMode, Type.Null()]),
1896
+ allowedWorkspaceModes: RuntimeProfileAllowedWorkspaceModes,
1897
+ sessionTtlSec: Type.Integer({
1898
+ minimum: 1,
1899
+ maximum: 86400
1900
+ }),
1901
+ workspaceTtlSec: Type.Integer({
1902
+ minimum: 1,
1903
+ maximum: 86400
1904
+ }),
1905
+ leaseTtlSec: RuntimeProfileLeaseTtlSec,
1906
+ heartbeatIntervalMs: RuntimeProfileHeartbeatIntervalMs,
1907
+ maxBatchSize: RuntimeProfileMaxBatchSize,
1908
+ maxTurns: RuntimeProfileMaxTurns,
1909
+ maxBashTimeouts: RuntimeProfileMaxBashTimeouts,
1910
+ toolEnforcement: RuntimeProfileToolEnforcement,
1911
+ requiredEnv: Type.Array(RuntimeProfileEnvName, { maxItems: 100 }),
1912
+ requiredTools: Type.Array(RuntimeProfileToolName, { maxItems: 100 }),
1913
+ requiredExecutables: Type.Array(RuntimeProfileToolName, { maxItems: 100 }),
1914
+ context: Type.Array(RuntimeProfileContext, { maxItems: 5 }),
1915
+ revision: Type.Integer({ minimum: 1 }),
1916
+ definitionCid: Type.String({
1836
1917
  minLength: 1,
1837
1918
  maxLength: 100
1838
1919
  }),
1839
1920
  createdByAgentId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1840
- expiresAt: Type.Union([Type.String({ format: "date-time" }), Type.Null()]),
1841
- createdAt: Type.String({ format: "date-time" })
1842
- }, { $id: "TaskArtifact" });
1843
- Type.Object({
1844
- artifacts: Type.Array(TaskArtifact),
1845
- nextCursor: Type.Union([Type.String({ minLength: 1 }), Type.Null()])
1846
- }, { $id: "TaskArtifactList" });
1847
- Type.Object({
1848
- limit: Type.Optional(Type.Integer({
1849
- minimum: 1,
1850
- maximum: 100
1851
- })),
1852
- cursor: Type.Optional(Type.String({ minLength: 1 }))
1921
+ createdByHumanId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1922
+ createdAt: Type.String({ format: "date-time" }),
1923
+ updatedAt: Type.String({ format: "date-time" })
1853
1924
  }, {
1854
- $id: "ListTaskArtifactsQuery",
1925
+ $id: "RuntimeProfile",
1855
1926
  additionalProperties: false
1856
1927
  });
1857
- var HeaderSafeContentType = Type.String({
1858
- minLength: 1,
1859
- maxLength: 200,
1860
- pattern: "^[\\x21-\\x7e][\\x20-\\x7e]*$"
1861
- });
1862
- var HeaderSafeContentEncoding = Type.String({
1863
- minLength: 1,
1864
- maxLength: 100,
1865
- pattern: "^[\\x21-\\x7e][\\x20-\\x7e]*$"
1866
- });
1928
+ //#endregion
1929
+ //#region ../../libs/runtime-profiles/src/runtime-sessions.ts
1930
+ var RuntimeSessionKind = Type.Union([
1931
+ Type.Literal("root"),
1932
+ Type.Literal("extend"),
1933
+ Type.Literal("fork")
1934
+ ]);
1935
+ var RuntimeSessionCheckpointKind = Type.Union([Type.Literal("attempt_final")]);
1867
1936
  Type.Object({
1868
- kind: Type.String({
1937
+ id: Type.String({ format: "uuid" }),
1938
+ teamId: Type.String({ format: "uuid" }),
1939
+ taskId: Type.String({ format: "uuid" }),
1940
+ attemptN: Type.Integer({ minimum: 1 }),
1941
+ sourceSlotId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1942
+ sourceRuntimeProfileId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1943
+ sessionKind: RuntimeSessionKind,
1944
+ parentSessionId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
1945
+ contentType: Type.String({
1946
+ minLength: 1,
1947
+ maxLength: 200
1948
+ }),
1949
+ contentEncoding: Type.Union([Type.String({
1869
1950
  minLength: 1,
1870
1951
  maxLength: 100
1952
+ }), Type.Null()]),
1953
+ sizeBytes: Type.Integer({ minimum: 0 }),
1954
+ sha256: Type.String({
1955
+ minLength: 64,
1956
+ maxLength: 64
1871
1957
  }),
1872
- title: Type.String({
1958
+ storageClass: Type.String({
1873
1959
  minLength: 1,
1874
- maxLength: 255
1960
+ maxLength: 100
1875
1961
  }),
1876
- contentType: Type.Optional(HeaderSafeContentType),
1877
- contentEncoding: Type.Optional(HeaderSafeContentEncoding)
1962
+ checkpointKind: RuntimeSessionCheckpointKind,
1963
+ uploadedAt: Type.String({ format: "date-time" })
1964
+ }, { $id: "RuntimeSession" });
1965
+ Type.Object({
1966
+ sourceSlotId: Type.Optional(Type.String({ format: "uuid" })),
1967
+ sourceRuntimeProfileId: Type.Optional(Type.String({ format: "uuid" })),
1968
+ sessionKind: RuntimeSessionKind,
1969
+ parentSessionId: Type.Optional(Type.String({ format: "uuid" }))
1878
1970
  }, {
1879
- $id: "UploadTaskArtifactQuery",
1971
+ $id: "UploadRuntimeSessionQuery",
1880
1972
  additionalProperties: false
1881
1973
  });
1882
1974
  Type.String({
1883
- $id: "TaskArtifactContent",
1884
- description: "Task artifact content stream.",
1975
+ $id: "RuntimeSessionContent",
1976
+ description: "Runtime session content stream.",
1885
1977
  format: "binary"
1886
1978
  });
1887
- Type.Object({ taskId: Type.String({ format: "uuid" }) }, {
1888
- $id: "TaskArtifactTaskParams",
1889
- additionalProperties: false
1890
- });
1891
1979
  Type.Object({
1892
1980
  taskId: Type.String({ format: "uuid" }),
1893
1981
  attemptN: Type.Integer({ minimum: 1 })
1894
1982
  }, {
1895
- $id: "TaskArtifactAttemptParams",
1983
+ $id: "RuntimeSessionAttemptParams",
1896
1984
  additionalProperties: false
1897
1985
  });
1898
- Type.Object({
1899
- taskId: Type.String({ format: "uuid" }),
1900
- attemptN: Type.Integer({ minimum: 1 }),
1901
- cid: Type.String({
1986
+ //#endregion
1987
+ //#region ../../libs/runtime-profiles/src/runtime-slots.ts
1988
+ var RuntimeWorkspaceKind = Type.Union([
1989
+ Type.Literal("origin"),
1990
+ Type.Literal("fork"),
1991
+ Type.Literal("scratch")
1992
+ ]);
1993
+ var RuntimeSlotState = Type.Union([Type.Literal("active"), Type.Literal("idle")]);
1994
+ var RuntimeWorkspace = Type.Object({
1995
+ id: Type.String({ format: "uuid" }),
1996
+ teamId: Type.String({ format: "uuid" }),
1997
+ workspaceId: Type.String({ minLength: 1 }),
1998
+ worktreePath: Type.String({ minLength: 1 }),
1999
+ worktreeBranch: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
2000
+ kind: RuntimeWorkspaceKind,
2001
+ createdAtMs: Type.Integer({ minimum: 0 }),
2002
+ lastUsedAtMs: Type.Integer({ minimum: 0 })
2003
+ }, { $id: "RuntimeWorkspace" });
2004
+ var RuntimeSlot = Type.Object({
2005
+ id: Type.String({ format: "uuid" }),
2006
+ teamId: Type.String({ format: "uuid" }),
2007
+ agentName: Type.String({
1902
2008
  minLength: 1,
1903
2009
  maxLength: 100
1904
- })
1905
- }, {
1906
- $id: "TaskArtifactContentParams",
1907
- additionalProperties: false
1908
- });
1909
- Type.Object({
1910
- contentType: Type.Optional(HeaderSafeContentType),
1911
- contentEncoding: Type.Optional(HeaderSafeContentEncoding)
1912
- }, {
1913
- $id: "StageTaskArtifactQuery",
1914
- additionalProperties: false
1915
- });
1916
- Type.Object({
1917
- cid: Type.String({
2010
+ }),
2011
+ runtimeProfileId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
2012
+ provider: Type.String({
1918
2013
  minLength: 1,
1919
2014
  maxLength: 100
1920
2015
  }),
1921
- sizeBytes: Type.Integer({ minimum: 0 }),
1922
- contentType: Type.String({
2016
+ model: Type.String({
1923
2017
  minLength: 1,
1924
2018
  maxLength: 200
1925
- })
1926
- }, { $id: "StagedTaskArtifact" });
1927
- Type.Object({
1928
- taskId: Type.String({ format: "uuid" }),
1929
- cid: Type.String({
2019
+ }),
2020
+ slotKey: Type.String({ minLength: 1 }),
2021
+ taskType: Type.String({
2022
+ minLength: 1,
2023
+ maxLength: 100
2024
+ }),
2025
+ state: RuntimeSlotState,
2026
+ lastTaskId: Type.String({ format: "uuid" }),
2027
+ lastAttemptN: Type.Integer({ minimum: 1 }),
2028
+ sessionDir: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
2029
+ sessionPath: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
2030
+ workspaceRowId: Type.Union([Type.String({ format: "uuid" }), Type.Null()]),
2031
+ createdAtMs: Type.Integer({ minimum: 0 }),
2032
+ lastUsedAtMs: Type.Integer({ minimum: 0 }),
2033
+ expiresAtMs: Type.Integer({ minimum: 0 })
2034
+ }, { $id: "RuntimeSlot" });
2035
+ var ResolvedRuntimeSlot = Type.Object({
2036
+ slot: RuntimeSlot,
2037
+ workspace: Type.Union([RuntimeWorkspace, Type.Null()])
2038
+ }, { $id: "ResolvedRuntimeSlot" });
2039
+ Type.Object({ items: Type.Array(ResolvedRuntimeSlot) }, { $id: "RuntimeSlotListResponse" });
2040
+ Type.Object({
2041
+ agentName: Type.String({
1930
2042
  minLength: 1,
1931
2043
  maxLength: 100
1932
- })
1933
- }, {
1934
- $id: "TaskArtifactTaskContentParams",
1935
- additionalProperties: false
1936
- });
1937
- //#endregion
1938
- //#region ../../libs/tasks/src/task-types/assess-brief.ts
1939
- /**
1940
- * `assess_brief` — independently evaluate a fulfilled brief.
1941
- *
1942
- * output_kind: judgment
1943
- * criteria: required (`successCriteria.rubric` — same envelope as
1944
- * `judge_pack`)
1945
- * references: required (must reference the target `fulfill_brief` task)
1946
- *
1947
- * The assessor is a different agent from the producer (enforced by the
1948
- * server / runtime at claim time — not in the wire schema).
1949
- *
1950
- * The rubric in `successCriteria` IS the job spec — the assessor applies
1951
- * it to the target task's output and emits per-criterion scores. Other
1952
- * sections (`assertions`, `gates`, `sideEffects`) MAY be present and are
1953
- * evaluated against the *assessor's output*.
1954
- */
1955
- var ASSESS_BRIEF_TYPE = "assess_brief";
1956
- var AssessBriefInput = Type.Object({
1957
- targetTaskId: Type.String({ format: "uuid" }),
1958
- successCriteria: SuccessCriteria
1959
- }, {
1960
- $id: "AssessBriefInput",
1961
- additionalProperties: false
1962
- });
1963
- /** One score line. */
1964
- var AssessBriefScore = Type.Object({
1965
- criterionId: Type.String({ minLength: 1 }),
1966
- score: Type.Number({
1967
- minimum: 0,
1968
- maximum: 1
1969
2044
  }),
1970
- rationale: Type.Optional(Type.String()),
1971
- evidence: Type.Optional(Type.Object({
1972
- commitsVerified: Type.Number(),
1973
- commitsTotal: Type.Number(),
1974
- signatureFailures: Type.Array(Type.String())
1975
- }, { additionalProperties: false }))
2045
+ runtimeProfileId: Type.String({ format: "uuid" }),
2046
+ provider: Type.String({
2047
+ minLength: 1,
2048
+ maxLength: 100
2049
+ }),
2050
+ model: Type.String({
2051
+ minLength: 1,
2052
+ maxLength: 200
2053
+ }),
2054
+ slotKey: Type.String({ minLength: 1 }),
2055
+ taskType: Type.String({
2056
+ minLength: 1,
2057
+ maxLength: 100
2058
+ }),
2059
+ sessionDir: Type.Optional(Type.String({ minLength: 1 })),
2060
+ sessionPath: Type.Optional(Type.String({ minLength: 1 })),
2061
+ workspaceId: Type.Optional(Type.String({ minLength: 1 })),
2062
+ worktreePath: Type.Optional(Type.String({ minLength: 1 })),
2063
+ worktreeBranch: Type.Optional(Type.String({ minLength: 1 })),
2064
+ workspaceKind: Type.Optional(RuntimeWorkspaceKind),
2065
+ lastTaskId: Type.String({ format: "uuid" }),
2066
+ lastAttemptN: Type.Integer({ minimum: 1 })
1976
2067
  }, {
1977
- $id: "AssessBriefScore",
2068
+ $id: "BeginRuntimeSlotBody",
1978
2069
  additionalProperties: false
1979
2070
  });
1980
- var AssessBriefOutput = Type.Object({
1981
- scores: Type.Array(AssessBriefScore, { minItems: 1 }),
1982
- composite: Type.Number({
1983
- minimum: 0,
1984
- maximum: 1
2071
+ Type.Object({
2072
+ agentName: Type.String({
2073
+ minLength: 1,
2074
+ maxLength: 100
1985
2075
  }),
1986
- verdict: Type.String({ minLength: 1 }),
1987
- judgeModel: Type.Optional(Type.String())
2076
+ runtimeProfileId: Type.String({ format: "uuid" }),
2077
+ provider: Type.String({
2078
+ minLength: 1,
2079
+ maxLength: 100
2080
+ }),
2081
+ model: Type.String({
2082
+ minLength: 1,
2083
+ maxLength: 200
2084
+ }),
2085
+ slotKey: Type.String({ minLength: 1 }),
2086
+ taskId: Type.String({ format: "uuid" }),
2087
+ attemptN: Type.Integer({ minimum: 1 }),
2088
+ sessionPath: Type.Optional(Type.String({ minLength: 1 }))
1988
2089
  }, {
1989
- $id: "AssessBriefOutput",
2090
+ $id: "FinishRuntimeSlotBody",
1990
2091
  additionalProperties: false
1991
2092
  });
1992
- /**
1993
- * Async preflight (#1096):
1994
- * - `targetTaskId` resolves to a real task the caller can see.
1995
- * - The target is a `fulfill_brief` (you cannot grade an arbitrary
1996
- * task type as if it were a brief fulfillment).
1997
- * - Unless readiness checks are explicitly deferred, the target is
1998
- * `completed` with an accepted attempt — grading an in-flight or
1999
- * failed task would either race or grade nothing.
2000
- *
2001
- * Agent-distinctness ("assessor ≠ producer") is a runtime / auth-
2002
- * layer concern and intentionally NOT checked here. It belongs in
2003
- * an auth-aware claim-time check.
2004
- */
2005
- async function validateAssessBriefInputAsync(input, ctx) {
2006
- const { targetTaskId } = input;
2007
- const errors = [];
2008
- const target = await ctx.resolveTask(targetTaskId);
2009
- if (!target) {
2010
- errors.push({
2011
- field: "targetTaskId",
2012
- message: `targetTaskId ${targetTaskId} does not resolve to a task you can read`
2013
- });
2014
- return errors;
2015
- }
2016
- if (target.taskType !== "fulfill_brief") errors.push({
2017
- field: "targetTaskId",
2018
- message: `targetTaskId ${targetTaskId} is a ${target.taskType}, not a fulfill_brief`
2019
- });
2020
- if (!ctx.deferReadinessChecks && (target.status !== "completed" || target.acceptedAttemptN === null)) errors.push({
2021
- field: "targetTaskId",
2022
- message: `targetTaskId ${targetTaskId} is not completed with an accepted attempt (status=${target.status}, acceptedAttemptN=${target.acceptedAttemptN})`
2023
- });
2024
- return errors;
2025
- }
2026
- //#endregion
2027
- //#region ../../libs/tasks/src/task-types/curate-pack.ts
2028
- /**
2029
- * `curate_pack` — select and rank diary entries into a context pack.
2030
- *
2031
- * output_kind: artifact
2032
- * criteria: not required (rubric-less curation recipe)
2033
- * references: optional (e.g. a prior rendered pack being re-curated)
2034
- *
2035
- * This is step 1 of the three-session attribution loop (#875). The agent
2036
- * runs a structured exploration over a diary — tag inventory, hybrid
2037
- * search, type/tag narrowing — and emits a ranked entry list via
2038
- * `moltnet_pack_create`. The prompt is deterministic given the input
2039
- * (no operator interaction), so two runs with the same input should
2040
- * converge on similar packs.
2041
- *
2042
- * Related: `render_pack`, `judge_pack`.
2043
- */
2044
- var CURATE_PACK_TYPE = "curate_pack";
2045
- var EntryTypeFilter = Type.Union([
2046
- Type.Literal("episodic"),
2047
- Type.Literal("semantic"),
2048
- Type.Literal("procedural"),
2049
- Type.Literal("reflection")
2050
- ]);
2051
- var CuratePackInput = Type.Object({
2052
- diaryId: Type.String({ format: "uuid" }),
2053
- taskPrompt: Type.String({ minLength: 1 }),
2054
- entryTypes: Type.Optional(Type.Array(EntryTypeFilter, { minItems: 1 })),
2055
- tagFilters: Type.Optional(Type.Object({
2056
- include: Type.Optional(Type.Array(Type.String())),
2057
- exclude: Type.Optional(Type.Array(Type.String())),
2058
- prefix: Type.Optional(Type.String())
2059
- }, { additionalProperties: false })),
2060
- tokenBudget: Type.Optional(Type.Number({ minimum: 500 })),
2061
- recipe: Type.Optional(Type.Union([Type.Literal("topic-focused-v1"), Type.Literal("scope-inventory-v1")])),
2062
- successCriteria: Type.Optional(SuccessCriteria)
2093
+ Type.Object({
2094
+ taskId: Type.String({ format: "uuid" }),
2095
+ attemptN: Type.Integer({ minimum: 1 })
2063
2096
  }, {
2064
- $id: "CuratePackInput",
2097
+ $id: "FindLatestRuntimeSlotForAttemptQuery",
2065
2098
  additionalProperties: false
2066
2099
  });
2067
- /**
2068
- * Index of the curated pack plus the reasoning trace. The pack itself
2069
- * lives in the database (created via `moltnet_pack_create`); this output
2070
- * is the receipt.
2071
- */
2072
- var CuratePackOutput = Type.Object({
2073
- packId: Type.String({ format: "uuid" }),
2074
- packCid: Type.String({ minLength: 1 }),
2075
- entries: Type.Array(Type.Object({
2076
- entryId: Type.String({ format: "uuid" }),
2077
- rank: Type.Number({ minimum: 1 }),
2078
- rationale: Type.String({ minLength: 1 })
2079
- }, { additionalProperties: false }), { minItems: 1 }),
2080
- recipeParams: Type.Record(Type.String(), Type.Unknown()),
2081
- checkpoints: Type.Optional(Type.Array(Type.Object({
2082
- phase: Type.String({ minLength: 1 }),
2083
- candidateIds: Type.Array(Type.String({ format: "uuid" })),
2084
- droppedIds: Type.Optional(Type.Array(Type.String({ format: "uuid" }))),
2085
- notes: Type.String({ minLength: 1 })
2086
- }, { additionalProperties: false }))),
2087
- summary: Type.String({ minLength: 1 }),
2088
- verification: Type.Optional(VerificationRecord)
2100
+ Type.Object({
2101
+ agentName: Type.Optional(Type.String({
2102
+ minLength: 1,
2103
+ maxLength: 100
2104
+ })),
2105
+ runtimeProfileId: Type.Optional(Type.String({ format: "uuid" })),
2106
+ state: Type.Optional(RuntimeSlotState),
2107
+ limit: Type.Optional(Type.Integer({
2108
+ minimum: 1,
2109
+ maximum: 200
2110
+ }))
2089
2111
  }, {
2090
- $id: "CuratePackOutput",
2112
+ $id: "ListRuntimeSlotsQuery",
2091
2113
  additionalProperties: false
2092
2114
  });
2093
2115
  //#endregion
@@ -3359,12 +3381,18 @@ var COMMON_OPTIONAL_FLAGS = `\
3359
3381
  sandbox policy.
3360
3382
  --agent-root <path> Directory that owns .moltnet/<agent>. Default:
3361
3383
  CWD, with git root fallback when available.
3384
+ --git-author <"Name <email>">
3385
+ Non-secret git identity projected into the
3386
+ guest for host-brokered commit signing. Default:
3387
+ host git config (OAuth2) or
3388
+ <identityId>+<agent>[bot]@users.noreply.github.com.
3389
+ Env: MOLTNET_GIT_AUTHOR.
3362
3390
  --guest-credential-mode <mode>
3363
3391
  Guest trust boundary: host-authenticated or
3364
3392
  guest-config. Defaults to host-authenticated for
3365
- agent-key and guest-config for OAuth2. Explicit
3366
- guest-config exposes the complete local agent
3367
- credential tree to the VM.
3393
+ both agent-key and OAuth2 authentication.
3394
+ Explicit guest-config exposes the complete local
3395
+ agent credential tree to the VM.
3368
3396
  --lease-ttl-sec <n> Sliding liveness window. Silence longer than
3369
3397
  this ends the attempt with lease_expired.
3370
3398
  Default: 300.
@@ -3540,16 +3568,18 @@ function isHelpFlag(args) {
3540
3568
  //#region src/lib/agent-context.ts
3541
3569
  /**
3542
3570
  * Guest credentials are an explicit trust decision, never an incidental
3543
- * consequence of files found on disk. Agent-key mode defaults to the
3544
- * configless host-authenticated boundary; OAuth2 keeps its config-backed
3545
- * behavior. OAuth2 cannot use the host-authenticated mode because its Agent is
3546
- * itself resolved from the local credential tree.
3571
+ * consequence of files found on disk. The guest boundary is independent of
3572
+ * how the daemon itself authenticates: both agent-key and OAuth2 default to
3573
+ * the host-authenticated boundary, where structured MoltNet operations reuse
3574
+ * the trusted host-side Agent and the guest receives no credential material.
3575
+ * OAuth2 still resolves that Agent from the local config and secret provider
3576
+ * on the host — reading `moltnet.json` on the host does not imply projecting
3577
+ * it into the guest. `guest-config` remains an explicit compatibility opt-in
3578
+ * for tasks that need credential-bearing guest-shell operations.
3547
3579
  */
3548
- function resolveDaemonGuestCredentialMode(authMode, requested) {
3580
+ function resolveDaemonGuestCredentialMode(requested) {
3549
3581
  if (requested !== void 0 && requested !== "guest-config" && requested !== "host-authenticated") throw new Error(`Invalid --guest-credential-mode "${requested}": expected guest-config or host-authenticated.`);
3550
- const mode = requested ?? (authMode === "agent-key" ? "host-authenticated" : "guest-config");
3551
- if (authMode === "oauth2" && mode === "host-authenticated") throw new Error("--guest-credential-mode host-authenticated requires agent-key authentication. OAuth2 requires the local agent configuration.");
3552
- return mode;
3582
+ return requested ?? "host-authenticated";
3553
3583
  }
3554
3584
  /**
3555
3585
  * Report which auth mode `connect()` will use, without ever reading the secret
@@ -3570,18 +3600,18 @@ function detectAuthMode(env) {
3570
3600
  *
3571
3601
  * Rules (see design entry edb848a1):
3572
3602
  * - The subject must be an `agent`; a human credential can never run the daemon.
3573
- * - A team-bound agent key (`credentialBinding.boundTeamId` set) must match the
3603
+ * - A team-bound agent key (`credentialBinding.bindingScope === 'team'`) must match the
3574
3604
  * `--team` the daemon was started with. A key is an immutable team ceiling, so
3575
3605
  * a mismatch would only surface as an obscure mid-poll 403 otherwise.
3576
- * - An unbound key or an OAuth2 identity (no `boundTeamId`) is accepted; normal
3577
- * team-scoped authorization governs those requests.
3606
+ * - An identity-scoped key or an OAuth2 identity is accepted; normal team-scoped
3607
+ * authorization governs those requests.
3578
3608
  */
3579
3609
  function assessStartupBinding(whoami, teamId) {
3580
3610
  if (whoami.subjectType !== "agent") return {
3581
3611
  ok: false,
3582
3612
  reason: `the daemon must authenticate as an agent, but whoami reported subjectType "${whoami.subjectType}". Provide agent credentials (an agent key or the agent's client id/secret).`
3583
3613
  };
3584
- const boundTeamId = whoami.credentialBinding?.boundTeamId;
3614
+ const boundTeamId = whoami.credentialBinding?.bindingScope === "team" ? whoami.credentialBinding.boundTeamId : void 0;
3585
3615
  if (teamId && boundTeamId && boundTeamId !== teamId) return {
3586
3616
  ok: false,
3587
3617
  reason: `the agent key is bound to team ${boundTeamId}, but the daemon was started with --team ${teamId}. Restart with --team ${boundTeamId}, or issue a key for team ${teamId}.`
@@ -3623,8 +3653,8 @@ async function validateStartupBinding(options) {
3623
3653
  async function resolveAgentContext(agentName, options = {}) {
3624
3654
  if (!/^[a-zA-Z0-9_-]+$/.test(agentName)) throw new Error(`Invalid agent name "${agentName}": must match /^[a-zA-Z0-9_-]+$/`);
3625
3655
  const roots = resolveCredentialRoots(options.agentRootDir);
3656
+ const guestCredentialMode = resolveDaemonGuestCredentialMode(options.guestCredentialMode);
3626
3657
  if (options.authMode === "agent-key") {
3627
- const guestCredentialMode = resolveDaemonGuestCredentialMode("agent-key", options.guestCredentialMode);
3628
3658
  const { rootDir, agentDir } = guestCredentialMode === "guest-config" ? resolveCompleteGuestCredentials(roots, agentName) : {
3629
3659
  rootDir: roots[0] ?? process.cwd(),
3630
3660
  agentDir: join(roots[0] ?? process.cwd(), ".moltnet", agentName)
@@ -3636,17 +3666,17 @@ async function resolveAgentContext(agentName, options = {}) {
3636
3666
  guestCredentialMode
3637
3667
  };
3638
3668
  }
3639
- resolveDaemonGuestCredentialMode("oauth2", options.guestCredentialMode);
3640
- for (const rootDir of roots) {
3641
- const agentDir = join(rootDir, ".moltnet", agentName);
3642
- if (existsSync(join(agentDir, "moltnet.json"))) return {
3643
- agentDir,
3644
- agentRootDir: rootDir,
3645
- agent: await connect({
3646
- configDir: agentDir,
3647
- secretProviders: createNodeSecretProviderRegistry()
3648
- }),
3649
- guestCredentialMode: "guest-config"
3669
+ const located = guestCredentialMode === "guest-config" ? resolveCompleteGuestCredentials(roots, agentName) : locateAgentConfig(roots, agentName);
3670
+ if (located) {
3671
+ const agent = await connect({
3672
+ configDir: located.agentDir,
3673
+ secretProviders: createNodeSecretProviderRegistry()
3674
+ });
3675
+ return {
3676
+ agentDir: located.agentDir,
3677
+ agentRootDir: located.rootDir,
3678
+ agent,
3679
+ guestCredentialMode
3650
3680
  };
3651
3681
  }
3652
3682
  const tried = roots.map((root) => join(root, ".moltnet", agentName));
@@ -3658,6 +3688,15 @@ function isTransientWhoamiError(error) {
3658
3688
  const statusCode = error.statusCode;
3659
3689
  return typeof statusCode === "number" && (statusCode === 408 || statusCode === 429 || statusCode >= 500);
3660
3690
  }
3691
+ function locateAgentConfig(roots, agentName) {
3692
+ for (const rootDir of roots) {
3693
+ const agentDir = join(rootDir, ".moltnet", agentName);
3694
+ if (existsSync(join(agentDir, "moltnet.json"))) return {
3695
+ rootDir,
3696
+ agentDir
3697
+ };
3698
+ }
3699
+ }
3661
3700
  function resolveCompleteGuestCredentials(roots, agentName) {
3662
3701
  const partial = [];
3663
3702
  for (const rootDir of roots) {
@@ -3703,6 +3742,7 @@ function loadConfig() {
3703
3742
  piCodingAgentDir: process.env["PI_CODING_AGENT_DIR"] ?? "",
3704
3743
  authMode: detectAuthMode(process.env),
3705
3744
  signingPrivateKey: process.env["MOLTNET_PRIVATE_KEY"] ?? "",
3745
+ gitAuthor: process.env["MOLTNET_GIT_AUTHOR"] ?? "",
3706
3746
  traceIdlePolling: readBoolean("MOLTNET_TRACE_IDLE_POLLING", process.env["MOLTNET_TRACE_IDLE_POLLING"])
3707
3747
  };
3708
3748
  }
@@ -3727,6 +3767,30 @@ async function abortActiveAttemptOnSignal(opts) {
3727
3767
  }
3728
3768
  }
3729
3769
  //#endregion
3770
+ //#region src/lib/agent-identity.ts
3771
+ /**
3772
+ * Build the non-secret identity projected into guests. Host git config is a
3773
+ * non-secret input and is consulted only on OAuth2 hosts, which already read
3774
+ * that configuration for the signing seed; configless agent-key hosts never
3775
+ * touch a config directory.
3776
+ */
3777
+ async function resolveDaemonAgentIdentity(input) {
3778
+ let hostGit;
3779
+ if (input.gitAuthor === void 0 && input.authMode === "oauth2") {
3780
+ const config = await readConfig(input.agentDir);
3781
+ hostGit = config?.git ? {
3782
+ name: config.git.name,
3783
+ email: config.git.email
3784
+ } : void 0;
3785
+ }
3786
+ return resolveAgentIdentity({
3787
+ agentName: input.agentName,
3788
+ whoami: input.whoami,
3789
+ gitAuthor: input.gitAuthor,
3790
+ hostGit
3791
+ });
3792
+ }
3793
+ //#endregion
3730
3794
  //#region src/lib/correlation.ts
3731
3795
  var execFileAsync = promisify(execFile);
3732
3796
  var CORRELATION_TRAILER_KEY = "Moltnet-Correlation-Id";
@@ -4245,6 +4309,19 @@ function recoverScratchWorkspacePath(producer, stateDirs) {
4245
4309
  const fallback = join(stateDirs.rootDir, "task-workspaces", producer.workspace.workspaceId);
4246
4310
  return existsSync(fallback) ? fallback : null;
4247
4311
  }
4312
+ //#endregion
4313
+ //#region ../../libs/crypto-service/src/ssh.ts
4314
+ /**
4315
+ * SSH key format conversion for MoltNet Ed25519 keys
4316
+ *
4317
+ * Converts MoltNet agent keys (ed25519:<base64>) to OpenSSH format
4318
+ * for use with git commit signing and SSH authentication.
4319
+ */
4320
+ if (!ed.etc.sha512Sync) ed.etc.sha512Sync = (...m) => {
4321
+ const hash = createHash$1("sha512");
4322
+ m.forEach((msg) => hash.update(msg));
4323
+ return hash.digest();
4324
+ };
4248
4325
  new TextEncoder();
4249
4326
  //#endregion
4250
4327
  //#region ../../libs/crypto-service/src/crypto.service.ts
@@ -4397,19 +4474,7 @@ ed.etc.sha512Sync = (...m) => {
4397
4474
  m.forEach((msg) => hash.update(msg));
4398
4475
  return hash.digest();
4399
4476
  };
4400
- //#endregion
4401
- //#region ../../libs/crypto-service/src/ssh.ts
4402
- /**
4403
- * SSH key format conversion for MoltNet Ed25519 keys
4404
- *
4405
- * Converts MoltNet agent keys (ed25519:<base64>) to OpenSSH format
4406
- * for use with git commit signing and SSH authentication.
4407
- */
4408
- if (!ed.etc.sha512Sync) ed.etc.sha512Sync = (...m) => {
4409
- const hash = createHash$1("sha512");
4410
- m.forEach((msg) => hash.update(msg));
4411
- return hash.digest();
4412
- };
4477
+ new TextEncoder().encode("SSHSIG");
4413
4478
  //#endregion
4414
4479
  //#region src/lib/executor-attestation.ts
4415
4480
  var DAEMON_REQUIRED_SCOPES = AGENT_CREDENTIAL_SCOPES;
@@ -4931,6 +4996,7 @@ function commonOptionDefs() {
4931
4996
  },
4932
4997
  "agent-root": { type: "string" },
4933
4998
  "guest-credential-mode": { type: "string" },
4999
+ "git-author": { type: "string" },
4934
5000
  "lease-ttl-sec": { type: "string" },
4935
5001
  "heartbeat-interval-ms": { type: "string" },
4936
5002
  "max-batch-size": { type: "string" },
@@ -5034,102 +5100,6 @@ function runWithDaemonRuntimeContext(context, callback) {
5034
5100
  return storage.run(context, callback);
5035
5101
  }
5036
5102
  //#endregion
5037
- //#region src/lib/runtime-profile.ts
5038
- var RuntimeProfilePrerequisiteError = class extends Error {
5039
- constructor(profileName, missingEnv, missingTools, missingExecutables) {
5040
- const parts = [
5041
- missingEnv.length > 0 ? `missing env: ${missingEnv.join(", ")}` : null,
5042
- missingTools.length > 0 ? `missing tools: ${missingTools.join(", ")}` : null,
5043
- missingExecutables.length > 0 ? `missing guest executables: ${missingExecutables.join(", ")}` : null
5044
- ].filter(Boolean);
5045
- super(`Runtime profile "${profileName}" prerequisites are not satisfied: ${parts.join("; ")}`);
5046
- this.profileName = profileName;
5047
- this.missingEnv = missingEnv;
5048
- this.missingTools = missingTools;
5049
- this.missingExecutables = missingExecutables;
5050
- this.name = "RuntimeProfilePrerequisiteError";
5051
- }
5052
- };
5053
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
5054
- async function resolveRuntimeProfile(options) {
5055
- const profile = UUID_RE.test(options.profile) ? await options.agent.runtimeProfiles.get(options.profile) : await resolveProfileByName(options);
5056
- if (options.teamId && profile.teamId !== options.teamId) throw new Error(`Runtime profile "${options.profile}" belongs to team ${profile.teamId}, not ${options.teamId}.`);
5057
- if (!Value.Check(RuntimeProfileSandbox, profile.sandbox)) throw new Error(`Runtime profile "${profile.name}" contains unsupported sandbox fields.`);
5058
- return {
5059
- id: profile.id,
5060
- name: profile.name,
5061
- teamId: profile.teamId,
5062
- runtimeKind: profile.runtimeKind,
5063
- definitionCid: profile.definitionCid,
5064
- provider: profile.provider,
5065
- model: profile.model,
5066
- thinkingLevel: profile.thinkingLevel ?? null,
5067
- temperature: profile.temperature ?? null,
5068
- topP: profile.topP ?? null,
5069
- topK: profile.topK ?? null,
5070
- maxOutputTokens: profile.maxOutputTokens ?? null,
5071
- leaseTtlSec: profile.leaseTtlSec,
5072
- heartbeatIntervalMs: profile.heartbeatIntervalMs,
5073
- maxBatchSize: profile.maxBatchSize,
5074
- maxTurns: profile.maxTurns,
5075
- maxBashTimeouts: profile.maxBashTimeouts,
5076
- sessionTtlSec: profile.sessionTtlSec,
5077
- workspaceTtlSec: profile.workspaceTtlSec,
5078
- defaultWorkspaceMode: profile.defaultWorkspaceMode ?? null,
5079
- allowedWorkspaceModes: profile.allowedWorkspaceModes,
5080
- requiredEnv: profile.requiredEnv,
5081
- requiredTools: profile.requiredTools,
5082
- requiredExecutables: profile.requiredExecutables,
5083
- toolEnforcement: profile.toolEnforcement,
5084
- context: profile.context ?? [],
5085
- sandboxConfig: profile.sandbox,
5086
- mountPath: resolve(options.cwd),
5087
- source: `runtime-profile:${profile.id}`
5088
- };
5089
- }
5090
- async function resolveRuntimeProfiles(options) {
5091
- const seen = /* @__PURE__ */ new Set();
5092
- const out = [];
5093
- for (const profile of options.profiles) {
5094
- const resolved = await resolveRuntimeProfile({
5095
- agent: options.agent,
5096
- profile,
5097
- teamId: options.teamId,
5098
- cwd: options.cwd
5099
- });
5100
- if (seen.has(resolved.id)) continue;
5101
- seen.add(resolved.id);
5102
- out.push(resolved);
5103
- }
5104
- return out;
5105
- }
5106
- function validateRuntimeProfilePrerequisites(profile, env, inventory) {
5107
- const missingEnv = profile.requiredEnv.filter((name) => !env[name]);
5108
- const available = new Set(inventory?.tools ?? []);
5109
- const executableInventory = new Set(inventory?.executables ?? []);
5110
- const missingTools = profile.requiredTools.filter((tool) => !available.has(tool));
5111
- const missingExecutables = profile.requiredExecutables.filter((executable) => !executableInventory.has(executable));
5112
- if (missingEnv.length > 0 || missingTools.length > 0 || missingExecutables.length > 0) throw new RuntimeProfilePrerequisiteError(profile.name, missingEnv, missingTools, missingExecutables);
5113
- }
5114
- function resolveProfileWarmSessionTtlSec(profile) {
5115
- return Math.min(profile.sessionTtlSec, profile.workspaceTtlSec);
5116
- }
5117
- async function resolveProfileByName(options) {
5118
- if (!options.teamId) throw new Error(`Runtime profile name "${options.profile}" requires --team. Use a profile UUID when running without a team-scoped list.`);
5119
- const matches = (await options.agent.runtimeProfiles.list({ teamId: options.teamId })).items.filter((item) => item.name === options.profile);
5120
- if (matches.length === 0) throw new Error(`Runtime profile "${options.profile}" was not found in team ${options.teamId}.`);
5121
- if (matches.length > 1) throw new Error(`Runtime profile name "${options.profile}" is ambiguous in team ${options.teamId}. Use the profile UUID instead.`);
5122
- const profile = matches[0];
5123
- return {
5124
- ...profile,
5125
- thinkingLevel: profile.thinkingLevel ?? null,
5126
- temperature: profile.temperature ?? null,
5127
- topP: profile.topP ?? null,
5128
- topK: profile.topK ?? null,
5129
- maxOutputTokens: profile.maxOutputTokens ?? null
5130
- };
5131
- }
5132
- //#endregion
5133
5103
  //#region src/lib/runtime-profile-retry-triage.ts
5134
5104
  function createRuntimeProfileRetryTriage(options) {
5135
5105
  return createPiRetryTriage({
@@ -5737,7 +5707,7 @@ async function runPolling(opts) {
5737
5707
  if (taskTypes.length === 0) console.error(`[${opts.modeLabel}] --task-types is empty — daemon will accept any registered type. Pass an explicit list to limit scope (e.g. --task-types fulfill_brief).`);
5738
5708
  const cfg = loadConfig();
5739
5709
  const agentRootDir = resolve(process.cwd(), values["agent-root"] ?? process.cwd());
5740
- const { ctx, signingPrivateKey, startupWhoami } = await (async () => {
5710
+ const { ctx, signingPrivateKey, startupWhoami, agentIdentity, hostCapabilitySigner } = await (async () => {
5741
5711
  let gate = "resolve_agent_context";
5742
5712
  try {
5743
5713
  const resolvedContext = await resolveAgentContext(baseCommon.agent, {
@@ -5763,10 +5733,24 @@ async function runPolling(opts) {
5763
5733
  whoami,
5764
5734
  signingPrivateKey: privateKey
5765
5735
  });
5736
+ gate = "resolve_agent_identity";
5737
+ const agentIdentity = await resolveDaemonAgentIdentity({
5738
+ agentName: baseCommon.agent,
5739
+ whoami,
5740
+ authMode: cfg.authMode,
5741
+ agentDir: resolvedContext.agentDir,
5742
+ gitAuthor: values["git-author"] ?? (cfg.gitAuthor || void 0)
5743
+ });
5766
5744
  return {
5767
5745
  ctx: resolvedContext,
5768
5746
  signingPrivateKey: privateKey,
5769
- startupWhoami: whoami
5747
+ startupWhoami: whoami,
5748
+ agentIdentity,
5749
+ hostCapabilitySigner: createLocalSeedSigner({
5750
+ privateKeySeed: privateKey,
5751
+ agent: resolvedContext.agent,
5752
+ identity: agentIdentity
5753
+ })
5770
5754
  };
5771
5755
  } catch (error) {
5772
5756
  await logDaemonStartupFailure({
@@ -5926,7 +5910,9 @@ async function runPolling(opts) {
5926
5910
  rootLogger.info({
5927
5911
  authMode: cfg.authMode,
5928
5912
  subjectType: startupWhoami.subjectType,
5929
- boundTeamId: startupWhoami.credentialBinding?.boundTeamId ?? null,
5913
+ bindingScope: startupWhoami.credentialBinding?.bindingScope ?? null,
5914
+ credentialKeyId: startupWhoami.credentialBinding?.keyId ?? null,
5915
+ boundTeamId: startupWhoami.credentialBinding?.bindingScope === "team" ? startupWhoami.credentialBinding.boundTeamId : null,
5930
5916
  guestCredentialMode: ctx.guestCredentialMode,
5931
5917
  taskTypes: taskTypes.length > 0 ? taskTypes : ["*"],
5932
5918
  correlationId: values["correlation-id"] ?? null,
@@ -6195,6 +6181,9 @@ async function runPolling(opts) {
6195
6181
  const rawExecuteTask = selected.preparedRuntime.createTaskExecutor({
6196
6182
  agentName: common.agent,
6197
6183
  moltnetAgent: ctx.agent,
6184
+ agentIdentity,
6185
+ hostCapabilitySigner,
6186
+ hostCapabilityLogger: taskLogger,
6198
6187
  guestCredentialMode: ctx.guestCredentialMode,
6199
6188
  agentRootDir: ctx.agentRootDir,
6200
6189
  mountPath: sandbox.rootDir,
@@ -6210,7 +6199,8 @@ async function runPolling(opts) {
6210
6199
  onVmDiagnostic: (diagnostic) => {
6211
6200
  const fields = {
6212
6201
  event: diagnostic.event,
6213
- credentialMode: diagnostic.credentialMode
6202
+ credentialMode: diagnostic.credentialMode,
6203
+ ...diagnostic.brokeredSecretCount !== void 0 && { brokeredSecretCount: diagnostic.brokeredSecretCount }
6214
6204
  };
6215
6205
  if (diagnostic.level === "warning") taskLogger.warn(fields, diagnostic.message);
6216
6206
  else taskLogger.info(fields, diagnostic.message);
@@ -6358,7 +6348,7 @@ async function runOnce(argv, runtimeAdapter = defaultPiDaemonAdapter) {
6358
6348
  const cfg = loadConfig();
6359
6349
  const initialOpts = opts;
6360
6350
  const agentRootDir = resolve(process.cwd(), values["agent-root"] ?? process.cwd());
6361
- const { ctx, signingPrivateKey } = await (async () => {
6351
+ const { ctx, signingPrivateKey, agentIdentity, hostCapabilitySigner } = await (async () => {
6362
6352
  let gate = "resolve_agent_context";
6363
6353
  try {
6364
6354
  const resolvedContext = await resolveAgentContext(initialOpts.agent, {
@@ -6384,9 +6374,23 @@ async function runOnce(argv, runtimeAdapter = defaultPiDaemonAdapter) {
6384
6374
  whoami,
6385
6375
  signingPrivateKey: privateKey
6386
6376
  });
6377
+ gate = "resolve_agent_identity";
6378
+ const agentIdentity = await resolveDaemonAgentIdentity({
6379
+ agentName: initialOpts.agent,
6380
+ whoami,
6381
+ authMode: cfg.authMode,
6382
+ agentDir: resolvedContext.agentDir,
6383
+ gitAuthor: values["git-author"] ?? (cfg.gitAuthor || void 0)
6384
+ });
6387
6385
  return {
6388
6386
  ctx: resolvedContext,
6389
- signingPrivateKey: privateKey
6387
+ signingPrivateKey: privateKey,
6388
+ agentIdentity,
6389
+ hostCapabilitySigner: createLocalSeedSigner({
6390
+ privateKeySeed: privateKey,
6391
+ agent: resolvedContext.agent,
6392
+ identity: agentIdentity
6393
+ })
6390
6394
  };
6391
6395
  } catch (error) {
6392
6396
  await logDaemonStartupFailure({
@@ -6561,6 +6565,9 @@ async function runOnce(argv, runtimeAdapter = defaultPiDaemonAdapter) {
6561
6565
  const rawExecuteTask = preparedRuntime.createTaskExecutor({
6562
6566
  agentName: opts.agent,
6563
6567
  moltnetAgent: ctx.agent,
6568
+ agentIdentity,
6569
+ hostCapabilitySigner,
6570
+ hostCapabilityLogger: rootLogger,
6564
6571
  guestCredentialMode: ctx.guestCredentialMode,
6565
6572
  agentRootDir: ctx.agentRootDir,
6566
6573
  mountPath: sandbox.rootDir,
@@ -6576,7 +6583,8 @@ async function runOnce(argv, runtimeAdapter = defaultPiDaemonAdapter) {
6576
6583
  onVmDiagnostic: (diagnostic) => {
6577
6584
  const fields = {
6578
6585
  event: diagnostic.event,
6579
- credentialMode: diagnostic.credentialMode
6586
+ credentialMode: diagnostic.credentialMode,
6587
+ ...diagnostic.brokeredSecretCount !== void 0 && { brokeredSecretCount: diagnostic.brokeredSecretCount }
6580
6588
  };
6581
6589
  if (diagnostic.level === "warning") rootLogger.warn(fields, diagnostic.message);
6582
6590
  else rootLogger.info(fields, diagnostic.message);