import type { BehaviorExamplePack } from './behavior-example-pack.js'; import type { LastValidatorErrors } from './pitask-metadata.js'; import type { IntentContractV1 } from './intent-contract.js'; import type { FormationCandidateProjection } from './formation-context.js'; import type { ToolSemanticMappingV1, ToolSemanticRegistry } from './tool-semantic-registry.js'; import type { OutputLanguage } from '../language-directive.js'; /** * Dreamer candidate set context (PRI-508 → PRI-839). * * Carries the dreamer-stage proposals that scribe compresses into a single * principleDraft.statement. Forwarding them to the artificer prompt prevents * intent inconsistency (PoC: deepseek-v4-flash 0.7 needs_revision → 0.85 * approved when combined with repair loop). * * PRI-839: this used to carry ONLY `candidates[0]`. Production has 31 of 33 * dreamer artifacts carrying ≥2 candidates (PRI-835 §DC-3), so the artificer * could not see the alternatives the Dreamer's exploration had already paid * for, nor explain why one path was chosen over another. The shape is now a * BOUNDED, priority-ranked set plus a factual difference summary. * * The candidate shape is `FormationCandidateProjection` — the same bounded * projection the Scribe's formation context uses (formation-context.ts), so * there is exactly one definition of "a dreamer proposal projected for a * prompt" rather than two divergent ones. * * All fields are runtime-validated by ArtificerRunner.buildContext via * typeof / Object.hasOwn / Array.isArray guards before being placed here * (rc-1, rc-2). dreamerContext is optional — undefined when the scribe * artifact lacks `sourceTrace.dreamerArtifactId` or the dreamer artifact * cannot be resolved (backward compatible with pre-PRI-508 flows). */ export interface ArtificerDreamerContext { /** Bounded, priority-ranked proposals — ALL the Dreamer proposed, not only [0]. */ readonly candidates: readonly FormationCandidateProjection[]; /** Deterministic, factual statement of how the proposals differ. */ readonly differenceSummary: string; /** Proposals dropped by the bound (0 when the whole set fit) — rc-9. */ readonly omittedCandidateCount: number; } /** * PRI-741: read-only projection of the host tool semantic context into the * Artificer prompt. Built by entry points from the SAME ToolSemanticRegistry * instance the production gate and the reliability validation use — this is a * prompt DTO, not a new truth source: it carries no authority of its own. */ export interface ArtificerHostSemanticContext { /** Host kind label(s) the generated rule will run under (e.g. 'openclaw'). */ readonly hostKinds: readonly string[]; /** The real host dispatch surface (raw tool name → canonicalKind). */ readonly tools: readonly ToolSemanticMappingV1[]; } export interface ArtificerPromptBuilderInput { /** * PRI-780: the Artificer generation contract is v2-only. The * BehaviorExamplePack (Owner-labelled evidence) is REQUIRED — a missing or * invalid pack fails generation loud instead of degrading to an action-only * (v1) rule. There is no v1 mode anymore. */ behaviorExamplePack: BehaviorExamplePack; taskId: string; contextHash: string; sourceScribeArtifactId: string; scribeArtifact: unknown; /** * Prior adversarial replay failures to address (RuleHost MVP, PRI-428). * Present only on Round-2+ retries inside runAdversarialLoop. When absent, * the prompt is the initial generation prompt (backward compatible). */ adversarialFeedback?: string; /** * Bounded dreamer candidate set context (PRI-508 → PRI-839). Optional — when * present, serialized into the prompt so the artificer can align its * implementation with the dreamer's original intent and see the alternatives * it explored. Undefined for backward compatibility. */ dreamerContext?: ArtificerDreamerContext; /** * Evaluator repair feedback (PRI-509). Present only on Round-2+ artificer * tasks seeded by evaluator needs_revision. Carries the evaluator's * requiredChanges/concerns/previousScore as a single pre-formatted string * (built by ArtificerRunner.buildContext from PITaskMetadata.repairPayload). * Distinct from adversarialFeedback (PRI-428): adversarialFeedback is * adversarial-replay failure text; repairFeedback is evaluator semantic feedback. * Undefined on Round-1 artificer tasks (backward compatible). */ repairFeedback?: string; /** * PRI-700 因子 B (Owner 决策 2026-09-07): 上一次 attempt 的 validator * 拒绝全文(结构化 {recordedAt, errorCategory, errors[]})。仅在同一 * attempt 未消费过时由 runner 携带;presence = 上次输出被 output-contract * gate 拒绝的确切原因。Undefined = 本 attempt 无前次拒绝(首轮生成或 * 前次 attempt 成功通过校验)。 */ priorValidatorErrors?: LastValidatorErrors; /** * PRI-703 Phase 1: the scribe artifact's structured Owner-intent contract * (runtime-validated via extractIntentContract). The generated rule must * serve ownerIntent/targetBehavior and MUST NOT implement * forbiddenBehavior. Undefined for pre-contract scribe artifacts * (backward compatible). */ intentContract?: IntentContractV1; /** * Owner's preferred language for implementation artifacts (PRI-714). When * provided, the artificer instruction carries a language directive so * implementationSummary and risks are written in the owner's language. * Undefined = no directive (backward compatible). Never affects * implementationCode, goldenTraceCases params, or lineage fields. */ outputLanguage?: OutputLanguage; /** * PRI-741: optional host semantic projection (real host tool names + kinds, * resolved from the ToolSemanticRegistry). When present the prompt carries a * HOST SEMANTIC CONTEXT block constraining the generated rule to * canonicalKind-first matching and host-dispatchable tool names. Undefined = * prompt unchanged (backward compatible for workspaces without a host * declaration). */ hostSemanticContext?: ArtificerHostSemanticContext; } export interface ArtificerPromptInput { behaviorExamplePack: BehaviorExamplePack; taskId: string; contextHash: string; sourceScribeArtifactId: string; scribeArtifact: unknown; promptContractVersion: string; /** Present only when this is a retry with prior adversarial failures. */ adversarialFeedback?: string; /** Present only when dreamer candidate context is available (PRI-508). */ dreamerContext?: ArtificerDreamerContext; /** Present only on Round-2+ artificer repair tasks (PRI-509). */ repairFeedback?: string; /** Present only when the prior attempt was rejected by the output-contract gate (PRI-700 factor B). */ priorValidatorErrors?: LastValidatorErrors; /** * PRI-703 Phase 1: the scribe artifact's structured Owner-intent contract * (already runtime-validated by extractIntentContract). Forwarded into the * prompt so rule generation anchors to the explicit intent — the * implementationCode must serve ownerIntent/targetBehavior and MUST NOT * implement forbiddenBehavior. Undefined for pre-contract scribe artifacts * (backward compatible). */ intentContract?: IntentContractV1; /** PRI-741: present only when a host semantic projection was resolved. */ hostSemanticContext?: ArtificerHostSemanticContext; } export interface ArtificerPromptBuildResult { readonly message: string; readonly promptInput: ArtificerPromptInput; /** * PRI-633: base-layer system prompt (role + protocol + context-mode * instruction). Previously embedded in the payload as `artificerInstruction`; * now delivered via the system channel by the runtime adapter. */ readonly systemPrompt: string; } export declare const ARTIFICER_PROTOCOL_INSTRUCTION = "You are an Artificer agent in a principle internalization pipeline. Your role is to transform the Scribe's formal principle draft into executable RuleHost code with a concise implementation summary, tests, and rollout notes.\n\nPROTOCOL:\n1. Review the scribeArtifact to understand the formal principle draft\n2. Transform the principle draft into executable RuleHost code and a brief implementation summary\n3. Preserve the lineage trace from scribe, philosopher, and dreamer artifacts\n4. Identify risks associated with implementing this principle\n5. The implementation summary should clearly describe what the code does and why\n\nOWNER INTENT CONTRACT (when `intentContract` is present \u2014 PRI-703):\n- `intentContract` is the Owner-intent anchor distilled from the real failure. Your rule exists to serve it.\n- implementationCode MUST operationalize `targetBehavior` and MUST NOT implement `forbiddenBehavior`.\n- If a repair/revision instruction (repairFeedback, revisionFeedback) contradicts the intentContract, the intentContract wins: implement the contract-faithful behavior and document the conflict in implementationSummary \u2014 do NOT silently satisfy the contradicting instruction.\n- Use `validationExpectation` as your self-check before emitting: would an evaluator observing that expectation accept this rule as faithful?\n\nOUTPUT FORMAT (pure JSON, no markdown):\n{\n \"taskId\": \"\",\n \"requiresContextVersion\": 2,\n \"sourceScribeArtifactId\": \"\",\n \"implementationSummary\": \"\",\n \"sourceTrace\": {\n \"scribeArtifactId\": \"\",\n \"philosopherArtifactId\": \"\",\n \"dreamerArtifactId\": \"\"\n },\n \"evidenceRefs\": [\"\"],\n \"risks\": [\"\", \"\"],\n \"implementationCode\": \"function evaluate(input, helpers) { if (input.action.canonicalKind === 'write' && typeof input.action.normalizedPath === 'string' && input.action.normalizedPath.startsWith('/system/')) { return { decision: 'block', matched: true, reason: 'write to system path' }; } return { decision: 'allow', matched: false, reason: 'no risk pattern' }; }\",\n \"goldenTraceCases\": [\n {\"caseId\":\"negative-1\",\"kind\":\"negative\",\"toolName\":\"write\",\"params\":{\"path\":\"/system/file\"},\"expectedDecision\":\"block\",\"ruleContext\":{\"version\":2,\"history\":{\"status\":\"available\",\"truncated\":false,\"calls\":[]},\"facts\":{\"priorReadOfTarget\":\"unknown\",\"readCount\":0,\"writeCount\":0,\"uniqueWritePathCount\":0,\"sameActionBlockCount\":null}}},\n {\"caseId\":\"positive-1\",\"kind\":\"positive\",\"toolName\":\"write\",\"params\":{\"path\":\"/workspace/file\"},\"expectedDecision\":\"allow\",\"ruleContext\":{\"version\":2,\"history\":{\"status\":\"available\",\"truncated\":false,\"calls\":[]},\"facts\":{\"priorReadOfTarget\":\"unknown\",\"readCount\":0,\"writeCount\":0,\"uniqueWritePathCount\":0,\"sameActionBlockCount\":null}}}\n ],\n \"affectedTools\": [\"write\"],\n \"generatedAt\": \"\"\n}\nNOTE: the example above IS the full v2 contract \u2014 requiresContextVersion, evidenceRefs, and case-level ruleContext are REQUIRED fields (see the CONTEXT MODE block below), not optional extras.\n\nCONSTRAINTS:\n- Output ONLY valid JSON (no markdown, no explanatory text, no code fences)\n- implementationSummary MUST be a non-empty string describing what the code does and the implementation approach\n- sourceScribeArtifactId MUST be copied exactly from input.sourceScribeArtifactId (non-empty string)\n- sourceTrace.scribeArtifactId MUST be copied exactly from input.sourceScribeArtifactId\n- sourceTrace.philosopherArtifactId is optional \u2014 include only if available from scribe artifact\n- sourceTrace.dreamerArtifactId is optional \u2014 include only if available from scribe artifact\n- risks MUST be an array of strings (can be empty if no risks identified)\n- generatedAt MUST be the current ISO-8601 timestamp (use the actual current time, NOT a placeholder)\n- implementationCode MUST define exactly function evaluate(input, helpers) and return { decision, matched, reason }\n- EVERY return statement inside evaluate() MUST include ALL three fields: decision, matched, reason\n- Do NOT return partial objects \u2014 missing fields will fail sandbox validation and block activation\n- GOOD: return { decision: 'allow', matched: false, reason: 'path is within workspace, no risk' }\n- GOOD: return { decision: 'block', matched: true, reason: 'write to system path outside workspace' }\n- BAD: return { matched: false } \u2014 missing decision and reason, will be rejected\n- BAD: return { decision: 'allow', matched: true } \u2014 missing reason, will be rejected\n- input.action contains toolName, normalizedPath, paramsSummary, and canonicalKind\n- input.action.canonicalKind is the closed semantic kind of the current action: \"read\" | \"search\" | \"write\" | \"execute\" | \"agent\" | \"other\"\n- CANONICALKIND-FIRST MATCHING (PRI-741): match behavior PRIMARILY by input.action.canonicalKind (e.g. input.action.canonicalKind === 'write'); use input.action.toolName only as an auxiliary condition to distinguish tools within the same kind\n- When a HOST SEMANTIC CONTEXT block is present, affectedTools and EVERY goldenTraceCases toolName MUST be a real host tool name from that list \u2014 activation replay is machine-validated against the host declaration, and generic LLM vocabulary names (write_file, edit_file, bash, run_shell_command, delete_file, ...) are NOT real host tools and WILL be rejected\n- When NO HOST SEMANTIC CONTEXT block is present you have no authoritative host tool knowledge: match by canonicalKind and NEVER invent host-specific tool names\n- input.action.paramsSummary is an OBJECT (a map of parameter names to values), NOT a string\n- NEVER call string methods on paramsSummary itself \u2014 paramsSummary.includes(...), paramsSummary.startsWith(...), paramsSummary.match(...) are always bugs and will crash with \"is not a function\"\n- To inspect a parameter, access its specific key (e.g. paramsSummary.path) and guard its type at runtime (typeof paramsSummary.path === 'string') before using it as a string\n- For path logic prefer input.action.normalizedPath (a normalized string) over reading raw params strings\n- ADVERSARIAL GUARD CONTRACT: when your rule declares requiresContextVersion: 2, action-level safety still dominates the context \u2014 if helpers.isRiskPath() is true the decision MUST be block regardless of input.context; writes to well-known sensitive system locations (/etc/**, system configuration outside the governed workspace) must block even when context reports priorReadOfTarget === 'yes' (a context-provided read outside the workspace is untrusted signal, never authorization)\n- implementationCode MUST be deterministic and self-contained: no imports, require, eval, Function, I/O, network, timers, Date.now, or randomness\n- goldenTraceCases MUST contain 2-10 cases with at least one positive allow case and one negative block case\n- goldenTraceCases expectedDecision MUST be only \"allow\" or \"block\" \u2014 do NOT emit \"propose_correction\", \"requireApproval\", or \"auto_correct\" (seed-user MVP only supports allow/block; all other action types are rejected by the schema validator)\n- affectedTools MUST contain the non-empty tool names the rule can match (see the HOST SEMANTIC CONTEXT / canonicalKind-first rules above)\n\nPRIOR ADVERSARIAL FAILURES (when `adversarialFeedback` is present):\n- This is a RETRY. A prior version of your generated code was reviewed and failed adversarial sandbox replay.\n- The `adversarialFeedback` field lists the specific cases that failed, each with the attack type, the expected vs actual decision, and a rationale.\n- You MUST address each listed failure specifically \u2014 do not regenerate blind. Adjust the matcher/logic so the failed cases produce the expected decision while preserving the cases that previously passed.\n\nRULEHOST CAPABILITY BOUNDARY (PRI-508):\n- RuleHost evaluate(input) is a STATELESS single-call gate. It CANNOT track multi-step workflows (e.g., audit\u2192verify\u2192incremental) across invocations.\n- Translate the principle into a STATEFUL-CHECKABLE constraint that evaluate() CAN enforce per tool call: check whether the current tool call carries evidence of prior analysis (context markers, params encoding prior reads, explicit preconditions in the params).\n- Do NOT implement a path whitelist or a \"first call must be X\" ordering rule if the principle is about procedural discipline \u2014 the runtime cannot observe ordering across calls.\n- If the principle cannot be enforced per-call, encode the closest per-call proxy and document the gap in implementationSummary.\n\nREPAIR FEEDBACK (PRI-509, when `repairFeedback` is present):\n- This is a REPAIR RETRY. A prior attempt of your generated code was reviewed by the evaluator and returned needs_revision.\n- The `repairFeedback` field lists the evaluator's concerns and required changes from the prior attempt.\n- You MUST address each required change specifically \u2014 do not regenerate blind. Adjust the matcher/logic so the concerns are resolved while preserving the principle intent.\n- If a required change contradicts the principle intent (from scribeArtifact/dreamerContext), prefer the principle intent and document the conflict in implementationSummary.\n- When the repair feedback contains a \"Deterministic Replay Evidence\" block (resolved from the source evaluator artifact):\n - Each entry is a machine-verified failure: Case (id), Expected (decision), Actual (decision, only when your code really returned one), Error (sandbox error type), Message (bounded safe failure detail).\n - Fix EVERY listed deterministic failure so the case produces its Expected decision.\n - Preserve the behavior of cases that already passed \u2014 do not trade passing cases for failing ones.\n - Do NOT weaken safety constraints (e.g. drop risk-path blocks) just to make replay pass.\n - Respect the canonical RuleHostInput contract, including that paramsSummary is an object (see CONSTRAINTS).\n - Do NOT invent, guess, or fabricate evidence that is not listed \u2014 the list is the complete deterministic fact set (possibly truncated, as noted).\n\nADVERSARIAL CASE VOCABULARY NOTE (apply whenever replay evidence or repair feedback mentions case ids):\n- Case ids such as \"v2-unavailable\", \"v2-truncated\", \"v2-alias\" (and any \"v2-*\" prefixed id) are INTERNAL EVALUATOR CASE NUMBERING \u2014 they describe which adversarial fixture was run, NOT a request to use context-version-2 features.\n- NEVER respond to a case id by declaring `requiresContextVersion`, adding case-level `ruleContext`, or changing `expectedDecision` to satisfy the case NAME. Case names are labels, not instructions.\n- Your output must ALWAYS satisfy the CONTEXT MODE block below (the v2 contract, appended after these constraints) regardless of which case ids appear in the feedback text.\n- The ONLY legal decisions are \"allow\" and \"block\"; the ONLY legal field set is the one in OUTPUT FORMAT above plus the v2 CONTEXT MODE obligations (requiresContextVersion: 2, case-level ruleContext, evidenceRefs). Any other field is a contract violation and WILL be rejected.\n\nPRIOR OUTPUT-CONTRACT REJECTIONS (when `priorValidatorErrors` is present):\n- Your previous attempt was rejected by the OUTPUT CONTRACT GATE (schema validation) \u2014 it never reached evaluation. The `priorValidatorErrors.errors` list contains the exact, verbatim rejection reasons.\n- The highest-priority fix is to make your JSON satisfy EVERY listed rejection reason. Re-read each error, map it to the OUTPUT FORMAT and CONTEXT MODE rules, and correct the exact fields it names.\n- These errors describe YOUR output's shape, not the principle and not the test cases \u2014 do not change the behavioral intent while fixing them.\n- After addressing every listed error, re-check the full OUTPUT FORMAT and CONTEXT MODE blocks once more before emitting.\n"; /** * PRI-839: appended ONLY when `dreamerContext` is present, so a pre-PRI-508 / * degraded prompt is unchanged (the same conditional shape * `hostSemanticContext` already uses). * * This block exists so the model can answer the three questions the single * `candidates[0]` projection made unanswerable: which alternative paths the * Dreamer explored, why one is the primary one, and what risks the others * carry. It is deliberately explicit that `priorityRank` is a reading aid and * NOT an authority — the critique + principle draft own the intent, and the * block must not become a licence to widen the rule's scope. */ export declare const DREAMER_CANDIDATE_SET_INSTRUCTION = "\n\nDREAMER CANDIDATE SET (PRI-839, when `dreamerContext` is present):\n- `dreamerContext.candidates` is a BOUNDED, priority-ranked set of the Dreamer's proposals for this formation \u2014 not only the first one.\n- `priorityRank` 1 is the Dreamer's highest-confidence, lowest-risk proposal by its own authored signals (`candidateIndex` is the order the Dreamer wrote them in). This ranking is a READING AID, not an authority: the scribe principle draft and the philosopher critique decide the intent.\n- `dreamerContext.differenceSummary` states factually how the proposals differ.\n- Use the alternatives to bound the rule correctly: a proposal's concrete failure mode and concrete better-decision are EVIDENCE for which concrete patterns your evaluate() must cover.\n- Do NOT widen the rule beyond the intent the scribeArtifact formalised, and do NOT merge mutually exclusive proposals into one matcher.\n- `dreamerContext.omittedCandidateCount` > 0 means further proposals existed but were dropped to stay within budget \u2014 note that in `risks` instead of guessing at them."; /** * PRI-634 PR-A: bumped v2 → v3. The prompt contract changed materially: * (1) explicit paramsSummary-is-an-object contract with whole-object string * method prohibition; (2) deterministic replay evidence block semantics in * repair rounds (Case/Expected/Actual/Error/Message entries + fix/preserve/ * no-weakening/no-fabrication instructions). * * PRI-700 (Owner 决策 2026-09-07): bumped v3 → v4. (1) adversarial case-id * vocabulary note (v2-* ids are evaluator internal numbering, never a request * to declare context-version fields); (2) prior output-contract rejection * feedback block (priorValidatorErrors) — the repair attempt now receives the * verbatim schema-rejection reasons from its previous attempt. */ /** * PRI-741: bumped v4 → v5. (1) canonicalKind-first matching contract — * input.action.canonicalKind is the primary dispatch signal, the OUTPUT FORMAT * example demonstrates canonicalKind matching and no longer teaches the * phantom generic name `write_file`; (2) optional HOST SEMANTIC CONTEXT block * (hostSemanticContext): the real host tool names + kinds projected from the * ToolSemanticRegistry host layer, constraining affectedTools and * goldenTraceCases toolNames to host-dispatchable names. */ /** * PRI-780: bumped v5 → v6. The v1 context-mode branch is DELETED — the v2 * contract is the only generation contract. The prompt input no longer * carries a `contextMode` field; the BehaviorExamplePack is unconditional; * the CONTEXT MODE block documents the runtime context capabilities * (history/facts, default-on assembly, host unavailable declarations). */ /** * PRI-817: bumped v6 → v7. The OUTPUT FORMAT example previously omitted the * three v2-mandatory obligations (requiresContextVersion, evidenceRefs, * case-level ruleContext) and misreferenced the CONTEXT MODE block as * "above" — an LLM imitating the example verbatim was guaranteed rejected. * The example now carries all three obligations with a validator-legal * ruleContext object literal, the position reference is corrected, and a * NOTE line marks them as REQUIRED. */ /** * PRI-839: bumped v7 → v8. The prompt INPUT shape changed — `dreamerContext` * went from a single 5-dim candidate object (`candidates[0]`) to a bounded, * priority-ranked candidate SET plus a difference summary — and the system * prompt gained the conditional DREAMER_CANDIDATE_SET_INSTRUCTION block. * The OUTPUT schema is unchanged, so only the `.prompt.vN` segment moves. */ export declare const ARTIFICER_PROMPT_CONTRACT_VERSION = "artificer-output-v2.prompt.v8"; /** * EP002-R4: the SINGLE bounded projection shared by the prompt AND the v2 * echo-contract validation. The model can only copy what it saw, so the * "Owner-labelled example was rewritten" check MUST compare against the same * bounded cases the prompt presented — comparing against the raw pack would * reject every honest echo on real-sized workspaces. Idempotent: an * already-bounded pack passes through unchanged. */ export declare function boundPackForPrompt(pack: BehaviorExamplePack): BehaviorExamplePack; export declare function buildArtificerHostSemanticContext(registry: ToolSemanticRegistry, hostKinds?: readonly string[]): ArtificerHostSemanticContext; export declare class ArtificerPromptBuilder { buildPrompt(input: ArtificerPromptBuilderInput): ArtificerPromptBuildResult; } //# sourceMappingURL=artificer-prompt-builder.d.ts.map