melchizedek-agents 1.0.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/.env.example +29 -2
  2. package/AGENT_SETUP.md +3 -1
  3. package/CHANGELOG.md +524 -0
  4. package/DOCUMENTATION.md +178 -43
  5. package/ONBOARDING.md +339 -0
  6. package/QUICKSTART.md +15 -2
  7. package/README.md +6 -2
  8. package/config/agents/README.md +2 -2
  9. package/config/agents/examples/ares.yaml +6 -10
  10. package/config/agents/examples/assistant.yaml +6 -6
  11. package/config/agents/examples/augustin.yaml +9 -15
  12. package/config/agents/examples/cartographers.yaml +6 -6
  13. package/config/agents/examples/council.yaml +7 -7
  14. package/config/agents/examples/critic.yaml +24 -24
  15. package/config/agents/examples/harness.yaml +4 -4
  16. package/config/agents/examples/image_production.yaml +37 -35
  17. package/config/agents/examples/librarian.yaml +4 -4
  18. package/config/agents/examples/patient_advocate.yaml +6 -10
  19. package/config/agents/examples/pipeline.yaml +20 -19
  20. package/config/agents/examples/research.yaml +36 -43
  21. package/config/agents/examples/scribe.yaml +31 -32
  22. package/config/agents/examples/scriptorium.yaml +6 -6
  23. package/config/agents/examples/structured_critic.yaml +82 -0
  24. package/config/agents/examples/style_council.yaml +9 -11
  25. package/config/agents/examples/syndicate.yaml +3 -5
  26. package/config/agents/examples/tutor.yaml +2 -2
  27. package/config/agents/examples/weather.yaml +2 -2
  28. package/config/agents/syndicate.schema.json +859 -13
  29. package/config/agents/syndicateSchema.yaml +122 -73
  30. package/config/agents/templates/README.md +1 -1
  31. package/config/agents/templates/account_memory.yaml +4 -4
  32. package/config/agents/templates/case_desk.yaml +6 -6
  33. package/config/agents/templates/conversational.yaml +2 -2
  34. package/config/agents/templates/draft_review.yaml +6 -6
  35. package/config/agents/templates/intake_extractor.yaml +64 -62
  36. package/config/agents/templates/research_brief.yaml +6 -6
  37. package/config/agents/templates/research_desk.yaml +6 -6
  38. package/config/agents/templates/review_panel.yaml +8 -8
  39. package/config/agents/templates/support_triage.yaml +30 -29
  40. package/config/agents/templates/systems_operator.yaml +24 -5
  41. package/db/migrations/0014_durable_runs.sql +31 -0
  42. package/dist/lib/a2a/app.d.ts +27 -0
  43. package/dist/lib/a2a/app.js +64 -5
  44. package/dist/lib/a2a/executor.d.ts +7 -1
  45. package/dist/lib/a2a/executor.js +43 -5
  46. package/dist/lib/a2a/oauthSetup.d.ts +106 -0
  47. package/dist/lib/a2a/oauthSetup.js +259 -0
  48. package/dist/lib/agentDialect.d.ts +76 -0
  49. package/dist/lib/agentDialect.js +151 -0
  50. package/dist/lib/compile.d.ts +42 -6
  51. package/dist/lib/compile.js +97 -45
  52. package/dist/lib/compileNative.d.ts +11 -3
  53. package/dist/lib/compileNative.js +20 -1
  54. package/dist/lib/dispatch.d.ts +10 -5
  55. package/dist/lib/dispatch.js +10 -5
  56. package/dist/lib/doctor.d.ts +110 -1
  57. package/dist/lib/doctor.js +205 -9
  58. package/dist/lib/loadSyndicate.d.ts +54 -2
  59. package/dist/lib/loadSyndicate.js +22 -2
  60. package/dist/lib/memory/namespace.d.ts +6 -5
  61. package/dist/lib/memory/namespace.js +6 -5
  62. package/dist/lib/memory/providers.js +3 -4
  63. package/dist/lib/models/capabilities.d.ts +25 -1
  64. package/dist/lib/models/capabilities.js +79 -1
  65. package/dist/lib/models/chatCompletionsAdapter.d.ts +11 -3
  66. package/dist/lib/models/chatCompletionsAdapter.js +19 -5
  67. package/dist/lib/models/claudeAdapter.js +4 -0
  68. package/dist/lib/models/contract.d.ts +5 -2
  69. package/dist/lib/models/gateway.d.ts +2 -1
  70. package/dist/lib/models/gateway.js +4 -2
  71. package/dist/lib/models/gatewayAdapter.d.ts +7 -1
  72. package/dist/lib/models/gatewayAdapter.js +8 -0
  73. package/dist/lib/models/geminiAdapter.js +8 -2
  74. package/dist/lib/models/genaiMapping.d.ts +8 -4
  75. package/dist/lib/models/genaiMapping.js +23 -9
  76. package/dist/lib/models/gptAdapter.d.ts +4 -2
  77. package/dist/lib/models/gptAdapter.js +11 -4
  78. package/dist/lib/models/grokAdapter.d.ts +3 -1
  79. package/dist/lib/models/grokAdapter.js +11 -3
  80. package/dist/lib/models/kimiAdapter.d.ts +2 -1
  81. package/dist/lib/models/kimiAdapter.js +3 -3
  82. package/dist/lib/models/reasoning.d.ts +30 -2
  83. package/dist/lib/models/reasoning.js +56 -5
  84. package/dist/lib/observability/tracer.d.ts +8 -1
  85. package/dist/lib/observability/tracer.js +33 -5
  86. package/dist/lib/onboarding.d.ts +134 -0
  87. package/dist/lib/onboarding.js +539 -0
  88. package/dist/lib/runtime/approvals.d.ts +8 -0
  89. package/dist/lib/runtime/approvals.js +4 -3
  90. package/dist/lib/runtime/credentials.d.ts +6 -0
  91. package/dist/lib/runtime/native/agentLoop.d.ts +23 -3
  92. package/dist/lib/runtime/native/agentLoop.js +107 -11
  93. package/dist/lib/runtime/native/checkpoint.d.ts +171 -0
  94. package/dist/lib/runtime/native/checkpoint.js +359 -0
  95. package/dist/lib/runtime/native/delegate.d.ts +222 -18
  96. package/dist/lib/runtime/native/delegate.js +390 -39
  97. package/dist/lib/runtime/native/interrupts.d.ts +184 -2
  98. package/dist/lib/runtime/native/interrupts.js +391 -1
  99. package/dist/lib/runtime/native/request.d.ts +13 -3
  100. package/dist/lib/runtime/native/request.js +28 -4
  101. package/dist/lib/runtime/native/telemetry.js +10 -15
  102. package/dist/lib/runtime/questions.d.ts +7 -4
  103. package/dist/lib/runtime/sessions.d.ts +1 -1
  104. package/dist/lib/runtime/syndicateTurn.d.ts +11 -3
  105. package/dist/lib/runtime/syndicateTurn.js +353 -68
  106. package/dist/lib/runtime/turnControl.d.ts +56 -0
  107. package/dist/lib/runtime/turnControl.js +10 -0
  108. package/dist/lib/session/transcript.d.ts +9 -0
  109. package/dist/lib/session/transcript.js +20 -1
  110. package/dist/lib/skills.d.ts +18 -0
  111. package/dist/lib/skills.js +73 -1
  112. package/dist/lib/storage/postgres/index.d.ts +12 -2
  113. package/dist/lib/storage/postgres/index.js +8 -3
  114. package/dist/lib/storage/postgres/taskQueue.d.ts +20 -4
  115. package/dist/lib/storage/postgres/taskQueue.js +29 -5
  116. package/dist/lib/storage/postgres/taskStore.d.ts +26 -2
  117. package/dist/lib/storage/postgres/taskStore.js +74 -8
  118. package/dist/lib/syndicateSchema.d.ts +316 -1
  119. package/dist/lib/syndicateSchema.js +203 -29
  120. package/dist/lib/tools/auth.d.ts +20 -6
  121. package/dist/lib/tools/auth.js +21 -5
  122. package/dist/lib/tools/credentialEnv.d.ts +28 -0
  123. package/dist/lib/tools/credentialEnv.js +52 -0
  124. package/dist/lib/tools/credentialHosts.d.ts +88 -0
  125. package/dist/lib/tools/credentialHosts.js +165 -0
  126. package/dist/lib/tools/credentialStore.js +9 -2
  127. package/dist/lib/tools/credentialUses.d.ts +92 -0
  128. package/dist/lib/tools/credentialUses.js +112 -0
  129. package/dist/lib/tools/mcpToolFactory.d.ts +25 -2
  130. package/dist/lib/tools/mcpToolFactory.js +179 -21
  131. package/dist/lib/tools/oauthConsent.js +8 -1
  132. package/dist/lib/tools/oauthHosts.d.ts +73 -0
  133. package/dist/lib/tools/oauthHosts.js +154 -0
  134. package/dist/lib/tools/oauthTools.d.ts +242 -0
  135. package/dist/lib/tools/oauthTools.js +447 -0
  136. package/dist/lib/tools/openapiTools.d.ts +11 -6
  137. package/dist/lib/tools/openapiTools.js +88 -38
  138. package/dist/lib/tools/taskTools.d.ts +61 -6
  139. package/dist/lib/tools/taskTools.js +145 -21
  140. package/dist/lib/workflow/turn.d.ts +22 -3
  141. package/dist/lib/workflow/turn.js +151 -31
  142. package/dist/lib/workflow.d.ts +14 -7
  143. package/dist/lib/workflow.js +14 -7
  144. package/dist/lib/workflowConfig.d.ts +6 -0
  145. package/dist/scripts/a2a_server.d.ts +36 -0
  146. package/dist/scripts/a2a_server.js +131 -1
  147. package/dist/scripts/assistant_worker.d.ts +12 -0
  148. package/dist/scripts/assistant_worker.js +81 -22
  149. package/dist/scripts/doctor.d.ts +7 -2
  150. package/dist/scripts/doctor.js +9 -4
  151. package/dist/scripts/setup.d.ts +23 -0
  152. package/dist/scripts/setup.js +154 -0
  153. package/dist/scripts/skills_install.d.ts +3 -1
  154. package/dist/scripts/skills_install.js +17 -2
  155. package/dist/scripts/yaml_codemod.d.ts +62 -0
  156. package/dist/scripts/yaml_codemod.js +652 -0
  157. package/package.json +8 -2
  158. package/skills/README.md +11 -2
  159. package/skills/briefs/_shared.md +1 -1
  160. package/skills/briefs/melchizedek-author.md +7 -5
  161. package/skills/briefs/melchizedek-models.md +7 -4
  162. package/skills/briefs/melchizedek.md +1 -0
  163. package/skills/briefs/skills-readme.md +3 -1
  164. package/skills/melchizedek/SKILL.md +1 -0
  165. package/skills/melchizedek-author/SKILL.md +7 -4
  166. package/skills/melchizedek-author/assets/minimal.yaml +13 -13
  167. package/skills/melchizedek-models/SKILL.md +11 -4
  168. package/skills/melchizedek-onboard/SKILL.md +49 -0
  169. package/skills/melchizedek-onboard-cloud/SKILL.md +38 -0
  170. package/skills/melchizedek-onboard-keys/SKILL.md +35 -0
  171. package/skills/melchizedek-onboard-local/SKILL.md +41 -0
  172. package/skills/melchizedek-onboard-serve/SKILL.md +43 -0
