[P0] First-class bounded RLM subagent fallback + KB command binding #144

Closed
opened 2026-08-21 05:49:57 +00:00 by lost-rob0t · 7 comments
lost-rob0t commented 2026-08-21 05:49:57 +00:00 (Migrated from github.com)

Parent: #141. Reusable result-acceptance follow-up: #56.

Outcome

Completed on current main through PRs #146, #147, #149, and #180.

The canonical domain-neutral path is now:

unknown/unresolved parent state
-> closed KB command `delegate_subagent`
-> ordinary `tool(rlm_subagent)` schema/capability/authority boundary
-> supervised child with narrowed capability and authority possession
-> bounded child-owned RLM completion on the existing async worker pool
-> typed child result with usage, trace, and parent/child correlation
-> parent result delivery and continuation/replan

The final closure in #180 binds completion tools to the spawned child's exact normalized capability ceiling, narrowed authority context, and trusted runtime/agent lineage. The parent-bound subagent tool fails closed if placed in its own child ceiling; recursive rlm(...) plans remain available only under existing completion depth, parallel, model, token, and wall-time budgets.

No second scheduler, authority system, effect ledger, verifier stack, ambient capability, arbitrary call/1, or product-specific AgentProlog branch was added. Broader evidence/result acceptance remains #56.

Acceptance

  • deterministic unresolved parent selects the canonical subagent tool rather than fabricating an answer
  • invocation uses ordinary tool schema, capability, and authority mediation
  • child capabilities and authority are equal-or-narrower and own inner tool execution
  • parent/child trace and runtime/agent correlation are explicit and deterministic
  • depth, parallel width, agent count, model, token, and wall-time limits are enforced
  • parent cancellation invalidates admitted child work through the existing scheduler
  • child returns a typed status/value/usage/trace/correlation envelope
  • parent consumes the result and continues/replans to a final result
  • parent-bound recursive subagent registration fails closed without a depth-aware binding
  • unavailable, capability-denied, authority-denied, budget-exhausted, cancelled, and failed paths are structured failures
  • direct terse prompts and reusable prompt references compile deterministically
  • unknown -> delegate_subagent resolves to inert canonical tool(rlm_subagent) data
  • missing, ambiguous, and invalid bindings fail explicitly
  • compiler output records provenance and a stable fingerprint without mutating authority or Frozen Spec
  • no model or KB term becomes an arbitrary callable

Final verification

  • focused subagent: 12/12
  • focused async architecture: 54/54
  • runner integrity: 19/19
  • deterministic aggregate: 75 suites, 783/783 passed, 0 failed/timeout/blocked/fixme
  • deterministic benchmark: 16/16
  • deep experiment: 15/15
  • JSON CLI demo: pass
  • Nix flake checks: 3/3
  • exact-head GitHub CI, clean pack install, Nix, Tree-sitter FFI, and REAL OpenRouter integration: green
Parent: #141. Reusable result-acceptance follow-up: #56. ## Outcome Completed on current `main` through PRs #146, #147, #149, and #180. The canonical domain-neutral path is now: ```text unknown/unresolved parent state -> closed KB command `delegate_subagent` -> ordinary `tool(rlm_subagent)` schema/capability/authority boundary -> supervised child with narrowed capability and authority possession -> bounded child-owned RLM completion on the existing async worker pool -> typed child result with usage, trace, and parent/child correlation -> parent result delivery and continuation/replan ``` The final closure in #180 binds completion tools to the spawned child's exact normalized capability ceiling, narrowed authority context, and trusted runtime/agent lineage. The parent-bound subagent tool fails closed if placed in its own child ceiling; recursive `rlm(...)` plans remain available only under existing completion depth, parallel, model, token, and wall-time budgets. No second scheduler, authority system, effect ledger, verifier stack, ambient capability, arbitrary `call/1`, or product-specific AgentProlog branch was added. Broader evidence/result acceptance remains #56. ## Acceptance - [x] deterministic unresolved parent selects the canonical subagent tool rather than fabricating an answer - [x] invocation uses ordinary tool schema, capability, and authority mediation - [x] child capabilities and authority are equal-or-narrower and own inner tool execution - [x] parent/child trace and runtime/agent correlation are explicit and deterministic - [x] depth, parallel width, agent count, model, token, and wall-time limits are enforced - [x] parent cancellation invalidates admitted child work through the existing scheduler - [x] child returns a typed status/value/usage/trace/correlation envelope - [x] parent consumes the result and continues/replans to a final result - [x] parent-bound recursive subagent registration fails closed without a depth-aware binding - [x] unavailable, capability-denied, authority-denied, budget-exhausted, cancelled, and failed paths are structured failures - [x] direct terse prompts and reusable prompt references compile deterministically - [x] `unknown -> delegate_subagent` resolves to inert canonical `tool(rlm_subagent)` data - [x] missing, ambiguous, and invalid bindings fail explicitly - [x] compiler output records provenance and a stable fingerprint without mutating authority or Frozen Spec - [x] no model or KB term becomes an arbitrary callable ## Final verification - focused subagent: 12/12 - focused async architecture: 54/54 - runner integrity: 19/19 - deterministic aggregate: 75 suites, 783/783 passed, 0 failed/timeout/blocked/fixme - deterministic benchmark: 16/16 - deep experiment: 15/15 - JSON CLI demo: pass - Nix flake checks: 3/3 - exact-head GitHub CI, clean pack install, Nix, Tree-sitter FFI, and REAL OpenRouter integration: green
lost-rob0t commented 2026-08-21 06:48:56 +00:00 (Migrated from github.com)

