@principles/host-runtime 0.3.10 → 0.3.11

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.
@@ -14,7 +14,7 @@
14
14
  * dedupes by `${artifactId}::${channel}`; reopen idempotency is owned by
15
15
  * orchestrator.reopenTaskForRevision.
16
16
  */
17
- import { ActivationDispatcher, PromptWriter, DeferArchiveWriter, RuleHostWriter, SqliteConnection, SqliteActivationStateStore, SqliteApprovalQueueStore, SqlitePIArtifactStore, createProductionGateDeps, createPITaskDiagnosticJson, computeFeatureFlagsFromConfig, isFeatureEnabled, } from '@principles/core/runtime-v2';
17
+ import { ActivationDispatcher, PromptWriter, DeferArchiveWriter, RuleHostWriter, SqliteConnection, SqliteActivationStateStore, SqliteApprovalQueueStore, SqlitePIArtifactStore, createProductionGateDeps, createPITaskDiagnosticJson, artificerRepairTaskId, computeFeatureFlagsFromConfig, isFeatureEnabled, } from '@principles/core/runtime-v2';
18
18
  import { loadPdConfigForPlugin } from './pd-config.js';
19
19
  function normalizeDecision(decision) {
20
20
  if (decision.decision === 'activated') {
@@ -116,10 +116,21 @@ export function createEvaluatorRepairDeps(workspaceDir, stateManager, logger) {
116
116
  seedArtificerRepairTask: async (params) => {
117
117
  // P0-4: 确定性 revision identity — evaluatorTaskId + iteration 唯一定位
118
118
  // 一个逻辑 repair 任务; 重放 (consumer 重复周期 / crash 恢复) reuse 而非再建。
119
- const repairTaskId = `artificer-repair-${params.repairPayload.sourceEvaluatorTaskId}-r${params.repairPayload.repairIteration}`;
119
+ // PRI-718: id 约定收敛到 pitask-metadata 的单一 owner。
120
+ const repairTaskId = artificerRepairTaskId(params.repairPayload.sourceEvaluatorTaskId, params.repairPayload.repairIteration);
120
121
  const existing = await stateManager.getTask(repairTaskId);
121
122
  if (existing) {
122
- logger?.info?.(`[PD:Consumer] repair task ${repairTaskId} already exists; reusing (idempotent seed)`);
123
+ // PRI-718 (revise ≠ resume): a TERMINAL repair round is finished
124
+ // corrective work, not a vehicle for new corrective work. Returning
125
+ // it here made the evaluator re-run against a superseded artifact
126
+ // forever (EP002-R2: same-artifact score oscillation, one LLM call
127
+ // per cycle, no new repair). New work requires a new revision epoch
128
+ // (Owner revise_once) — surface as a seed failure so the evaluator
129
+ // degrades to needs_human_review instead of looping.
130
+ if (existing.status === 'succeeded' || existing.status === 'failed' || existing.status === 'needs_human_review') {
131
+ throw new Error(`repair task ${repairTaskId} already reached terminal status ${existing.status}; refusing to reuse it as new corrective work (PRI-718 revise-ne-resume)`);
132
+ }
133
+ logger?.info?.(`[PD:Consumer] repair task ${repairTaskId} already exists (in-flight ${existing.status}); reusing (idempotent seed)`);
123
134
  return repairTaskId;
124
135
  }
125
136
  await stateManager.createTask({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/host-runtime",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "description": "Shared host-neutral orchestration for Principles Disciple MVP-Core hook paths.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",