package/.env.example CHANGED
@@ -1,3 +1,7 @@
1
+ # Not sure which of these you need? `npx melchizedek-setup` (in a clone: `npm run setup`)
2
+ # asks what you have and prints the names to set for it; --auto detects it.
3
+ # Only names and shapes live here: type the values yourself, never commit .env.
4
+
1
5
  # ── Required for cloud models ─────────────────────────────────────────────────
2
6
  # Google AI Studio API key — powers all Gemini model inference.
3
7
  # Also required for the gemini-embedding-001 embedding model used by long-term memory.
@@ -33,8 +37,11 @@ ALLOW_PRIVATE_MCP=false
33
37
  # ── Optional: OpenAPI tools (an agent's `openapi:` list) ──────────────────────
34
38
  # ALLOW_PRIVATE_OPENAPI: set to "true" to let an OpenAPI tool call a localhost /
35
39
  # private / link-local server. Off by default as an SSRF guard. Credentials an
36
- # `openapi:` entry names (auth.bearer_env, auth.api_key.env) are read from this
37
- # file or the environment, never written in YAML.
40
+ # `openapi:` entry names (auth.bearer_env, auth.api_key.env, and an OAuth
41
+ # grant's auth.oauth2.client_id_env / client_secret_env, which an MCP server's
42
+ # mcp_auth.oauth2 uses too) are read from this file or the environment, never
43
+ # written in YAML. Give each API its own variable: the framework's own
44
+ # settings below are refused (ADR 0112).
38
45
  # ALLOW_PRIVATE_OPENAPI=false
39
46
 
40
47
  # ── Optional: Anthropic / Claude ──────────────────────────────────────────────
@@ -245,6 +252,26 @@ PUBLIC_URL=
245
252
  # out of the database and its backups. Unset = no credential store. A row
246
253
  # sealed with another key stays unreadable (the user reconnects).
247
254
  # MELCHIZEDEK_CREDENTIAL_KEY=
