@principles/core 1.241.0 → 1.243.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.
- package/dist/runtime-v2/feature-flags/__tests__/context-manifest-budget-flag.test.d.ts +12 -0
- package/dist/runtime-v2/feature-flags/__tests__/context-manifest-budget-flag.test.d.ts.map +1 -0
- package/dist/runtime-v2/feature-flags/__tests__/context-manifest-budget-flag.test.js +114 -0
- package/dist/runtime-v2/feature-flags/__tests__/context-manifest-budget-flag.test.js.map +1 -0
- package/dist/runtime-v2/feature-flags/__tests__/progressive-evaluator-flag.test.d.ts +8 -0
- package/dist/runtime-v2/feature-flags/__tests__/progressive-evaluator-flag.test.d.ts.map +1 -0
- package/dist/runtime-v2/feature-flags/__tests__/progressive-evaluator-flag.test.js +56 -0
- package/dist/runtime-v2/feature-flags/__tests__/progressive-evaluator-flag.test.js.map +1 -0
- package/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js +14 -0
- package/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.d.ts +15 -0
- package/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.js +301 -0
- package/dist/runtime-v2/internalization/__tests__/candidate-lineage.property.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/context-manifest.property.test.d.ts +12 -0
- package/dist/runtime-v2/internalization/__tests__/context-manifest.property.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/context-manifest.property.test.js +176 -0
- package/dist/runtime-v2/internalization/__tests__/context-manifest.property.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/progressive-evaluator.property.test.d.ts +11 -0
- package/dist/runtime-v2/internalization/__tests__/progressive-evaluator.property.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/progressive-evaluator.property.test.js +154 -0
- package/dist/runtime-v2/internalization/__tests__/progressive-evaluator.property.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/prompt-budget-manager.property.test.d.ts +12 -0
- package/dist/runtime-v2/internalization/__tests__/prompt-budget-manager.property.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/prompt-budget-manager.property.test.js +254 -0
- package/dist/runtime-v2/internalization/__tests__/prompt-budget-manager.property.test.js.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/resolve-injection.property.test.d.ts +15 -0
- package/dist/runtime-v2/internalization/__tests__/resolve-injection.property.test.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/__tests__/resolve-injection.property.test.js +150 -0
- package/dist/runtime-v2/internalization/__tests__/resolve-injection.property.test.js.map +1 -0
- package/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/artificer-runner.js +12 -0
- package/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/candidate-lineage.d.ts +136 -0
- package/dist/runtime-v2/internalization/candidate-lineage.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/candidate-lineage.js +230 -0
- package/dist/runtime-v2/internalization/candidate-lineage.js.map +1 -0
- package/dist/runtime-v2/internalization/context-manifest.d.ts +117 -0
- package/dist/runtime-v2/internalization/context-manifest.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/context-manifest.js +156 -0
- package/dist/runtime-v2/internalization/context-manifest.js.map +1 -0
- package/dist/runtime-v2/internalization/context-manifests.d.ts +74 -0
- package/dist/runtime-v2/internalization/context-manifests.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/context-manifests.js +192 -0
- package/dist/runtime-v2/internalization/context-manifests.js.map +1 -0
- package/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts +54 -0
- package/dist/runtime-v2/internalization/dimension-coverage-policy.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/dimension-coverage-policy.js +70 -0
- package/dist/runtime-v2/internalization/dimension-coverage-policy.js.map +1 -0
- package/dist/runtime-v2/internalization/dreamer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/dreamer-runner.js +13 -1
- package/dist/runtime-v2/internalization/dreamer-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.d.ts +26 -0
- package/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-output.js +7 -1
- package/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/evaluator-runner.js +13 -0
- package/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/progressive-evaluator.d.ts +115 -0
- package/dist/runtime-v2/internalization/progressive-evaluator.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/progressive-evaluator.js +248 -0
- package/dist/runtime-v2/internalization/progressive-evaluator.js.map +1 -0
- package/dist/runtime-v2/internalization/prompt-budget-manager.d.ts +90 -0
- package/dist/runtime-v2/internalization/prompt-budget-manager.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/prompt-budget-manager.js +149 -0
- package/dist/runtime-v2/internalization/prompt-budget-manager.js.map +1 -0
- package/dist/runtime-v2/internalization/resolve-injection.d.ts +62 -0
- package/dist/runtime-v2/internalization/resolve-injection.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/resolve-injection.js +78 -0
- package/dist/runtime-v2/internalization/resolve-injection.js.map +1 -0
- package/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
- package/dist/runtime-v2/internalization/scribe-runner.js +10 -0
- package/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
- package/dist/runtime-v2/internalization/summary-field-reader.d.ts +38 -0
- package/dist/runtime-v2/internalization/summary-field-reader.d.ts.map +1 -0
- package/dist/runtime-v2/internalization/summary-field-reader.js +108 -0
- package/dist/runtime-v2/internalization/summary-field-reader.js.map +1 -0
- package/dist/runtime-v2/runner/base-peer-runner.d.ts +36 -0
- package/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -1
- package/dist/runtime-v2/runner/base-peer-runner.js +71 -0
- package/dist/runtime-v2/runner/base-peer-runner.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 2 — CandidateLineage: on-demand ancestry traversal (design §6.4).
|
|
3
|
+
*
|
|
4
|
+
* Pure logic with **injected** I/O (artifact store + task reader). Walks an
|
|
5
|
+
* artifact's ancestry via `lineageArtifactIds`, determining each node's stage
|
|
6
|
+
* by the two-hop `artifact.sourceTaskId → task.taskKind` (F1 — never by
|
|
7
|
+
* `artifactKind`, which is ambiguous: all internalization artifacts are
|
|
8
|
+
* `principle`).
|
|
9
|
+
*
|
|
10
|
+
* Result contract (rc-9, design §6.4 error table):
|
|
11
|
+
* - data corruption (unparseable / shape-invalid / store-throw) → `ok: false`
|
|
12
|
+
* + a `LineageError`; the caller MUST surface it as an explicit failure or
|
|
13
|
+
* structured degradation — never silently fall through.
|
|
14
|
+
* - expected absence (no lineage ids / ancestor pruned / task missing / depth
|
|
15
|
+
* limit / cycle) → `ok: true` with a partial chain + notes; `complete` is
|
|
16
|
+
* false and `notes` is non-empty.
|
|
17
|
+
*
|
|
18
|
+
* Request-scoped cache: a single `CandidateLineage` instance lives for one
|
|
19
|
+
* `buildContext`; repeated `getArtifactById` calls for the same id hit the
|
|
20
|
+
* cache, not the store (CP-18).
|
|
21
|
+
*
|
|
22
|
+
* rc-1: every `contentJson` stays `unknown` — it is never narrowed or cast.
|
|
23
|
+
*/
|
|
24
|
+
import type { PIArtifactStore } from './pi-artifact.js';
|
|
25
|
+
import type { ArtifactSummary, SummaryRunnerKind } from './artifact-summary.js';
|
|
26
|
+
export interface LineageNode {
|
|
27
|
+
readonly artifactId: string;
|
|
28
|
+
readonly taskId: string;
|
|
29
|
+
/** Stage determined by the two-hop sourceTaskId → task.taskKind (F1). */
|
|
30
|
+
readonly taskKind: string;
|
|
31
|
+
readonly runnerKind: SummaryRunnerKind | 'unknown';
|
|
32
|
+
/** rc-1: remains `unknown`; the caller narrows it. */
|
|
33
|
+
readonly contentJson: unknown;
|
|
34
|
+
readonly summary?: ArtifactSummary;
|
|
35
|
+
}
|
|
36
|
+
export type LineageNoteCode = 'source_trace_missing' | 'ancestor_pruned' | 'task_missing' | 'depth_limit_reached' | 'cycle_detected';
|
|
37
|
+
export interface LineageNote {
|
|
38
|
+
readonly code: LineageNoteCode;
|
|
39
|
+
readonly artifactId: string;
|
|
40
|
+
readonly detail: string;
|
|
41
|
+
}
|
|
42
|
+
export interface LineageChain {
|
|
43
|
+
/** From start node upstream, in traversal order. */
|
|
44
|
+
readonly nodes: readonly LineageNode[];
|
|
45
|
+
/** false when notes is non-empty (partial chain). */
|
|
46
|
+
readonly complete: boolean;
|
|
47
|
+
readonly notes: readonly LineageNote[];
|
|
48
|
+
}
|
|
49
|
+
export type LineageError = {
|
|
50
|
+
readonly kind: 'content_json_unparseable';
|
|
51
|
+
readonly artifactId: string;
|
|
52
|
+
readonly detail: string;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: 'artifact_shape_invalid';
|
|
55
|
+
readonly artifactId: string;
|
|
56
|
+
readonly detail: string;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: 'store_failure';
|
|
59
|
+
readonly detail: string;
|
|
60
|
+
};
|
|
61
|
+
export type LineageResult = {
|
|
62
|
+
readonly ok: true;
|
|
63
|
+
readonly value: LineageChain;
|
|
64
|
+
} | {
|
|
65
|
+
readonly ok: false;
|
|
66
|
+
readonly error: LineageError;
|
|
67
|
+
};
|
|
68
|
+
/** Lineage telemetry event (forwarded to the caller's emit, if provided). */
|
|
69
|
+
export type LineageEvent = {
|
|
70
|
+
readonly type: 'lineage_data_corrupt';
|
|
71
|
+
readonly artifactId: string;
|
|
72
|
+
readonly detail: string;
|
|
73
|
+
readonly errorKind: LineageError['kind'];
|
|
74
|
+
} | {
|
|
75
|
+
readonly type: 'lineage_store_failure';
|
|
76
|
+
readonly detail: string;
|
|
77
|
+
} | {
|
|
78
|
+
readonly type: 'lineage_partial';
|
|
79
|
+
readonly artifactId: string;
|
|
80
|
+
readonly noteCode: LineageNoteCode;
|
|
81
|
+
readonly detail: string;
|
|
82
|
+
};
|
|
83
|
+
/** Two-hop task reader (F1) — resolves taskKind from a taskId. */
|
|
84
|
+
export interface LineageTaskReader {
|
|
85
|
+
getTaskById(taskId: string): Promise<{
|
|
86
|
+
readonly taskId: string;
|
|
87
|
+
readonly taskKind: string;
|
|
88
|
+
} | null>;
|
|
89
|
+
}
|
|
90
|
+
export interface CandidateLineageDeps {
|
|
91
|
+
readonly artifacts: Pick<PIArtifactStore, 'getArtifactById'>;
|
|
92
|
+
readonly tasks: LineageTaskReader;
|
|
93
|
+
/** Default 6 (longest pipeline chain + 1). */
|
|
94
|
+
readonly maxDepth?: number;
|
|
95
|
+
readonly emit?: (event: LineageEvent) => void;
|
|
96
|
+
}
|
|
97
|
+
export declare class CandidateLineage {
|
|
98
|
+
private readonly artifacts;
|
|
99
|
+
private readonly tasks;
|
|
100
|
+
private readonly maxDepth;
|
|
101
|
+
private readonly emit;
|
|
102
|
+
/** request-scoped: artifactId → resolved record (or null if known-absent). */
|
|
103
|
+
private readonly cache;
|
|
104
|
+
/** request-scoped: taskId → resolved taskKind (or null). */
|
|
105
|
+
private readonly taskCache;
|
|
106
|
+
constructor(deps: CandidateLineageDeps);
|
|
107
|
+
/**
|
|
108
|
+
* Resolve the full ancestry chain starting from `startArtifactId`.
|
|
109
|
+
* Walks `lineageArtifactIds` upstream, building an ordered node list.
|
|
110
|
+
*/
|
|
111
|
+
resolve(startArtifactId: string): Promise<LineageResult>;
|
|
112
|
+
/**
|
|
113
|
+
* Find the nearest ancestor node with a given `taskKind` (F1 — never by
|
|
114
|
+
* `artifactKind`). Returns `{ ok: true, node: null }` when no ancestor
|
|
115
|
+
* matches (a valid result, not an error).
|
|
116
|
+
*/
|
|
117
|
+
findAncestorByTaskKind(startArtifactId: string, taskKind: string): Promise<{
|
|
118
|
+
readonly ok: true;
|
|
119
|
+
readonly node: LineageNode | null;
|
|
120
|
+
readonly notes: readonly LineageNote[];
|
|
121
|
+
} | {
|
|
122
|
+
readonly ok: false;
|
|
123
|
+
readonly error: LineageError;
|
|
124
|
+
}>;
|
|
125
|
+
/**
|
|
126
|
+
* Iterative BFS resolution with cycle detection (via `visited`) and depth
|
|
127
|
+
* limiting. `visited` carries artifactIds already resolved (prevents cycles
|
|
128
|
+
* and redundant fetches across the whole traversal, not just one path).
|
|
129
|
+
*/
|
|
130
|
+
private resolveChain;
|
|
131
|
+
/** Cached artifact fetch. Returns `ok:false` on store failure or corruption. */
|
|
132
|
+
private getArtifactCached;
|
|
133
|
+
/** Cached task fetch (two-hop). Returns `ok:false` only on reader failure (treated as store_failure). */
|
|
134
|
+
private getTaskCached;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=candidate-lineage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-lineage.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/candidate-lineage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 2 — CandidateLineage: on-demand ancestry traversal (design §6.4).
|
|
3
|
+
*
|
|
4
|
+
* Pure logic with **injected** I/O (artifact store + task reader). Walks an
|
|
5
|
+
* artifact's ancestry via `lineageArtifactIds`, determining each node's stage
|
|
6
|
+
* by the two-hop `artifact.sourceTaskId → task.taskKind` (F1 — never by
|
|
7
|
+
* `artifactKind`, which is ambiguous: all internalization artifacts are
|
|
8
|
+
* `principle`).
|
|
9
|
+
*
|
|
10
|
+
* Result contract (rc-9, design §6.4 error table):
|
|
11
|
+
* - data corruption (unparseable / shape-invalid / store-throw) → `ok: false`
|
|
12
|
+
* + a `LineageError`; the caller MUST surface it as an explicit failure or
|
|
13
|
+
* structured degradation — never silently fall through.
|
|
14
|
+
* - expected absence (no lineage ids / ancestor pruned / task missing / depth
|
|
15
|
+
* limit / cycle) → `ok: true` with a partial chain + notes; `complete` is
|
|
16
|
+
* false and `notes` is non-empty.
|
|
17
|
+
*
|
|
18
|
+
* Request-scoped cache: a single `CandidateLineage` instance lives for one
|
|
19
|
+
* `buildContext`; repeated `getArtifactById` calls for the same id hit the
|
|
20
|
+
* cache, not the store (CP-18).
|
|
21
|
+
*
|
|
22
|
+
* rc-1: every `contentJson` stays `unknown` — it is never narrowed or cast.
|
|
23
|
+
*/
|
|
24
|
+
import { SUMMARY_RUNNER_KINDS } from './artifact-summary.js';
|
|
25
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
26
|
+
const DEFAULT_MAX_DEPTH = 6;
|
|
27
|
+
function isRecord(value) {
|
|
28
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read an existing ArtifactSummary off a contentJson (Layer 0 envelope), with
|
|
32
|
+
* full value-type validation (rc-2). Returns null when absent or malformed —
|
|
33
|
+
* the node simply carries no `summary`, which is a valid partial state.
|
|
34
|
+
*/
|
|
35
|
+
function readSummary(contentJson) {
|
|
36
|
+
if (!isRecord(contentJson) || !Object.hasOwn(contentJson, 'summary'))
|
|
37
|
+
return undefined;
|
|
38
|
+
const { summary } = contentJson;
|
|
39
|
+
if (!isRecord(summary))
|
|
40
|
+
return undefined;
|
|
41
|
+
// rc-2: full value-type validation, then construct a typed object (no as cast).
|
|
42
|
+
if (Object.hasOwn(summary, 'schemaVersion') && summary.schemaVersion === 1
|
|
43
|
+
&& Object.hasOwn(summary, 'runnerKind') && typeof summary.runnerKind === 'string'
|
|
44
|
+
&& SUMMARY_RUNNER_KINDS.includes(summary.runnerKind)
|
|
45
|
+
&& Object.hasOwn(summary, 'headline') && typeof summary.headline === 'string'
|
|
46
|
+
&& Object.hasOwn(summary, 'fields') && isRecord(summary.fields)
|
|
47
|
+
&& Object.values(summary.fields).every((v) => typeof v === 'string')
|
|
48
|
+
&& Object.hasOwn(summary, 'derivedFrom') && summary.derivedFrom === 'structured_output'
|
|
49
|
+
&& Object.hasOwn(summary, 'omittedFields') && Array.isArray(summary.omittedFields)
|
|
50
|
+
&& summary.omittedFields.every((v) => typeof v === 'string')) {
|
|
51
|
+
// runtime-contract-exempt: ERR-001 narrowing after full value-type validation: runnerKind checked against SUMMARY_RUNNER_KINDS, fields checked via Object.values().every(typeof string), omittedFields checked via Array.isArray + every. The casts are type-only — the values are already validated at runtime above.
|
|
52
|
+
return {
|
|
53
|
+
schemaVersion: 1,
|
|
54
|
+
runnerKind: summary.runnerKind, // runtime-contract-exempt: ERR-001 validated via SUMMARY_RUNNER_KINDS.includes above
|
|
55
|
+
headline: summary.headline,
|
|
56
|
+
fields: summary.fields, // runtime-contract-exempt: ERR-001 validated via Object.values().every(typeof===string) above
|
|
57
|
+
derivedFrom: 'structured_output',
|
|
58
|
+
omittedFields: summary.omittedFields, // runtime-contract-exempt: ERR-001 validated via Array.isArray + every(typeof===string) above
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
// ── CandidateLineage ─────────────────────────────────────────────────────────
|
|
64
|
+
export class CandidateLineage {
|
|
65
|
+
artifacts;
|
|
66
|
+
tasks;
|
|
67
|
+
maxDepth;
|
|
68
|
+
emit;
|
|
69
|
+
/** request-scoped: artifactId → resolved record (or null if known-absent). */
|
|
70
|
+
cache = new Map();
|
|
71
|
+
/** request-scoped: taskId → resolved taskKind (or null). */
|
|
72
|
+
taskCache = new Map();
|
|
73
|
+
constructor(deps) {
|
|
74
|
+
this.artifacts = deps.artifacts;
|
|
75
|
+
this.tasks = deps.tasks;
|
|
76
|
+
this.maxDepth = deps.maxDepth ?? DEFAULT_MAX_DEPTH;
|
|
77
|
+
this.emit = deps.emit ?? (() => undefined);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve the full ancestry chain starting from `startArtifactId`.
|
|
81
|
+
* Walks `lineageArtifactIds` upstream, building an ordered node list.
|
|
82
|
+
*/
|
|
83
|
+
async resolve(startArtifactId) {
|
|
84
|
+
return this.resolveChain(startArtifactId, new Set());
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Find the nearest ancestor node with a given `taskKind` (F1 — never by
|
|
88
|
+
* `artifactKind`). Returns `{ ok: true, node: null }` when no ancestor
|
|
89
|
+
* matches (a valid result, not an error).
|
|
90
|
+
*/
|
|
91
|
+
async findAncestorByTaskKind(startArtifactId, taskKind) {
|
|
92
|
+
const result = await this.resolve(startArtifactId);
|
|
93
|
+
if (!result.ok)
|
|
94
|
+
return { ok: false, error: result.error };
|
|
95
|
+
const node = result.value.nodes.find((n) => n.taskKind === taskKind) ?? null;
|
|
96
|
+
return { ok: true, node, notes: result.value.notes };
|
|
97
|
+
}
|
|
98
|
+
// ── Internal traversal ─────────────────────────────────────────────────────
|
|
99
|
+
/**
|
|
100
|
+
* Iterative BFS resolution with cycle detection (via `visited`) and depth
|
|
101
|
+
* limiting. `visited` carries artifactIds already resolved (prevents cycles
|
|
102
|
+
* and redundant fetches across the whole traversal, not just one path).
|
|
103
|
+
*/
|
|
104
|
+
async resolveChain(startArtifactId, visited) {
|
|
105
|
+
const nodes = [];
|
|
106
|
+
const notes = [];
|
|
107
|
+
// BFS-style frontier of artifact ids to resolve, seeded with the start.
|
|
108
|
+
// We process in order; each node's lineageArtifactIds extend the frontier.
|
|
109
|
+
const queue = [startArtifactId];
|
|
110
|
+
let depth = 0;
|
|
111
|
+
while (queue.length > 0) {
|
|
112
|
+
if (depth >= this.maxDepth) {
|
|
113
|
+
const [last] = queue;
|
|
114
|
+
notes.push({ code: 'depth_limit_reached', artifactId: last ?? startArtifactId, detail: `maxDepth (${this.maxDepth}) reached; remaining ${queue.length} ancestor(s) not traversed` });
|
|
115
|
+
this.emit({ type: 'lineage_partial', artifactId: last ?? startArtifactId, noteCode: 'depth_limit_reached', detail: `maxDepth ${this.maxDepth}` });
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
const artifactId = queue.shift();
|
|
119
|
+
if (artifactId === undefined)
|
|
120
|
+
break;
|
|
121
|
+
// Cycle detection.
|
|
122
|
+
if (visited.has(artifactId)) {
|
|
123
|
+
notes.push({ code: 'cycle_detected', artifactId, detail: `artifact ${artifactId} already on the resolution path` });
|
|
124
|
+
this.emit({ type: 'lineage_partial', artifactId, noteCode: 'cycle_detected', detail: 'cycle detected' });
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
visited.add(artifactId);
|
|
128
|
+
// Fetch artifact (cached).
|
|
129
|
+
const artifactResult = await this.getArtifactCached(artifactId);
|
|
130
|
+
if (!artifactResult.ok)
|
|
131
|
+
return artifactResult; // propagate corruption / store failure
|
|
132
|
+
const artifact = artifactResult.value;
|
|
133
|
+
if (artifact === null) {
|
|
134
|
+
// Ancestor referenced but pruned — expected, partial.
|
|
135
|
+
notes.push({ code: 'ancestor_pruned', artifactId, detail: `ancestor artifact ${artifactId} not found (pruned)` });
|
|
136
|
+
this.emit({ type: 'lineage_partial', artifactId, noteCode: 'ancestor_pruned', detail: 'artifact not found' });
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Parse contentJson (rc-1: stays unknown on success; unparseable = corruption).
|
|
140
|
+
let contentJson;
|
|
141
|
+
try {
|
|
142
|
+
contentJson = JSON.parse(artifact.contentJson);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
const err = { kind: 'content_json_unparseable', artifactId, detail: `contentJson of ${artifactId} is not valid JSON` };
|
|
146
|
+
this.emit({ type: 'lineage_data_corrupt', artifactId, detail: err.detail, errorKind: 'content_json_unparseable' });
|
|
147
|
+
return { ok: false, error: err };
|
|
148
|
+
}
|
|
149
|
+
// Shape check: must have sourceTaskId (rc-3 fail loud on corruption).
|
|
150
|
+
if (typeof artifact.sourceTaskId !== 'string' || artifact.sourceTaskId === '') {
|
|
151
|
+
const err = { kind: 'artifact_shape_invalid', artifactId, detail: `artifact ${artifactId} missing required sourceTaskId` };
|
|
152
|
+
this.emit({ type: 'lineage_data_corrupt', artifactId, detail: err.detail, errorKind: 'artifact_shape_invalid' });
|
|
153
|
+
return { ok: false, error: err };
|
|
154
|
+
}
|
|
155
|
+
// Two-hop: sourceTaskId → task.taskKind (F1).
|
|
156
|
+
const taskResult = await this.getTaskCached(artifact.sourceTaskId);
|
|
157
|
+
if (!taskResult.ok)
|
|
158
|
+
return taskResult;
|
|
159
|
+
const task = taskResult.value;
|
|
160
|
+
let taskKind;
|
|
161
|
+
let runnerKind;
|
|
162
|
+
if (task === null) {
|
|
163
|
+
taskKind = 'unknown';
|
|
164
|
+
runnerKind = 'unknown';
|
|
165
|
+
notes.push({ code: 'task_missing', artifactId, detail: `task ${artifact.sourceTaskId} not found; cannot determine stage via two-hop` });
|
|
166
|
+
this.emit({ type: 'lineage_partial', artifactId, noteCode: 'task_missing', detail: `task ${artifact.sourceTaskId} missing` });
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
({ taskKind } = task);
|
|
170
|
+
runnerKind = SUMMARY_RUNNER_KINDS.includes(taskKind)
|
|
171
|
+
? taskKind
|
|
172
|
+
: 'unknown';
|
|
173
|
+
}
|
|
174
|
+
const node = {
|
|
175
|
+
artifactId,
|
|
176
|
+
taskId: artifact.sourceTaskId,
|
|
177
|
+
taskKind,
|
|
178
|
+
runnerKind,
|
|
179
|
+
contentJson,
|
|
180
|
+
summary: readSummary(contentJson),
|
|
181
|
+
};
|
|
182
|
+
nodes.push(node);
|
|
183
|
+
// Extend frontier with lineage ids (ancestry).
|
|
184
|
+
const lineageIds = Array.isArray(artifact.lineageArtifactIds) ? artifact.lineageArtifactIds : [];
|
|
185
|
+
if (lineageIds.length === 0 && nodes.length === 1) {
|
|
186
|
+
// The start node has no ancestry — not an error, just a short chain.
|
|
187
|
+
}
|
|
188
|
+
for (const id of lineageIds) {
|
|
189
|
+
if (typeof id === 'string' && id !== '') {
|
|
190
|
+
queue.push(id);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
depth++;
|
|
194
|
+
}
|
|
195
|
+
return { ok: true, value: { nodes, complete: notes.length === 0, notes } };
|
|
196
|
+
}
|
|
197
|
+
/** Cached artifact fetch. Returns `ok:false` on store failure or corruption. */
|
|
198
|
+
async getArtifactCached(artifactId) {
|
|
199
|
+
if (this.cache.has(artifactId)) {
|
|
200
|
+
return { ok: true, value: this.cache.get(artifactId) ?? null };
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
const record = await this.artifacts.getArtifactById(artifactId);
|
|
204
|
+
this.cache.set(artifactId, record);
|
|
205
|
+
return { ok: true, value: record };
|
|
206
|
+
}
|
|
207
|
+
catch (storeErr) {
|
|
208
|
+
const err = { kind: 'store_failure', detail: storeErr instanceof Error ? storeErr.message : String(storeErr) };
|
|
209
|
+
this.emit({ type: 'lineage_store_failure', detail: err.detail });
|
|
210
|
+
return { ok: false, error: err };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/** Cached task fetch (two-hop). Returns `ok:false` only on reader failure (treated as store_failure). */
|
|
214
|
+
async getTaskCached(taskId) {
|
|
215
|
+
if (this.taskCache.has(taskId)) {
|
|
216
|
+
return { ok: true, value: this.taskCache.get(taskId) ?? null };
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
const task = await this.tasks.getTaskById(taskId);
|
|
220
|
+
this.taskCache.set(taskId, task);
|
|
221
|
+
return { ok: true, value: task };
|
|
222
|
+
}
|
|
223
|
+
catch (readerErr) {
|
|
224
|
+
const err = { kind: 'store_failure', detail: readerErr instanceof Error ? readerErr.message : String(readerErr) };
|
|
225
|
+
this.emit({ type: 'lineage_store_failure', detail: err.detail });
|
|
226
|
+
return { ok: false, error: err };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=candidate-lineage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"candidate-lineage.js","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/candidate-lineage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layer 1 — ContextManifest: declarative field/budget declaration (design §6.2).
|
|
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
|
+
* A `ContextManifest` declares which field paths a runner (or an evaluator
|
|
8
|
+
* stage) needs, layered into tier0/tier1/tier2, plus a token budget and a
|
|
9
|
+
* priority ordering. Layer 1's `allocateContext` (prompt-budget-manager.ts)
|
|
10
|
+
* consumes it; Layer 3's CLI surfaces its resolution.
|
|
11
|
+
*
|
|
12
|
+
* rc-4: tier* and priority array elements are validated element-wise as
|
|
13
|
+
* strings before use. rc-5: object keys read via `Object.hasOwn`.
|
|
14
|
+
*/
|
|
15
|
+
import type { SummaryRunnerKind } from './artifact-summary.js';
|
|
16
|
+
export declare const CONTEXT_MANIFEST_SCHEMA_VERSION: 1;
|
|
17
|
+
/**
|
|
18
|
+
* A declarative context-injection manifest (design §6.2).
|
|
19
|
+
*
|
|
20
|
+
* Field-path naming convention (design §6.6):
|
|
21
|
+
* `<stage>.summary.<key>` — read from an ArtifactSummary
|
|
22
|
+
* `<stage>.predecessorSummary.*` — read from a forwarded predecessor summary
|
|
23
|
+
* `<stage>.raw.<path>` — read from tier2 full contentJson
|
|
24
|
+
*/
|
|
25
|
+
export interface ContextManifest {
|
|
26
|
+
readonly manifestId: string;
|
|
27
|
+
readonly schemaVersion: typeof CONTEXT_MANIFEST_SCHEMA_VERSION;
|
|
28
|
+
readonly runnerKind: SummaryRunnerKind;
|
|
29
|
+
readonly tier0: readonly string[];
|
|
30
|
+
readonly tier1: readonly string[];
|
|
31
|
+
/** Non-empty tier2 means CandidateLineage (Layer 2) may be triggered. */
|
|
32
|
+
readonly tier2: readonly string[];
|
|
33
|
+
/** Cross-level injection field budget (design §6.2.1). */
|
|
34
|
+
readonly budgetTokens: number;
|
|
35
|
+
/** Full priority sequence. Fields not listed here sort last (see rankOf). */
|
|
36
|
+
readonly priority: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
export type ManifestWellFormednessError = {
|
|
39
|
+
readonly kind: 'budget_not_positive';
|
|
40
|
+
readonly budgetTokens: number;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'non_string_element';
|
|
43
|
+
readonly array: 'tier0' | 'tier1' | 'tier2' | 'priority';
|
|
44
|
+
readonly index: number;
|
|
45
|
+
readonly value: unknown;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: 'priority_does_not_cover_fields';
|
|
48
|
+
readonly missing: readonly string[];
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: 'manifest_criterion_misaligned';
|
|
51
|
+
readonly detail: string;
|
|
52
|
+
};
|
|
53
|
+
export type ManifestValidationResult = {
|
|
54
|
+
readonly ok: true;
|
|
55
|
+
} | {
|
|
56
|
+
readonly ok: false;
|
|
57
|
+
readonly error: ManifestWellFormednessError;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* INV-MANIFEST-CRITERION (design §6.6.1): every non-excluded dreamer dimension
|
|
61
|
+
* that the fidelity criteria may adjudicate must have a corresponding injected
|
|
62
|
+
* path in the adjudicating manifest's tier0 ∪ tier1 ∪ tier2. The criteria must
|
|
63
|
+
* never ask the model to judge a dimension it cannot see.
|
|
64
|
+
*
|
|
65
|
+
* This is the direct regression guard for the Phase 0 root cause "criteria ask
|
|
66
|
+
* 5 dims, manifest injects 4" (design §12.1 conclusion 2 root cause 2). It only
|
|
67
|
+
* applies to manifests whose runnerKind is the adjudicator (evaluator); other
|
|
68
|
+
* stages are not fidelity-adjudicating and are skipped.
|
|
69
|
+
*
|
|
70
|
+
* NOTE: this checks that each non-excluded dimension's summary path
|
|
71
|
+
* (`dreamer.summary.<dim>`) is present. A future change promoting a dimension
|
|
72
|
+
* from `excluded` to `required`/`optional` in DIMENSION_COVERAGE_POLICY without
|
|
73
|
+
* adding its path to the evaluator manifest will fail this check.
|
|
74
|
+
*
|
|
75
|
+
* @param manifest the manifest to check
|
|
76
|
+
* @param isAdjudicator true only for evaluator-stage manifests (the ones whose
|
|
77
|
+
* injected fields the fidelity criteria see). Callers pass false for
|
|
78
|
+
* non-evaluator manifests so this invariant is scoped correctly.
|
|
79
|
+
*/
|
|
80
|
+
export declare function checkManifestCriterionAlignment(manifest: ContextManifest, isAdjudicator: boolean): ManifestWellFormednessError | null;
|
|
81
|
+
/**
|
|
82
|
+
* Validate a manifest is well-formed (design §6.2, requirements 4.2–4.8, 4.12,
|
|
83
|
+
* 4.13, 4.15).
|
|
84
|
+
*
|
|
85
|
+
* Checks:
|
|
86
|
+
* - budgetTokens > 0
|
|
87
|
+
* - every tier* and priority element is a string (rc-4)
|
|
88
|
+
* - priority covers every field in tier0 ∪ tier1 ∪ tier2 (with a documented
|
|
89
|
+
* escape hatch: unlisted fields are allowed but sort last via rankOf; this
|
|
90
|
+
* check is intentionally NOT enforced because rankOf defines their rank —
|
|
91
|
+
* see the note below)
|
|
92
|
+
* - INV-MANIFEST-CRITERION when the manifest is an adjudicator (§6.6.1)
|
|
93
|
+
*
|
|
94
|
+
* Note on `priority` coverage: design §6.2 requires "priority covers tier0 ∪
|
|
95
|
+
* tier1 ∪ tier2", but rankOf assigns unlisted fields a rank of
|
|
96
|
+
* `priority.length + declarationOrder` (sorting them last), which is the
|
|
97
|
+
* intended behaviour. The check here therefore only flags an empty priority
|
|
98
|
+
* when fields exist (a clear misconfiguration), rather than requiring every
|
|
99
|
+
* field be listed. The built-in manifests DO list every field.
|
|
100
|
+
*/
|
|
101
|
+
export declare function validateManifest(manifest: ContextManifest, opts?: {
|
|
102
|
+
readonly isAdjudicator?: boolean;
|
|
103
|
+
}): ManifestValidationResult;
|
|
104
|
+
/**
|
|
105
|
+
* The rank of a field path within a manifest (design §6.2 / requirement 4.6).
|
|
106
|
+
*
|
|
107
|
+
* Listed fields get their index in `priority` (0-based, ascending = higher
|
|
108
|
+
* priority). Unlisted fields get `priority.length + declarationOrder`, where
|
|
109
|
+
* declarationOrder is the field's position in dedupe(tier0 ++ tier1 ++ tier2)
|
|
110
|
+
* — so unlisted fields sort AFTER all listed fields, in a stable declaration
|
|
111
|
+
* order. This replaces the base proposal's `indexOf(...) `-1`` which sorted
|
|
112
|
+
* unlisted fields FIRST (opposite of intent).
|
|
113
|
+
*/
|
|
114
|
+
export declare function rankOf(fieldPath: string, manifest: ContextManifest): number;
|
|
115
|
+
/** All declared field paths of a manifest, deduped, in tier order. */
|
|
116
|
+
export declare function declaredFields(manifest: ContextManifest): string[];
|
|
117
|
+
//# sourceMappingURL=context-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-manifest.d.ts","sourceRoot":"","sources":["../../../src/runtime-v2/internalization/context-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAO/D,eAAO,MAAM,+BAA+B,EAAG,CAAU,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,OAAO,+BAA+B,CAAC;IAC/D,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0DAA0D;IAC1D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAID,MAAM,MAAM,2BAA2B,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAClJ;IAAE,QAAQ,CAAC,IAAI,EAAE,gCAAgC,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACxF;IAAE,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GACrB;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAyBxE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,eAAe,EACzB,aAAa,EAAE,OAAO,GACrB,2BAA2B,GAAG,IAAI,CAmBpC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,IAAI,GAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9C,wBAAwB,CA6B1B;AAID;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,MAAM,CAc3E;AAID,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,CAElE"}
|