Worker A progress: opened draft PR #146 on a branch cut from exact main f21df8e, deliberately avoiding Worker B's #145 and #122/#125/#132 surfaces. First TDD slice implements the closed KB command-binding contract: terse prompt/2 + trigger + action records compile deterministically; delegate_subagent resolves only to canonical data tool(rlm_subagent); missing/ambiguous/invalid bindings are structured failures; arbitrary callable actions are rejected; output carries KB provenance + SHA-256 fingerprint. This does not claim the runtime fallback is complete. Next required slice remains canonical rlm_subagent execution through ordinary tool/capability/authority/budget boundaries with child completion/evidence/trace correlation and parent resume/replan.

Worker A progress: opened draft PR #146 on a branch cut from exact `main` `f21df8e`, deliberately avoiding Worker B's #145 and #122/#125/#132 surfaces. First TDD slice implements the closed KB command-binding contract: terse `prompt/2` + trigger + action records compile deterministically; `delegate_subagent` resolves only to canonical data `tool(rlm_subagent)`; missing/ambiguous/invalid bindings are structured failures; arbitrary callable actions are rejected; output carries KB provenance + SHA-256 fingerprint. This does **not** claim the runtime fallback is complete. Next required slice remains canonical `rlm_subagent` execution through ordinary tool/capability/authority/budget boundaries with child completion/evidence/trace correlation and parent resume/replan.
lost-rob0t commented 2026-08-21 07:48:51 +00:00 (Migrated from github.com)

Worker A progress: merged #146 at 1d1ee7594962accafabdd61d26a725d8bdb86a05 after exact-head 27479d32d92773e5c597d453e8593152516130b7 passed CI, Tree-sitter FFI, and clean SWI pack install with no review threads. This completes the closed short-KB command-binding slice: inert prompt/trigger/action records, deterministic direct/reference compilation, delegate_subagent -> tool(rlm_subagent), stable SHA-256 fingerprint/provenance, and explicit missing/ambiguous/invalid-action failures without call/1 or authority/Spec mutation.

#144 remains open. Executable audit still shows the runtime half is missing: rlm_agent:agent_spawn creates a supervised child handle with capability/authority narrowing and bounded agent runtime, but there is still no canonical registered rlm_subagent handler that composes child supervision with bounded rlm_completion, returns structured child evidence/usage/trace correlation, and resumes/replans the parent. The next non-conflicting slice should implement that generic runtime path on top of the ordinary rlm_tool invocation boundary; do not duplicate Worker B's #145 flake surface or #122/#125/#132.

Worker A progress: merged #146 at `1d1ee7594962accafabdd61d26a725d8bdb86a05` after exact-head `27479d32d92773e5c597d453e8593152516130b7` passed CI, Tree-sitter FFI, and clean SWI pack install with no review threads. This completes the closed short-KB command-binding slice: inert prompt/trigger/action records, deterministic direct/reference compilation, `delegate_subagent -> tool(rlm_subagent)`, stable SHA-256 fingerprint/provenance, and explicit missing/ambiguous/invalid-action failures without `call/1` or authority/Spec mutation. #144 remains open. Executable audit still shows the runtime half is missing: `rlm_agent:agent_spawn` creates a supervised child handle with capability/authority narrowing and bounded agent runtime, but there is still no canonical registered `rlm_subagent` handler that composes child supervision with bounded `rlm_completion`, returns structured child evidence/usage/trace correlation, and resumes/replans the parent. The next non-conflicting slice should implement that generic runtime path on top of the ordinary `rlm_tool` invocation boundary; do not duplicate Worker B's #145 flake surface or #122/#125/#132.
lost-rob0t commented 2026-08-21 08:51:25 +00:00 (Migrated from github.com)