255
+ # The OAuth consent callback (ADR 0085), exactly as registered at every
256
+ # provider a YAML grant names: https, no query. Mounts the callback and lets a
257
+ # run ask a user to connect a provider. Needs MELCHIZEDEK_CREDENTIAL_KEY.
258
+ # OAUTH_REDIRECT_URI=https://agents.example.com/oauth/callback
259
+ # Who may complete a callback (ADR 0114): required (default) — the browser
260
+ # carries the user's identity, which only A2A_AUTH=header behind a gateway
261
+ # gives it; state — the single-use state alone binds the flow to its user.
262
+ # OAUTH_CALLBACK_IDENTITY=required
263
+ # The hosts each provider's tokens may be sent to (ADR 0114), the operator's
264
+ # binding, never the YAML's: provider=host,host;provider=host. A host is a
265
+ # hostname, *.domain (subdomains only), IPv4 or [IPv6]; no scheme or port.
266
+ # Unset: authorization_code grants are refused, client_credentials allowed.
267
+ # Set: every grant's provider is listed and every host it calls is its own.
268
+ # MELCHIZEDEK_OAUTH_HOSTS=tracker=api.tracker.example.com,auth.tracker.example.com
269
+ # The hosts each static credential variable a YAML sends may be sent to
270
+ # (ADR 0122): bearer_env, api_key.env and client_secret_env, each entry the
271
+ # variable's name, '=', then its hosts (as above). Unset: each goes to the
272
+ # host the YAML names, and the server and the doctor name it as unbound.
273
+ # Set: it is the whole list; an unlisted variable is sent nowhere.
274
+ # MELCHIZEDEK_CREDENTIAL_HOSTS=TRACKER_TOKEN=api.tracker.example.com;WEATHER_API_KEY=api.weather.example.com
248
275
 
249
276
  # ── Optional: Knowledge Bundle (wiki) ─────────────────────────────────────────
250
277
  # WIKI_ROOT: filesystem path of the OKF knowledge bundle the wiki tools serve.
package/AGENT_SETUP.md CHANGED
@@ -26,7 +26,9 @@ Set up the melchizedek-agents framework on this machine.
26
26
  it. Never ask me to paste API keys into this chat, never read keys
27
27
  from elsewhere on my machine, and never commit .env.
28
28
  4. Run the offline test suite (`npm test`) and confirm every shipped
29
- syndicate compiles.
29
+ syndicate compiles. Then run `npm run setup -- --auto`: it reports
30
+ which authentication level my environment is at, by variable name
31
+ only. Follow the melchizedek-onboard skill in skills/ to pick my level.
30
32
  5. Read README.md and QUICKSTART.md. Then report back with:
31
33
  - what you did and the test results,
