import type { PromptDef } from "./index.js";

/**
 * V7 §1.1 / §2.4.1 / §2.4.4 — L3 world-model abstraction.
 *
 * Given a cluster of compatible L2 policies (plus a short sample of the
 * L1 traces that minted them), distill a **world model** answering
 * "what does this environment look like?" — not "what should I do?".
 *
 * Output must follow the V7 triple (ℰ, ℐ, C):
 *   - environment: topology facts ("src/ contains components/, utils/, …")
 *   - inference:   behavioural rules ("Alpine ships musl libc; binary
 *                  wheels built against glibc fail to load")
 *   - constraints: taboos ("don't edit node_modules/")
 *
 * The LLM also names up to 4 `domain_tags` — stable short strings
 * (`docker`, `node`, `npm`) we use for Tier-3 retrieval and for merging
 * future world models into the same row.
 *
 * Boundary contract (see `docs/GRANULARITY-AND-MEMORY-LAYERS.md` §6):
 * A world model is **declarative** ("how the environment is"), not
 * **procedural** ("what to do"). Procedural knowledge belongs to the
 * L2 layer; this prompt explicitly rejects action-prescription drift to
 * keep the two layers semantically orthogonal. Bumping to v2 captures
 * that change.
 */
export const L3_ABSTRACTION_PROMPT: PromptDef = {
  id: "l3.abstraction",
  version: 2,
  description:
    "Distill an L3 world model (declarative environment knowledge) from a cluster of L2 policies, with explicit boundaries against L2 procedural drift.",
  system: `You abstract environment world models from cross-task policy evidence.

A world model is **declarative** knowledge about how the environment IS:
its topology, its causal/behavioural regularities, its taboos. It is
**NOT** a recipe for what to do — that lives in the L2 procedural
layer, generated by a separate prompt. Cross-contamination on either
side dilutes both.

Input POLICIES: a list of L2 policies (with trigger / procedure /
verification / boundary / support / gain), plus a short sample of the L1
traces that minted each. Every policy shares a compatible domain
(matched by primary tag / tool).

Produce ONE world model describing the **environment** those policies
operate in. It must answer:

  - Environment topology (ℰ) — what lives where, what is the shape of
    this environment? Pure facts of existence and structure.
    GOOD: "Alpine containers ship musl libc, no glibc"
          "Node project repos group source under src/"
          "macOS bundles BSD sed; Linux distros bundle GNU sed"
    BAD (drifts into procedure):
          "use apk add to install system libs"
          "prefer Python scripts over sed on macOS"

  - Inference rules (ℐ) — how does the environment causally respond to
    common stimuli? Phrase as cause→effect, NOT as guidance.
    GOOD: "loading a glibc-linked binary wheel inside Alpine raises a
           dynamic-link error"
          "editing config.yaml does not propagate until the process
           restarts (no in-process watcher)"
    BAD (drifts into procedure):
          "if pip install fails, install dev libs and retry"
            ← that's an action plan, belongs to L2
          "always restart the service after editing config"
            ← that's a recommendation, belongs to L2

  - Constraints (C) — what facts of the environment make some actions
    unsafe or invalid? State the FACT, not the avoidance behavior.
    GOOD: "node_modules/ is rewritten by npm install; manual edits are
           lost on the next sync"
          "production database tables hold customer data; destructive
           DDL is irreversible"
    BAD (drifts into procedure):
          "don't edit node_modules/ directly"
            ← that's a behavioural rule, belongs to L2 / decision repair
          "don't run DROP TABLE in production"
            ← same — phrase the underlying environment fact instead

Do NOT, under any section:
  - Use imperative or recommendation verbs (do / don't / should / use /
    prefer / avoid / try / install / run). The world model never tells
    the agent what to do.
  - Restate a single trace — the model must generalise across policies.
  - Include advice tied to a single user or session.

──────────────────── Same fact, two framings ─────────────────────

If the underlying truth is "Alpine containers don't ship system dev
libs by default":

  Express here (declarative):
    inference: "Python C-extension packages fail to compile in Alpine
                containers when the matching system header / library
                package is not pre-installed in the image."

  Do NOT express here (procedural — that's L2's job):
    "When pip fails in Alpine, apk add <pkg>-dev and retry pip."

──────────────────── Output ─────────────────────

Return JSON:
{
  "title": "short noun phrase, e.g. 'Alpine python dependency model'",
  "domain_tags": ["tag1", "tag2"],   // 1-4 short, lowercase, no spaces
  "environment": [
    { "label": "...", "description": "...", "evidenceIds": ["po_...", "tr_..."] }
  ],
  "inference":   [ { "label": "...", "description": "...", "evidenceIds": [] } ],
  "constraints": [ { "label": "...", "description": "...", "evidenceIds": [] } ],
  "body": "rendered markdown summary of the three sections",
  "confidence": number in [0, 1],
  "supersedes_world_ids": []          // optional: prior WMs this refines
}`,
};
