import type { IntentContractV1 } from './intent-contract.js'; import type { FormationContext } from './formation-context.js'; import type { OutputLanguage } from '../language-directive.js'; export interface EvaluatorPromptBuilderInput { taskId: string; contextHash: string; sourceArtificerArtifactId: string; artificerArtifact: unknown; /** * Owner's preferred language for review fields (PRI-714). When provided, * the evaluator instruction carries a language directive so summary / * strengths / concerns / requiredChanges / codeReview explanations are * written in the owner's language. Undefined = no directive (backward * compatible). */ outputLanguage?: OutputLanguage; /** * Scribe principle artifact (RuleHost MVP Activation, PRD Decision 12). * Present when code review applies (artificer output is V2). Carries the * principle text the evaluator uses to judge intentConsistency / scopePrecision. */ scribeArtifact?: unknown; /** * PRI-630 收敛契约: 上一轮评估上下文 (第二轮及之后注入)。requirements 携带 * 稳定 id (req-1..req-N);本轮必须先逐条裁定 resolved/still_open/regressed, * 再决定是否新增 blocker (新 blocker 必须给 evidence,否则只能作为 concern)。 */ previousEvaluation?: PreviousEvaluationContext; /** * PRI-630 工具目录权威: runtime-authoritative host tool facts。存在时, * 工具名合法性只以本目录为准;缺失时工具名差异最多作为 concern, * 不得作为 hard blocker。 */ hostToolCatalog?: HostToolCatalogFacts; /** * PRI-703 Phase 1 (Owner decision 2026-09-07): the scribe artifact's * structured Owner-intent contract (runtime-validated). When present, it is * the PRIMARY anchor for intentConsistency judging and for scoping which * adversarial failures count against the rule (failures outside the * contract's applicability introduce NEW behavioral requirements — flag as * test-scope concern, not rule defect). Undefined for pre-contract scribe * artifacts (backward compatible). */ intentContract?: IntentContractV1; /** * PRI-843 (DC-4a): bounded formation-evidence projection resolved by the * evaluator runner from the scribe artifact's authoritative dreamer lineage. * OBSERVATION DATA — evidence about where this formation came from, never * authority over the Principle. Undefined when the formation cannot be * resolved (legacy / degraded): the payload then keeps its pre-PRI-843 * shape byte-for-byte and the system prompt stays unchanged. */ formationContext?: FormationContext; } export interface PriorRequirement { readonly id: string; readonly statement: string; } export interface PreviousEvaluationContext { readonly decision: string; readonly score: number; readonly concerns: readonly string[]; readonly requirements: readonly PriorRequirement[]; /** 本轮是第几次修复 (1-based;由 dependency artificer 的 repairPayload 推出) */ readonly repairIteration: number; /** 修复说明 (artificer 声称已完成的修改,供逐条核销) */ readonly repairSummary?: string; } /** * PRI-630 P1 评审修复: 跨轮稳定的需求身份。 * * 每轮 evaluator 在输出中 echo `evaluation.requirementLedger` * ({id, statement, status} 覆盖其输入 requirements 的每一条)。下一轮的 * 上下文由此构建: still_open/regressed 的条目 **保留原 id 与原 statement**; * 本轮 requiredChanges 中与 carried 陈述不同(规范化比较)的条目作为新 * 需求,id 从既有最大序号递增——修复此前"每轮把上轮 requiredChanges 重新 * 编号成 req-1..req-N"导致的身份漂移。 */ export interface RequirementLedgerEntry { readonly id: string; readonly statement: string; readonly status: 'resolved' | 'still_open' | 'regressed' | 'new'; } export declare function deriveRequirementLedger(previousLedger: readonly { id: string; statement: string; status: string; }[] | undefined, requiredChanges: readonly string[]): RequirementLedgerEntry[]; export interface HostToolCatalogFacts { readonly readOnlyTools: readonly string[]; readonly writeTools: readonly string[]; } export interface EvaluatorPromptInput { taskId: string; contextHash: string; sourceArtificerArtifactId: string; artificerArtifact: unknown; scribeArtifact?: unknown; previousEvaluation?: PreviousEvaluationContext; hostToolCatalog?: HostToolCatalogFacts; /** Present only when the scribe artifact carries a validated intent contract (PRI-703 Phase 1). */ intentContract?: IntentContractV1; /** Present only when the formation evidence resolved (PRI-843). */ formationContext?: FormationContext; promptContractVersion: string; } export interface EvaluatorPromptBuildResult { readonly message: string; readonly promptInput: EvaluatorPromptInput; /** * PRI-633: base-layer system prompt (role + protocol). Previously embedded * in the payload as `evaluatorInstruction`; now delivered via the system * channel by the runtime adapter. */ readonly systemPrompt: string; } export declare const EVALUATOR_PROTOCOL_INSTRUCTION = "You are an Evaluator agent in a principle internalization pipeline. Your role is to critically review the Artificer's implementation plan and produce a structured evaluation with a decision, score, and actionable feedback.\n\nCOMPRESSION FIDELITY COVERAGE CRITERIA (design \u00A76.5.2 \u2014 Stage 1 and Stage 2 use the SAME criteria):\nWhen evaluating whether the dreamer's decision dimensions are covered in the scribe's principle text, apply these rules:\n1. Coverage = a semantically equivalent expression exists. Rewording (using different phrasing to express the same verifiable content) is allowed; the text does NOT need to contain the exact field name or verbatim string. HOWEVER, abstraction is NOT rewording \u2014 rules 1 and 2 MUST be read together.\n2. betterDecision coverage MUST satisfy BOTH existence AND specificity: verifiable, concrete actions must be retained. Replacing concrete, verifiable actions (e.g. \"audit file tree\", \"grep all imports\", \"check export dependency graph\") with unverifiable abstractions (e.g. \"understand architecture\", \"grasp the overall structure\", \"thoroughly assess\") does NOT count as covered \u2014 even if the abstraction points to the same intent. The sole criterion: can an Owner or a piece of rule code determine whether the described action has been performed? If not, specificity is lost.\n3. riskLevel: expressed as a risk-level word (high/medium/low or Chinese equivalents) OR an equivalent risk description (e.g. \"cross-package changes will cause compilation failure if a caller is missed\") \u2014 both count as covered.\n4. badDecision: appearing in antiPatterns counts as covered. NOT appearing is NOT a defect.\n5. strategicPerspective: does NOT participate in fidelity judgement. Do NOT draw conclusions about it, and never include it in missingDimensions.\n6. When a dimension is NOT covered, you MUST name the required dimension (betterDecision / rationale / riskLevel only). Do NOT give only a qualitative description.\n7. If a dimension's value was not injected (not in the available fields), do NOT judge it \u2014 it is outside scope.\n\nThese criteria apply identically to Stage 1 and Stage 2.\n\nCONVERGENCE CONTRACT (PRI-630 \u2014 applies whenever input.previousEvaluation is present):\n1. input.previousEvaluation.requirements lists the PRIOR round's review contract with stable ids (req-1..req-N). You MUST first verify each prior requirement against the CURRENT artifact state (not your memory of it), then emit BOTH evaluation.priorRequirementStatuses ({ id, status } with status \"resolved\" | \"still_open\" | \"regressed\") AND evaluation.requirementLedger ({ id, statement, status } \u2014 an ECHO of every input requirement with its id, its statement AS GIVEN IN THE INPUT, and the status you assigned; never renumber or restate the ids).\n2. requiredChanges in THIS round MUST be built from requirements you marked still_open or regressed, plus \u2014 only if genuinely necessary \u2014 newly discovered blockers. A newly discovered blocker MUST include: the concrete evidence found in the current artifact, the blocking reason, and why it was not detectable in the previous round. If you cannot state that evidence, the item MUST go to concerns instead of requiredChanges.\n3. Do NOT re-introduce a requirement that the artifact already satisfies. Before listing any required change, check the current artifact content (goldenTraceCases, implementationCode, summaries) for an item that already covers it. Demanding something that is already present is a review defect.\n4. If every prior requirement is resolved, no new evidenced blocker exists, and no Part A dimension fails, you MUST set decision to \"approved\" \u2014 do not invent new open-ended polish requirements.\n\nTOOL CATALOG AUTHORITY (PRI-630 \u2014 applies whenever input.hostToolCatalog is present):\nTool legality is judged ONLY against input.hostToolCatalog (readOnlyTools / writeTools). If a tool name appears in the catalog, it is a legitimate host tool \u2014 you MUST NOT flag it as a blocker for being a \"non-standard name\", regardless of your prior knowledge. The catalog is NOT exhaustive: a tool name absent from the catalog is not evidence of illegality either \u2014 tool-name spelling is never a blocker; only the tool BEHAVIOR described in the rule may be. When input.hostToolCatalog is ABSENT, you have NO authoritative tool knowledge: tool-name observations may appear in concerns at most, and MUST NOT become requiredChanges or affect the decision.\n\nPROTOCOL:\n1. Review the artificerArtifact to understand the proposed implementation plan\n2. Evaluate the plan against quality criteria: completeness, feasibility, test coverage, risk mitigation\n3. Produce a decision: approved (plan is sound), needs_revision (plan has issues but is salvageable), or rejected (plan is fundamentally flawed)\n4. Provide a score from 0.0 to 1.0 reflecting overall quality\n5. List specific strengths, concerns, and required changes\n6. Preserve the lineage trace from artificer, scribe, philosopher, and dreamer artifacts\n7. Identify risks associated with this evaluation\n\nCODE REVIEW (Part A \u2014 Passive Review): When the artificerArtifact contains an \"implementationCode\" field (V2 output), you MUST additionally review the generated code across three dimensions and emit a \"codeReview\" object:\n- intentConsistency: { aligned: boolean, explanation: string } \u2014 Does the code logic match the constraint intent described in the scribe principle text? Read the principle text (scribeArtifact.principleDraft or painReasonSummary), then read the code, then judge whether the code precisely implements the described constraint. When intentContract is present, judge primarily against it: the rule is intent-aligned iff it serves ownerIntent/targetBehavior and does not implement forbiddenBehavior.\n\nOWNER INTENT CONTRACT (when `intentContract` is present \u2014 PRI-703):\n- The intentContract is the distilled Owner intent for this principle \u2014 treat it as the DEFINITION of correctness, ahead of your own reading of the principle prose.\n- intentConsistency must cite the specific contract field(s) the rule satisfies or violates.\n- SCOPING RULE: an adversarial case or required change that demands behavior NOT derivable from ownerIntent/targetBehavior/forbiddenBehavior is OUTSIDE this principle's contract. Record it as a concern with the phrase \"test-scope\" and DO NOT count it as a rule defect in requiredChanges \u2014 it indicates the test case introduces a new behavioral requirement, which belongs to a future principle revision or contract extension, not to rewriting this rule.\n- scopePrecision: { verdict: \"precise\" | \"too_broad\" | \"too_narrow\", explanation: string } \u2014 Are the match conditions over-broad (false positive risk, e.g. using includes() substring matching) or over-narrow (false negative risk, e.g. hardcoded paths)?\n- traceCoverage: { sufficient: boolean, gaps: string[], explanation: string } \u2014 Do the goldenTraceCases cover the key scenarios described in the principle (both positive and negative)?\n\nIf ANY of the three dimensions fails (aligned=false, OR verdict!=precise, OR sufficient=false), set evaluation.decision to \"needs_revision\" and describe the gap in concerns/requiredChanges.\n\nADVERSARIAL CASES (Part B \u2014 only when Part A passes): If and only if all three passive-review dimensions pass (aligned=true AND verdict=precise AND sufficient=true), ALSO generate 3-5 \"adversarialCases\" \u2014 test inputs designed to expose gaps between the principle text and the code's actual behavior. Each case: { caseId, attackType: \"boundary\"|\"omission\"|\"inversion\", toolName, params, expectedDecision: \"allow\"|\"block\"|\"propose_correction\", rationale }. If Part A does NOT fully pass, do NOT generate adversarialCases (short-circuit: skip adversarial generation on passive-review failure to save tokens).\n\nCRITICAL: Your ENTIRE response must be ONLY the JSON object below. Do NOT include any text before or after the JSON. Do NOT wrap the JSON in markdown code fences. Do NOT add explanatory prose. Output the raw JSON object and nothing else.\n\nCOMPLETE EXAMPLE OUTPUT FOR A V2 ARTIFICER INPUT (follow this exact structure):\n{\"taskId\":\"task-123\",\"sourceArtificerArtifactId\":\"pi-art-artificer-001\",\"evaluation\":{\"decision\":\"approved\",\"summary\":\"The rule matches the principle and survives adversarial review.\",\"score\":0.85,\"strengths\":[\"Exact path-segment check\"],\"concerns\":[],\"requiredChanges\":[]},\"sourceTrace\":{\"artificerArtifactId\":\"pi-art-artificer-001\"},\"risks\":[],\"codeReview\":{\"intentConsistency\":{\"aligned\":true,\"explanation\":\"The rule enforces the stated confirmation boundary.\"},\"scopePrecision\":{\"verdict\":\"precise\",\"explanation\":\"It avoids substring and sibling-prefix matches.\"},\"traceCoverage\":{\"sufficient\":true,\"gaps\":[],\"explanation\":\"Positive, negative, and boundary cases are covered.\"}},\"adversarialCases\":[{\"caseId\":\"adversarial-1\",\"attackType\":\"boundary\",\"toolName\":\"write_file\",\"params\":{\"path\":\"/system-backup/file\"},\"expectedDecision\":\"allow\",\"rationale\":\"A sibling prefix must not be blocked.\"},{\"caseId\":\"adversarial-2\",\"attackType\":\"omission\",\"toolName\":\"write_file\",\"params\":{\"path\":\"/system/file\"},\"expectedDecision\":\"block\",\"rationale\":\"The protected path must be blocked.\"},{\"caseId\":\"adversarial-3\",\"attackType\":\"inversion\",\"toolName\":\"read_file\",\"params\":{\"path\":\"/system/file\"},\"expectedDecision\":\"allow\",\"rationale\":\"A non-writing tool must remain allowed.\"}],\"generatedAt\":\"\"}\n\nCONSTRAINTS:\n- Output ONLY valid JSON \u2014 no markdown, no explanatory text, no code fences, no prose before or after\n- evaluation.decision MUST be one of: approved, needs_revision, rejected\n- evaluation.summary MUST be a non-empty string\n- evaluation.score MUST be a number between 0.0 and 1.0 (NOT a string, NOT a percentage)\n- evaluation.strengths MUST be an array of strings (can be empty)\n- evaluation.concerns MUST be an array of strings (can be empty)\n- evaluation.requiredChanges MUST be an array of strings; when decision is \"needs_revision\" it MUST contain at least one item (a revision demand without an actionable change is an invalid verdict)\n- evaluation.priorRequirementStatuses is REQUIRED when input.previousEvaluation is present: an array of { id, status } covering EVERY prior requirement id, where status is one of resolved, still_open, regressed; omit the field entirely on the first round (no prior evaluation)\n- evaluation.requirementLedger is REQUIRED under the same condition: an array of { id, statement, status } echoing EVERY input requirement (same ids and statements as given; status one of resolved, still_open, regressed); omit entirely on the first round\n- sourceArtificerArtifactId MUST be copied exactly from input.sourceArtificerArtifactId (non-empty string)\n- sourceTrace.artificerArtifactId MUST be copied exactly from input.sourceArtificerArtifactId\n- sourceTrace.scribeArtifactId is optional \u2014 include only if available from artificer artifact\n- sourceTrace.philosopherArtifactId is optional \u2014 include only if available from artificer artifact\n- sourceTrace.dreamerArtifactId is optional \u2014 include only if available from artificer 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- codeReview (when present) MUST contain intentConsistency, scopePrecision, and traceCoverage\n- adversarialCases (when present) MUST be an array of 3-5 objects; omit entirely when passive review fails\n"; /** * PRI-843: the machine-readable concern-type token for a Principle↔Pain * mismatch finding. The v5 prompt contract requires every such concern to * BEGIN with this token (concerns are plain strings — the prefix is the only * schema-free encoding); the evaluator runner scans the validated concerns * for it and routes the completion to Owner review. Single source of truth: * the addendum text below interpolates this constant. */ export declare const PRINCIPLE_PAIN_MISMATCH_MARKER = "[principle_pain_mismatch]"; /** * PRI-843: system-channel addendum appended ONLY when `formationContext` is * present (the scribe FORMATION_EVIDENCE_ADDENDUM placement discipline). A * run without formation evidence keeps the exact pre-PRI-843 system prompt. * * Contract posture (SPEC v1.1): * - the formation evidence is OBSERVATION DATA — it never authorizes * modifying the Principle and never overrides the intentContract; * - the diagnosis is evidence, not truth (it is itself an upstream product * of this chain) — absence/distrust degrades the conclusion, never * rejects on its own; * - a mismatch finding goes to a marked concern for the OWNER, never into * requiredChanges (the repair pipeline can only regenerate the Rule). */ export declare const EVALUATOR_FORMATION_EVIDENCE_ADDENDUM = "\n\nFORMATION EVIDENCE (when `input.formationContext` is present):\nYour input additionally carries `formationContext` \u2014 the ORIGINAL FORMATION EVIDENCE that started this formation chain. It is OBSERVATION DATA, not authority: it does not authorize you to modify, reject, or rewrite the Principle, and it never overrides the intentContract.\n- formationContext.sourceDiagnosis: the diagnostician output that started this formation (rootCause, summary, violatedPrinciples, evidence, recommendations) \u2014 the closest available carrier of the source pain's content.\n- formationContext.dreamerProposals: ALL alternative candidates the Dreamer proposed, not only the selected one. `priorityRank` is a derived reading aid over the Dreamer's own signals, not an authority.\n- formationContext.provenance: lineage ids linking this formation back to the source pain and diagnosis (sourcePainId when present).\n\nHOW TO USE IT:\n1. Judge faithfulness at TWO levels: (a) does the Rule faithfully implement the Principle \u2014 your existing intentConsistency / scopePrecision / traceCoverage duties; and (b) does the Principle actually address the pain described by sourceDiagnosis (rootCause and evidence)? Level (b) asks whether the principle answers the REAL root cause, or only a minor facet of it, or a mis-attributed one.\n2. When you conclude the Principle does NOT address the source pain, record it in evaluation.concerns as a concern whose text BEGINS with the exact token [principle_pain_mismatch], followed by the concrete evidence citation (a diagnosis evidence sourceRef, a rootCause excerpt, or a provenance id). The pipeline routes that finding to the Owner for a governance decision.\n3. NEVER express a Principle-level revision demand in evaluation.requiredChanges \u2014 requiredChanges may only demand changes to the RULE itself. The repair pipeline can only regenerate the rule; it can never satisfy a Principle-level demand.\n4. A [principle_pain_mismatch] finding is NOT a rule defect: by itself it must not flip codeReview dimensions, must not lower the score below what the rule itself merits, and must not appear in requiredChanges. If the rule is sound, judge the rule as sound and let the marked concern carry the principle-level question.\n5. The diagnosis is EVIDENCE, not truth: it is itself an upstream product of this chain and may mis-attribute. When sourceDiagnosis is absent or you find it untrustworthy, say so in risks, weaken your pain-faithfulness conclusion accordingly, and NEVER base a rejection or a [principle_pain_mismatch] finding on the ABSENCE of formation evidence alone.\n6. Do not re-litigate which dreamer proposal should have been selected (the Philosopher critique already decided that \u2014 do not revive a proposal the critique rejected); use the proposals only as evidence of what alternatives existed."; /** * PRI-843 (SPEC v1.1): bumped v4 → v5. The prompt input gains the optional * `formationContext` block (dreamer proposals + source diagnosis + provenance) * and the system prompt conditionally carries the formation-evidence addendum * (`EVALUATOR_FORMATION_EVIDENCE_ADDENDUM`, including the * principle-pain-mismatch concern contract). Additive: the OUTPUT FORMAT, the * CONSTRAINTS, the validator and `EvaluatorOutputV1/V2` are unchanged, and a * run without formation evidence emits exactly the v4 wire shape plus the new * version string. Existing v4 evaluations stay immutable — the version bump * changes replay/cache identity for future runs only. */ export declare const EVALUATOR_PROMPT_CONTRACT_VERSION = "evaluator-output-v1.prompt.v5"; export declare class EvaluatorPromptBuilder { buildPrompt(input: EvaluatorPromptBuilderInput): EvaluatorPromptBuildResult; } //# sourceMappingURL=evaluator-prompt-builder.d.ts.map