32
34
  - the list of available syndicates (one line each, from the README
package/CHANGELOG.md CHANGED
@@ -6,6 +6,530 @@ the starter pack and the templates), not the repo's full history.
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 1.2.0 — 2026-10-09
10
+
11
+ Release 1.2.0 carries pauses and consent further down a turn and gives the
12
+ YAML its last v2 keys (ADRs 0117–0123). A delegated subagent may run skill
13
+ scripts and ask for OAuth consent; a nested workflow pauses the turn as a
14
+ dispatch route or a workflow node; a nested dispatch syndicate routes as it
15
+ does at the top; static credentials go only to hosts the operator binds;
16
+ `tool_choice:` and `reasoning: xhigh | max` complete the provider-neutral
17
+ keys; a background job's checkpoint has a cap, and a durable run resumes
18
+ inside a dispatch route. `melchizedek-setup` is the new onboarding command.
19
+
20
+ ### Upgrade first
21
+
22
+ Read this list before deploying 1.2.0 over 1.1.0.
23
+
24
+ - **The older spelling's `reasoningEffort: xhigh` and `max` now reach the
25
+ provider** (ADR 0117). Since 1.0.0 they were read by nothing and sent
26
+ nowhere; an agent that still carries one now asks its model for that
27
+ effort (or the model's highest, see Added), and beside a `thinkingConfig`
28
+ that says `high` the word wins. Such an agent thinks harder and costs
29
+ more. Remove the word to keep the old behaviour.
30
+ - **`ReasoningLevel` (`melchizedek-agents/models/contract`) gains `xhigh`
31
+ and `max`**, and `REASONING_BUDGETS` gains both keys (16,384 each,
32
+ `high`'s budget). An exhaustive `Record<ReasoningLevel, …>` or a `switch`
33
+ over the levels no longer type-checks without them (ADR 0117).
34
+ - **A nested dispatch syndicate answers with its route's text, not its
35
+ classifier's JSON** (ADR 0120). A `yaml_reference` to a plan-dispatch
36
+ syndicate used to compile to its classifier alone, so its caller got the
37
+ routing verdict and its routes never ran; a prompt or parser that relied
38
+ on that verdict sees the specialist's answer now. A gate or skill scripts
39
+ on one of its routes is no longer a load error. `compileSubagentSpec`
40
+ refuses a reference to a dispatch syndicate by name: compile it with
41
+ `compileEntrySpec`.
42
+ - **Child session keys for routes and nodes carry their kind and the agent
43
+ path** (ADR 0119, ADR 0120). A nested syndicate or nested workflow run as
44
+ a dispatch route is filed under `<app>/route:<route>`, and as a workflow
45
+ node under `<walk's app>/node:<node>` (`app/route:Writer/node:Inner` two
46
+ levels down), no longer under the entry's name alone, so it no longer
47
+ shares a row with a same-named entry of another syndicate, and neither
48
+ can share a key with a delegated subagent's (`<app>/<caller>/<subagent>`,
49
+ unchanged). A session 1.1.0 stored under the entry's name, or under
50
+ `<app>/<entry>`, is still continued when the entry ran in that
51
+ conversation before; nothing stored is rewritten. Code that read the
52
+ walk's events at `{ appName: '<entry>' }` or `<app>/<entry>` reads them
53
+ at the kind key now.
54
+ - **`melchizedek-doctor --check` exits 1 on a grant whose hosts the OAuth
55
+ host allowlist refuses.** The doctor already printed each such grant
56
+ (`✗ … is not one of them`, `MELCHIZEDEK_OAUTH_HOSTS`, ADR 0114) and still
57
+ exited 0; a CI step that runs `--check` against a served syndicate now
58
+ fails on it. A blocked syndicate, a runtime problem and the OAuth and
59
+ credential setup's problems fail it as before.
60
+
61
+ ### Added
62
+
63
+ - **Skill scripts on a delegated subagent.** `skills.scripts: local` is no
64
+ longer a load error on a delegated subagent (or a nested delegate
65
+ syndicate's): a `run_skill_script` call there pauses the turn
66
+ `input-required` with `approval.path`, and the decision runs or refuses the
67
+ script in the subagent before its caller continues. An agent a map node
68
+ runs still may not carry scripts (ADR 0118).
69
+ - **OAuth consent inside a delegated subagent.** A subagent's
70
+ `authorization_code` tool (an `mcp_auth` or OpenAPI `auth.oauth2` grant)
71
+ now asks for a missing grant instead of answering `not_connected`: the turn
72
+ ends `input-required` with `consent`, whose new optional `path` names the
73
+ agents from the turn's own down to the one that asked (`PendingConsent.path`;
74
+ the A2A `consent_request` data part carries `path` too). The callback stores
75
+ the grant under the conversation's app, and the next message resumes the
76
+ subagent's call. The host allowlist's checks are unchanged. The
77
+ systems_operator template's comment says authorization_code works on its
78
+ Systems subagent (ADR 0118).
79
+ - **Nested dispatch syndicates route as at the top**
80
+ ([ADR 0120](./wiki/decisions/0120-nested-dispatch-syndicates-route-as-at-the-top.md)).
81
+ A `yaml_reference` to a plan-dispatch syndicate runs as a turn of its own
82
+ on its own conversation, wherever it appears (a delegated subagent, a
83
+ dispatch route, a workflow node): its classifier picks one of its routes
84
+ and the route answers, under the turn's `max_steps`, deadline and cancel.
85
+ Approvals, `ask_user` questions and OAuth consent on its routes, and
86
+ inside a route's own delegation, pause the turn `input-required` with
87
+ the path (`["Boss", "Team", "Ops"]` delegated, `["Team", "Ops"]` as a
88
+ route), over `runSyndicateTurn` and A2A; the answer resumes that route
89
+ without classifying again. Its grants are stored under the root's app.
90
+ As a workflow node it fails on a consent pause. A route carrying the
91
+ entry's own name, a `map` node over one, and a reference cycle below it
92
+ are refused by name before any model call. Surface:
93
+ `melchizedek-agents/compile` gains the `DispatchSpec` type, a
94
+ `{ kind: 'dispatch'; dispatch: DispatchSpec }` variant on `EntrySpec` and
95
+ `SpecTool`, and an optional `WorkflowSpec.dispatches`; `melchizedek-agents/runtime/turnControl`
96
+ gains the optional `TurnControl.nestedDispatch` hook and the
97
+ `NestedDispatchRun` and `NestedDispatchEnd` types. The generated
98
+ `syndicate.schema.json` describes `yaml_reference` accordingly.
99
+ - **Static credentials go only to hosts the operator binds** (ADR 0122).
100
+ `MELCHIZEDEK_CREDENTIAL_HOSTS="TRACKER_TOKEN=api.tracker.example.com;…"`,
101
+ or `createA2AApp({ credentialHosts })`, binds each credential variable a
102
+ YAML sends (`bearer_env`, `api_key.env`, `client_secret_env`) to its hosts.
103
+ Unset, nothing changes: `melchizedek-serve` warns at boot and
104
+ `melchizedek-doctor` shows a `credentials` warning naming each unbound
105
+ variable. Set, it is the whole list, checked when a syndicate loads, when
106
+ it compiles and before each send; a refused call sends nothing. New
107
+ modules `melchizedek-agents/tools/credentialHosts` and
108
+ `melchizedek-agents/tools/credentialUses` (through the existing
109
+ `./tools/*` export); `openApiServers` in `tools/openapiTools`;
110
+ `DoctorResult.credentials`; the server's banner gains a `creds` line,
111
+ and `oauthServerSetup` returns `credentialSummary`.
112
+ - **`tool_choice:`**, a v2 agent key (ADR 0117): `auto` (the default),
113
+ `none`, `required` (some tool) or `{ name: <tool> }` (that tool). It
114
+ replaces `generateContentConfig.toolConfig.functionCallingConfig`, may not
115
+ sit beside it, and is refused on a `yaml_reference` or `a2a_agent_url`
116
+ subagent. Each provider sends it as before, weakening a forced choice
117
+ where it must (`llm.tool_choice.weakened`).
118
+ - **`reasoning: xhigh` and `reasoning: max`** (ADR 0117). They reach the
119
+ models that take them: both as `output_config.effort` on Claude's adaptive
120
+ generations, `max` on Kimi K3 (and `xhigh` rounds up to it, so K3 can be
121
+ sent `max` again), `xhigh` on GPT-5.2 and later and on grok-4.7. Every
122
+ other path sends the model's highest setting (`high`, Gemini's `HIGH`,
123
+ or `high`'s 16,384-token budget on Claude 4.6 and earlier and Gemini 2.x;
124
+ `high` on a gateway for any id) and marks the `llm.request` span
125
+ `llm.reasoning.weakened` with the level asked for. The capability
126
+ matrix states each path: `REASONING_ABOVE_HIGH`
127
+ (`melchizedek-agents/models/capabilities`), rendered under
128
+ `npm run doctor -- --matrix`.
129
+ - `melchizedek-agents/models/reasoning` exports `effortCeiling(model)`,
130
+ `effortWord(model, setting, ceiling?)`, `isAboveHigh` and
131
+ `REASONING_ORDER`. `ChatCompletionsAdapter` gains the protected hooks
132
+ `reasoningCeiling(model)` and `effortFor(model, setting)`.
133
+ - **A cap on a background job's checkpoint**
134
+ ([ADR 0121](./wiki/decisions/0121-checkpoint-cap-and-dispatch-route-resume.md)).
135
+ A checkpoint above `MELCHIZEDEK_CHECKPOINT_MAX_BYTES` (the worker's
136
+ variable; a positive whole number of bytes of JSON, default 5 MiB) is
137
+ not stored: the job keeps its previous checkpoint, the save still reports
138
+ whether the claim holds (a cancel still stops the run), and one log line
139
+ names the job id and the sizes. New in `melchizedek-agents/tools/taskTools`:
140
+ `TaskBackendOptions` (`checkpointMaxBytes`, `log`), `fileTaskBackendWith`,
141
+ `checkpointJson`, `checkpointMaxBytesSetting`, `DEFAULT_CHECKPOINT_MAX_BYTES`
142
+ and `CHECKPOINT_MAX_BYTES_ENV`; `PostgresStorageOptions.taskQueue` passes
143
+ the options to the Postgres queue. The file store's checkpoint sidecar is
144
+ written compact; one written by 1.1.0 still reads.
145
+ - **`melchizedek-setup`, the onboarding command** (new bin; `npm run setup`
146
+ in a clone). A menu of nine authentication levels (no key / local
147
+ Ollama, one provider's key, several, a gateway key, Vertex AI / Bedrock /
148
+ Azure credentials, per-caller keys when serving, caller identities
149
+ through `A2A_AUTH`, OAuth tool grants, and subscription sign-ins), each
150
+ with a startup guide: the variables to set (names and shapes only), the
151
+ doctor check, the shipped templates and examples that run there, and the
152
+ first commands. `--auto` reads the doctor's result and prints the guide
153
+ for the highest level it detects, never a value; `--level <id|n>` prints
154
+ one guide; `--write-env` creates `.env` from `.env.example` with the
155
+ level's names blank, never over an existing file and only when git
156
+ ignores `.env` (ADR 0123).
157
+ - **`ONBOARDING.md`** ships in the package: the same guides, generated from
158
+ the same code (`npm run setup -- --markdown`).
159
+ - **Five onboarding skills** in `skills/`: `melchizedek-onboard` (triage:
160
+ "what do you have?") and `melchizedek-onboard-local`, `-keys`, `-cloud`
161
+ and `-serve`. `npx melchizedek-skills install` puts them in
162
+ `.claude/skills/` and `.agents/skills/` with the rest of the suite.
163
+ - **`melchizedek-skills install --agents-md`** also writes a pointer to the
164
+ skills into the project's `AGENTS.md` (created when absent; only the
165
+ block between its markers is ever rewritten).
166
+ - **The doctor's `serving` line.** When any A2A identity or billing variable
167
+ is set, `npm run doctor` prints the `A2A_AUTH` mode, `A2A_KEY_MODE`,
168
+ which serving variables are set and what the server would refuse to start
169
+ on, by name. `--json` gains `providers` (the providers line as data) and
170
+ `serving`.
171
+ - **`ToolCredentialError.allowlist`** (`melchizedek-agents/tools/auth`,
172
+ with the `HostAllowlist` type): on a `host_refused` error, `'oauth'` when
173
+ the OAuth host allowlist refused a token's host (ADR 0114) and
174
+ `'credential'` when the credential host allowlist refused a client
175
+ secret's (ADR 0122). The constructor takes it as an optional third
176
+ argument.
177
+
178
+ ### Changed
179
+
180
+ - **A nested workflow run as a dispatch route or a workflow node pauses the
181
+ turn** ([ADR 0119](./wiki/decisions/0119-workflow-routes-and-nodes-pause-the-turn.md)).
182
+ Its `ask_user` nodes and gated agent nodes (`require_approval`, skill
183
+ scripts) are no longer a load error there: the turn ends `input-required`
184
+ with `result.input` or `result.approval`, whose `path` runs from the route
185
+ or node down to the node that asked (`["Writer", "Send"]`, and further
186
+ down through a node that is itself a nested workflow), over
187
+ `runSyndicateTurn` and A2A. The next message answers it: a decision, or a
188
+ plain-text reply to the question, resumes a paused route without running
189
+ the classifier (`route.decidedBy` `approval` or `answer`); any other
190
+ message while an approval waits repeats the request and runs nothing. A
191
+ workflow node resumes inside the caller's walk. The conversation of a
192
+ paused route ends on the route's pause record (no content, the walk's
193
+ open interrupt ids in `longRunningToolIds`) in place of its answer.
194
+ - `compileEntrySpec` and `compileWorkflowSpec` still accept their
195
+ `delegated` argument; it no longer changes what compiles.
196
+ - **`melchizedek-codemod` converts the rest of `generateContentConfig`**
197
+ (ADR 0117): `toolConfig` becomes `tool_choice:` (mode `ANY` with several
198
+ allowed names becomes `required`, which is what the engine already sent,
199
+ with a note), `reasoningEffort: xhigh | max` becomes `reasoning:`, and
200
+ `thinkingConfig.includeThoughts` is dropped whatever its value: nothing
201
+ reads it, and the Gemini adapter asks for the thought trace whenever
202
+ reasoning is not `none` (a `true` gets a note). Only `toolConfig` mode
203
+ `VALIDATED` and `thinkingBudget: -1` stay, with a note.
204
+ - **The council example's Moderator consults both subagents in one step**
205
+ (`config/agents/examples/council.yaml`). Its instruction asks for the
206
+ Advocate and the Skeptic together, both function calls in one response,
207
+ each given the user's full claim verbatim, so the two run at once under
208
+ `max_concurrency` (ADR 0116). Its role, its three-part verdict and its
209
+ guardrails are unchanged; the YAML keeps its v2 keys. A project that
210
+ copied the example keeps the old prompt until it copies it again.
211
+ - The header comments of `examples/critic.yaml`, `examples/image_production.yaml`
212
+ and `templates/intake_extractor.yaml` say that a schema on a leaf is
213
+ their choice, not a rule: an orchestrator that delegates may hold one
214
+ (ADR 0109). Comments only; the agents are unchanged.
215
+
216
+ ### Fixed
217
+
218
+ - **A durable dispatch run resumes inside its agent route** (ADR 0121). A
219
+ background job killed mid-step inside a plan-dispatch route used to start
220
+ over (its checkpoint was set aside); it now resumes from its checkpoint,
221
+ classifying again and storing what an uninterrupted run stores. A nested
222
+ dispatch syndicate's route resumes the same way, and checkpoints 1.1.0
223
+ saved inside a route restore.
224
+ - **An unrecognised `MODEL_GATEWAY` is never echoed.** The doctor (its
225
+ `gateway` line and `--json`), `gatewayProblem()` and the boot log said
226
+ the value back, which may be a key pasted into the wrong variable. They
227
+ now say `MODEL_GATEWAY is set to an unrecognised value (not shown)` and
228
+ name the accepted values (`vercel`, `openrouter`).
229
+ - **A `host_refused` refusal names the allowlist that refused.** A client
230
+ secret refused by the credential host allowlist was reported as the OAuth
231
+ host allowlist's refusal. The message now names
232
+ `MELCHIZEDEK_OAUTH_HOSTS` for a token's host and
233
+ `MELCHIZEDEK_CREDENTIAL_HOSTS` for a client secret's.
234
+
235
+ ### Not supported, on purpose
236
+
237
+ - ChatGPT / Codex, Claude.ai and Gemini CLI subscription sign-ins are not a
238
+ way to fund the engine, and nothing reads their tokens. The setup menu's
239
+ level 9 says so and routes to each vendor's API key or cloud platform.
240
+
241
+ ## 1.1.0 — 2026-10-09
242
+
243
+ Release 1.1.0 closes workstream 6 of the ADK-independence plan (ADRs
244
+ 0109–0116): the first features built on the engine's own loop. An
245
+ orchestrator can delegate and answer in its own JSON schema; a pause inside
246
+ a delegated subagent or a nested syndicate reaches the turn; tools can hold
247
+ OAuth grants declared in YAML, sent only to hosts the operator binds;
248
+ background jobs checkpoint and resume, and cancel works across replicas; a
249
+ step's subagent calls run at once; and the YAML gains provider-neutral v2
250
+ keys, with a codemod. Two fixes: `trace: false` now records nothing, and
251
+ MCP settings on an orchestrator are honoured.
252
+
253
+ ### Upgrade
254
+
255
+ Read this list before deploying 1.1.0.
256
+
257
+ 1. **Apply migration `0014_durable_runs` before you deploy**
258
+ (`db/migrations/0014_durable_runs.sql`, through `npx melchizedek-db
259
+ apply`) on any server or worker that uses `DATABASE_URL`. Every save
260
+ of the Postgres task stores now writes the new columns
261
+ (`adk_a2a_tasks.cancel_requested_at`, `melchizedek_tasks.checkpoint`),
262
+ so without the migration every Postgres task-store save fails. The A2A
263
+ server refuses to start against a database behind 0014 unless
264
+ `ALLOW_SCHEMA_MISMATCH=true` is set, and with that override its saves
265
+ fail. The migration adds nullable columns only and is safe to re-run.
266
+ 2. **New OAuth environment variables** for `melchizedek-serve`, needed
267
+ only when a served syndicate declares an `oauth2` grant:
268
+ `MELCHIZEDEK_OAUTH_HOSTS` (which hosts each provider's tokens may go to),
269
+ `OAUTH_REDIRECT_URI` (the consent callback: https, or http on a loopback
270
+ host) and `OAUTH_CALLBACK_IDENTITY` (`required`, the default, or
271
+ `state`). `MELCHIZEDEK_CREDENTIAL_KEY` keys the credential store.
272
+ 3. **`authorization_code` grants are refused until an allowlist is set.**
273
+ With no `MELCHIZEDEK_OAUTH_HOSTS` (or `createA2AApp({ oauthHosts })`), a
274
+ syndicate holding an `authorization_code` grant is refused when served;
275
+ `client_credentials` grants are allowed.
276
+ 4. **`max_concurrency` now runs a step's subagent calls at once**, at most
277
+ four by default. Set `max_concurrency: 1` at the root of a delegate
278
+ syndicate to restore the old one-after-another order.
279
+ 5. **YAML v2 keys.** `sampling:`, `output:` and `model_overrides:` replace
280
+ `generateContentConfig` and `outputSchema`. The old spellings are
281
+ deprecated, not removed: a v1 file loads and behaves as before, with one
282
+ deprecation line per file per process. `npx melchizedek-codemod
283
+ [--check] <file|dir>…` rewrites v1 files to v2.
284
+ 6. **`trace: false` now records nothing.** A turn run with
285
+ `runSyndicateTurn({ trace: false })` writes no telemetry row and exports
286
+ no span. If you relied on its agent, model or tool spans, trace the turn.
287
+ 7. **Child sessions are keyed by agent path.** A delegated subagent's
288
+ session is filed under `<app>/<caller>/<subagent>`; conversations stored
289
+ under the old key still resume. Code that reads a subagent's session by
290
+ its name alone reads the path instead.
291
+ 8. **The capability matrix has a new member, `structured_output_with_tools`.**
292
+ Code that builds a `Record<Capability, …>` must add it.
293
+ 9. **An A2A task cancelled while waiting for the turn lock now ends
294
+ `canceled`**, not `rejected`.
295
+
296
+ ### Breaking — read before upgrading
297
+
298
+ - **Breaking: migration 0014 is required** on a Postgres deployment
299
+ (Upgrade item 1).
300
+ - **Breaking: `Capability`, `CAPABILITIES` and `CAPABILITY_MATRIX`
301
+ (`melchizedek-agents/models/capabilities`) gain
302
+ `structured_output_with_tools`**, so an exhaustive
303
+ `Record<Capability, …>` no longer type-checks without it.
304
+ - **Breaking: a step's calls to subagents run concurrently by default**
305
+ (ADR 0116). See Changed; `max_concurrency: 1` keeps the old order.
306
+ - **Breaking: a delegated subagent's own session is filed under its agent
307
+ path** (ADR 0111). See Changed; stored conversations still resume.
308
+ - **Breaking: `runSyndicateTurn({ trace: false })` records nothing**: no
309
+ span of any kind, no ledger row, no export. See Fixed.
310
+ - **Breaking: an A2A task cancelled while it waits for its conversation's
311
+ turn lock ends `canceled`**, not `rejected` (ADR 0113).
312
+
313
+ ### Added
314
+
315
+ - **An orchestrator that delegates can answer in its own `outputSchema`**
316
+ (ADR 0109). An agent holding an `outputSchema` beside subagents or tools
317
+ calls them first, then ends its turn on one JSON object matching the
318
+ schema; no relay leaf or `dispatch:` block is needed (plan-dispatch stays
319
+ available). On Claude from Opus 4.8, Sonnet 5 and Haiku 5.5, on every
320
+ OpenAI id, and on Gemini 2 and later through Vertex AI, the schema now
321
+ travels in the provider's own structured-output field in the same request
322
+ as the tools (`output_config.format`, `text.format`, `responseJsonSchema`)
323
+ instead of as a `set_model_response` tool, on the agent's `fallback_model`
324
+ too; every other path keeps `set_model_response`.
325
+ - **The capability matrix gains `structured_output_with_tools`**
326
+ (`melchizedek-agents/models/capabilities`): supported on Anthropic and
327
+ OpenAI (and Gemini on Vertex AI), degraded (`set_model_response`) on the
328
+ Gemini API, xAI, Moonshot, Ollama and the gateway. `npm run doctor` names
329
+ it as a gap for an agent with a schema beside tools on a degraded path.
330
+ `outputSchemaBesideTools(model)` says whether a model's path takes both.
331
+ - **New starter-pack example `config/agents/examples/structured_critic.yaml`**
332
+ (`npm run syndicate:structured-critic`): the critic as one agent, an
333
+ orchestrator on `claude-opus-5-5` that asks a Drafter on
334
+ `claude-haiku-5-5` for a draft and grades it in its own `output.schema`.
335
+ It needs only `ANTHROPIC_API_KEY`.
336
+ - **A pause inside a delegated subagent reaches the turn** (WS6-2a,
337
+ [ADR 0110](./wiki/decisions/0110-pauses-inside-delegated-subagents-reach-the-turn.md)).
338
+ `require_approval` and `ask_user` are allowed on a delegated subagent, and
339
+ gates inside a nested delegate syndicate (`yaml_reference`) no longer fail
340
+ to load. The turn ends `input-required` with the request or question; the
341
+ decision or answer goes back down to the subagent, which finishes before
342
+ its caller continues. Before, a gate there was a load error and a pause
343
+ answered the call with an empty text.
344
+ - `PendingApproval.path` and `PendingInput.path` (optional): the agents from
345
+ the turn's own agent down to the one that asked, set only for a pause
346
+ inside a delegated subagent. The A2A `approval_request` and
347
+ `input_request` data parts carry `path` beside their fields when it is set.
348
+ - **Pauses inside nested syndicates reach the turn** (WS6-2b,
349
+ [ADR 0111](./wiki/decisions/0111-pauses-inside-nested-syndicates.md)). An
350
+ approval request or `ask_user` question raised inside a `yaml_reference`
351
+ subagent ends the turn `input-required` with the agent path, over
352
+ `runSyndicateTurn` and A2A, and the answer resumes it. A nested dispatch
353
+ syndicate may gate its classifier (a gate on one of its routes, which never
354
+ run nested, is refused by name). A nested workflow delegated to as a
355
+ subagent may hold `ask_user` nodes and gated agent nodes; the path ends at
356
+ the node. As a dispatch route or a workflow node, a nested workflow's
357
+ pauses stay refused, with a message that says so.
358
+ - **OAuth grants in YAML (`auth: { oauth2 }`, `mcp_auth: { oauth2 }`;
359
+ ADR 0112).** An `openapi:` entry's `auth` takes a third form, `oauth2`,
360
+ and an agent with `mcp_server_url` may declare `mcp_auth: { oauth2 }`.
361
+ The block names a `provider`, a `grant` (`authorization_code` or
362
+ `client_credentials`), `authorization_url`, `token_url`, `client_id` or
363
+ `client_id_env`, `client_secret_env` and `scopes`; secrets are
364
+ environment variable names, never values, under the same rule as
365
+ `bearer_env`. `authorization_code` sends the run's user's own token
366
+ (`ctx.accessToken`, so the consent pause asks a user who has not granted
367
+ it); `client_credentials` sends the server's own token from the token
368
+ endpoint, held in memory until shortly before it expires. A token goes
369
+ only over https (or http to a loopback host). An authorization-code MCP
370
+ server needs `mcp_tools` and runs each user on their own connection.
371
+ `npm run doctor` lists every tool that needs a grant. New module
372
+ `melchizedek-agents/tools/oauthTools` (`oauthClientsFor`, which builds
373
+ `oauthConsent({ providers })` from the YAML, `oauthRefreshProviders`,
374
+ which gives `credentialStore({ providers })` the matching refresh hooks,
375
+ `clientCredentialsGrant`, `oauthTokenSource`, `tokenTransportProblem`)
376
+ and `melchizedek-agents/tools/credentialEnv` (`credentialEnvProblem`,
377
+ still exported from `tools/openapiTools`), both under the existing
378
+ `./tools/*` export. `OAuthTokenSource` takes the call's destination
379
+ (`(ctx, destination)`), and `oauthTokenSource` accepts several servers.
380
+ `ToolCredentialError` gains the codes `unavailable` and `grant_failed`,
381
+ and `createMcpTools` / `loadMcpTools` an optional second argument. The
382
+ systems_operator template carries a commented `mcp_auth` block.
383
+ - **The OAuth host allowlist (`MELCHIZEDEK_OAUTH_HOSTS`,
384
+ `createA2AApp({ oauthHosts })`; ADR 0114).** The operator binds each
385
+ provider to the hosts its tokens and client secret may be sent to
386
+ (`provider=host,host;…`; `*.domain` for subdomains). With none, an
387
+ `authorization_code` grant is refused and `client_credentials` allowed;
388
+ with one, every grant's provider must be listed and its server, token
389
+ endpoint and authorization endpoint must be that provider's hosts. A
390
+ syndicate that breaks it is refused when served, when compiled and at
391
+ each call (`ToolCredentialError` code `host_refused`). New module
392
+ `melchizedek-agents/tools/oauthHosts` (`parseOAuthHosts`,
393
+ `checkOAuthHosts`, `setOAuthHosts`, `oauthHosts`, `hostAllowed`,
394
+ `oauthHostProblem`) under the existing `./tools/*` export;
395
+ `tools/oauthTools` gains `oauthGrantHostProblems`, `oauthCallProblem`,
396
+ `syndicateOAuthGrants` and `syndicateOAuthHostProblems`, and
397
+ `oauthClientsFor` an `allowlist` option.
398
+ - **`melchizedek-serve` wires tool credentials and the consent step**
399
+ from `MELCHIZEDEK_CREDENTIAL_KEY` (rows in Postgres with `DATABASE_URL`,
400
+ else process memory), `OAUTH_REDIRECT_URI`, `OAUTH_CALLBACK_IDENTITY`
401
+ (`required`, the default, or `state`) and `MELCHIZEDEK_OAUTH_HOSTS`, with
402
+ the consent clients and refresh hooks built from the served syndicate
403
+ files. `melchizedek-agents/server` exports `serverOAuth` and
404
+ `servedFileSyndicates`. `npm run doctor` prints an `oauth` line (which
405
+ variables are set, and each problem by name) and each grant's host
406
+ refusals; `--check` fails on an OAuth problem.
407
+ - **Durable long-running runs** (WS6-5, ADR 0113):
408
+ - **The worker resumes a job instead of starting over.**
409
+ `melchizedek-worker` checkpoints each job's sessions beside the job at
410
+ every step boundary (Postgres: the `checkpoint` column; the JSON store:
411
+ `<store>.checkpoints.json`). A job claimed again after its worker
412
+ stopped resumes from its last checkpoint. A dispatch syndicate
413
+ checkpointed inside an agent route starts over, and its classifier runs
414
+ again.
415
+ - **SIGTERM re-queues the job in hand** with its checkpoint, so the next
416
+ worker finishes it. Before, the job was recorded as failed.
417
+ - **A running background job can be cancelled.** `task_update` with
418
+ `status: cancelled` now accepts a running job. The worker stops at its
419
+ next lease renewal or checkpoint save and writes no result.
420
+ - **A2A cancel works across replicas**
421
+ (`melchizedek-agents/storage/postgres`): a `tasks/cancel` that reaches a
422
+ replica not running the task answers `canceled` and records the
423
+ request; the replica holding the task's lease aborts the run on its
424
+ lease heartbeat; the stored task stays `canceled`; the reaper keeps a
425
+ cancel that was already reported. New:
426
+ `PostgresTaskStore.requestCancel(taskId, context)`, the optional
427
+ `leases.cancelRequested` on `postgresStorage()`, and the optional
428
+ `storage.leases.cancelRequested` option of `createA2AApp`.
429
+ - **`TaskBackend` (`melchizedek-agents/tools/taskTools`), additive only:**
430
+ new optional members `saveCheckpoint` and `loadCheckpoint`; `renew` may
431
+ resolve `false` when the claim is gone; new export `taskCheckpointPath`.
432
+ A backend you wrote yourself still type-checks. It just does not
433
+ checkpoint.
434
+ - **YAML schema v2: provider-neutral keys** (WS6-4, ADR 0115).
435
+ `sampling: { temperature, top_p, max_output_tokens, stop }`,
436
+ `output: { schema, mime }` (`application/json` or `text/plain`) and
437
+ `reasoning:` (ADR 0047) replace `generateContentConfig` and
438
+ `outputSchema`. `model_overrides.<provider>` (`gemini`, `anthropic`,
439
+ `openai`, `xai`, `moonshot`, `ollama`) gives one provider its own
440
+ `instruction` or an `instruction_append`, applied for the provider the
441
+ agent's model routes to.
442
+ - **New bin `melchizedek-codemod [--check] <file|dir>…`** rewrites v1 YAML
443
+ into v2, keeping comments and layout; idempotent; `--check` exits
444
+ non-zero when a file would change. A registry row is migrated by running
445
+ it on the file it was published from and republishing.
446
+ - **`LoadSyndicateOptions.onWarning`** receives the v1 deprecation line
447
+ (default `console.warn`). The agent YAML types (`AgentYamlConfig`,
448
+ `SubagentYamlConfig`) gain `sampling`, `output` and `model_overrides`.
449
+ - **`max_concurrency`**, a new optional root key of a delegate syndicate:
450
+ a positive integer up to 32, default 4 (ADR 0116). See Changed.
451
+ - **`turnUntraced()`** (`melchizedek-agents/runtime/turnControl`) says
452
+ whether the running code belongs to a turn that opted out of tracing;
453
+ `createTurnControl` takes `untraced`, and `TurnControl` carries it.
454
+ **`startEngineSpan(tracerName, name, options?)`**
455
+ (`melchizedek-agents/observability/tracer`) starts a span the way the
456
+ engine does: a non-recording one, without starting the tracer, inside an
457
+ untraced turn.
458
+ - Engine internals with no exports map entry: `delegatedPauses`,
459
+ `openCalls`, `resumedDelegations` in `lib/runtime/native/interrupts.ts`;
460
+ `resumeSubagent`, `SubagentPause`, `resumeWorkflowSubagent`,
461
+ `childAppName`, `legacyChild` in `lib/runtime/native/delegate.ts`;
462
+ `runDurableTurn`, `checkpointingSessions` in
463
+ `lib/runtime/native/checkpoint.ts` (the worker's runner).
464
+
465
+ ### Changed
466
+
467
+ - **A step's calls to subagents run at once** (ADR 0116). When an
468
+ orchestrator's model calls several subagents in one step (the council's
469
+ Advocate and Skeptic, say), they now run concurrently instead of one after
470
+ another, at most `max_concurrency` at a time (default 4).
471
+ `max_concurrency: 1` keeps the old order. Two calls to the same subagent
472
+ in one step still run one after the other on its one session. The stored
473
+ responses stay in call order whatever order the subagents finish in, so
474
+ stored history does not change; a pause, a cancel, `max_steps` and durable
475
+ checkpoints keep their rules. The key is refused beside `workflow:` (use
476
+ `workflow.max_concurrency`) and `dispatch:`. Other tool calls are
477
+ unchanged.
478
+ - **A delegated subagent's own session is filed under its agent path**
479
+ (WS6-2b, ADR 0111): `<app>/<caller>/<subagent>`, and below a nested
480
+ syndicate `<app>/<caller>/<subagent>/<inner>`, instead of the subagent's
481
+ name alone, so two syndicates with a same-named subagent on one
482
+ conversation no longer share it. A conversation stored before keeps its
483
+ subagents' sessions under the old key: they are still read, continued and
484
+ resumed. Code that read a subagent's session directly by its name reads
485
+ the path instead. The stored events do not change.
486
+ - **`generateContentConfig` and `outputSchema` are deprecated, not
487
+ removed** (ADR 0115). A v1 file loads and behaves exactly as before; each
488
+ load that finds them prints one line, once per file or registry id per
489
+ process, naming the key paths (never their values). A v2 key beside its
490
+ v1 spelling on one agent (`sampling.temperature` with
491
+ `generateContentConfig.temperature`, `output.schema` with
492
+ `outputSchema`, …) is a load error. `toolConfig` and the effort words
493
+ `xhigh` and `max` have no v2 key yet and stay readable there.
494
+ `syndicate.schema.json` marks both keys `deprecated`. The loader (and
495
+ `validateSyndicateConfig`) returns the engine form: `sampling` and
496
+ `output` arrive folded into `generateContentConfig` and `outputSchema`.
497
+ - **Every shipped example, template, the annotated `syndicateSchema.yaml`
498
+ and the author skill's `minimal.yaml` are in the v2 spelling.** Copies of
499
+ them keep working either way. The `ares` example's search agent now says
500
+ `reasoning: none` (`thinkingLevel: MINIMAL` on Gemini 3) where it said
501
+ `thinkingBudget: 0`.
502
+ - **An A2A task cancelled during the turn-lock wait** now ends `canceled`,
503
+ not `rejected` (ADR 0113).
504
+ - **An OpenAPI `auth` that sets two forms** now reads "exactly one of
505
+ bearer_env, api_key or oauth2" (was "exactly one of bearer_env or
506
+ api_key").
507
+ - **The authoring skill (`skills/melchizedek-author`) allows an
508
+ `output: { schema }` on an orchestrator that delegates** when the answer
509
+ is the orchestrator's own structured judgment (ADR 0109), and points at
510
+ `structured_critic.yaml`; a schema on a leaf stays the choice when the
511
+ user should receive a specialist's answer.
512
+
513
+ ### Fixed
514
+
515
+ - **`runSyndicateTurn({ trace: false })` records nothing.** It used to drop
516
+ only the turn's root span: the agent, model-step, `llm.request` and tool
517
+ spans still started the global tracer, so with `TELEMETRY_SUPABASE=true`
518
+ an untraced turn still wrote `adk_telemetry` rows (and could write
519
+ `adk_payloads` rows), and with `OTEL_EXPORTER_OTLP_ENDPOINT` set it still
520
+ exported. Now a turn with `trace: false` opens no span of any kind, sends
521
+ nothing to the ledger, the console exporter, `onSpanEnd` listeners or an
522
+ OTLP endpoint, and does not start the tracer. Its step budget and its
523
+ `usage` are unchanged. The default (traced) is unchanged, and the A2A
524
+ server and the chat bin trace as before.
525
+ - **`mcp_server_url` and `mcp_tools` on the orchestrator are honoured.**
526
+ The schema accepted them there, but only subagents read them, so a
527
+ one-agent syndicate with an MCP server on its orchestrator got no MCP
528
+ tools and no warning. The orchestrator now resolves them as a subagent
529
+ does (narrowed by `mcp_tools`, gateable by its `require_approval`). On a
530
+ plan-dispatch syndicate the orchestrator is the classifier, and an MCP
531
+ server declared there is now dialled at compile time.
532
+
9
533
  ## 1.0.3 — 2026-10-09
10
534
 
11
535
  Dependency updates and one packaging fix. No export, bin, YAML key or