[P1] Add normalized task IR and prompt compilation/rendering APIs #429

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

Goal

Implement the first child slice of #68: represent prompt/workflow intent as normalized inspectable Prolog data, then render standalone model-targeted execution prompts from that IR.

Required model

The source requirement list is not the final prompt. Compile it into a closed IR with fields equivalent in semantics to:

task_ir{
    goal:Goal,
    current_state:StateRefs,
    authorities:Authorities,
    hard_invariants:Hard,
    preferences:Preferences,
    non_goals:NonGoals,
    required_discovery:Discovery,
    allowed_mutations:Mutations,
    approval_boundary:Approval,
    acceptance_gates:Gates,
    output_contract:Output,
    continuation_policy:Continuation,
    provenance:Provenance
}.

Exact representation may follow repository conventions, but it must be closed, ground, schema-validated, and inspectable.

Public APIs

Add regular public predicates equivalent to:

task_ir_normalize(+Requirements, +Context, +Options, -Outcome).
task_ir_validate(+TaskIR, -Outcome).
prompt_profile(+ProviderOrModel, -Profile).
prompt_render(+TaskIR, +Profile, +Options, -Outcome).
prompt_compile(+Requirements, +Context, +Profile, +Options, -Outcome).

Where latency-bearing provider-assisted normalization/rendering is supported, follow #54 with canonical async variants and sync wrappers over the same execution path.

Normalization semantics

  • Collapse superseded conversational constraints into the current semantic rule.
  • Separate hard invariants from preferences.
  • Separate observations/facts from inference.
  • Preserve source provenance.
  • Reject contradictory hard constraints structurally unless an explicit authority rule resolves them.
  • Never turn model prose into arbitrary callable Prolog.
  • Preserve frozen acceptance criteria for a run; changing them requires a new/versioned task IR.

Model-native rendering

Rendering may adapt wording/structure for a model/provider profile, but profiles are semantic renderers, not magic-trigger-word catalogs.

Profiles may specify things such as:

  • preferred section structure;
  • concise vs explicit instruction density;
  • provider/model vocabulary conventions;
  • whether examples/XML/schema blocks materially help;
  • where long context versus final query should appear;
  • which execution controls belong in API options rather than prompt prose.

The canonical TaskIR remains model-neutral.

Fresh-root contract

The rendered prompt must be a standalone execution artifact suitable for a fresh thread/agent. It should not require the exploratory conversation history to recover hard requirements.

Integration

Reuse existing structured outcomes, artifacts, traces, completion/provider APIs, and #54 async rules. Do not build another template engine with hidden global state.

Acceptance

  • Task IR schema is closed and deterministic.
  • Normalization collapses superseded requirement history correctly.
  • Contradictory unresolved hard constraints fail structurally.
  • Provenance survives normalization and rendering.
  • Rendering from the same IR/profile/options is deterministic absent an explicitly requested provider-assisted pass.
  • At least two model/provider profiles demonstrate backend-specific rendering without changing task semantics.
  • Fresh-root output includes goal, authority, invariants, non-goals, allowed mutations, evidence/acceptance gates, and continuation policy.
  • Tests cover normalization, supersession, contradictions, profile rendering, malformed IR, and round-trip inspection.

Refs #68 #54 #56

## Goal Implement the first child slice of #68: represent prompt/workflow intent as normalized inspectable Prolog data, then render standalone model-targeted execution prompts from that IR. ## Required model The source requirement list is not the final prompt. Compile it into a closed IR with fields equivalent in semantics to: ```prolog task_ir{ goal:Goal, current_state:StateRefs, authorities:Authorities, hard_invariants:Hard, preferences:Preferences, non_goals:NonGoals, required_discovery:Discovery, allowed_mutations:Mutations, approval_boundary:Approval, acceptance_gates:Gates, output_contract:Output, continuation_policy:Continuation, provenance:Provenance }. ``` Exact representation may follow repository conventions, but it must be closed, ground, schema-validated, and inspectable. ## Public APIs Add regular public predicates equivalent to: ```prolog task_ir_normalize(+Requirements, +Context, +Options, -Outcome). task_ir_validate(+TaskIR, -Outcome). prompt_profile(+ProviderOrModel, -Profile). prompt_render(+TaskIR, +Profile, +Options, -Outcome). prompt_compile(+Requirements, +Context, +Profile, +Options, -Outcome). ``` Where latency-bearing provider-assisted normalization/rendering is supported, follow #54 with canonical async variants and sync wrappers over the same execution path. ## Normalization semantics - Collapse superseded conversational constraints into the current semantic rule. - Separate hard invariants from preferences. - Separate observations/facts from inference. - Preserve source provenance. - Reject contradictory hard constraints structurally unless an explicit authority rule resolves them. - Never turn model prose into arbitrary callable Prolog. - Preserve frozen acceptance criteria for a run; changing them requires a new/versioned task IR. ## Model-native rendering Rendering may adapt wording/structure for a model/provider profile, but profiles are semantic renderers, not magic-trigger-word catalogs. Profiles may specify things such as: - preferred section structure; - concise vs explicit instruction density; - provider/model vocabulary conventions; - whether examples/XML/schema blocks materially help; - where long context versus final query should appear; - which execution controls belong in API options rather than prompt prose. The canonical TaskIR remains model-neutral. ## Fresh-root contract The rendered prompt must be a standalone execution artifact suitable for a fresh thread/agent. It should not require the exploratory conversation history to recover hard requirements. ## Integration Reuse existing structured outcomes, artifacts, traces, completion/provider APIs, and #54 async rules. Do not build another template engine with hidden global state. ## Acceptance - [ ] Task IR schema is closed and deterministic. - [ ] Normalization collapses superseded requirement history correctly. - [ ] Contradictory unresolved hard constraints fail structurally. - [ ] Provenance survives normalization and rendering. - [ ] Rendering from the same IR/profile/options is deterministic absent an explicitly requested provider-assisted pass. - [ ] At least two model/provider profiles demonstrate backend-specific rendering without changing task semantics. - [ ] Fresh-root output includes goal, authority, invariants, non-goals, allowed mutations, evidence/acceptance gates, and continuation policy. - [ ] Tests cover normalization, supersession, contradictions, profile rendering, malformed IR, and round-trip inspection. Refs #68 #54 #56
Author
Owner

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

Duplicate of #69 (pre-existing Forgejo mirror with GitHub number parity). Closing this accidental duplicate created by today's open-state sync; #69 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#429
No description provided.