create-principles-disciple 1.147.1 → 1.147.3

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 (66) hide show
  1. package/_release/product-identity.json +1 -1
  2. package/codex-adapter/dist/ingestion/admission.d.ts +5 -10
  3. package/codex-adapter/dist/ingestion/admission.js +19 -77
  4. package/codex-adapter/dist/ingestion/explicit-owner-statement.js +1 -1
  5. package/codex-adapter/dist/ingestion/ingestion.d.ts +0 -2
  6. package/codex-adapter/dist/ingestion/ingestion.js +6 -4
  7. package/codex-adapter/dist/pd-hook.js +5 -7
  8. package/codex-adapter/package.json +1 -1
  9. package/core/dist/runtime-v2/evidence-triage/index.d.ts +0 -1
  10. package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -1
  11. package/core/dist/runtime-v2/evidence-triage/index.js +0 -2
  12. package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -1
  13. package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +3 -8
  14. package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts.map +1 -1
  15. package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +5 -17
  16. package/core/dist/runtime-v2/evidence-triage/source-descriptors.js.map +1 -1
  17. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +11 -9
  18. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -1
  19. package/core/dist/runtime-v2/evidence-triage/triage-policy.js +10 -103
  20. package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -1
  21. package/core/dist/runtime-v2/evidence-triage/trigger-controller.js +1 -1
  22. package/core/dist/runtime-v2/evidence-triage/trigger-controller.js.map +1 -1
  23. package/core/dist/runtime-v2/evidence-triage/types.d.ts +4 -16
  24. package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -1
  25. package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -1
  26. package/core/dist/runtime-v2/index.d.ts +1 -1
  27. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  28. package/core/dist/runtime-v2/index.js +1 -1
  29. package/core/dist/runtime-v2/index.js.map +1 -1
  30. package/core/package.json +1 -1
  31. package/dist/installer.d.ts +20 -0
  32. package/dist/installer.d.ts.map +1 -1
  33. package/dist/installer.js +49 -97
  34. package/dist/installer.js.map +1 -1
  35. package/dist/mvp-config.d.ts +11 -0
  36. package/dist/mvp-config.d.ts.map +1 -1
  37. package/dist/mvp-config.js.map +1 -1
  38. package/dist/update/release-metadata.d.ts +13 -5
  39. package/dist/update/release-metadata.d.ts.map +1 -1
  40. package/dist/update/release-metadata.js.map +1 -1
  41. package/host-runtime/dist/governance-signal-admission.d.ts +1 -77
  42. package/host-runtime/dist/governance-signal-admission.js +34 -294
  43. package/host-runtime/dist/production-pain-evidence.d.ts +8 -69
  44. package/host-runtime/dist/production-pain-evidence.js +19 -157
  45. package/host-runtime/package.json +1 -1
  46. package/package.json +4 -3
  47. package/pd-cli/package.json +1 -1
  48. package/pd-mcp-server/dist/version.d.ts +1 -1
  49. package/pd-mcp-server/dist/version.js +1 -1
  50. package/pd-mcp-server/package.json +1 -1
  51. package/plugin/dist/bundle.js +411 -412
  52. package/plugin/dist/hooks/after-tool-call-helpers.d.ts +2 -35
  53. package/plugin/dist/hooks/after-tool-call-types.d.ts +1 -30
  54. package/plugin/dist/hooks/pain.d.ts +6 -19
  55. package/plugin/dist/hooks/trajectory-evidence.d.ts +3 -10
  56. package/plugin/dist/hooks/triage-adapter.d.ts +7 -20
  57. package/plugin/dist/host-runtime/openclaw-host-runtime.d.ts +0 -1
  58. package/plugin/dist/openclaw.plugin.json +1 -1
  59. package/plugin/openclaw.plugin.json +1 -1
  60. package/plugin/package.json +1 -1
  61. package/release-manager/dist/installer.js +49 -97
  62. package/release-manager/package.json +2 -1
  63. package/workbuddy-adapter/dist/pd-hook.js +0 -26
  64. package/workbuddy-adapter/dist/worker/workspace-worker.d.ts +1 -7
  65. package/workbuddy-adapter/dist/worker/workspace-worker.js +11 -21
  66. package/workbuddy-adapter/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "productVersion": "2.8.0",
4
- "sourceCommit": "32312b70d5b4f8a661949680fe765e91077e5c16"
4
+ "sourceCommit": "5c3371c3935192081585d741f50a899bc4445b0e"
5
5
  }
@@ -29,17 +29,12 @@ export declare function buildLiveCorrectionCandidate(args: {
29
29
  fields: PayloadFields;
30
30
  rolloutIdentity: string;
31
31
  }): GovernanceSignalCandidate | null;
32
- /** Live PostToolUse payload → tool-failure candidate (logical key mirrors the observation). */
33
- export declare function buildLiveToolCandidate(args: {
34
- fields: PayloadFields;
35
- rolloutIdentity: string;
36
- projectDir?: string;
37
- }): GovernanceSignalCandidate | null;
38
32
  /**
39
- * Decoded transcript observations → candidates. User turns carry visibleText;
40
- * tool calls carry the CommandExecution facts projection. The logical keys are
41
- * the decoded ones, so a replay of an already-admitted live event is an
42
- * observation-level no-op (SPEC §10).
33
+ * Decoded transcript observations → candidates. Only user turns produce
34
+ * candidates: tool-call observations remain technical trajectory (recorded by
35
+ * the workflow's own writers), never a behavioral-deviation Pain by themselves.
36
+ * The logical keys are the decoded ones, so a replay of an already-admitted
37
+ * live event is an observation-level no-op (SPEC §10).
43
38
  */
