[P1] Add closed project-op plan vocabulary and plan dependency-graph executor #454

Closed
opened 2026-09-10 21:18:26 +00:00 by nsaspy · 1 comment
Owner

Goal

Harden the existing SPEC/PLAN separation and add the missing long-horizon execution layer:

  1. Closed project-op plan vocabulary — typed plan ops (sync_remote/1, index/1, search/2, locate/1, read/1, diff/2, edit/2, create/2, delete/1, run/1, validate/1, delegate/2) as inert data constructors that compile into the existing rlm_plan closed-AST world: each validated step executes through rlm_plan as [tool(Op, literal(Args), Bind), final(var(Bind))] — rlm_plan remains the only step executor; no second plan interpreter, no second scheduler.
  2. Plan dependency-graph executor — model-proposed plans as step/2 + depends_on/2 facts compiled into a validated acyclic graph; runtime decides executability via ready_step/1 semantics (all dependencies completed), with failed/blocked dependency propagation as structured outcomes. LLM proposes the graph; Prolog decides what is executable; expert KB (host expert registry) decides who executes — except the D6-11 plan-native deterministic set (sync_remote/1, run/1, index/1, delete/1), which executes at the plan layer and is excluded from expert mapping; capability system decides whether; SPEC validator decides acceptability.
  3. Normalized symbol/source-span reference contract — closed symbol_ref/source_span data terms plus a bounded resolver over host-supplied index facts, consumed by locate/1, diff/2, edit/2. Language independence: plans speak symbol(foo), not pythonFunction(foo).

