create-principles-disciple 1.127.1 → 1.128.0

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 (114) hide show
  1. package/console/dist/server/config/pd-config-store.js +7 -2
  2. package/console/dist/server/models/HealthCheckModel.d.ts +4 -1
  3. package/console/dist/server/models/HealthCheckModel.js +6 -5
  4. package/console/dist/server/routes/update.js +8 -83
  5. package/console/dist/server/utils/installed-layout.d.ts +21 -0
  6. package/console/dist/server/utils/installed-layout.js +92 -0
  7. package/console/dist/server/utils/pd-backups.d.ts +9 -0
  8. package/console/dist/server/utils/pd-backups.js +5 -1
  9. package/console/dist/ui/pages/settings/UpdatePage.js +2 -1
  10. package/console/dist/web/assets/app.js +975 -824
  11. package/console/dist/web/index.html +4 -0
  12. package/core/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js +69 -0
  13. package/core/dist/runtime-v2/activation/__tests__/production-gate-deps.test.js.map +1 -1
  14. package/core/dist/runtime-v2/activation/production-gate-deps.d.ts.map +1 -1
  15. package/core/dist/runtime-v2/activation/production-gate-deps.js +13 -46
  16. package/core/dist/runtime-v2/activation/production-gate-deps.js.map +1 -1
  17. package/core/dist/runtime-v2/config/__tests__/pd-config-sparse-bootstrap.test.d.ts +2 -0
  18. package/core/dist/runtime-v2/config/__tests__/pd-config-sparse-bootstrap.test.d.ts.map +1 -0
  19. package/core/dist/runtime-v2/config/__tests__/pd-config-sparse-bootstrap.test.js +143 -0
  20. package/core/dist/runtime-v2/config/__tests__/pd-config-sparse-bootstrap.test.js.map +1 -0
  21. package/core/dist/runtime-v2/feature-flags/__tests__/installer-config-parity.test.js +44 -27
  22. package/core/dist/runtime-v2/feature-flags/__tests__/installer-config-parity.test.js.map +1 -1
  23. package/core/dist/runtime-v2/internalization/__tests__/adversarial-feedback.test.js +9 -0
  24. package/core/dist/runtime-v2/internalization/__tests__/adversarial-feedback.test.js.map +1 -1
  25. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js +15 -5
  26. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder.test.js.map +1 -1
  27. package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.d.ts +2 -0
  28. package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.d.ts.map +1 -0
  29. package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.js +377 -0
  30. package/core/dist/runtime-v2/internalization/__tests__/context-resolution.test.js.map +1 -0
  31. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.d.ts +2 -0
  32. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.d.ts.map +1 -0
  33. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js +413 -0
  34. package/core/dist/runtime-v2/internalization/__tests__/evaluator-artificer-repair-replay.test.js.map +1 -0
  35. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js +136 -0
  36. package/core/dist/runtime-v2/internalization/__tests__/evaluator-gate-authority.test.js.map +1 -1
  37. package/core/dist/runtime-v2/internalization/__tests__/progressive-disclosure-spike.test.js +8 -8
  38. package/core/dist/runtime-v2/internalization/__tests__/progressive-disclosure-spike.test.js.map +1 -1
  39. package/core/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.d.ts +2 -0
  40. package/core/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.d.ts.map +1 -0
  41. package/core/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.js +340 -0
  42. package/core/dist/runtime-v2/internalization/__tests__/repair-replay-resolver.test.js.map +1 -0
  43. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.d.ts +2 -0
  44. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.d.ts.map +1 -0
  45. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js +628 -0
  46. package/core/dist/runtime-v2/internalization/__tests__/shared-information-plane-runner.test.js.map +1 -0
  47. package/core/dist/runtime-v2/internalization/adversarial-feedback.d.ts.map +1 -1
  48. package/core/dist/runtime-v2/internalization/adversarial-feedback.js +7 -1
  49. package/core/dist/runtime-v2/internalization/adversarial-feedback.js.map +1 -1
  50. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts +9 -2
  51. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  52. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +19 -1
  53. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  54. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts +23 -0
  55. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
  56. package/core/dist/runtime-v2/internalization/artificer-runner.js +184 -16
  57. package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
  58. package/core/dist/runtime-v2/internalization/context-manifests.d.ts +90 -17
  59. package/core/dist/runtime-v2/internalization/context-manifests.d.ts.map +1 -1
  60. package/core/dist/runtime-v2/internalization/context-manifests.js +124 -27
  61. package/core/dist/runtime-v2/internalization/context-manifests.js.map +1 -1
  62. package/core/dist/runtime-v2/internalization/context-resolution.d.ts +189 -0
  63. package/core/dist/runtime-v2/internalization/context-resolution.d.ts.map +1 -0
  64. package/core/dist/runtime-v2/internalization/context-resolution.js +317 -0
  65. package/core/dist/runtime-v2/internalization/context-resolution.js.map +1 -0
  66. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +18 -1
  67. package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
  68. package/core/dist/runtime-v2/internalization/evaluator-output.js +12 -2
  69. package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
  70. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts +32 -0
  71. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  72. package/core/dist/runtime-v2/internalization/evaluator-runner.js +171 -12
  73. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  74. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.d.ts +18 -1
  75. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.d.ts.map +1 -1
  76. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js +20 -0
  77. package/core/dist/runtime-v2/internalization/refiner-sandbox-wrapper.js.map +1 -1
  78. package/core/dist/runtime-v2/internalization/repair-replay-resolver.d.ts +112 -0
  79. package/core/dist/runtime-v2/internalization/repair-replay-resolver.d.ts.map +1 -0
  80. package/core/dist/runtime-v2/internalization/repair-replay-resolver.js +332 -0
  81. package/core/dist/runtime-v2/internalization/repair-replay-resolver.js.map +1 -0
  82. package/core/dist/runtime-v2/runner/base-peer-runner.d.ts +62 -17
  83. package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -1
  84. package/core/dist/runtime-v2/runner/base-peer-runner.js +116 -10
  85. package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -1
  86. package/core/dist/telemetry-event.d.ts +2 -2
  87. package/core/dist/telemetry-event.d.ts.map +1 -1
  88. package/core/dist/telemetry-event.js +61 -0
  89. package/core/dist/telemetry-event.js.map +1 -1
  90. package/core/package.json +1 -1
  91. package/dist/installer.d.ts.map +1 -1
  92. package/dist/installer.js +16 -12
  93. package/dist/installer.js.map +1 -1
  94. package/dist/mvp-config.d.ts +22 -15
  95. package/dist/mvp-config.d.ts.map +1 -1
  96. package/dist/mvp-config.js +48 -106
  97. package/dist/mvp-config.js.map +1 -1
  98. package/host-runtime/package.json +1 -1
  99. package/install-layout/package.json +7 -3
  100. package/package.json +1 -1
  101. package/pd-cli/dist/commands/console.d.ts +13 -0
  102. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  103. package/pd-cli/dist/commands/console.js +104 -0
  104. package/pd-cli/dist/commands/console.js.map +1 -1
  105. package/pd-cli/dist/commands/runtime-init.d.ts.map +1 -1
  106. package/pd-cli/dist/commands/runtime-init.js +8 -12
  107. package/pd-cli/dist/commands/runtime-init.js.map +1 -1
  108. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  109. package/pd-cli/dist/commands/runtime-internalization-run-once.js +7 -1
  110. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  111. package/pd-cli/package.json +1 -1
  112. package/plugin/dist/bundle.js +449 -437
  113. package/plugin/dist/governance-audit.js +141 -141
  114. package/plugin/dist/rulehost-evidence.js +153 -153
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Shared Information Plane — context resolution composition (design §6.4/§6.6).
3
+ *
4
+ * Pure logic only: no I/O, no fs, no DB, no network (Core vs Plugin boundary,
5
+ * AGENTS.md `antipattern-core-io`).
6
+ *
7
+ * This module is the seam that turns three independent fact-acquisition
8
+ * channels into ONE `available` map consumed by `resolveInjection`:
9
+ *
10
+ * 1. predecessor summary envelope → `summary-field-reader` (pure, Layer 1)
11
+ * 2. ancestry content → `CandidateLineage` nodes (Layer 2; the
12
+ * traversal/I/O is owned by the caller).
13
+ * Serves BOTH `<stage>.raw.*` and
14
+ * `<stage>.summary.*` for any ancestor.
15
+ * 3. related references → explicit caller-provided sources
16
+ * (e.g. the PR-A replay evidence), which
17
+ * are causal references — NOT ancestry
18
+ *
19
+ * Why three channels stay separate at acquisition but merge at composition
20
+ * (design §33 / INV-LINEAGE-SCOPE): `lineageArtifactIds` expresses *content
21
+ * ancestry*; a repair's `sourceEvaluatorTaskId` expresses *causal reference*.
22
+ * Collapsing them into one data structure would silently redefine what
23
+ * "lineage" means. They are unified at read time, never at write time.
24
+ *
25
+ * rc-1/rc-5: every source `contentJson` stays `unknown`; all reads use
26
+ * `Object.hasOwn` + typeof/Array.isArray guards — no `as` casts.
27
+ */
28
+ import type { TruncationRecord } from './prompt-budget-manager.js';
29
+ /**
30
+ * Context field path grammar (design §6.6, extended for tier2 + related refs):
31
+ * `<ns>.summary.<key>` — ArtifactSummary / related summary table
32
+ * `<ns>.predecessorSummary.<key>` — forwarded predecessor summary
33
+ * `<ns>.raw.<dotted.path>` — full contentJson (ancestry) or a related
34
+ * raw table (related refs)
35
+ */
36
+ export type ContextPathLayer = 'raw' | 'summary' | 'predecessorSummary';
37
+ export interface ParsedContextPath {
38
+ readonly namespace: string;
39
+ readonly layer: ContextPathLayer;
40
+ /** Path segments after the layer marker. Empty is never valid. */
41
+ readonly rest: readonly string[];
42
+ }
43
+ /**
44
+ * Split a manifest field path into namespace / layer / rest.
45
+ * Returns null for paths that do not follow the grammar (e.g. malformed,
46
+ * too short) so callers can skip them instead of throwing.
47
+ */
48
+ export declare function parseContextPath(fieldPath: string): ParsedContextPath | null;
49
+ /**
50
+ * Read a dotted path out of an untrusted contentJson (rc-1/rc-5).
51
+ *
52
+ * Supports array element addressing via numeric segments
53
+ * (`candidates.0.betterDecision`) because several durable artifacts nest their
54
+ * semantic payload under an array (DreamerOutput.candidates). No I/O, no
55
+ * lineage traversal, no manifest knowledge — it only walks a path.
56
+ *
57
+ * Returns undefined for: non-object intermediates, missing own properties,
58
+ * out-of-range or non-numeric array access, and forbidden keys.
59
+ */
60
+ export declare function readRawField(rawPath: readonly string[], contentJson: unknown): unknown | undefined;
61
+ /**
62
+ * A manifest NAMESPACE is a *semantic* stage; a lineage node's stage is the
63
+ * *producer taskKind* (two-hop F1). Explicit fixed mapping — never fuzzy:
64
+ *
65
+ * diagnostician → the manifest addresses the final diagnosis artifact
66
+ * (DiagnosticianOutputV1). Its canonical producer on the DEFAULT split
67
+ * pipeline is taskKind `diag_router` (SplitDiagnosticianRunner stage C);
68
+ * the legacy monolithic runner committed the identical output contract
69
+ * under taskKind `diagnostician`. Both must resolve the same namespace.
70
+ *
71
+ * Adding an alias here is a contract change — the resolver's nearest-match
72
+ * then accepts the listed producer kinds for that namespace.
73
+ */
74
+ export declare const SEMANTIC_STAGE_ALIASES: Readonly<Record<string, readonly string[]>>;
75
+ /**
76
+ * One durable ancestry node exposed to the raw reader. Built by the caller
77
+ * from `CandidateLineage` nodes — this module never performs the traversal.
78
+ *
79
+ * `stage` is the two-hop `sourceTaskId → task.taskKind` value (design §6.4,
80
+ * F1), never `artifactKind`: every internalization artifact is `principle`,
81
+ * so `artifactKind` carries no stage authority.
82
+ */
83
+ export interface RawStageSource {
84
+ readonly stage: string;
85
+ /** rc-1: stays `unknown`; narrowed only by `readRawField`. */
86
+ readonly contentJson: unknown;
87
+ }
88
+ /**
89
+ * Convert CandidateLineage nodes into raw stage sources.
90
+ *
91
+ * Order is preserved, which is what makes stage selection deterministic:
92
+ * `CandidateLineage.resolve` walks BFS from the start artifact, so the FIRST
93
+ * node matching a stage is the NEAREST ancestor (design §20). Later duplicates
94
+ * are ignored — never a positional/arbitrary pick.
95
+ *
96
+ * Nodes whose stage could not be determined (`taskKind === 'unknown'`) carry no
97
+ * stage authority and are dropped.
98
+ */
99
+ export declare function toRawStageSources(nodes: readonly {
100
+ readonly taskKind: string;
101
+ readonly contentJson: unknown;
102
+ }[]): readonly RawStageSource[];
103
+ /**
104
+ * Split a manifest's tier2 into (ancestry raw paths, related raw paths).
105
+ *
106
+ * Related namespaces are excluded from the ancestry walk explicitly: a related
107
+ * reference is a causal pointer supplied by the caller, so it must never be
108
+ * mistaken for an ancestor stage — even if a taskKind happened to share the
109
+ * name. This is the executable form of INV-LINEAGE-SCOPE (design §33).
110
+ */
111
+ export declare function partitionTier2Paths(tier2Paths: readonly string[], relatedNamespaces: readonly string[]): {
112
+ readonly ancestry: readonly string[];
113
+ readonly related: readonly string[];
114
+ };
115
+ /**
116
+ * Resolve ancestor-declared paths against ancestry sources — BOTH layers:
117
+ *
118
+ * `<stage>.raw.<dotted.path>` — full contentJson walk (`readRawField`)
119
+ * `<stage>.summary.<key>` — the ancestor's own Layer 0 envelope
120
+ * (`readSummaryField`)
121
+ *
122
+ * Why the summary layer needs the ancestry channel too (PR B, evidence-backed):
123
+ * `readSummaryField` deliberately STRIPS the leading `<stage>.` namespace and
124
+ * reads only its single `predecessorContentJson`. That convention is correct
125
+ * for manifests whose stage namespace is the runner's direct predecessor
126
+ * (dreamer/scribe/artificer), but a manifest that names an ancestor further up
127
+ * the chain (the Evaluator's `scribe.*` / `dreamer.*` / `diagnostician.*`)
128
+ * would otherwise have those paths structurally unreachable — they would land
129
+ * in `absent` forever and force the information-floor fallback on every run.
130
+ * The lineage walk already holds every ancestor's contentJson, so the same
131
+ * traversal that serves `raw` also serves `summary`, with no extra store read.
132
+ *
133
+ * First (nearest) matching stage wins; unresolvable paths are omitted so the
134
+ * caller's information-floor logic records them in `absent`.
135
+ *
136
+ * `predecessorSummary` is intentionally NOT answered here: it is the
137
+ * direct-predecessor forwarding concept owned by Channel 1.
138
+ *
139
+ * Namespace → node matching honors `SEMANTIC_STAGE_ALIASES`: a manifest
140
+ * namespace is the SEMANTIC stage, a node's stage is the producer taskKind.
141
+ */
142
+ export declare function resolveAncestryPaths(fieldPaths: readonly string[], sources: readonly RawStageSource[]): ReadonlyMap<string, unknown>;
143
+ /**
144
+ * A related — NOT ancestral — fact source, exposed under its own namespace.
145
+ *
146
+ * Deliberately narrow: a flat namespace with two flat lookup tables. It is not
147
+ * a relation graph and cannot express arbitrary edges. Each source is supplied
148
+ * explicitly by the caller, so nothing is discovered or inferred at read time.
149
+ *
150
+ * Values are already-bounded objects: this seam never re-expands a durable
151
+ * artifact. For replay evidence the caller passes the PR-A
152
+ * `RepairReplayContext`, whose ≤16 bound (MAX_REPLAY_FAILURES_IN_REPAIR) is
153
+ * therefore preserved through the information plane (design §43).
154
+ */
155
+ export interface RelatedContextSource {
156
+ /** Manifest namespace this source answers, e.g. `replay`. */
157
+ readonly namespace: string;
158
+ readonly summary?: Readonly<Record<string, unknown>>;
159
+ readonly raw?: Readonly<Record<string, unknown>>;
160
+ }
161
+ /**
162
+ * Resolve `<ns>.summary.<key>` / `<ns>.raw.<key>` against related sources.
163
+ * Related refs expose flat keys only — a multi-segment rest path is not a
164
+ * related reference and is skipped (it belongs to the ancestry reader).
165
+ */
166
+ export declare function resolveRelatedPaths(fieldPaths: readonly string[], sources: readonly RelatedContextSource[]): ReadonlyMap<string, unknown>;
167
+ /**
168
+ * Merge the channel maps into one `available` map. FIRST WRITER WINS: the
169
+ * predecessor summary envelope is the highest-authority local source, then
170
+ * ancestry raw, then related. Channel namespaces are disjoint by construction
171
+ * (a path is either a summary path, an ancestry raw path, or a related path),
172
+ * so the rule only matters defensively — but it keeps the result deterministic.
173
+ */
174
+ export declare function mergeContextFields(base: ReadonlyMap<string, unknown>, extras: readonly ReadonlyMap<string, unknown>[]): ReadonlyMap<string, unknown>;
175
+ /**
176
+ * Required paths that did NOT reach the prompt — either absent from the
177
+ * available map or dropped/truncated by the budget.
178
+ *
179
+ * This is the regression guard for "Stage2 enabled + raw fields silently
180
+ * absent": a required field that was truncated by `PromptBudgetManager` counts
181
+ * as unresolved just like an absent one, because the runner's semantic
182
+ * requirement was still not met.
183
+ */
184
+ export declare function findUnresolvedRequiredPaths(params: {
185
+ readonly required: readonly string[];
186
+ readonly absent: readonly string[];
187
+ readonly truncated: readonly TruncationRecord[];
188
+ }): readonly string[];
189
+ //# sourceMappingURL=context-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-resolution.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/context-resolution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,317 @@
1
+ /**
2
+ * Shared Information Plane — context resolution composition (design §6.4/§6.6).
3
+ *
4
+ * Pure logic only: no I/O, no fs, no DB, no network (Core vs Plugin boundary,
5
+ * AGENTS.md `antipattern-core-io`).
6
+ *
7
+ * This module is the seam that turns three independent fact-acquisition
8
+ * channels into ONE `available` map consumed by `resolveInjection`:
9
+ *
10
+ * 1. predecessor summary envelope → `summary-field-reader` (pure, Layer 1)
11
+ * 2. ancestry content → `CandidateLineage` nodes (Layer 2; the
12
+ * traversal/I/O is owned by the caller).
13
+ * Serves BOTH `<stage>.raw.*` and
14
+ * `<stage>.summary.*` for any ancestor.
15
+ * 3. related references → explicit caller-provided sources
16
+ * (e.g. the PR-A replay evidence), which
17
+ * are causal references — NOT ancestry
18
+ *
19
+ * Why three channels stay separate at acquisition but merge at composition
20
+ * (design §33 / INV-LINEAGE-SCOPE): `lineageArtifactIds` expresses *content
21
+ * ancestry*; a repair's `sourceEvaluatorTaskId` expresses *causal reference*.
22
+ * Collapsing them into one data structure would silently redefine what
23
+ * "lineage" means. They are unified at read time, never at write time.
24
+ *
25
+ * rc-1/rc-5: every source `contentJson` stays `unknown`; all reads use
26
+ * `Object.hasOwn` + typeof/Array.isArray guards — no `as` casts.
27
+ */
28
+ import { readSummaryField } from './summary-field-reader.js';
29
+ import { deriveArtifactSummary, SUMMARY_RUNNER_KINDS, } from './artifact-summary.js';
30
+ /**
31
+ * Split a manifest field path into namespace / layer / rest.
32
+ * Returns null for paths that do not follow the grammar (e.g. malformed,
33
+ * too short) so callers can skip them instead of throwing.
34
+ */
35
+ export function parseContextPath(fieldPath) {
36
+ const parts = fieldPath.split('.');
37
+ if (parts.length < 3)
38
+ return null;
39
+ const [namespace, layer] = parts;
40
+ const rest = parts.slice(2);
41
+ if (namespace === undefined || namespace === '')
42
+ return null;
43
+ if (layer !== 'raw' && layer !== 'summary' && layer !== 'predecessorSummary')
44
+ return null;
45
+ if (rest.length === 0 || rest.some((segment) => segment === ''))
46
+ return null;
47
+ return { namespace, layer, rest };
48
+ }
49
+ // ── Pure raw field reader (design §16–§18) ──────────────────────────────────
50
+ /**
51
+ * Keys that must never be traversed: reading them is how prototype pollution
52
+ * enters a context map. Rejected at every segment, not just the first.
53
+ */
54
+ const FORBIDDEN_SEGMENTS = new Set([
55
+ '__proto__',
56
+ 'constructor',
57
+ 'prototype',
58
+ ]);
59
+ function isRecord(value) {
60
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
61
+ }
62
+ /** A dotted segment addressing an array element, e.g. `0` in `candidates.0`. */
63
+ const ARRAY_INDEX = /^(0|[1-9][0-9]*)$/;
64
+ /**
65
+ * Read a dotted path out of an untrusted contentJson (rc-1/rc-5).
66
+ *
67
+ * Supports array element addressing via numeric segments
68
+ * (`candidates.0.betterDecision`) because several durable artifacts nest their
69
+ * semantic payload under an array (DreamerOutput.candidates). No I/O, no
70
+ * lineage traversal, no manifest knowledge — it only walks a path.
71
+ *
72
+ * Returns undefined for: non-object intermediates, missing own properties,
73
+ * out-of-range or non-numeric array access, and forbidden keys.
74
+ */
75
+ export function readRawField(rawPath, contentJson) {
76
+ let current = contentJson;
77
+ for (const segment of rawPath) {
78
+ if (FORBIDDEN_SEGMENTS.has(segment))
79
+ return undefined;
80
+ if (Array.isArray(current)) {
81
+ if (!ARRAY_INDEX.test(segment))
82
+ return undefined;
83
+ if (!Object.hasOwn(current, segment))
84
+ return undefined;
85
+ current = current[Number(segment)];
86
+ continue;
87
+ }
88
+ if (!isRecord(current))
89
+ return undefined;
90
+ if (!Object.hasOwn(current, segment))
91
+ return undefined;
92
+ current = current[segment];
93
+ }
94
+ return current;
95
+ }
96
+ // ── Channel 2: ancestry raw resolution (CandidateLineage) ───────────────────
97
+ /**
98
+ * A manifest NAMESPACE is a *semantic* stage; a lineage node's stage is the
99
+ * *producer taskKind* (two-hop F1). Explicit fixed mapping — never fuzzy:
100
+ *
101
+ * diagnostician → the manifest addresses the final diagnosis artifact
102
+ * (DiagnosticianOutputV1). Its canonical producer on the DEFAULT split
103
+ * pipeline is taskKind `diag_router` (SplitDiagnosticianRunner stage C);
104
+ * the legacy monolithic runner committed the identical output contract
105
+ * under taskKind `diagnostician`. Both must resolve the same namespace.
106
+ *
107
+ * Adding an alias here is a contract change — the resolver's nearest-match
108
+ * then accepts the listed producer kinds for that namespace.
109
+ */
110
+ export const SEMANTIC_STAGE_ALIASES = {
111
+ diagnostician: ['diagnostician', 'diag_router'],
112
+ };
113
+ /**
114
+ * Producer taskKind used for the read-time summary projection (below).
115
+ * `diagnostician` is NOT a SummaryRunnerKind, but its output is byte-for-byte
116
+ * the diag_router contract, so the derivation reuses the diag_router resolver.
117
+ */
118
+ const SUMMARY_DERIVATION_STAGE = {
119
+ diagnostician: 'diag_router',
120
+ };
121
+ /**
122
+ * Read `<stage>.summary.<key>` from an ancestry node, with a bounded
123
+ * read-time projection fallback.
124
+ *
125
+ * Why the fallback exists (review round): the writer-side envelope for diag
126
+ * outputs is SKIPPED (`output_summary_key_collision`, base-peer-runner) —
127
+ * DiagnosticianOutputV1 owns a top-level `summary` STRING that the Layer 0
128
+ * envelope must not overwrite. So `diagnostician.summary.rootSymptom` /
129
+ * `category` would be structurally absent forever. The fields are derivable
130
+ * from the unchanged durable output via the SAME derivation the writer would
131
+ * have used (`deriveArtifactSummary`, pure, no I/O), so the read side applies
132
+ * it as a bounded projection. Deterministic: same output → same fields. Only
133
+ * fires when the direct envelope read misses; still-absent → `absent` floor.
134
+ */
135
+ function readSummaryWithProjection(fieldPath, stage, contentJson) {
136
+ const direct = readSummaryField(fieldPath, contentJson);
137
+ if (direct !== undefined)
138
+ return direct;
139
+ if (!isRecord(contentJson))
140
+ return undefined;
141
+ const derivationStage = SUMMARY_DERIVATION_STAGE[stage]
142
+ ?? (SUMMARY_RUNNER_KINDS.includes(stage) ? stage : undefined);
143
+ if (derivationStage === undefined)
144
+ return undefined;
145
+ const derived = deriveArtifactSummary(derivationStage, contentJson);
146
+ if (!derived.ok)
147
+ return undefined;
148
+ const parsed = parseContextPath(fieldPath);
149
+ if (parsed === null)
150
+ return undefined;
151
+ const [key] = parsed.rest;
152
+ if (key === undefined || FORBIDDEN_SEGMENTS.has(key))
153
+ return undefined;
154
+ if (key === 'headline')
155
+ return derived.value.headline;
156
+ if (!Object.hasOwn(derived.value.fields, key))
157
+ return undefined;
158
+ return derived.value.fields[key];
159
+ }
160
+ /**
161
+ * Convert CandidateLineage nodes into raw stage sources.
162
+ *
163
+ * Order is preserved, which is what makes stage selection deterministic:
164
+ * `CandidateLineage.resolve` walks BFS from the start artifact, so the FIRST
165
+ * node matching a stage is the NEAREST ancestor (design §20). Later duplicates
166
+ * are ignored — never a positional/arbitrary pick.
167
+ *
168
+ * Nodes whose stage could not be determined (`taskKind === 'unknown'`) carry no
169
+ * stage authority and are dropped.
170
+ */
171
+ export function toRawStageSources(nodes) {
172
+ const sources = [];
173
+ for (const node of nodes) {
174
+ if (node.taskKind === 'unknown' || node.taskKind === '')
175
+ continue;
176
+ sources.push({ stage: node.taskKind, contentJson: node.contentJson });
177
+ }
178
+ return sources;
179
+ }
180
+ /**
181
+ * Split a manifest's tier2 into (ancestry raw paths, related raw paths).
182
+ *
183
+ * Related namespaces are excluded from the ancestry walk explicitly: a related
184
+ * reference is a causal pointer supplied by the caller, so it must never be
185
+ * mistaken for an ancestor stage — even if a taskKind happened to share the
186
+ * name. This is the executable form of INV-LINEAGE-SCOPE (design §33).
187
+ */
188
+ export function partitionTier2Paths(tier2Paths, relatedNamespaces) {
189
+ const related = new Set(relatedNamespaces);
190
+ const ancestry = [];
191
+ const relatedPaths = [];
192
+ for (const fieldPath of tier2Paths) {
193
+ const parsed = parseContextPath(fieldPath);
194
+ if (parsed !== null && parsed.layer === 'raw' && related.has(parsed.namespace)) {
195
+ relatedPaths.push(fieldPath);
196
+ continue;
197
+ }
198
+ ancestry.push(fieldPath);
199
+ }
200
+ return { ancestry, related: relatedPaths };
201
+ }
202
+ /**
203
+ * Resolve ancestor-declared paths against ancestry sources — BOTH layers:
204
+ *
205
+ * `<stage>.raw.<dotted.path>` — full contentJson walk (`readRawField`)
206
+ * `<stage>.summary.<key>` — the ancestor's own Layer 0 envelope
207
+ * (`readSummaryField`)
208
+ *
209
+ * Why the summary layer needs the ancestry channel too (PR B, evidence-backed):
210
+ * `readSummaryField` deliberately STRIPS the leading `<stage>.` namespace and
211
+ * reads only its single `predecessorContentJson`. That convention is correct
212
+ * for manifests whose stage namespace is the runner's direct predecessor
213
+ * (dreamer/scribe/artificer), but a manifest that names an ancestor further up
214
+ * the chain (the Evaluator's `scribe.*` / `dreamer.*` / `diagnostician.*`)
215
+ * would otherwise have those paths structurally unreachable — they would land
216
+ * in `absent` forever and force the information-floor fallback on every run.
217
+ * The lineage walk already holds every ancestor's contentJson, so the same
218
+ * traversal that serves `raw` also serves `summary`, with no extra store read.
219
+ *
220
+ * First (nearest) matching stage wins; unresolvable paths are omitted so the
221
+ * caller's information-floor logic records them in `absent`.
222
+ *
223
+ * `predecessorSummary` is intentionally NOT answered here: it is the
224
+ * direct-predecessor forwarding concept owned by Channel 1.
225
+ *
226
+ * Namespace → node matching honors `SEMANTIC_STAGE_ALIASES`: a manifest
227
+ * namespace is the SEMANTIC stage, a node's stage is the producer taskKind.
228
+ */
229
+ export function resolveAncestryPaths(fieldPaths, sources) {
230
+ const resolved = new Map();
231
+ for (const fieldPath of fieldPaths) {
232
+ const parsed = parseContextPath(fieldPath);
233
+ if (parsed === null)
234
+ continue;
235
+ if (parsed.layer === 'predecessorSummary')
236
+ continue;
237
+ const producerStages = [
238
+ parsed.namespace,
239
+ ...(SEMANTIC_STAGE_ALIASES[parsed.namespace] ?? []),
240
+ ];
241
+ const source = sources.find((candidate) => producerStages.includes(candidate.stage));
242
+ if (source === undefined)
243
+ continue;
244
+ const value = parsed.layer === 'raw'
245
+ ? readRawField(parsed.rest, source.contentJson)
246
+ : readSummaryWithProjection(fieldPath, source.stage, source.contentJson);
247
+ if (value !== undefined)
248
+ resolved.set(fieldPath, value);
249
+ }
250
+ return resolved;
251
+ }
252
+ /**
253
+ * Resolve `<ns>.summary.<key>` / `<ns>.raw.<key>` against related sources.
254
+ * Related refs expose flat keys only — a multi-segment rest path is not a
255
+ * related reference and is skipped (it belongs to the ancestry reader).
256
+ */
257
+ export function resolveRelatedPaths(fieldPaths, sources) {
258
+ const resolved = new Map();
259
+ for (const fieldPath of fieldPaths) {
260
+ const parsed = parseContextPath(fieldPath);
261
+ if (parsed === null)
262
+ continue;
263
+ if (parsed.rest.length !== 1)
264
+ continue;
265
+ if (parsed.layer === 'predecessorSummary')
266
+ continue;
267
+ const source = sources.find((candidate) => candidate.namespace === parsed.namespace);
268
+ if (source === undefined)
269
+ continue;
270
+ const table = parsed.layer === 'raw' ? source.raw : source.summary;
271
+ if (table === undefined)
272
+ continue;
273
+ const [key] = parsed.rest;
274
+ if (key === undefined || FORBIDDEN_SEGMENTS.has(key))
275
+ continue;
276
+ if (!Object.hasOwn(table, key))
277
+ continue;
278
+ const value = table[key];
279
+ if (value !== undefined)
280
+ resolved.set(fieldPath, value);
281
+ }
282
+ return resolved;
283
+ }
284
+ // ── Composition ─────────────────────────────────────────────────────────────
285
+ /**
286
+ * Merge the channel maps into one `available` map. FIRST WRITER WINS: the
287
+ * predecessor summary envelope is the highest-authority local source, then
288
+ * ancestry raw, then related. Channel namespaces are disjoint by construction
289
+ * (a path is either a summary path, an ancestry raw path, or a related path),
290
+ * so the rule only matters defensively — but it keeps the result deterministic.
291
+ */
292
+ export function mergeContextFields(base, extras) {
293
+ const merged = new Map(base);
294
+ for (const extra of extras) {
295
+ for (const [fieldPath, value] of extra) {
296
+ if (!merged.has(fieldPath))
297
+ merged.set(fieldPath, value);
298
+ }
299
+ }
300
+ return merged;
301
+ }
302
+ // ── Information floor: required-evidence gate (design §33–§37) ──────────────
303
+ /**
304
+ * Required paths that did NOT reach the prompt — either absent from the
305
+ * available map or dropped/truncated by the budget.
306
+ *
307
+ * This is the regression guard for "Stage2 enabled + raw fields silently
308
+ * absent": a required field that was truncated by `PromptBudgetManager` counts
309
+ * as unresolved just like an absent one, because the runner's semantic
310
+ * requirement was still not met.
311
+ */
312
+ export function findUnresolvedRequiredPaths(params) {
313
+ const absentPaths = new Set(params.absent);
314
+ const truncatedPaths = new Set(params.truncated.map((record) => record.fieldPath));
315
+ return params.required.filter((path) => absentPaths.has(path) || truncatedPaths.has(path));
316
+ }
317
+ //# sourceMappingURL=context-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-resolution.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/context-resolution.ts"],"names":[],"mappings":"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"}
@@ -27,9 +27,26 @@ export interface AdversarialCase {
27
27
  export interface AdversarialFailedCase {
28
28
  readonly caseId: string;
29
29
  readonly attackType: AdversarialAttackType;
30
- readonly actualDecision: string;
30
+ /**
31
+ * PRI-634 PR-A (SPEC §14): present ONLY when the rule produced a real
32
+ * decision that mismatched the expected one. Never carries an errorType
33
+ * value — legacy artifacts that stored e.g. actualDecision='runtime_error'
34
+ * are normalized by readers (repair-replay-resolver), not migrated.
35
+ */
36
+ readonly actualDecision?: string;
31
37
  readonly expectedDecision: string;
32
38
  readonly rationale: string;
39
+ /**
40
+ * PRI-634 PR-A: sandbox error classification (runtime_error / timeout /
41
+ * syntax_error / validation_failed / forbidden_pattern / unknown).
42
+ * Present on runtime-written evidence; absent on legacy artifacts.
43
+ */
44
+ readonly errorType?: string;
45
+ /**
46
+ * PRI-634 PR-A: bounded safe failure message from the deterministic replay
47
+ * sandbox. Present on runtime-written evidence; absent on legacy artifacts.
48
+ */
49
+ readonly message?: string;
33
50
  }
34
51
  export interface EvaluatorCodeReview {
35
52
  readonly intentConsistency: {
@@ -1 +1 @@
1
- {"version":3,"file":"evaluator-output.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/evaluator-output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluator-output.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/evaluator-output.ts"],"names":[],"mappings":"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"}
@@ -174,8 +174,18 @@ function validateAdversarialResult(raw) {
174
174
  if (!Object.hasOwn(entry, 'attackType') || typeof entry.attackType !== 'string' || !ADVERSARIAL_ATTACK_TYPES.has(entry.attackType)) {
175
175
  errors.push(`${prefix}.attackType must be one of boundary|omission|inversion, got ${String(entry.attackType)}`);
176
176
  }
177
- if (!Object.hasOwn(entry, 'actualDecision') || typeof entry.actualDecision !== 'string') {
178
- errors.push(`${prefix}.actualDecision must be a string`);
177
+ // PRI-634 PR-A (SPEC §14/§21): actualDecision is optional — present only
178
+ // when a real decision mismatched. errorType carries the sandbox error
179
+ // classification. Legacy artifacts (actualDecision=<error enum>) stay
180
+ // valid; readers normalize. Both fields are string-when-present.
181
+ if (Object.hasOwn(entry, 'actualDecision') && entry.actualDecision !== undefined && typeof entry.actualDecision !== 'string') {
182
+ errors.push(`${prefix}.actualDecision must be a string when present`);
183
+ }
184
+ if (Object.hasOwn(entry, 'errorType') && entry.errorType !== undefined && typeof entry.errorType !== 'string') {
185
+ errors.push(`${prefix}.errorType must be a string when present`);
186
+ }
187
+ if (Object.hasOwn(entry, 'message') && entry.message !== undefined && typeof entry.message !== 'string') {
188
+ errors.push(`${prefix}.message must be a string when present`);
179
189
  }
180
190
  if (!Object.hasOwn(entry, 'expectedDecision') || typeof entry.expectedDecision !== 'string') {
181
191
  errors.push(`${prefix}.expectedDecision must be a string`);