44
39
  export declare function buildTranscriptCandidates(observations: readonly GovernanceObservationInput[]): readonly GovernanceSignalCandidate[];
45
40
  /**
@@ -14,9 +14,6 @@
14
14
  * authority exists here.
15
15
  */
16
16
  import { admitGovernanceSignals, ensureGovernanceContinuation, } from '@principles/host-runtime';
17
- import { isRecord, own } from './ingestion-fields.js';
18
- /** The live host-event source used by the identity derivation (parity with the dispatch handler). */
19
- const CODEX_POST_TOOL_USE_SOURCE = 'codex:post_tool_use';
20
17
  /** Live UserPromptSubmit payload → correction candidate (logical key mirrors the observation). */
21
18
  export function buildLiveCorrectionCandidate(args) {
22
19
  const { fields } = args;
@@ -33,85 +30,30 @@ export function buildLiveCorrectionCandidate(args) {
33
30
  observedAt: new Date().toISOString(),
34
31
  };
35
32
  }
36
- /** Live PostToolUse payload → tool-failure candidate (logical key mirrors the observation). */
37
- export function buildLiveToolCandidate(args) {
38
- const { fields } = args;
39
- if (fields.turnId === null || fields.toolUseId === null)
40
- return null;
41
- return {
42
- kind: 'tool_failure',
43
- hostKind: 'codex',
44
- logicalObservationKey: `codex|${args.rolloutIdentity}|${fields.toolUseId}`,
45
- rolloutIdentity: args.rolloutIdentity,
46
- rootSessionId: fields.sessionId,
47
- hostTurnId: fields.turnId,
48
- toolName: fields.toolName ?? '',
49
- source: CODEX_POST_TOOL_USE_SOURCE,
50
- // Merge semantics (WorkBuddy × SPEC-CODEX-PAIN-CLOSURE-001): the same host
51
- // `tool_use_id` feeds TWO consumers, so the candidate carries both views.
52
- // I1 identity parity — the live handler derives the canonical pain from the
53
- // same tool_use_id, so `toolCallId` must be present (one real call → one
54
- // canonical pain across the admission + dispatch deliveries).
55
- toolCallId: fields.toolUseId,
56
- // CR-01 — `toolUseId` is recorded into tool_calls.tool_use_id and used for
57
- // the admission dedup join against the live PostToolUse row.
58
- toolUseId: fields.toolUseId,
59
- ...(args.projectDir !== undefined ? { projectDir: args.projectDir } : {}),
60
- ...(fields.toolInput !== undefined ? { toolInput: fields.toolInput } : {}),
61
- ...(fields.toolResponse !== undefined ? { toolOutput: fields.toolResponse } : {}),
62
- observedAt: new Date().toISOString(),
63
- };
64
- }
65
33
  /**
66
- * Decoded transcript observations → candidates. User turns carry visibleText;
67
- * tool calls carry the CommandExecution facts projection. The logical keys are
68
- * the decoded ones, so a replay of an already-admitted live event is an
69
- * observation-level no-op (SPEC §10).
34
+ * Decoded transcript observations → candidates. Only user turns produce
35
+ * candidates: tool-call observations remain technical trajectory (recorded by
36
+ * the workflow's own writers), never a behavioral-deviation Pain by themselves.
37
+ * The logical keys are the decoded ones, so a replay of an already-admitted
38
+ * live event is an observation-level no-op (SPEC §10).
70
39
  */