Current execution truth (evidence)

  • prolog/rlm_plan.pl: closed AST ops context/3, model/4, rlm/2, tool/3, spawn_agent/3, parallel/2, retry/3, checkpoint/1, final/1; whole-plan validation before side effects; host tool registry + preflight; budgets.
  • prolog/rlm_spec_lang.pl + prolog/rlm_spec.pl + prolog/rlm_verify.pl: closed SPEC authoring, validation, freeze, verify.
  • prolog/rlm_spec_workflow.pl: spec_plan_bind binds plans to frozen Spec fingerprints; repair loop over rlm_graph.
  • prolog/rlm_project_source.pl: Project/File/Language/grammar registry (#95); syntax/symbol layers (#96-#99) still open.

Invariants

  • No second plan interpreter, no second scheduler: plan_graph_run_async/4 submits ONE execute predicate to rlm_async; the ready-step loop runs inside that worker calling rlm_plan execute ABIs directly (no nested Future waits); the synchronous facade awaits the same Future.
  • Plan ops are inert data until validated; expert closures are host-supplied only; the op vocabulary is validated against the closed set BEFORE desugaring so model data can never name a tool outside it.
  • Per-op capability term is exactly tool(Op) (closed capability_shape/1 grammar; plan_op(...) is invalid today).
  • An aggregate graph budget bounds totals across step executions (steps, tool/model/context ops, output bytes) via plan_result.budget_remaining feed-forward.
  • Cancellation is not ordinary failure: error(rlm_cancelled(Token), _) aborts the graph and rethrows; no further step executes; no re-submission.
  • Child/delegate capabilities narrow by default through the existing rlm_tool:capabilities_narrow/3 / spawn path.
  • Externally effectful execution (sync_remote, edit, create, delete, run in real use) must route through the durable effect boundary with trusted adapter/attempt identity; this slice adds no new external-effect path (shipped handlers are pure host closures). Per D6-11 (docs/research/spec-plan-authority.md §6.3), the plan-native deterministic set (sync_remote/1, run/1, index/1, delete/1) executes at the plan layer through the canonical boundary — schema → capability → authority → durable effect admission → dispatch → observe — exactly like a tool/3 step, and is excluded from expert mapping and the future expert registry; edit/2/create/2 remain write-expert-owned (§8.3).
  • Graph validation rejects cycles, unknown ops, unknown dependencies, and duplicate step ids before any step executes. abandoned is terminal state, never retry authorization.

Non-goals

  • No full Tree-sitter semantic extraction (owned by #96-#98); the symbol contract resolves over host-supplied index facts only.
  • No coding-agent tool catalog or product UX.
  • No durable cross-restart graph resume in this slice (rlm_graph-backed durability is follow-up).

Acceptance criteria

  • Deterministic PlUnit coverage: parse (JSON + term), closed-vocabulary rejection, cycle/unknown-dep/duplicate-id rejection, ready-step scheduling order, failure→blocked propagation, cancellation abort + token rethrow, aggregate-budget enforcement, per-op capability denial, expert-registry resolution, delegate narrowing, symbol_ref→source_span resolution incl. ambiguous/unresolved/unsupported states, async/sync parity.
  • Contract check script loops over Prolog requirement facts asserting the public surface is defined (presence gate; behavioral evidence lives in PlUnit).
  • Full deterministic gate green: check_runtime, load_all, run_tests, benchmark deterministic, CLI demo smoke.
  • Docs: new docs/plan-graph-runtime.md + typed-plans/spec-verify cross-links + roadmap reconciliation if AgentProlog readiness changes.

Review evidence

Adversarial subprocess review of research/RLM-RESEARCH-027-spec-plan-graph-executor.org: verdict sound-with-changes; report rage/288-review-research-report.md; required changes folded into the research record and this issue body.

Refs #93 #71 #176

## Goal Harden the existing SPEC/PLAN separation and add the missing long-horizon execution layer: 1. **Closed project-op plan vocabulary** — typed plan ops (`sync_remote/1`, `index/1`, `search/2`, `locate/1`, `read/1`, `diff/2`, `edit/2`, `create/2`, `delete/1`, `run/1`, `validate/1`, `delegate/2`) as inert *data constructors* that compile into the existing `rlm_plan` closed-AST world: each validated step executes through `rlm_plan` as `[tool(Op, literal(Args), Bind), final(var(Bind))]` — `rlm_plan` remains the only step executor; no second plan interpreter, no second scheduler. 2. **Plan dependency-graph executor** — model-proposed plans as `step/2` + `depends_on/2` facts compiled into a validated acyclic graph; runtime decides executability via `ready_step/1` semantics (all dependencies completed), with failed/blocked dependency propagation as structured outcomes. LLM proposes the graph; Prolog decides what is executable; expert KB (host expert registry) decides who executes — except the D6-11 plan-native deterministic set (`sync_remote/1`, `run/1`, `index/1`, `delete/1`), which executes at the plan layer and is excluded from expert mapping; capability system decides whether; SPEC validator decides acceptability. 3. **Normalized symbol/source-span reference contract** — closed `symbol_ref`/`source_span` data terms plus a bounded resolver over host-supplied index facts, consumed by `locate/1`, `diff/2`, `edit/2`. Language independence: plans speak `symbol(foo)`, not `pythonFunction(foo)`. ## Current execution truth (evidence) - `prolog/rlm_plan.pl`: closed AST ops `context/3, model/4, rlm/2, tool/3, spawn_agent/3, parallel/2, retry/3, checkpoint/1, final/1`; whole-plan validation before side effects; host tool registry + preflight; budgets. - `prolog/rlm_spec_lang.pl` + `prolog/rlm_spec.pl` + `prolog/rlm_verify.pl`: closed SPEC authoring, validation, freeze, verify. - `prolog/rlm_spec_workflow.pl`: spec_plan_bind binds plans to frozen Spec fingerprints; repair loop over `rlm_graph`. - `prolog/rlm_project_source.pl`: Project/File/Language/grammar registry (#95); syntax/symbol layers (#96-#99) still open. ## Invariants - No second plan interpreter, no second scheduler: `plan_graph_run_async/4` submits ONE execute predicate to `rlm_async`; the ready-step loop runs inside that worker calling `rlm_plan` execute ABIs directly (no nested Future waits); the synchronous facade awaits the same Future. - Plan ops are inert data until validated; expert closures are host-supplied only; the op vocabulary is validated against the closed set BEFORE desugaring so model data can never name a tool outside it. - Per-op capability term is exactly `tool(Op)` (closed `capability_shape/1` grammar; `plan_op(...)` is invalid today). - An aggregate graph budget bounds totals across step executions (steps, tool/model/context ops, output bytes) via `plan_result.budget_remaining` feed-forward. - Cancellation is not ordinary failure: `error(rlm_cancelled(Token), _)` aborts the graph and rethrows; no further step executes; no re-submission. - Child/delegate capabilities narrow by default through the existing `rlm_tool:capabilities_narrow/3` / spawn path. - Externally effectful execution (`sync_remote`, `edit`, `create`, `delete`, `run` in real use) must route through the durable effect boundary with trusted adapter/attempt identity; **this slice adds no new external-effect path** (shipped handlers are pure host closures). Per D6-11 (`docs/research/spec-plan-authority.md` §6.3), the plan-native deterministic set (`sync_remote/1`, `run/1`, `index/1`, `delete/1`) executes at the plan layer through the canonical boundary — schema → capability → authority → durable effect admission → dispatch → observe — exactly like a `tool/3` step, and is excluded from expert mapping and the future expert registry; `edit/2`/`create/2` remain write-expert-owned (§8.3). - Graph validation rejects cycles, unknown ops, unknown dependencies, and duplicate step ids before any step executes. `abandoned` is terminal state, never retry authorization. ## Non-goals - No full Tree-sitter semantic extraction (owned by #96-#98); the symbol contract resolves over host-supplied index facts only. - No coding-agent tool catalog or product UX. - No durable cross-restart graph resume in this slice (rlm_graph-backed durability is follow-up). ## Acceptance criteria - Deterministic PlUnit coverage: parse (JSON + term), closed-vocabulary rejection, cycle/unknown-dep/duplicate-id rejection, ready-step scheduling order, failure→blocked propagation, cancellation abort + token rethrow, aggregate-budget enforcement, per-op capability denial, expert-registry resolution, delegate narrowing, symbol_ref→source_span resolution incl. ambiguous/unresolved/unsupported states, async/sync parity. - Contract check script loops over Prolog requirement facts asserting the public surface is defined (presence gate; behavioral evidence lives in PlUnit). - Full deterministic gate green: check_runtime, load_all, run_tests, benchmark deterministic, CLI demo smoke. - Docs: new `docs/plan-graph-runtime.md` + typed-plans/spec-verify cross-links + roadmap reconciliation if AgentProlog readiness changes. ## Review evidence Adversarial subprocess review of `research/RLM-RESEARCH-027-spec-plan-graph-executor.org`: verdict sound-with-changes; report `rage/288-review-research-report.md`; required changes folded into the research record and this issue body. Refs #93 #71 #176
Author
Owner

Duplicate of #293 (pre-existing Forgejo mirror). Closing this accidental duplicate created by today's open-state sync; #293 stays canonical on Forgejo.

Duplicate of #293 (pre-existing Forgejo mirror). Closing this accidental duplicate created by today's open-state sync; #293 stays canonical on Forgejo.
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#454
No description provided.