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

Open
opened 2026-08-17 06:55:22 +00:00 by lost-rob0t · 2 comments
lost-rob0t commented 2026-08-17 06:55:22 +00:00 (Migrated from github.com)

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
lost-rob0t commented 2026-08-18 07:15:36 +00:00 (Migrated from github.com)

Draft PR #92 establishes the dependency direction for acceptance criteria: operator requirements can freeze into an exact SpecRef, while TaskIR should carry/reference that Frozen Spec plus task/execution metadata rather than becoming a second canonical owner of verification requirements.

#69 remains open. The TaskIR representation/normalization itself is not implemented in this slice.

Draft PR #92 establishes the dependency direction for acceptance criteria: operator requirements can freeze into an exact `SpecRef`, while TaskIR should carry/reference that Frozen Spec plus task/execution metadata rather than becoming a second canonical owner of verification requirements. #69 remains open. The TaskIR representation/normalization itself is not implemented in this slice.
lost-rob0t commented 2026-08-18 14:29:06 +00:00 (Migrated from github.com)

SPEC authoring-language slice landed on main via PR #100 after the first-class Spec/Verify substrate landed via #92.

Canonical ownership is now explicit:

  • rlm_spec_lang provides closed SPEC source syntax plus spec_language_catalog/2, spec_source_normalize/2, and spec_source_compile/4;
  • compilation ends in the existing immutable Frozen Spec / exact SpecRef;
  • assertion kinds remain trusted-registry/provider-defined and the sanitized catalog can expose declarative argument_schema metadata without exposing validator/evaluator/observer closures;
  • TaskIR should reference the resulting exact Frozen Spec and retain only task/execution metadata around it, not duplicate acceptance requirements.

#69 remains open for the actual TaskIR normalization/rendering work.

SPEC authoring-language slice landed on `main` via PR #100 after the first-class Spec/Verify substrate landed via #92. Canonical ownership is now explicit: - `rlm_spec_lang` provides closed SPEC source syntax plus `spec_language_catalog/2`, `spec_source_normalize/2`, and `spec_source_compile/4`; - compilation ends in the existing immutable Frozen Spec / exact `SpecRef`; - assertion kinds remain trusted-registry/provider-defined and the sanitized catalog can expose declarative `argument_schema` metadata without exposing validator/evaluator/observer closures; - TaskIR should reference the resulting exact Frozen Spec and retain only task/execution metadata around it, not duplicate acceptance requirements. #69 remains open for the actual TaskIR normalization/rendering work.
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#69
No description provided.