71
40
  export function buildTranscriptCandidates(observations) {
72
41
  const candidates = [];
73
42
  for (const observation of observations) {
74
- if (observation.kind === 'user_turn') {
75
- if (observation.visibleText === undefined)
76
- continue;
77
- candidates.push({
78
- kind: 'user_correction',
79
- hostKind: 'codex',
80
- logicalObservationKey: observation.logicalObservationKey,
81
- rolloutIdentity: observation.rolloutIdentity,
82
- rootSessionId: observation.rootSessionId,
83
- hostTurnId: observation.hostTurnId,
84
- text: observation.visibleText,
85
- observedAt: observation.observedAt,
86
- });
87
- }
88
- else if (observation.kind === 'tool_call') {
89
- const facts = observation.toolFacts;
90
- if (!isRecord(facts))
91
- continue;
92
- const toolName = own(facts, 'toolName');
93
- const exitCode = own(facts, 'exitCode');
94
- candidates.push({
95
- kind: 'tool_failure',
96
- hostKind: 'codex',
97
- logicalObservationKey: observation.logicalObservationKey,
98
- rolloutIdentity: observation.rolloutIdentity,
99
- rootSessionId: observation.rootSessionId,
100
- hostTurnId: observation.hostTurnId,
101
- toolName: typeof toolName === 'string' ? toolName : '',
102
- source: CODEX_POST_TOOL_USE_SOURCE,
103
- // Merge semantics: both merged views of the same host tool_use_id.
104
- // I1 identity parity — the decoded observation carries the same
105
- // tool_use_id the live delivery derived its canonical pain from, so a
106
- // transcript replay converges on that pain instead of a second one.
107
- ...(typeof observation.toolUseId === 'string' && observation.toolUseId.length > 0 ? { toolCallId: observation.toolUseId } : {}),
108
- // CR-01 — recorded into tool_calls.tool_use_id for the dedup join.
109
- ...(observation.toolUseId !== undefined ? { toolUseId: observation.toolUseId } : {}),
110
- toolInput: own(facts, 'command') ?? null,
111
- ...(exitCode !== undefined ? { toolOutput: { exitCode, stdout: own(facts, 'stdout') ?? null, stderr: own(facts, 'stderr') ?? null } } : {}),
112
- observedAt: observation.observedAt,
113
- });
114
- }
43
+ if (observation.kind !== 'user_turn')
44
+ continue;
45
+ if (observation.visibleText === undefined)
46
+ continue;
47
+ candidates.push({
48
+ kind: 'user_correction',
49
+ hostKind: 'codex',
50
+ logicalObservationKey: observation.logicalObservationKey,
51
+ rolloutIdentity: observation.rolloutIdentity,
52
+ rootSessionId: observation.rootSessionId,
53
+ hostTurnId: observation.hostTurnId,
54
+ text: observation.visibleText,
55
+ observedAt: observation.observedAt,
56
+ });
115
57
  }
116
58
  return candidates;
117
59
  }