Worker A continued #144 on a fresh branch from merged #146 and opened draft #147 (agent/rlm-subagent-runtime, exact head 916e4c4d0181546c98079d70941466692ef7afc0). This is the first canonical runtime slice: rlm_subagent is registered through ordinary rlm_tool; its trusted handler composes rlm_agent child supervision/narrowing with bounded rlm_completion; the returned envelope carries completed/failed status, value, usage, explicit parent/child correlation and agent trace. Focused TDD covers success, tool capability denial before child creation, and child capability widening as structured failure. CI, Tree-sitter FFI, and clean-pack runs are now queued on the exact head, so #147 remains draft/unmerged.

This does not claim all #144 acceptance yet. Next after exact-head feedback: cancellation/depth/concurrency end-to-end, explicit unknown->tool selection->parent continue/replan fixture, and richer evidence/provenance/result-acceptance integration. Worker B #145 and #122/#125/#132 remain untouched.

Worker A continued #144 on a fresh branch from merged #146 and opened draft #147 (`agent/rlm-subagent-runtime`, exact head `916e4c4d0181546c98079d70941466692ef7afc0`). This is the first canonical runtime slice: `rlm_subagent` is registered through ordinary `rlm_tool`; its trusted handler composes `rlm_agent` child supervision/narrowing with bounded `rlm_completion`; the returned envelope carries completed/failed status, value, usage, explicit parent/child correlation and agent trace. Focused TDD covers success, tool capability denial before child creation, and child capability widening as structured failure. CI, Tree-sitter FFI, and clean-pack runs are now queued on the exact head, so #147 remains draft/unmerged. This does not claim all #144 acceptance yet. Next after exact-head feedback: cancellation/depth/concurrency end-to-end, explicit unknown->tool selection->parent continue/replan fixture, and richer evidence/provenance/result-acceptance integration. Worker B #145 and #122/#125/#132 remain untouched.
lost-rob0t commented 2026-08-21 09:47:04 +00:00 (Migrated from github.com)

Worker A post-merge executable audit (2026-08-21): PR #147 merged as 09d9418911acdebb851c8a8362fcd02ca1b5fdeb after exact head 916e4c4d0181546c98079d70941466692ef7afc0 passed CI, Tree-sitter FFI, and clean SWI-pack gates with no review threads.

Important: #147 is a real first-class rlm_subagent tool registration/envelope slice, but it does not yet satisfy the full #144 supervision/cancellation contract. Source audit on merged main shows rlm_subagent_handler/7 calls agent_spawn(...) to allocate a child identity and then calls rlm_completion(...) directly in the tool handler. The completion is not dispatched through the child's mailbox/worker lifecycle. Therefore the spawned child currently does not own the completion work, parent agent_cancel/4 cannot be claimed to cancel that in-flight completion through signal_agent_workers, and the child's state/result lifecycle is not the authoritative completion path.

rlm_agent already has the machinery we should compose instead of inventing another scheduler: request messages dispatch through the bounded worker pool; agent_cancel/4 recursively cancels children and signals their workers; worker results return through the child's engine. There is also a second gap: notify_parent_from_reply/3 currently forwards only failed child replies, not successful completed/result replies.

Next runtime slice should therefore make the RLM subagent completion actually execute as child-owned supervised work (or add the smallest generic supervised-call API over the existing mailbox/worker path), forward a structured successful child result to the parent, and TDD cancellation/depth/concurrency/agent-limit behavior plus parent continuation. Do not add a second scheduler. Keep the ordinary rlm_tool capability/authority boundary from #147 and the merged closed KB command binding from #146.

Remaining unchecked acceptance is real: unresolved-state policy -> tool(rlm_subagent) -> child-owned bounded completion -> structured evidence/result -> parent consume/replan, with cancellation/time/token/depth/concurrency proofs and structured unavailable/denied/failed paths.

