create-principles-disciple 1.144.11 → 1.144.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/_release/product-identity.json +1 -1
  2. package/codex-adapter/dist/pd-hook.js +23 -5
  3. package/codex-adapter/dist/worker/workspace-worker.d.ts +6 -0
  4. package/codex-adapter/dist/worker/workspace-worker.js +7 -0
  5. package/codex-adapter/package.json +1 -1
  6. package/console/dist/server/models/ApprovalsConsoleModel.d.ts +1 -1
  7. package/console/dist/server/models/ApprovalsConsoleModel.js +4 -4
  8. package/console/dist/server/models/ApprovalsGroupedConsoleModel.d.ts +5 -5
  9. package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +18 -18
  10. package/console/dist/shared/prompt-injection-contract.d.ts +5 -5
  11. package/console/dist/ui/pages/focus/FocusPage.js +1 -1
  12. package/console/dist/ui/pages/focus/focus-validation.js +1 -1
  13. package/console/dist/ui/utils/approval-warning-localization.js +1 -1
  14. package/console/dist/ui/utils/validators.d.ts +1 -1
  15. package/console/dist/ui/utils/validators.js +2 -2
  16. package/console/package.json +3 -3
  17. package/core/dist/principle-tree-ledger.d.ts +50 -0
  18. package/core/dist/principle-tree-ledger.d.ts.map +1 -1
  19. package/core/dist/principle-tree-ledger.js +133 -1
  20. package/core/dist/principle-tree-ledger.js.map +1 -1
  21. package/core/dist/runtime-v2/adapter/output-schema-registry.d.ts.map +1 -1
  22. package/core/dist/runtime-v2/adapter/output-schema-registry.js +4 -0
  23. package/core/dist/runtime-v2/adapter/output-schema-registry.js.map +1 -1
  24. package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts +24 -0
  25. package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.d.ts.map +1 -1
  26. package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js +36 -1
  27. package/core/dist/runtime-v2/adapter/principle-tree-ledger-adapter.js.map +1 -1
  28. package/core/dist/runtime-v2/bridge-result-shaper.d.ts +8 -0
  29. package/core/dist/runtime-v2/bridge-result-shaper.d.ts.map +1 -1
  30. package/core/dist/runtime-v2/bridge-result-shaper.js +61 -3
  31. package/core/dist/runtime-v2/bridge-result-shaper.js.map +1 -1
  32. package/core/dist/runtime-v2/candidate-intake-service.d.ts +152 -3
  33. package/core/dist/runtime-v2/candidate-intake-service.d.ts.map +1 -1
  34. package/core/dist/runtime-v2/candidate-intake-service.js +405 -47
  35. package/core/dist/runtime-v2/candidate-intake-service.js.map +1 -1
  36. package/core/dist/runtime-v2/candidate-intake.d.ts +44 -0
  37. package/core/dist/runtime-v2/candidate-intake.d.ts.map +1 -1
  38. package/core/dist/runtime-v2/candidate-intake.js +7 -0
  39. package/core/dist/runtime-v2/candidate-intake.js.map +1 -1
  40. package/core/dist/runtime-v2/config/index.d.ts +2 -2
  41. package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
  42. package/core/dist/runtime-v2/config/index.js +1 -1
  43. package/core/dist/runtime-v2/config/index.js.map +1 -1
  44. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts +7 -1
  45. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
  46. package/core/dist/runtime-v2/config/pd-config-defaults.js +11 -0
  47. package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
  48. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
  49. package/core/dist/runtime-v2/config/pd-config-effective.js +24 -1
  50. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
  51. package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -1
  52. package/core/dist/runtime-v2/config/pd-config-redaction.js +2 -0
  53. package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -1
  54. package/core/dist/runtime-v2/config/pd-config-types.d.ts +39 -0
  55. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
  56. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
  57. package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
  58. package/core/dist/runtime-v2/config/pd-config-validate.js +44 -0
  59. package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
  60. package/core/dist/runtime-v2/index.d.ts +14 -1
  61. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  62. package/core/dist/runtime-v2/index.js +21 -1
  63. package/core/dist/runtime-v2/index.js.map +1 -1
  64. package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
  65. package/core/dist/runtime-v2/pain-signal-bridge.js +107 -2
  66. package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
  67. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +29 -14
  68. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  69. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +215 -46
  70. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  71. package/core/dist/runtime-v2/principle-reuse/reuse-domain.d.ts +89 -0
  72. package/core/dist/runtime-v2/principle-reuse/reuse-domain.d.ts.map +1 -0
  73. package/core/dist/runtime-v2/principle-reuse/reuse-domain.js +16 -0
  74. package/core/dist/runtime-v2/principle-reuse/reuse-domain.js.map +1 -0
  75. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-output.d.ts +40 -0
  76. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-output.d.ts.map +1 -0
  77. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-output.js +97 -0
  78. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-output.js.map +1 -0
  79. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-runner.d.ts +111 -0
  80. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-runner.d.ts.map +1 -0
  81. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-runner.js +232 -0
  82. package/core/dist/runtime-v2/principle-reuse/reuse-evaluation-runner.js.map +1 -0
  83. package/core/dist/runtime-v2/principle-reuse/reuse-proposal.d.ts +87 -0
  84. package/core/dist/runtime-v2/principle-reuse/reuse-proposal.d.ts.map +1 -0
  85. package/core/dist/runtime-v2/principle-reuse/reuse-proposal.js +99 -0
  86. package/core/dist/runtime-v2/principle-reuse/reuse-proposal.js.map +1 -0
  87. package/core/dist/runtime-v2/principle-reuse/reuse-retrieval.d.ts +36 -0
  88. package/core/dist/runtime-v2/principle-reuse/reuse-retrieval.d.ts.map +1 -0
  89. package/core/dist/runtime-v2/principle-reuse/reuse-retrieval.js +118 -0
  90. package/core/dist/runtime-v2/principle-reuse/reuse-retrieval.js.map +1 -0
  91. package/core/dist/runtime-v2/principle-reuse/reuse-shortlist.d.ts +40 -0
  92. package/core/dist/runtime-v2/principle-reuse/reuse-shortlist.d.ts.map +1 -0
  93. package/core/dist/runtime-v2/principle-reuse/reuse-shortlist.js +184 -0
  94. package/core/dist/runtime-v2/principle-reuse/reuse-shortlist.js.map +1 -0
  95. package/core/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.d.ts +7 -0
  96. package/core/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.d.ts.map +1 -1
  97. package/core/dist/runtime-v2/store/pain-diagnosis/pain-diagnosis-store.js.map +1 -1
  98. package/core/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.d.ts +1 -0
  99. package/core/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.d.ts.map +1 -1
  100. package/core/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.js +12 -0
  101. package/core/dist/runtime-v2/store/pain-diagnosis/sqlite-pain-diagnosis-store.js.map +1 -1
  102. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +5 -0
  103. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  104. package/core/dist/runtime-v2/store/runtime-state-manager.js +8 -0
  105. package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  106. package/core/dist/runtime-v2/types/principle-schema.d.ts +65 -0
  107. package/core/dist/runtime-v2/types/principle-schema.d.ts.map +1 -1
  108. package/core/dist/runtime-v2/types/principle-schema.js +14 -0
  109. package/core/dist/runtime-v2/types/principle-schema.js.map +1 -1
  110. package/core/dist/runtime-v2/types/principle-tree-store.d.ts +12 -0
  111. package/core/dist/runtime-v2/types/principle-tree-store.d.ts.map +1 -1
  112. package/core/dist/telemetry-event.d.ts +2 -2
  113. package/core/dist/telemetry-event.d.ts.map +1 -1
  114. package/core/dist/telemetry-event.js +13 -0
  115. package/core/dist/telemetry-event.js.map +1 -1
  116. package/core/package.json +2 -2
  117. package/host-runtime/dist/index.d.ts +2 -0
  118. package/host-runtime/dist/index.js +1 -0
  119. package/host-runtime/dist/production-rulehost-gate.d.ts +1 -0
  120. package/host-runtime/dist/production-rulehost-gate.js +1 -1
  121. package/host-runtime/dist/prompt-injection-projection.d.ts +5 -5
  122. package/host-runtime/dist/prompt-injection-projection.js +4 -4
  123. package/host-runtime/package.json +1 -1
  124. package/package.json +3 -3
  125. package/pd-cli/dist/commands/candidate.d.ts +27 -0
  126. package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
  127. package/pd-cli/dist/commands/candidate.js +508 -14
  128. package/pd-cli/dist/commands/candidate.js.map +1 -1
  129. package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -1
  130. package/pd-cli/dist/commands/config-doctor.js +14 -0
  131. package/pd-cli/dist/commands/config-doctor.js.map +1 -1
  132. package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
  133. package/pd-cli/dist/commands/diagnose.js +84 -14
  134. package/pd-cli/dist/commands/diagnose.js.map +1 -1
  135. package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
  136. package/pd-cli/dist/commands/pain-retry.js +97 -14
  137. package/pd-cli/dist/commands/pain-retry.js.map +1 -1
  138. package/pd-cli/dist/index.js +16 -2
  139. package/pd-cli/dist/index.js.map +1 -1
  140. package/pd-cli/dist/services/config-doctor.d.ts +11 -0
  141. package/pd-cli/dist/services/config-doctor.d.ts.map +1 -1
  142. package/pd-cli/dist/services/config-doctor.js +6 -0
  143. package/pd-cli/dist/services/config-doctor.js.map +1 -1
  144. package/pd-cli/dist/services/resolve-runtime-from-pd-config.d.ts +14 -0
  145. package/pd-cli/dist/services/resolve-runtime-from-pd-config.d.ts.map +1 -1
  146. package/pd-cli/dist/services/resolve-runtime-from-pd-config.js +20 -4
  147. package/pd-cli/dist/services/resolve-runtime-from-pd-config.js.map +1 -1
  148. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts +6 -0
  149. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
  150. package/pd-cli/dist/services/runtime-adapter-resolver.js +11 -2
  151. package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
  152. package/pd-cli/package.json +1 -1
  153. package/plugin/dist/bundle.js +550 -546
  154. package/plugin/dist/openclaw.plugin.json +1 -1
  155. package/plugin/openclaw.plugin.json +1 -1
  156. package/plugin/package.json +5 -5
  157. package/release-manager/package.json +3 -3
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Reuse Evaluation Output — the Semantic Reuse Evaluation Capability's
3
+ * proposal contract (PRI-917 SPEC v0.3.2 §4.2).
4
+ *
5
+ * This is a PROPOSAL-ONLY contract: it is what the LLM-backed evaluation
6
+ * returns to the Owner's review surface, never what it can do. The word
7
+ * "decision" deliberately does NOT appear here — in the reuse chain,
8
+ * "decision" belongs exclusively to the Owner; this layer can only
9
+ * recommend (SPEC v0.3.2 §3 naming boundary).
10
+ *
11
+ * Pure contract + runtime validator, zero I/O. The runtime validator is the
12
+ * trust boundary for an UNTRUSTED LLM output (rc-1/rc-2/rc-3):
13
+ * - closed field set: ANY key outside the schema is rejected, so a model
14
+ * output can never smuggle persistence-ish fields (`reuseEvidence`,
15
+ * `write`, `persist`, ...) — T7a of SPEC v0.3.2 §11;
16
+ * - cross-field rules: `recommendation=reuse` REQUIRES
17
+ * `selectedPrincipleId`; `recommendation=uncertain` FORBIDS it.
18
+ *
19
+ * Deliberate deviation from SPEC v0.3.2 §4.2 ("合法 UUID 形状"): the
20
+ * validator does NOT assert a UUID shape on `selectedPrincipleId`, because
21
+ * bootstrap core principles carry `T-xx` ids in the live ledger — a UUID
22
+ * assertion would wrongly reject them as reuse targets. Existence of the id
23
+ * is enforced one layer up, against the actual shortlist (INV-R08).
24
+ */
25
+ import { Type } from '@sinclair/typebox';
26
+ import { Value } from '@sinclair/typebox/value';
27
+ /** Registry key for OUTPUT_SCHEMA_REGISTRY (adapter-side validation). */
28
+ export const REUSE_EVALUATION_OUTPUT_SCHEMA_REF = 'reuse-evaluation-output-v1';
29
+ export const ReuseEvaluationRecommendationSchema = Type.Union([
30
+ Type.Literal('reuse'),
31
+ Type.Literal('create'),
32
+ Type.Literal('uncertain'),
33
+ ]);
34
+ export const ReuseEvaluationOutputV1Schema = Type.Object({
35
+ recommendation: ReuseEvaluationRecommendationSchema,
36
+ selectedPrincipleId: Type.Optional(Type.String({ minLength: 1 })),
37
+ rationale: Type.String({ minLength: 1 }),
38
+ confidence: Type.Number({ minimum: 0, maximum: 1 }),
39
+ });
40
+ function isRecord(value) {
41
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
42
+ }
43
+ const ALLOWED_KEYS = new Set([
44
+ 'recommendation',
45
+ 'selectedPrincipleId',
46
+ 'rationale',
47
+ 'confidence',
48
+ ]);
49
+ /**
50
+ * Runtime validation for the evaluation output (rc-1/rc-2/rc-3).
51
+ *
52
+ * Pure function, never throws. Returns the FIRST failure reason:
53
+ * - non-object input → `evaluation_is_not_an_object`
54
+ * - any key outside the closed field set → `unknown_field:<key>` (T7a)
55
+ * - schema violation (bad recommendation value, empty rationale,
56
+ * confidence out of [0,1], empty/non-string selectedPrincipleId) →
57
+ * `schema_validation_failed:<details>`
58
+ * - `recommendation=reuse` without `selectedPrincipleId` →
59
+ * `reuse_without_principle_id`
60
+ * - `recommendation=uncertain` WITH `selectedPrincipleId` →
61
+ * `uncertain_with_principle_id`
62
+ */
63
+ export function validateReuseEvaluationOutput(raw) {
64
+ if (!isRecord(raw)) {
65
+ return { ok: false, reason: 'evaluation_is_not_an_object' };
66
+ }
67
+ for (const key of Object.keys(raw)) {
68
+ if (!ALLOWED_KEYS.has(key)) {
69
+ return { ok: false, reason: `unknown_field:${key}` };
70
+ }
71
+ }
72
+ if (!Value.Check(ReuseEvaluationOutputV1Schema, raw)) {
73
+ const details = [...Value.Errors(ReuseEvaluationOutputV1Schema, raw)]
74
+ .slice(0, 5)
75
+ .map((e) => `${e.path || '/'}: ${e.message}`)
76
+ .join('; ');
77
+ return { ok: false, reason: `schema_validation_failed:${details}` };
78
+ }
79
+ const { recommendation, rationale, confidence } = raw;
80
+ const selected = raw.selectedPrincipleId;
81
+ if (recommendation === 'reuse' && (typeof selected !== 'string' || selected.trim() === '')) {
82
+ return { ok: false, reason: 'reuse_without_principle_id' };
83
+ }
84
+ if (recommendation === 'uncertain' && typeof selected === 'string' && selected.trim() !== '') {
85
+ return { ok: false, reason: 'uncertain_with_principle_id' };
86
+ }
87
+ return {
88
+ ok: true,
89
+ output: {
90
+ recommendation,
91
+ rationale,
92
+ confidence,
93
+ ...(typeof selected === 'string' && selected.trim() !== '' ? { selectedPrincipleId: selected } : {}),
94
+ },
95
+ };
96
+ }
97
+ //# sourceMappingURL=reuse-evaluation-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-evaluation-output.js","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-evaluation-output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * ReuseEvaluationRunner — the Semantic Reuse Evaluation Capability's execution
3
+ * path (PRI-917 SPEC v0.3.2 §7, Phase 3C-3).
4
+ *
5
+ * A PROPOSAL-ONLY runner. It compares a candidate against a bounded shortlist
6
+ * of existing Principles and returns a RECOMMENDATION. It has no path to any
7
+ * ledger writer: this module imports no ledger mutation API, and nothing here
8
+ * can create, modify, or record a Principle. The Owner decides (SPEC §5).
9
+ *
10
+ * Design constraints honoured here (SPEC §7):
11
+ * - ALL LLM execution goes through the injected PDRuntimeAdapter. This
12
+ * module creates no client, no inference abstraction, and no provider
13
+ * seam of its own; the repair loop drives the SAME adapter.
14
+ * - Structured output repair reuses `structured-output-repair` (the
15
+ * runtime-agnostic loop) with an adapter-backed `llmCaller`.
16
+ * - The output contract is the Phase 3C-1 schema, and the Phase 3C-1
17
+ * validator is the trust boundary (closed field set + cross-field rules).
18
+ *
19
+ * Failure is always fail-closed and observable: a timed-out run, unparsable
20
+ * output, or a payload that still violates the contract after repair throws a
21
+ * {@link ReuseEvaluationError}. It NEVER degrades into "no candidates, so
22
+ * create" — that is the caller's (review surface's) decision, not this
23
+ * runner's silent default (SPEC §9).
24
+ */
25
+ import type { PDRuntimeAdapter } from '../runtime-protocol.js';
26
+ import { type ReuseEvaluationOutputV1 } from './reuse-evaluation-output.js';
27
+ /** The candidate's semantic claim — the same claim intake resolves (4b/4c). */
28
+ export interface ReuseEvaluationCandidateInput {
29
+ text: string;
30
+ triggerPattern: string;
31
+ action: string;
32
+ }
33
+ /** One existing Principle from the deterministic shortlist. */
34
+ export interface ReuseEvaluationShortlistEntry {
35
+ principleId: string;
36
+ text: string;
37
+ triggerPattern: string;
38
+ action: string;
39
+ }
40
+ export interface ReuseEvaluationInput {
41
+ candidate: ReuseEvaluationCandidateInput;
42
+ /** Bounded Top-K from reuse-shortlist (caller guarantees ≤ 3). */
43
+ candidates: ReuseEvaluationShortlistEntry[];
44
+ }
45
+ export type ReuseEvaluationFailureReason = 'timeout' | 'run_failed' | 'output_unavailable' | 'output_invalid' | 'repair_failed';
46
+ /**
47
+ * Fail-closed error from the evaluation runner. Carries a structured reason
48
+ * and next action so the review surface can degrade OBSERVABLY (SPEC §9)
49
+ * instead of pretending the shortlist was semantically judged.
50
+ */
51
+ export declare class ReuseEvaluationError extends Error {
52
+ readonly reason: ReuseEvaluationFailureReason;
53
+ readonly nextAction: string;
54
+ readonly detail?: string;
55
+ readonly repairAttempts: number;
56
+ constructor(args: {
57
+ reason: ReuseEvaluationFailureReason;
58
+ message: string;
59
+ nextAction: string;
60
+ detail?: string;
61
+ repairAttempts?: number;
62
+ });
63
+ }
64
+ export interface ReuseEvaluationRunnerDeps {
65
+ /** The one and only LLM execution path (never constructed here). */
66
+ readonly runtimeAdapter: PDRuntimeAdapter;
67
+ }
68
+ export interface ReuseEvaluationRunnerOptions {
69
+ /** Per-run budget. Bounded polling never exceeds it. Default 30s. */
70
+ readonly timeoutMs?: number;
71
+ /** Bounded repair attempts after a contract violation. Default 1. */
72
+ readonly maxRepairAttempts?: number;
73
+ /** agentSpec label for telemetry/lineage. Not an agent registration. */
74
+ readonly agentId?: string;
75
+ /** Poll interval while waiting for the run. Default 200ms. */
76
+ readonly pollIntervalMs?: number;
77
+ }
78
+ export declare class ReuseEvaluationRunner {
79
+ private readonly runtimeAdapter;
80
+ private readonly timeoutMs;
81
+ private readonly maxRepairAttempts;
82
+ private readonly agentId;
83
+ private readonly pollIntervalMs;
84
+ constructor(deps: ReuseEvaluationRunnerDeps, options?: ReuseEvaluationRunnerOptions);
85
+ /**
86
+ * Role declaration delivered on the system channel (base-layer prompt,
87
+ * following CorrectionObserver's PRI-633 pattern). The "you recommend, the
88
+ * Owner decides" boundary is stated here so the model never narrates itself
89
+ * as a decision authority (SPEC §5).
90
+ */
91
+ static readonly SYSTEM_PROMPT: string;
92
+ /** Build the evaluation prompt (deterministic, bounded). */
93
+ static buildPrompt(input: ReuseEvaluationInput): string;
94
+ /**
95
+ * Run one semantic evaluation and return the validated RECOMMENDATION.
96
+ *
97
+ * @throws ReuseEvaluationError — timeout / run failure / unparsable output /
98
+ * contract violation surviving repair. Never a silent fallback.
99
+ */
100
+ recommend(input: ReuseEvaluationInput): Promise<ReuseEvaluationOutputV1>;
101
+ /** Bounded repair using the SAME adapter (no second LLM path). */
102
+ private repairAndValidate;
103
+ /**
104
+ * One adapter round-trip: start → bounded poll → fetch. This is the ONLY
105
+ * place the runner touches the runtime, for both the initial call and each
106
+ * repair attempt.
107
+ */
108
+ private invoke;
109
+ }
110
+ export declare function isValidReuseEvaluationOutput(value: unknown): boolean;
111
+ //# sourceMappingURL=reuse-evaluation-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-evaluation-runner.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-evaluation-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,8BAA8B,CAAC;AAQtC,+EAA+E;AAC/E,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+DAA+D;AAC/D,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,6BAA6B,CAAC;IACzC,kEAAkE;IAClE,UAAU,EAAE,6BAA6B,EAAE,CAAC;CAC7C;AAID,MAAM,MAAM,4BAA4B,GACpC,SAAS,GACT,YAAY,GACZ,oBAAoB,GACpB,gBAAgB,GAChB,eAAe,CAAC;AAEpB;;;;GAIG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,SAAgB,MAAM,EAAE,4BAA4B,CAAC;IACrD,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChC,SAAgB,cAAc,EAAE,MAAM,CAAC;IAEvC,YAAY,IAAI,EAAE;QAChB,MAAM,EAAE,4BAA4B,CAAC;QACrC,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,EAOA;CACF;AAID,MAAM,WAAW,yBAAyB;IACxC,oEAAoE;IACpE,QAAQ,CAAC,cAAc,EAAE,gBAAgB,CAAC;CAC3C;AAED,MAAM,WAAW,4BAA4B;IAC3C,qEAAqE;IACrE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAaD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,YAAY,IAAI,EAAE,yBAAyB,EAAE,OAAO,GAAE,4BAAiC,EAMtF;IAED;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,aAAa,SAIjB;IAEZ,4DAA4D;IAC5D,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAuCtD;IAED;;;;;OAKG;IACG,SAAS,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAW7E;IAED,kEAAkE;YACpD,iBAAiB;IAmD/B;;;;OAIG;YACW,MAAM;CA+DrB;AAID,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAKpE"}
@@ -0,0 +1,232 @@
1
+ import { ReuseEvaluationOutputV1Schema, validateReuseEvaluationOutput, } from './reuse-evaluation-output.js';
2
+ import { attemptStructuredOutputRepair, } from '../adapter/structured-output-repair.js';
3
+ /**
4
+ * Fail-closed error from the evaluation runner. Carries a structured reason
5
+ * and next action so the review surface can degrade OBSERVABLY (SPEC §9)
6
+ * instead of pretending the shortlist was semantically judged.
7
+ */
8
+ export class ReuseEvaluationError extends Error {
9
+ reason;
10
+ nextAction;
11
+ detail;
12
+ repairAttempts;
13
+ constructor(args) {
14
+ super(args.message);
15
+ this.name = 'ReuseEvaluationError';
16
+ this.reason = args.reason;
17
+ this.nextAction = args.nextAction;
18
+ this.detail = args.detail;
19
+ this.repairAttempts = args.repairAttempts ?? 0;
20
+ }
21
+ }
22
+ const DEFAULT_TIMEOUT_MS = 30_000;
23
+ const DEFAULT_POLL_INTERVAL_MS = 200;
24
+ const MAX_POLLED_FIELD_CHARS = 2000;
25
+ /** Bounded poll backoff (module-level: no runner state involved). */
26
+ function sleep(ms) {
27
+ return new Promise((resolve) => {
28
+ setTimeout(resolve, ms);
29
+ });
30
+ }
31
+ export class ReuseEvaluationRunner {
32
+ runtimeAdapter;
33
+ timeoutMs;
34
+ maxRepairAttempts;
35
+ agentId;
36
+ pollIntervalMs;
37
+ constructor(deps, options = {}) {
38
+ this.runtimeAdapter = deps.runtimeAdapter;
39
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
40
+ this.maxRepairAttempts = options.maxRepairAttempts ?? 1;
41
+ this.agentId = options.agentId ?? 'reuse-evaluation';
42
+ this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
43
+ }
44
+ /**
45
+ * Role declaration delivered on the system channel (base-layer prompt,
46
+ * following CorrectionObserver's PRI-633 pattern). The "you recommend, the
47
+ * Owner decides" boundary is stated here so the model never narrates itself
48
+ * as a decision authority (SPEC §5).
49
+ */
50
+ static SYSTEM_PROMPT = [
51
+ 'You are a semantic reuse evaluator for a principles-disciple knowledge base.',
52
+ 'You compare a NEW candidate claim against EXISTING principles and RECOMMEND whether an existing principle already covers the same experience.',
53
+ 'You are a recommender, NOT a decision maker: the Owner decides. Never claim a decision was made, never instruct that a principle be written, and never emit fields outside the requested JSON shape.',
54
+ ].join(' ');
55
+ /** Build the evaluation prompt (deterministic, bounded). */
56
+ static buildPrompt(input) {
57
+ const clip = (s) => (s.length > MAX_POLLED_FIELD_CHARS ? `${s.slice(0, MAX_POLLED_FIELD_CHARS)}…` : s);
58
+ const candidateBlock = [
59
+ ` text: ${clip(input.candidate.text)}`,
60
+ ` trigger: ${clip(input.candidate.triggerPattern)}`,
61
+ ` action: ${clip(input.candidate.action)}`,
62
+ ].join('\n');
63
+ const existingBlock = input.candidates.length === 0
64
+ ? ' (none)'
65
+ : input.candidates
66
+ .map((c, i) => [
67
+ ` [${i + 1}] principleId: ${c.principleId}`,
68
+ ` text: ${clip(c.text)}`,
69
+ ` trigger: ${clip(c.triggerPattern)}`,
70
+ ` action: ${clip(c.action)}`,
71
+ ].join('\n'))
72
+ .join('\n');
73
+ return [
74
+ '## TASK',
75
+ 'Decide whether ONE existing principle already expresses the same experience as the candidate claim.',
76
+ '',
77
+ '## Candidate claim',
78
+ candidateBlock,
79
+ '',
80
+ `## Existing principles (${input.candidates.length})`,
81
+ existingBlock,
82
+ '',
83
+ '## Rules',
84
+ '- Judge SEMANTIC coverage, not word overlap: shared vocabulary alone is NOT the same experience.',
85
+ '- recommendation=reuse: an existing principle already covers this claim. Set selectedPrincipleId to that principle\'s id (required).',
86
+ '- recommendation=create: no existing principle covers this claim; a new one is warranted.',
87
+ '- recommendation=uncertain: the evidence is genuinely ambiguous. Do NOT set selectedPrincipleId.',
88
+ '- rationale: one or two sentences naming WHY the coverage holds or fails.',
89
+ '- confidence: 0..1 in your recommendation.',
90
+ '- Emit ONLY these fields: recommendation, selectedPrincipleId (only for reuse), rationale, confidence.',
91
+ '',
92
+ 'Return strict JSON (no markdown):',
93
+ '{"recommendation": "reuse" | "create" | "uncertain", "selectedPrincipleId": string, "rationale": string, "confidence": number}',
94
+ ].join('\n');
95
+ }
96
+ /**
97
+ * Run one semantic evaluation and return the validated RECOMMENDATION.
98
+ *
99
+ * @throws ReuseEvaluationError — timeout / run failure / unparsable output /
100
+ * contract violation surviving repair. Never a silent fallback.
101
+ */
102
+ async recommend(input) {
103
+ const payload = await this.invoke(ReuseEvaluationRunner.buildPrompt(input), 'evaluate');
104
+ const validated = validateReuseEvaluationOutput(payload);
105
+ if (validated.ok) {
106
+ return validated.output;
107
+ }
108
+ // Contract violation (unknown field, bad cross-field pairing, bad types):
109
+ // the schema itself is permissive about extra keys, so this is where the
110
+ // closed field set bites. One bounded repair round, then fail closed.
111
+ return this.repairAndValidate(payload, validated.reason);
112
+ }
113
+ /** Bounded repair using the SAME adapter (no second LLM path). */
114
+ async repairAndValidate(invalidOutput, reason) {
115
+ if (this.maxRepairAttempts <= 0) {
116
+ throw new ReuseEvaluationError({
117
+ reason: 'repair_failed',
118
+ message: `Reuse evaluation output violated its contract (${reason}) and repair is disabled`,
119
+ nextAction: 'Review the evaluation output contract; repair attempts are configured to 0',
120
+ detail: reason,
121
+ });
122
+ }
123
+ const schemaErrors = [{ path: '/', message: reason, value: invalidOutput }];
124
+ const repair = await attemptStructuredOutputRepair(invalidOutput, schemaErrors, {
125
+ // The repair LLM is the SAME adapter — this callback only marshals
126
+ // prompt in and raw JSON text out.
127
+ llmCaller: async (prompt) => {
128
+ const repaired = await this.invoke(prompt, 'repair');
129
+ return JSON.stringify(repaired);
130
+ },
131
+ schemaCheck: (value) => validateReuseEvaluationOutput(value).ok,
132
+ }, {
133
+ maxRepairAttempts: this.maxRepairAttempts,
134
+ schemaRef: 'reuse-evaluation-output-v1',
135
+ schemaJson: JSON.stringify(ReuseEvaluationOutputV1Schema),
136
+ requiredKeys: ['recommendation', 'rationale', 'confidence'],
137
+ });
138
+ if (repair.repaired && repair.output) {
139
+ // The repair loop's schemaCheck is our validator, but re-validate the
140
+ // returned value explicitly: a caller-visible contract must never rely
141
+ // on a callback's internal check alone.
142
+ const revalidated = validateReuseEvaluationOutput(repair.output);
143
+ if (revalidated.ok) {
144
+ return revalidated.output;
145
+ }
146
+ }
147
+ throw new ReuseEvaluationError({
148
+ reason: 'repair_failed',
149
+ message: `Reuse evaluation output violated its contract (${reason}) and could not be repaired`,
150
+ nextAction: 'Re-run the review; if it persists, inspect the evaluation prompt/runtime output format',
151
+ detail: `${reason}; ${repair.repairSummary}`,
152
+ repairAttempts: repair.attemptsUsed,
153
+ });
154
+ }
155
+ /**
156
+ * One adapter round-trip: start → bounded poll → fetch. This is the ONLY
157
+ * place the runner touches the runtime, for both the initial call and each
158
+ * repair attempt.
159
+ */
160
+ async invoke(prompt, phase) {
161
+ const runHandle = await this.runtimeAdapter.startRun({
162
+ agentSpec: { agentId: this.agentId, schemaVersion: 'v1' },
163
+ taskRef: { taskId: `reuse_eval_${phase}_${Date.now()}` },
164
+ inputPayload: prompt,
165
+ contextItems: [],
166
+ outputSchemaRef: 'reuse-evaluation-output-v1',
167
+ timeoutMs: this.timeoutMs,
168
+ systemPrompt: ReuseEvaluationRunner.SYSTEM_PROMPT,
169
+ });
170
+ const deadline = Date.now() + this.timeoutMs;
171
+ let terminal = false;
172
+ while (Date.now() < deadline) {
173
+ const status = await this.runtimeAdapter.pollRun(runHandle.runId);
174
+ if (status.status === 'succeeded') {
175
+ terminal = true;
176
+ break;
177
+ }
178
+ if (status.status === 'failed' || status.status === 'timed_out' || status.status === 'cancelled') {
179
+ throw new ReuseEvaluationError({
180
+ reason: status.status === 'timed_out' ? 'timeout' : 'run_failed',
181
+ message: `Reuse evaluation ${phase} run finished as '${status.status}'`,
182
+ nextAction: 'Check the configured reuseEvaluation runtime profile and LLM channel health',
183
+ detail: status.reason,
184
+ });
185
+ }
186
+ await sleep(this.pollIntervalMs);
187
+ }
188
+ if (!terminal) {
189
+ try {
190
+ await this.runtimeAdapter.cancelRun(runHandle.runId);
191
+ }
192
+ catch { /* best effort: the run is already past its budget */ }
193
+ throw new ReuseEvaluationError({
194
+ reason: 'timeout',
195
+ message: `Reuse evaluation ${phase} run exceeded ${this.timeoutMs}ms`,
196
+ nextAction: 'Raise reuseEvaluation.timeoutMs or check the configured runtime profile',
197
+ });
198
+ }
199
+ let output;
200
+ try {
201
+ output = await this.runtimeAdapter.fetchOutput(runHandle.runId);
202
+ }
203
+ catch (err) {
204
+ // The adapter validates against outputSchemaRef and can also perform its
205
+ // own internal repair (pi-ai does). If it still fails, the raw text is
206
+ // unavailable for a runner-level repair — surface it fail-closed.
207
+ throw new ReuseEvaluationError({
208
+ reason: 'output_invalid',
209
+ message: `Reuse evaluation ${phase} output could not be parsed or validated by the runtime`,
210
+ nextAction: 'Inspect the runtime output format; the adapter rejected it against reuse-evaluation-output-v1',
211
+ detail: err instanceof Error ? err.message : String(err),
212
+ });
213
+ }
214
+ if (!output || output.payload === undefined || output.payload === null) {
215
+ throw new ReuseEvaluationError({
216
+ reason: 'output_unavailable',
217
+ message: `Reuse evaluation ${phase} run produced no output payload`,
218
+ nextAction: 'Re-run the review; the runtime returned an empty payload',
219
+ });
220
+ }
221
+ return output.payload;
222
+ }
223
+ }
224
+ // Re-exported for callers that want a plain boolean pre-check without
225
+ // constructing a runner (e.g. a surface deciding whether to show a warning).
226
+ export function isValidReuseEvaluationOutput(value) {
227
+ // PRI-917 review (P2): delegate to the FULL trust boundary (closed field
228
+ // set + cross-field rules). The bare TypeBox schema is an open field set,
229
+ // so a raw Value.Check would pass outputs the contract must reject (T7a).
230
+ return validateReuseEvaluationOutput(value).ok;
231
+ }
232
+ //# sourceMappingURL=reuse-evaluation-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-evaluation-runner.js","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-evaluation-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * PRI-917 Slice 2 — reuse proposal + decision contract (internal).
3
+ *
4
+ * This slice delivers the FLOW only: given a candidate, produce a bounded
5
+ * proposal of existing Principles that may already cover it, and let an
6
+ * injected decision function answer `reuse` or `create`.
7
+ *
8
+ * Deliberately NOT in this slice (SPEC v0.2 / task scope):
9
+ * - persistence of the decision or the relation (`reuseEvidence[]` is Slice 3)
10
+ * - any Console page, new approval subsystem, or automated decision model
11
+ * - any change to `derivedFromPainIds`, the ledger schema, or candidate status
12
+ *
13
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
14
+ */
15
+ import type { ReuseShortlist } from './reuse-domain.js';
16
+ import type { ReuseEvidenceActor } from '../types/principle-schema.js';
17
+ /**
18
+ * `pending` — credible existing Principles were found and an Owner decision is
19
+ * required before anything is written.
20
+ * `no_candidates` — nothing credible was found; the caller proceeds to create.
21
+ */
22
+ export type ReuseProposalStatus = 'pending' | 'no_candidates';
23
+ export interface ReuseProposalEntry {
24
+ /** Canonical Principle Ledger UUID. */
25
+ principleId: string;
26
+ score: number;
27
+ /** Human-readable reasons, one per evidence field. */
28
+ reasons: string[];
29
+ }
30
+ export interface ReuseProposal {
31
+ candidateId: string;
32
+ status: ReuseProposalStatus;
33
+ candidates: ReuseProposalEntry[];
34
+ /** Principles that passed status eligibility. */
35
+ eligibleCount: number;
36
+ }
37
+ /**
38
+ * The Owner's answer. There is no automatic option.
39
+ *
40
+ * A `reuse` verdict carries the SPEC §11 decision-exchange fields (`actor`,
41
+ * `reason`, `decidedAt`) because PRI-917 PR3B materialises the verdict into
42
+ * `Principle.reuseEvidence[]` verbatim (SPEC §12): the durable evidence must
43
+ * record WHO decided, WHY, and WHEN — an answer without them cannot be
44
+ * persisted as a reuse resolution, so the validator rejects it fail-closed.
45
+ */
46
+ export type ReuseDecision = {
47
+ decision: 'create';
48
+ } | {
49
+ decision: 'reuse';
50
+ selectedPrincipleId: string;
51
+ actor: ReuseEvidenceActor;
52
+ reason: string;
53
+ decidedAt: string;
54
+ };
55
+ /**
56
+ * Converts a deterministic shortlist into the proposal contract.
57
+ *
58
+ * The shortlist already guarantees determinism and a bounded Top-K, so this is
59
+ * a pure projection: it adds no ranking of its own and never widens the set.
60
+ */
61
+ export declare function buildReuseProposal(candidateId: string, shortlist: ReuseShortlist): ReuseProposal;
62
+ /** True when the proposal needs an Owner answer before writing. */
63
+ export declare function proposalNeedsDecision(proposal: ReuseProposal): boolean;
64
+ export type ReuseDecisionValidation = {
65
+ ok: true;
66
+ decision: ReuseDecision;
67
+ } | {
68
+ ok: false;
69
+ reason: string;
70
+ };
71
+ /**
72
+ * Runtime validator for the reuse decision (rc-1/rc-2/rc-3).
73
+ *
74
+ * The decision function is an untrusted boundary — an AI Owner parses model
75
+ * output into it — so its TypeScript type cannot be the guard. A bare
76
+ * `"create"` string, `{}`, `{decision:'REUSE'}`, a non-string principle id, or
77
+ * a missing id for reuse are ALL rejected here, because the alternative is
78
+ * silently reading a malformed answer as "go ahead and create" — the exact
79
+ * duplicate manufacturing this gate exists to prevent.
80
+ *
81
+ * PRI-917 PR3B Phase 2: a `reuse` verdict must additionally carry the
82
+ * SPEC §11 accountability fields (`actor` / `reason` / `decidedAt`) — they are
83
+ * materialised verbatim into `Principle.reuseEvidence[]`, and an answer
84
+ * without them cannot produce a self-contained, auditable evidence entry.
85
+ */
86
+ export declare function validateReuseDecision(raw: unknown): ReuseDecisionValidation;
87
+ //# sourceMappingURL=reuse-proposal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reuse-proposal.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/principle-reuse/reuse-proposal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,iDAAiD;IACjD,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,GACtB;IACE,QAAQ,EAAE,OAAO,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,cAAc,GACxB,aAAa,CAef;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAEtE;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,aAAa,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,uBAAuB,CAwC3E"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * PRI-917 Slice 2 — reuse proposal + decision contract (internal).
3
+ *
4
+ * This slice delivers the FLOW only: given a candidate, produce a bounded
5
+ * proposal of existing Principles that may already cover it, and let an
6
+ * injected decision function answer `reuse` or `create`.
7
+ *
8
+ * Deliberately NOT in this slice (SPEC v0.2 / task scope):
9
+ * - persistence of the decision or the relation (`reuseEvidence[]` is Slice 3)
10
+ * - any Console page, new approval subsystem, or automated decision model
11
+ * - any change to `derivedFromPainIds`, the ledger schema, or candidate status
12
+ *
13
+ * @see docs/specs/PRI-917-reuse-before-create-v0.1.md (SPEC v0.2)
14
+ */
15
+ /**
16
+ * Converts a deterministic shortlist into the proposal contract.
17
+ *
18
+ * The shortlist already guarantees determinism and a bounded Top-K, so this is
19
+ * a pure projection: it adds no ranking of its own and never widens the set.
20
+ */
21
+ export function buildReuseProposal(candidateId, shortlist) {
22
+ const candidates = shortlist.candidates.map((entry) => ({
23
+ principleId: entry.principleId,
24
+ score: entry.score,
25
+ reasons: [
26
+ entry.similarityReason,
27
+ ...entry.evidence.map((e) => `${e.field}: ${e.sharedTerms.slice(0, 5).join('、')}`),
28
+ ],
29
+ }));
30
+ return {
31
+ candidateId,
32
+ status: candidates.length > 0 ? 'pending' : 'no_candidates',
33
+ candidates,
34
+ eligibleCount: shortlist.eligibleCount,
35
+ };
36
+ }
37
+ /** True when the proposal needs an Owner answer before writing. */
38
+ export function proposalNeedsDecision(proposal) {
39
+ return proposal.status === 'pending';
40
+ }
41
+ /**
42
+ * Runtime validator for the reuse decision (rc-1/rc-2/rc-3).
43
+ *
44
+ * The decision function is an untrusted boundary — an AI Owner parses model
45
+ * output into it — so its TypeScript type cannot be the guard. A bare
46
+ * `"create"` string, `{}`, `{decision:'REUSE'}`, a non-string principle id, or
47
+ * a missing id for reuse are ALL rejected here, because the alternative is
48
+ * silently reading a malformed answer as "go ahead and create" — the exact
49
+ * duplicate manufacturing this gate exists to prevent.
50
+ *
51
+ * PRI-917 PR3B Phase 2: a `reuse` verdict must additionally carry the
52
+ * SPEC §11 accountability fields (`actor` / `reason` / `decidedAt`) — they are
53
+ * materialised verbatim into `Principle.reuseEvidence[]`, and an answer
54
+ * without them cannot produce a self-contained, auditable evidence entry.
55
+ */
56
+ export function validateReuseDecision(raw) {
57
+ if (raw === null || raw === undefined)
58
+ return { ok: false, reason: 'decision_is_nullish' };
59
+ if (typeof raw !== 'object' || Array.isArray(raw))
60
+ return { ok: false, reason: 'decision_is_not_an_object' };
61
+ const record = raw;
62
+ const { decision } = record;
63
+ if (decision === 'create')
64
+ return { ok: true, decision: { decision: 'create' } };
65
+ if (decision !== 'reuse')
66
+ return { ok: false, reason: `unknown_decision_value:${String(decision)}` };
67
+ const selected = record.selectedPrincipleId;
68
+ if (typeof selected !== 'string' || selected.length === 0) {
69
+ return { ok: false, reason: 'reuse_without_principle_id' };
70
+ }
71
+ const actorRaw = record.actor;
72
+ if (typeof actorRaw !== 'object' || actorRaw === null || Array.isArray(actorRaw)) {
73
+ return { ok: false, reason: 'reuse_actor_invalid' };
74
+ }
75
+ const actorRecord = actorRaw;
76
+ if (!(actorRecord.kind === 'owner' || actorRecord.kind === 'ai_owner')
77
+ || typeof actorRecord.id !== 'string'
78
+ || actorRecord.id.length === 0) {
79
+ return { ok: false, reason: 'reuse_actor_invalid' };
80
+ }
81
+ const { reason, decidedAt } = record;
82
+ if (typeof reason !== 'string' || reason.length === 0) {
83
+ return { ok: false, reason: 'reuse_reason_missing' };
84
+ }
85
+ if (typeof decidedAt !== 'string' || decidedAt.length === 0 || Number.isNaN(Date.parse(decidedAt))) {
86
+ return { ok: false, reason: 'reuse_decidedAt_invalid' };
87
+ }
88
+ return {
89
+ ok: true,
90
+ decision: {
91
+ decision: 'reuse',
92
+ selectedPrincipleId: selected,
93
+ actor: { kind: actorRecord.kind, id: actorRecord.id },
94
+ reason,
95
+ decidedAt,
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=reuse-proposal.js.map