@@ -78,7 +78,7 @@ export async function recordExplicitOwnerStatement(args) {
78
78
  if (outcome === undefined || !('disposition' in outcome)) {
79
79
  return { status: 'rejected', reason: 'continuation_failed', nextAction: 'The governance admission returned no disposition; nothing was recorded.' };
80
80
  }
81
- if (outcome.disposition === 'not_a_signal' || outcome.disposition === 'not_admitted') {
81
+ if (outcome.disposition === 'not_a_signal') {
82
82
  return { status: 'rejected', reason: 'continuation_failed', nextAction: 'reason' in outcome ? String(outcome.reason) : 'the signal was not admitted' };
83
83
  }
84
84
  if (outcome.disposition === 'rate_limited') {
@@ -23,8 +23,6 @@ import { type GovernanceSignalCandidate } from '@principles/host-runtime';
23
23
  import { type TranscriptPort } from './transcript-decoder.js';
24
24
  export interface CodexIngestionOptions {
25
25
  readonly workspaceDir: string;
26
- /** Native live-hook cwd; intentionally omitted for transcript catch-up. */
27
- readonly projectDir?: string;
28
26
  readonly env?: {
29
27
  CODEX_HOME?: string | undefined;
30
28
  };
@@ -4,7 +4,7 @@ import { validateCodexTranscriptPath } from './transcript-path.js';
4
4
  import { classifyCodexVersion, CODEX_VERSION_NEXT_ACTION } from './codex-version.js';
5
5
  import { decodeTranscriptWindow, createNodeTranscriptPort, CODEX_INGESTION_MAX_BATCH_BYTES, TranscriptReplacedError } from './transcript-decoder.js';
6
6
  import { extractFields } from './ingestion-fields.js';
7
- import { buildLiveCorrectionCandidate, buildLiveToolCandidate, buildTranscriptCandidates } from './admission.js';
7
+ import { buildLiveCorrectionCandidate, buildTranscriptCandidates } from './admission.js';
8
8
  let activePort = null;
9
9
  /** Test seam: inject/inspect the transcript filesystem boundary (zero-read proofs). */
10
10
  export function setCodexTranscriptPortForTest(port) {
@@ -13,7 +13,7 @@ export function setCodexTranscriptPortForTest(port) {
13
13
  function activeTranscriptPort(options) {
14
14
  return options.port ?? activePort ?? createNodeTranscriptPort();
15
15
  }
16
- function ingestLiveObservation({ fields, rolloutIdentity, workspaceDir, projectDir, now }) {
16
+ function ingestLiveObservation({ fields, rolloutIdentity, workspaceDir, now }) {
17
17
  const nowIso = now.toISOString();
18
18
  let observation = null;
19
19
  if (fields.turnId !== null && fields.prompt !== null) {
@@ -61,9 +61,11 @@ function ingestLiveObservation({ fields, rolloutIdentity, workspaceDir, projectD
61
61
  return { status: 'degraded', reason: result.reason ?? 'governance_write_failed', nextAction: result.nextAction ?? 'inspect the workspace trajectory database.', warnings: result.warnings };
62
62
  // Slice B: hand the live observation to the admission pass as a normalized
63
63
  // candidate (SPEC §12) — the caller (pd-hook) runs detection/admission.
64
+ // Phase A: tool-call observations stay technical trajectory only; they never
65
+ // become a behavioral-deviation Pain candidate by themselves.
64
66
  const candidate = observation.kind === 'user_turn'
65
67
  ? buildLiveCorrectionCandidate({ fields, rolloutIdentity })
66
- : buildLiveToolCandidate({ fields, rolloutIdentity, ...(projectDir !== undefined ? { projectDir } : {}) });
68
+ : null;
67
69
  return {
68
70
  status: 'ok', inserted: result.inserted, enriched: result.enriched, duplicates: result.duplicates, warnings: result.warnings, lagBytes: 0,
69
71
  admissionCandidates: candidate !== null ? [candidate] : [],
@@ -258,7 +260,7 @@ export function ingestCodexConversation(rawPayload, kind, options) {
258
260
  return { status: 'degraded', reason: validated.reason, nextAction: validated.nextAction, warnings: [] };
259
261
  const now = options.now ?? new Date();
260
262
  if (kind === 'before_prompt_build' || kind === 'after_tool_call') {
261
- return ingestLiveObservation({ fields, rolloutIdentity: validated.rolloutIdentity, workspaceDir: options.workspaceDir, ...(options.projectDir !== undefined ? { projectDir: options.projectDir } : {}), now });
263
+ return ingestLiveObservation({ fields, rolloutIdentity: validated.rolloutIdentity, workspaceDir: options.workspaceDir, now });
262
264
  }
263
265
  return ingestTranscriptDelta({
264
266
  fallbackRootSessionId: fields.sessionId,
@@ -151,17 +151,16 @@ function recordRuleHostEvaluations(stateDir, sessionId, evaluations) {
151
151
  // Runs only when BOTH host.codex and codex_conversation_ingestion are
152
152
  // enabled — the flag gate below happens BEFORE any transcript path
153
153
  // validation or filesystem I/O, so flag-off means the transcript boundary
154
- // receives zero calls (SPEC §10 hard privacy invariant). Admission runs
155
- // BEFORE dispatch so a live tool failure is admitted through the same
156
- // canonical derivation first and the production handler's duplicate probe
157
- // then converges to a no-op (exactly one pain per real tool call).
154
+ // receives zero calls (SPEC §10 hard privacy invariant). Admission covers
155
+ // Owner corrections only: tool-call facts stay technical trajectory and never
156
+ // become a behavioral-deviation Pain by themselves (Phase A).
158
157
  async function runConversationIngestion(args) {
159
- const { rawPayload, kind, workspaceDir, projectDir, env } = args;
158
+ const { rawPayload, kind, workspaceDir, env } = args;
160
159
  if (kind !== 'turn_complete' && kind !== 'before_prompt_build' && kind !== 'after_tool_call')
161
160
  return [];
162
161
  const diagnostics = [];
163
162
  try {
164
- const outcome = ingestCodexConversation(rawPayload, kind, { workspaceDir, ...(projectDir !== undefined ? { projectDir } : {}), env });
163
+ const outcome = ingestCodexConversation(rawPayload, kind, { workspaceDir, env });
165
164
  if (outcome.status === 'degraded') {
166
165
  diagnostics.push(diagnostic(outcome.reason, outcome.nextAction));
167
166
  }
@@ -334,7 +333,6 @@ export async function processHookInvocation(rawStdin, _env = process.env, cwd =
334
333
  rawPayload: parsed,
335
334
  kind: event.kind,
336
335
  workspaceDir: resolution.workspaceDir,
337
- projectDir: requestedCwd,
338
336
  env: _env,
339
337
  // CR-07: the prefix parse above already decided this turn's user
340
338
  // prompt belongs to the explicit path — suppress the generic
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principles/codex-adapter",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Codex CLI host adapter for Principles Disciple — implements HostAdapter interface for OpenAI Codex CLI's stdin/stdout JSON hook model (ADR-0020).",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -9,7 +9,6 @@ export { isSourceKind } from './types.js';
9
9
  export type { SourceDescriptor } from './source-descriptors.js';
10
10
  export { SOURCE_DESCRIPTORS, getSourceDescriptor } from './source-descriptors.js';
11
11
  export { evaluateTriage } from './triage-policy.js';
12
- export { RISKY_HIGH_SCORE_THRESHOLD, REPEATED_FAILURE_THRESHOLD } from './triage-policy.js';
13
12
  export type { RawObservation } from './observation-resolver.js';
14
13
  export { resolveSourceKind, buildToolFailureObservation, buildManualPainObservation, } from './observation-resolver.js';
15
14
  export type { TriggerOutcome, TriggerDecision, TriggerControllerInput, } from './trigger-controller.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAK5F,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EACV,cAAc,EACd,eAAe,EACf,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAKpD,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EACV,cAAc,EACd,eAAe,EACf,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
@@ -8,8 +8,6 @@ export { isSourceKind } from './types.js';
8
8
  export { SOURCE_DESCRIPTORS, getSourceDescriptor } from './source-descriptors.js';
9
9
  // Triage policy
10
10
  export { evaluateTriage } from './triage-policy.js';
11
- // PRI-446: upgrade thresholds (single source of truth, migrated from plugin)
12
- export { RISKY_HIGH_SCORE_THRESHOLD, REPEATED_FAILURE_THRESHOLD } from './triage-policy.js';
13
11
  export { resolveSourceKind, buildToolFailureObservation, buildManualPainObservation, } from './observation-resolver.js';
14
12
  export { evaluateTriggerController, shouldCreateTask, isAdmittedOutcome, isSkippedOutcome, } from './trigger-controller.js';
15
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAElF,gBAAgB;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,6EAA6E;AAC7E,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAM5F,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAElF,gBAAgB;AAChB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMpD,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,yBAAyB,CAAC"}
@@ -9,8 +9,9 @@
9
9
  * - defaultDecision: the default triage decision
10
10
  * - reason: why this default was chosen
11
11
  * - nextAction: what should happen when this decision is applied
12
- * - canUpgrade: whether the plugin adapter may upgrade the decision
13
- * (e.g., rulehost_block can be upgraded to 'admit' for unsafe actions)
12
+ *
13
+ * Phase A: descriptor decisions are final. Technical failures and RuleHost
14
+ * blocks never upgrade to an admitted Pain (no context flags, no escalation).
14
15
  *
15
16
  * ERR checklist:
16
17
  * - ERR-002: Every descriptor carries reason + nextAction.
@@ -22,12 +23,6 @@ export interface SourceDescriptor {
22
23
  readonly defaultDecision: TriageDecision;
23
24
  readonly reason: string;
24
25
  readonly nextAction: string;
25
- /**
26
- * Whether the plugin adapter may upgrade this decision.
27
- * When true, the adapter can override defaultDecision based on context
28
- * (e.g., isUnsafeHighConfidence for rulehost_block).
29
- */
30
- readonly canUpgrade: boolean;
31
26
  }
32
27
  /**
33
28
  * Source kind descriptors. Order does not matter — lookup is by kind.
@@ -1 +1 @@
1
- {"version":3,"file":"source-descriptors.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/source-descriptors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAID;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,UAAU,EAAE,gBAAgB,CA4FvE,CAAC;AAIH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAElF"}
1
+ {"version":3,"file":"source-descriptors.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/source-descriptors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,UAAU,EAAE,gBAAgB,CA+EvE,CAAC;AAIH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,GAAG,SAAS,CAElF"}
@@ -9,8 +9,9 @@
9
9
  * - defaultDecision: the default triage decision
10
10
  * - reason: why this default was chosen
11
11
  * - nextAction: what should happen when this decision is applied
12
- * - canUpgrade: whether the plugin adapter may upgrade the decision
13
- * (e.g., rulehost_block can be upgraded to 'admit' for unsafe actions)
12
+ *
13
+ * Phase A: descriptor decisions are final. Technical failures and RuleHost
14
+ * blocks never upgrade to an admitted Pain (no context flags, no escalation).
14
15
  *
15
16
  * ERR checklist:
16
17
  * - ERR-002: Every descriptor carries reason + nextAction.
@@ -33,91 +34,78 @@ export const SOURCE_DESCRIPTORS = new Map([
33
34
  defaultDecision: 'admit',
34
35
  reason: 'Owner explicitly reported pain. Highest confidence signal.',
35
36
  nextAction: 'none',
36
- canUpgrade: false,
37
37
  }],
38
38
  ['agent_on_owner_request', {
39
39
  kind: 'agent_on_owner_request',
40
40
  defaultDecision: 'admit',
41
41
  reason: 'Agent recorded pain at owner request. Owner intent preserved.',
42
42
  nextAction: 'none',
43
- canUpgrade: false,
44
43
  }],
45
44
  ['tool_failure', {
46
45
  kind: 'tool_failure',
47
46
  defaultDecision: 'evidence_only',
48
- reason: 'Tool failure is infrastructure noise. PD does not own tool repair (ADR-0014).',
47
+ reason: 'Tool failure is a technical trajectory fact, never a behavioral-deviation Pain by itself (Phase A).',
49
48
  nextAction: 'store_as_evidence_for_later_correlation',
50
- canUpgrade: false,
51
49
  }],
52
50
  ['dispatch_error', {
53
51
  kind: 'dispatch_error',
54
52
  defaultDecision: 'evidence_only',
55
53
  reason: 'Dispatch/subagent routing error. Not a behavior pattern.',
56
54
  nextAction: 'store_as_evidence_for_later_correlation',
57
- canUpgrade: false,
58
55
  }],
59
56
  ['provider_failure', {
60
57
  kind: 'provider_failure',
61
58
  defaultDecision: 'health_only',
62
59
  reason: 'LLM provider failure. Infrastructure health signal, not owner-relevant behavior.',
63
60
  nextAction: 'record_in_health_telemetry',
64
- canUpgrade: false,
65
61
  }],
66
62
  ['rate_limit', {
67
63
  kind: 'rate_limit',
68
64
  defaultDecision: 'health_only',
69
65
  reason: 'LLM provider rate limit. Infrastructure health signal, not owner-relevant behavior.',
70
66
  nextAction: 'record_in_health_telemetry',
71
- canUpgrade: false,
72
67
  }],
73
68
  ['rulehost_block', {
74
69
  kind: 'rulehost_block',
75
70
  defaultDecision: 'evidence_only',
76
- reason: 'RuleHost block is near-miss evidence. Default evidence-only.',
71
+ reason: 'RuleHost block is a technical block fact. Correct blocks are not Owner pain; wrong blocks reach correction detection (Phase A).',
77
72
  nextAction: 'store_as_evidence_for_later_correlation',
78
- canUpgrade: true, // adapter can upgrade to 'admit' for high-confidence unsafe actions
79
73
  }],
80
74
  ['empathy_inferred', {
81
75
  kind: 'empathy_inferred',
82
76
  defaultDecision: 'owner_confirm',
83
77
  reason: 'Empathy-inferred frustration. Never silently creates diagnosis (PRODUCT_IDENTITY: owner-governed).',
84
78
  nextAction: 'request_owner_confirmation_before_diagnosis',
85
- canUpgrade: false,
86
79
  }],
87
80
  ['semantic', {
88
81
  kind: 'semantic',
89
82
  defaultDecision: 'evidence_only',
90
83
  reason: 'Keyword/detection match. Not explicit owner pain. Needs accumulation.',
91
84
  nextAction: 'store_as_evidence_for_later_correlation',
92
- canUpgrade: false,
93
85
  }],
94
86
  ['llm_paralysis', {
95
87
  kind: 'llm_paralysis',
96
88
  defaultDecision: 'evidence_only',
97
89
  reason: 'Session health signal. GFI alone cannot create diagnosis.',
98
90
  nextAction: 'store_as_evidence_for_later_correlation',
99
- canUpgrade: false,
100
91
  }],
101
92
  ['subagent_error', {
102
93
  kind: 'subagent_error',
103
94
  defaultDecision: 'evidence_only',
104
95
  reason: 'Subagent workflow failure. Not a behavior pattern by itself.',
105
96
  nextAction: 'store_as_evidence_for_later_correlation',
106
- canUpgrade: false,
107
97
  }],
108
98
  ['gfi_threshold', {
109
99
  kind: 'gfi_threshold',
110
100
  defaultDecision: 'evidence_only',
111
101
  reason: 'Accumulated GFI. GFI alone cannot create diagnosis per acceptance criteria.',
112
102
  nextAction: 'store_as_evidence_for_later_correlation',
113
- canUpgrade: false,
114
103
  }],
115
104
  ['unknown', {
116
105
  kind: 'unknown',
117
106
  defaultDecision: 'evidence_only',
118
107
  reason: 'Unclassified source. Conservative default.',
119
108
  nextAction: 'classify_source_kind_and_store_as_evidence',
120
- canUpgrade: false,
121
109
  }],
122
110
  ]);
123
111
  // ── Lookup ───────────────────────────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"source-descriptors.js","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/source-descriptors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"source-descriptors.js","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/source-descriptors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAaH,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA8C,IAAI,GAAG,CAA+B;IACjH,CAAC,gBAAgB,EAAE;YACjB,IAAI,EAAE,gBAAgB;YACtB,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,4DAA4D;YACpE,UAAU,EAAE,MAAM;SACnB,CAAC;IACF,CAAC,wBAAwB,EAAE;YACzB,IAAI,EAAE,wBAAwB;YAC9B,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,+DAA+D;YACvE,UAAU,EAAE,MAAM;SACnB,CAAC;IACF,CAAC,cAAc,EAAE;YACf,IAAI,EAAE,cAAc;YACpB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,qGAAqG;YAC7G,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,gBAAgB,EAAE;YACjB,IAAI,EAAE,gBAAgB;YACtB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,0DAA0D;YAClE,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,kBAAkB,EAAE;YACnB,IAAI,EAAE,kBAAkB;YACxB,eAAe,EAAE,aAAa;YAC9B,MAAM,EAAE,kFAAkF;YAC1F,UAAU,EAAE,4BAA4B;SACzC,CAAC;IACF,CAAC,YAAY,EAAE;YACb,IAAI,EAAE,YAAY;YAClB,eAAe,EAAE,aAAa;YAC9B,MAAM,EAAE,qFAAqF;YAC7F,UAAU,EAAE,4BAA4B;SACzC,CAAC;IACF,CAAC,gBAAgB,EAAE;YACjB,IAAI,EAAE,gBAAgB;YACtB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,iIAAiI;YACzI,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,kBAAkB,EAAE;YACnB,IAAI,EAAE,kBAAkB;YACxB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,oGAAoG;YAC5G,UAAU,EAAE,6CAA6C;SAC1D,CAAC;IACF,CAAC,UAAU,EAAE;YACX,IAAI,EAAE,UAAU;YAChB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,uEAAuE;YAC/E,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,eAAe,EAAE;YAChB,IAAI,EAAE,eAAe;YACrB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,2DAA2D;YACnE,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,gBAAgB,EAAE;YACjB,IAAI,EAAE,gBAAgB;YACtB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,8DAA8D;YACtE,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,eAAe,EAAE;YAChB,IAAI,EAAE,eAAe;YACrB,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,6EAA6E;YACrF,UAAU,EAAE,yCAAyC;SACtD,CAAC;IACF,CAAC,SAAS,EAAE;YACV,IAAI,EAAE,SAAS;YACf,eAAe,EAAE,eAAe;YAChC,MAAM,EAAE,4CAA4C;YACpD,UAAU,EAAE,4CAA4C;SACzD,CAAC;CACH,CAAC,CAAC;AAEH,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAgB;IAClD,OAAO,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
@@ -4,20 +4,22 @@
4
4
  * Pure policy evaluation for pre-diagnosis evidence triage.
5
5
  * No I/O, no plugin imports, no side effects.
6
6
  *
7
- * This module evaluates a TriageInput against source descriptors
8
- * and returns a TriageResult. The plugin adapter calls this function
9
- * and uses the result to decide whether to proceed to diagnosis.
7
+ * This module evaluates a TriageInput against source descriptors and returns
8
+ * a TriageResult. The plugin adapter calls this function and uses the result to
9
+ * decide whether to proceed to diagnosis.
10
+ *
11
+ * Phase A (legacy retirement): the context-dependent upgrade rules that used to
12
+ * turn technical failures or RuleHost blocks into admitted Pain are gone
13
+ * (`rulehost_block` / `tool_failure` upgrades, risky high-score and
14
+ * `consecutiveErrors >= 4` escalation). Triage is now a pure descriptor
15
+ * evaluation: only Owner-reported / Owner-requested evidence admits.
10
16
  *
11
17
  * ERR checklist:
12
18
  * - ERR-001: No `as` casts. Input validated with runtime guards.
13
19
  * - ERR-002: Every result carries structured reason + nextAction.
14
20
  * - ERR-005: Input is unknown, validated field-by-field.
15
21
  */
16
- import type { TriageInput, TriageResult } from './types.js';
17
- /** Pain score at or above which a risky action upgrades to admit. */
18
- export declare const RISKY_HIGH_SCORE_THRESHOLD = 70;
19
- /** Consecutive failures at or above which a tool failure upgrades to admit. */
20
- export declare const REPEATED_FAILURE_THRESHOLD = 4;
22
+ import type { TriageResult, TriageInput } from './types.js';
21
23
  /**
22
24
  * Evaluate triage policy for incoming evidence.
23
25
  *
@@ -26,7 +28,7 @@ export declare const REPEATED_FAILURE_THRESHOLD = 4;
26
28
  * - Create diagnostic tasks
27
29
  * - Import anything from the plugin layer
28
30
  *
29
- * It only reads source descriptors and applies policy rules.
31
+ * It only reads source descriptors.
30
32
  *
31
33
  * @param input - Triage input with source kind and context
32
34
  * @returns Structured triage result with decision, reason, and nextAction
@@ -1 +1 @@
1
- {"version":3,"file":"triage-policy.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/triage-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAA8B,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAWxF,qEAAqE;AACrE,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAC7C,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAyF5C;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CA4C/D"}
1
+ {"version":3,"file":"triage-policy.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/evidence-triage/triage-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAc,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIxE;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,YAAY,CAsB/D"}
@@ -4,9 +4,15 @@
4
4
  * Pure policy evaluation for pre-diagnosis evidence triage.
5
5
  * No I/O, no plugin imports, no side effects.
6
6
  *
7
- * This module evaluates a TriageInput against source descriptors
8
- * and returns a TriageResult. The plugin adapter calls this function
9
- * and uses the result to decide whether to proceed to diagnosis.
7
+ * This module evaluates a TriageInput against source descriptors and returns
8
+ * a TriageResult. The plugin adapter calls this function and uses the result to
9
+ * decide whether to proceed to diagnosis.
10
+ *
11
+ * Phase A (legacy retirement): the context-dependent upgrade rules that used to
12
+ * turn technical failures or RuleHost blocks into admitted Pain are gone
13
+ * (`rulehost_block` / `tool_failure` upgrades, risky high-score and
14
+ * `consecutiveErrors >= 4` escalation). Triage is now a pure descriptor
15
+ * evaluation: only Owner-reported / Owner-requested evidence admits.
10
16
  *
11
17
  * ERR checklist:
12
18
  * - ERR-001: No `as` casts. Input validated with runtime guards.
@@ -15,85 +21,6 @@
15
21
  */
16
22
  import { isSourceKind } from './types.js';
17
23
  import { getSourceDescriptor } from './source-descriptors.js';
18
- // ── Upgrade Thresholds (PRI-446 — migrated verbatim from the plugin adapter) ──
19
- //
20
- // These constants previously lived inline in the plugin-side triage-adapter
21
- // as magic numbers `70` and `4`. They are moved here byte-for-byte so the
22
- // upgrade decision has a single source of truth. The adapter now passes
23
- // isRisky / consecutiveErrors through to core instead of overriding the result.
24
- /** Pain score at or above which a risky action upgrades to admit. */
25
- export const RISKY_HIGH_SCORE_THRESHOLD = 70;
26
- /** Consecutive failures at or above which a tool failure upgrades to admit. */
27
- export const REPEATED_FAILURE_THRESHOLD = 4;
28
- // ── Upgrade Rules ───────────────────────────────────────────────────────────
29
- /**
30
- * Apply upgrade rules for upgradable source kinds.
31
- *
32
- * Three rules (PRI-446 consolidated all of them into core):
33
- * 1. rulehost_block + isUnsafeHighConfidence → admit
34
- * 2. tool_failure (or any evidence_only upgradeable kind) + isRisky + score >= 70 → admit
35
- * 3. tool_failure (or any evidence_only upgradeable kind) + consecutiveErrors >= 4 → admit
36
- *
37
- * This is the ONLY place where context-dependent upgrades happen in core.
38
- * The plugin adapter sets the context flags based on hook context.
39
- *
40
- * Rule precedence matches the prior plugin implementation: risky high-score is
41
- * checked before repeated failure, but since both produce the same upgraded
42
- * decision with the same nextAction, the order is only observable via the
43
- * reason string. We preserve the plugin's prior order (risky first).
44
- */
45
- function applyUpgradeRules(input, defaultDecision) {
46
- if (defaultDecision !== 'evidence_only') {
47
- return defaultDecision;
48
- }
49
- // Rule 1: rulehost_block unsafe action (pre-existing).
50
- if (input.sourceKind === 'rulehost_block' && input.isUnsafeHighConfidence === true) {
51
- return 'admit';
52
- }
53
- // Rule 2: risky high-score (migrated from plugin, PRI-446).
54
- if (input.isRisky === true && input.score >= RISKY_HIGH_SCORE_THRESHOLD) {
55
- return 'admit';
56
- }
57
- // Rule 3: repeated failure (migrated from plugin, PRI-446).
58
- if (input.consecutiveErrors !== undefined && input.consecutiveErrors >= REPEATED_FAILURE_THRESHOLD) {
59
- return 'admit';
60
- }
61
- return defaultDecision;
62
- }
63
- function getUpgradeReason(sourceKind, decision, input) {
64
- if (decision !== 'admit') {
65
- return `Upgraded decision for ${sourceKind}: ${decision}`;
66
- }
67
- if (sourceKind === 'rulehost_block' && input.isUnsafeHighConfidence === true) {
68
- return `RuleHost blocked a high-confidence unsafe action (score=${input.score}). Upgrading to direct diagnosis.`;
69
- }
70
- // PRI-446: verbatim string from the plugin triage-adapter
71
- if (input.isRisky === true && input.score >= RISKY_HIGH_SCORE_THRESHOLD) {
72
- return 'Risky high-score operation overrides evidence-only decision. Immediate diagnosis required.';
73
- }
74
- // PRI-446: verbatim string from the plugin triage-adapter
75
- if (input.consecutiveErrors !== undefined && input.consecutiveErrors >= REPEATED_FAILURE_THRESHOLD) {
76
- return 'Repeated failures override evidence-only decision. Pattern suggests systemic issue requiring diagnosis.';
77
- }
78
- // Should not reach here — fallback
79
- return `Upgraded decision for ${sourceKind}: ${decision}`;
80
- }
81
- function getUpgradeNextAction(sourceKind, decision, input) {
82
- if (decision !== 'admit') {
83
- return 'none';
84
- }
85
- if (sourceKind === 'rulehost_block' && input.isUnsafeHighConfidence === true) {
86
- return 'none';
87
- }
88
- // PRI-446: verbatim nextAction from the plugin triage-adapter
89
- // (both risky-high-score and repeated-failure used 'create_diagnostic_task').
90
- if ((input.isRisky === true && input.score >= RISKY_HIGH_SCORE_THRESHOLD) ||
91
- (input.consecutiveErrors !== undefined && input.consecutiveErrors >= REPEATED_FAILURE_THRESHOLD)) {
92
- return 'create_diagnostic_task';
93
- }
94
- return 'none';
95
- }
96
- // ── Evaluation ──────────────────────────────────────────────────────────────
97
24
  /**
98
25
  * Evaluate triage policy for incoming evidence.
99
26
  *
@@ -102,7 +29,7 @@ function getUpgradeNextAction(sourceKind, decision, input) {
102
29
  * - Create diagnostic tasks
103
30
  * - Import anything from the plugin layer
104
31
  *
105
- * It only reads source descriptors and applies policy rules.
32
+ * It only reads source descriptors.
106
33
  *
107
34
  * @param input - Triage input with source kind and context
108
35
  * @returns Structured triage result with decision, reason, and nextAction
@@ -121,26 +48,6 @@ export function evaluateTriage(input) {
121
48
  nextAction: 'classify_source_kind_and_store_as_evidence',
122
49
  };
123
50
  }
124
- // Apply upgrade rules. PRI-446: rule 1 (rulehost_block) is gated by
125
- // descriptor.canUpgrade; rules 2/3 (risky high-score / repeated failure) are
126
- // context-driven and apply to any evidence_only kind when the relevant flag is
127
- // present, matching the prior plugin behavior. applyUpgradeRules internally
128
- // guards on defaultDecision === 'evidence_only', so non-upgradeable kinds
129
- // (admit/health_only/owner_confirm) are never affected.
130
- const upgradeable = descriptor.canUpgrade ||
131
- input.isRisky !== undefined ||
132
- input.consecutiveErrors !== undefined;
133
- if (upgradeable) {
134
- const upgraded = applyUpgradeRules(input, descriptor.defaultDecision);
135
- if (upgraded !== descriptor.defaultDecision) {
136
- return {
137
- decision: upgraded,
138
- sourceKind,
139
- reason: getUpgradeReason(sourceKind, upgraded, input),
140
- nextAction: getUpgradeNextAction(sourceKind, upgraded, input),
141
- };
142
- }
143
- }
144
51
  return {
145
52
  decision: descriptor.defaultDecision,
146
53
  sourceKind,