Worker A post-merge executable audit (2026-08-21): PR #147 merged as `09d9418911acdebb851c8a8362fcd02ca1b5fdeb` after exact head `916e4c4d0181546c98079d70941466692ef7afc0` passed CI, Tree-sitter FFI, and clean SWI-pack gates with no review threads. Important: #147 is a real first-class `rlm_subagent` *tool registration/envelope* slice, but it does **not** yet satisfy the full #144 supervision/cancellation contract. Source audit on merged main shows `rlm_subagent_handler/7` calls `agent_spawn(...)` to allocate a child identity and then calls `rlm_completion(...)` directly in the tool handler. The completion is not dispatched through the child's mailbox/worker lifecycle. Therefore the spawned child currently does not own the completion work, parent `agent_cancel/4` cannot be claimed to cancel that in-flight completion through `signal_agent_workers`, and the child's state/result lifecycle is not the authoritative completion path. `rlm_agent` already has the machinery we should compose instead of inventing another scheduler: request messages dispatch through the bounded worker pool; `agent_cancel/4` recursively cancels children and signals their workers; worker results return through the child's engine. There is also a second gap: `notify_parent_from_reply/3` currently forwards only `failed` child replies, not successful `completed`/result replies. Next runtime slice should therefore make the RLM subagent completion actually execute as child-owned supervised work (or add the smallest generic supervised-call API over the existing mailbox/worker path), forward a structured successful child result to the parent, and TDD cancellation/depth/concurrency/agent-limit behavior plus parent continuation. Do not add a second scheduler. Keep the ordinary `rlm_tool` capability/authority boundary from #147 and the merged closed KB command binding from #146. Remaining unchecked acceptance is real: unresolved-state policy -> `tool(rlm_subagent)` -> child-owned bounded completion -> structured evidence/result -> parent consume/replan, with cancellation/time/token/depth/concurrency proofs and structured unavailable/denied/failed paths.
lost-rob0t commented 2026-08-21 10:49:01 +00:00 (Migrated from github.com)

Worker A fresh-main conformance audit after #147 (09d9418911acdebb851c8a8362fcd02ca1b5fdeb) confirms the next implementation must change the generic rlm_agent supervision seam before adding more rlm_subagent wrapper logic.

Exact executable finding: rlm_subagent_handler/7 spawns a child and then calls rlm_completion/4 directly in the tool-handler thread. In rlm_agent, cancellation only signals threads recorded as agent_worker(RuntimeId, AgentId, CallId, Thread), which are created by the mailbox request(...) -> dispatch -> schedule_worker(...) path. Therefore the current completion is outside child worker ownership and parent cancellation cannot cancel it through the existing supervisor. Also notify_parent_from_reply/3 only forwards kind:failed; a successful worker result never becomes a canonical parent child_result.

Smallest coherent next seam, without a second scheduler: add a trusted host-facing supervised-call operation to rlm_agent that (1) admits a call into the child engine/pending set, (2) schedules the supplied trusted handler on the existing bounded runtime worker pool, (3) awaits/pumps that same child-owned call to a terminal structured result, and (4) preserves worker registration so agent_cancel/4 signals it. Then extend parent notification to forward successful terminal child results exactly once. rlm_subagent can use this seam with a code-owned completion handler instead of direct rlm_completion/4.

TDD contract for that seam before wiring fallback: successful child call is visible in child status and parent child-result; parent cancellation interrupts a deliberately blocked child worker; worker-pool saturation is structured; agent-count ceiling remains enforced by spawn; authority/capability narrowing remains unchanged. Then the #144 integration fixture should compose merged #146 unknown -> tool(rlm_subagent) with the merged #147 ordinary tool boundary and prove child completion -> parent continuation/replan.

I did not open a duplicate PR because current open #148 owns evolution-kernel files and #122/#125/#132 own skill/Harness/config surfaces; this mission should remain isolated to rlm_agent + rlm_subagent + focused tests. AgentProlog #1/#2 still have the correct dependency direction and need no downstream workaround.

Worker A fresh-main conformance audit after #147 (`09d9418911acdebb851c8a8362fcd02ca1b5fdeb`) confirms the next implementation must change the generic `rlm_agent` supervision seam before adding more `rlm_subagent` wrapper logic. Exact executable finding: `rlm_subagent_handler/7` spawns a child and then calls `rlm_completion/4` directly in the tool-handler thread. In `rlm_agent`, cancellation only signals threads recorded as `agent_worker(RuntimeId, AgentId, CallId, Thread)`, which are created by the mailbox `request(...) -> dispatch -> schedule_worker(...)` path. Therefore the current completion is outside child worker ownership and parent cancellation cannot cancel it through the existing supervisor. Also `notify_parent_from_reply/3` only forwards `kind:failed`; a successful worker result never becomes a canonical parent `child_result`. Smallest coherent next seam, without a second scheduler: add a trusted host-facing supervised-call operation to `rlm_agent` that (1) admits a call into the child engine/pending set, (2) schedules the supplied trusted handler on the existing bounded runtime worker pool, (3) awaits/pumps that same child-owned call to a terminal structured result, and (4) preserves worker registration so `agent_cancel/4` signals it. Then extend parent notification to forward successful terminal child results exactly once. `rlm_subagent` can use this seam with a code-owned completion handler instead of direct `rlm_completion/4`. TDD contract for that seam before wiring fallback: successful child call is visible in child status and parent child-result; parent cancellation interrupts a deliberately blocked child worker; worker-pool saturation is structured; agent-count ceiling remains enforced by spawn; authority/capability narrowing remains unchanged. Then the #144 integration fixture should compose merged #146 `unknown -> tool(rlm_subagent)` with the merged #147 ordinary tool boundary and prove child completion -> parent continuation/replan. I did not open a duplicate PR because current open #148 owns evolution-kernel files and #122/#125/#132 own skill/Harness/config surfaces; this mission should remain isolated to `rlm_agent` + `rlm_subagent` + focused tests. AgentProlog #1/#2 still have the correct dependency direction and need no downstream workaround.
lost-rob0t commented 2026-08-21 11:48:22 +00:00 (Migrated from github.com)

Worker A continued from fresh main 23d919628a449acc3ced08fc9bd8469cc2cbf8ea (after #148) and opened draft #149 from that exact head. This is a deliberate TDD-red conformance transaction, not a duplicate of #146/#147: it adds a deterministic test proving a successful child-owned worker result must propagate through the existing rlm_agent supervised parent path as canonical child_result with trace correlation. Current main only forwards kind:failed, so the new test is expected to fail until the generic supervision seam is fixed. Exact PR head is 4fd2d215536f3217d8ed6b36d04189d6ec2981c1; CI and clean-pack are queued.

Next implementation remains in #149: extend existing rlm_agent success propagation, add the smallest trusted child-owned supervised-call operation over the existing bounded worker pool/cancellation registration, switch rlm_subagent away from direct handler-thread rlm_completion/4, then add cancellation/backpressure and the full merged-#146 unknown -> tool(rlm_subagent) -> child outcome -> parent continuation fixture. #122/#125/#132 and legacy harness surfaces remain untouched.

Worker A continued from fresh `main` `23d919628a449acc3ced08fc9bd8469cc2cbf8ea` (after #148) and opened draft #149 from that exact head. This is a deliberate TDD-red conformance transaction, not a duplicate of #146/#147: it adds a deterministic test proving a successful child-owned worker result must propagate through the existing `rlm_agent` supervised parent path as canonical `child_result` with trace correlation. Current main only forwards `kind:failed`, so the new test is expected to fail until the generic supervision seam is fixed. Exact PR head is `4fd2d215536f3217d8ed6b36d04189d6ec2981c1`; CI and clean-pack are queued. Next implementation remains in #149: extend existing `rlm_agent` success propagation, add the smallest trusted child-owned supervised-call operation over the existing bounded worker pool/cancellation registration, switch `rlm_subagent` away from direct handler-thread `rlm_completion/4`, then add cancellation/backpressure and the full merged-#146 `unknown -> tool(rlm_subagent)` -> child outcome -> parent continuation fixture. #122/#125/#132 and legacy harness surfaces remain untouched.
lost-rob0t commented 2026-08-24 16:24:57 +00:00 (Migrated from github.com)

Closed by PR #180. Exact reviewed head c56c82dd5c passed all required deterministic, packaging, Tree-sitter, and REAL OpenRouter checks and merged as 0d8e1008ba. The issue body and roadmap now reflect the merged contract; broader verifier-backed result acceptance remains #56.

Closed by PR #180. Exact reviewed head c56c82dd5c774e976cf1af5858addea4e97c5619 passed all required deterministic, packaging, Tree-sitter, and REAL OpenRouter checks and merged as 0d8e1008ba525f0ec7e51cba2de34ede8a63cf6f. The issue body and roadmap now reflect the merged contract; broader verifier-backed result acceptance remains #56.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
nsaspy/prolog-rlm#144
No description provided.