create-agdf 0.13.2 → 0.13.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 (77) hide show
  1. package/generated/.agdf/control/templates/RUN_STATE.md +22 -0
  2. package/generated/.agdf/control/templates/artefacts/OR.md +22 -0
  3. package/generated/.github/skills/agdf-delivery-closeout/SKILL.md +7 -0
  4. package/generated/.github/skills/agdf-interaction-locales.json +2 -4
  5. package/generated/.github/skills/agdf-release-or/SKILL.md +14 -4
  6. package/generated/.github/skills/contracts/closeout.md +49 -0
  7. package/generated/.github/skills/contracts/control-scaffold.md +2 -0
  8. package/generated/.github/skills/contracts/interaction.md +23 -12
  9. package/generated/.opencode/agdf-interaction-locales.json +2 -4
  10. package/generated/.opencode/contracts/closeout.md +49 -0
  11. package/generated/.opencode/contracts/control-scaffold.md +2 -0
  12. package/generated/.opencode/contracts/interaction.md +23 -12
  13. package/generated/.opencode/skills/agdf-delivery-closeout/SKILL.md +7 -0
  14. package/generated/.opencode/skills/agdf-release-or/SKILL.md +14 -4
  15. package/generated/plugins/agdf/.claude-plugin/plugin.json +1 -1
  16. package/generated/plugins/agdf/.codex-plugin/plugin.json +1 -1
  17. package/generated/plugins/agdf/control/templates/RUN_STATE.md +22 -0
  18. package/generated/plugins/agdf/control/templates/artefacts/OR.md +22 -0
  19. package/generated/plugins/agdf/meta/agdf-interaction-locales.json +2 -4
  20. package/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  21. package/generated/plugins/agdf/meta/agent-skills-conformance.json +86 -0
  22. package/generated/plugins/agdf/meta/contracts/closeout.md +49 -0
  23. package/generated/plugins/agdf/meta/contracts/control-scaffold.md +2 -0
  24. package/generated/plugins/agdf/meta/contracts/interaction.md +23 -12
  25. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-interaction-locales.json +2 -4
  26. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  27. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/delivery-map.js +13 -3
  28. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/doctor.js +9 -2
  29. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/gate-check.js +6 -1
  30. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/gate-policy.js +16 -1
  31. package/generated/plugins/agdf/runtime/create-agdf/lib/control-evaluation/parent-reconciliation.js +284 -0
  32. package/generated/plugins/agdf/runtime/create-agdf/lib/control-state/run-state-parser.js +39 -1
  33. package/generated/plugins/agdf/runtime/create-agdf/lib/interaction-presentation.js +31 -14
  34. package/generated/plugins/agdf/runtime/create-agdf/package.json +1 -1
  35. package/generated/plugins/agdf/runtime/runtime-manifest.json +2 -2
  36. package/generated/plugins/agdf/scripts/agent-skills-conformance.mjs +543 -0
  37. package/generated/plugins/agdf/scripts/check-runtime-integrity.mjs +31 -17
  38. package/generated/plugins/agdf/skills/delivery-closeout/SKILL.md +7 -0
  39. package/generated/plugins/agdf/skills/release-or/SKILL.md +14 -4
  40. package/generated/plugins/agdf/submission/openai/availability.md +1 -1
  41. package/generated/plugins/agdf/submission/openai/capability-matrix.json +2 -2
  42. package/generated/plugins/agdf/submission/openai/release-notes.md +1 -1
  43. package/generated/plugins/agdf/submission/openai/reviewer-cases.json +1 -1
  44. package/generated/submissions/openai/agdf/.codex-plugin/plugin.json +1 -1
  45. package/generated/submissions/openai/agdf/meta/agdf-interaction-locales.json +2 -4
  46. package/generated/submissions/openai/agdf/meta/agdf-plugin.definition.json +1 -1
  47. package/generated/submissions/openai/agdf/meta/agent-skills-conformance.json +86 -0
  48. package/generated/submissions/openai/agdf/meta/contracts/closeout.md +49 -0
  49. package/generated/submissions/openai/agdf/meta/contracts/control-scaffold.md +2 -0
  50. package/generated/submissions/openai/agdf/meta/contracts/interaction.md +23 -12
  51. package/generated/submissions/openai/agdf/skills/delivery-closeout/SKILL.md +7 -0
  52. package/generated/submissions/openai/agdf/skills/release-or/SKILL.md +14 -4
  53. package/generated/submissions/openai/agdf/submission/openai/availability.md +1 -1
  54. package/generated/submissions/openai/agdf/submission/openai/capability-matrix.json +2 -2
  55. package/generated/submissions/openai/agdf/submission/openai/inventory.json +19 -15
  56. package/generated/submissions/openai/agdf/submission/openai/listing.json +1 -1
  57. package/generated/submissions/openai/agdf/submission/openai/readiness.json +2 -2
  58. package/generated/submissions/openai/agdf/submission/openai/readiness.md +2 -2
  59. package/generated/submissions/openai/agdf/submission/openai/release-notes.md +1 -1
  60. package/generated/submissions/openai/agdf/submission/openai/reviewer-cases.json +1 -1
  61. package/lib/control-evaluation/delivery-map.js +13 -3
  62. package/lib/control-evaluation/doctor.js +9 -2
  63. package/lib/control-evaluation/gate-check.js +6 -1
  64. package/lib/control-evaluation/gate-policy.js +16 -1
  65. package/lib/control-evaluation/parent-reconciliation.js +284 -0
  66. package/lib/control-state/run-state-parser.js +39 -1
  67. package/lib/interaction-presentation.js +31 -14
  68. package/lib/proportionality-benchmark/blind-prompt.js +2 -1
  69. package/lib/proportionality-benchmark/contracts.js +16 -7
  70. package/lib/proportionality-benchmark/corpus-loader.js +132 -21
  71. package/lib/proportionality-benchmark/evaluator.js +25 -15
  72. package/lib/proportionality-benchmark/index.js +1 -0
  73. package/lib/proportionality-benchmark/live-recorder.js +32 -10
  74. package/lib/proportionality-benchmark/profiles.js +102 -0
  75. package/lib/proportionality-benchmark/report.js +10 -1
  76. package/lib/proportionality-benchmark/source-fingerprint.js +6 -2
  77. package/package.json +4 -2
@@ -1,7 +1,8 @@
1
- import { existsSync, readFileSync, realpathSync } from "node:fs";
1
+ import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
2
2
  import { createHash } from "node:crypto";
3
- import { dirname, relative, resolve, sep } from "node:path";
4
- import { fail, validateBaseline } from "./contracts.js";
3
+ import { dirname, join, relative, resolve, sep } from "node:path";
4
+ import { DELIVERY_PATHS, fail, validateBaseline } from "./contracts.js";
5
+ import { getProfileDefinition, isStagedProfile } from "./profiles.js";
5
6
 
6
7
  function inside(root, candidate) {
7
8
  const target = resolve(root, candidate);
@@ -21,7 +22,7 @@ function existingInside(root, candidate) {
21
22
  function sha256(path) {
22
23
  return createHash("sha256").update(readFileSync(path)).digest("hex");
23
24
  }
24
- const stagedForbidden = /expected_|evidence_ref|classification|threshold|trivial_change|compact_delivery|verified_change|structured_slice|structured_delivery/i;
25
+ const stagedForbidden = /expected_|evidence_ref|classification|threshold|reason_code|target_rationale|grading_value|baseline_(version|path)|trivial_change|compact_delivery|verified_change|structured_slice|structured_delivery/i;
25
26
  export function validateStagedBlindScenario(scenario, evidencePack = null, baselineScenario = null) {
26
27
  if (stagedForbidden.test(JSON.stringify(scenario))) fail(`staged scenario leakage ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
27
28
  const quickTaskReferences = JSON.stringify(scenario).match(/quick_task/gi)?.length ?? 0;
@@ -30,31 +31,140 @@ export function validateStagedBlindScenario(scenario, evidencePack = null, basel
30
31
  || scenario.control_state_context !== "A durable UR is approved. Brownfield analysis is complete and the stored mode/slice decision is quick_task."
31
32
  || quickTaskReferences !== 1
32
33
  )) fail(`staged scenario path leakage ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
33
- if (evidencePack && stagedForbidden.test(JSON.stringify(evidencePack))) fail(`staged evidence-pack leakage ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
34
+ if (evidencePack) {
35
+ const leakageEvidence = JSON.parse(JSON.stringify(evidencePack));
36
+ const escalation = leakageEvidence.bounded_change_facts?.escalation;
37
+ if (escalation) {
38
+ if (!["structured_slice", "structured_delivery"].includes(escalation.target)) fail(`invalid structured escalation target ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
39
+ delete escalation.target;
40
+ }
41
+ if (stagedForbidden.test(JSON.stringify(leakageEvidence))) fail(`staged evidence-pack leakage ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
42
+ }
34
43
  if (baselineScenario && (
35
44
  JSON.stringify(scenario).includes(baselineScenario.rationale)
36
45
  || JSON.stringify(evidencePack ?? {}).includes(baselineScenario.rationale)
37
46
  )) fail(`staged rationale leakage ${scenario.scenario_id}`, "PROPORTIONALITY_LEAKAGE");
38
47
  return scenario;
39
48
  }
49
+ function recursiveFiles(root) {
50
+ return readdirSync(root, { withFileTypes: true }).flatMap((entry) => {
51
+ const path = join(root, entry.name);
52
+ return entry.isDirectory() ? recursiveFiles(path) : [path];
53
+ });
54
+ }
55
+ const requiredProtectedV2Files = [
56
+ "evals/proportionality/staged-manifest.json",
57
+ "evals/proportionality/staged-scenarios.json",
58
+ "evals/proportionality/fixtures/staged-catalog.json",
59
+ ".agdf/control/artefacts/agdf-staged-proportionality-observation/STAGED_PROPORTIONALITY_BASELINE.json",
60
+ ".agdf/control/artefacts/agdf-staged-proportionality-observation/STAGED_PROPORTIONALITY_REPORT.json",
61
+ ".agdf/control/artefacts/agdf-staged-proportionality-observation/STAGED_PROPORTIONALITY_REPORT.md",
62
+ ".agdf/control/artefacts/agdf-staged-proportionality-observation/QA_REPORT.md",
63
+ ".agdf/control/artefacts/agdf-staged-proportionality-observation/OR.md",
64
+ ];
65
+ const requiredProtectedV2Root = "evals/proportionality/observations/codex-gpt-5.6-sol-agdf-0.11.4-staged-v2-20260729-r3";
66
+ export function validateHistoryInventory(repoRoot, root, manifest) {
67
+ const inventoryPath = existingInside(root, manifest.history_provenance_path);
68
+ const inventory = JSON.parse(readFileSync(inventoryPath, "utf8"));
69
+ if (inventory.schema_version !== "1" || inventory.profile_id !== manifest.profile_id || inventory.inventory_version !== manifest.history_inventory_version) fail("history inventory version mismatch", "PROPORTIONALITY_HISTORY_DRIFT");
70
+ const declared = Object.keys(inventory.protected_files ?? {}).sort();
71
+ if (requiredProtectedV2Files.some((path) => !declared.includes(path))) fail("protected history inventory omits required staged-v2 evidence", "PROPORTIONALITY_HISTORY_DRIFT");
72
+ if (!Array.isArray(inventory.protected_roots) || inventory.protected_roots.length !== 1 || inventory.protected_roots[0] !== requiredProtectedV2Root) fail("protected history root mismatch", "PROPORTIONALITY_HISTORY_DRIFT");
73
+ if (declared.some((path) => !requiredProtectedV2Files.includes(path) && !path.startsWith(`${requiredProtectedV2Root}/`))) fail("protected history inventory contains an out-of-bound path", "PROPORTIONALITY_HISTORY_DRIFT");
74
+ for (const path of declared) {
75
+ const target = existingInside(repoRoot, path);
76
+ if (sha256(target) !== inventory.protected_files[path]) fail(`protected history drift ${path}`, "PROPORTIONALITY_HISTORY_DRIFT");
77
+ }
78
+ for (const protectedRoot of inventory.protected_roots ?? []) {
79
+ const absolute = existingInside(repoRoot, protectedRoot);
80
+ const actual = recursiveFiles(absolute).map((path) => relative(repoRoot, path).split(sep).join("/")).sort();
81
+ const expected = declared.filter((path) => path === protectedRoot || path.startsWith(`${protectedRoot}/`));
82
+ if (actual.length !== expected.length || actual.some((path, index) => path !== expected[index])) fail(`protected history inventory incomplete ${protectedRoot}`, "PROPORTIONALITY_HISTORY_DRIFT");
83
+ }
84
+ return inventory;
85
+ }
86
+ const verifiedFactGroups = ["ownership_boundary", "prohibited_impacts", "deterministic_controls", "baseline_state", "escalation"];
87
+ const impactFacts = ["product_semantics", "runtime", "policy", "persistence", "architecture", "security", "external_api", "cli_contract", "release", "cross_host"];
88
+ const depthTriggerFamilies = ["behavior_or_policy", "architecture_or_runtime", "persistence_or_security", "external_contract", "release_or_cross_host", "unbounded_coordination"];
89
+ const depthChecks = ["scope_boundary", "owner_map", "affected_surfaces", "validation_path", "rollback_boundary", "coordination_boundary", "uncertainty_register"];
90
+ const semanticDepthTargets = {
91
+ "PB-021": "behavior_or_policy",
92
+ "PB-031": "architecture_or_runtime",
93
+ "PB-033": "persistence_or_security",
94
+ "PB-034": "unbounded_coordination",
95
+ "PB-036": "release_or_cross_host",
96
+ "PB-037": "external_contract",
97
+ };
98
+ export function validateV3Facts(index, fixtures, baseline) {
99
+ for (const caseId of ["PB-008", "PB-010", "PB-011"]) {
100
+ const scenarios = index.scenarios.filter((item) => item.case_id === caseId);
101
+ if (!scenarios.length) fail(`missing targeted semantics ${caseId}`);
102
+ for (const scenario of scenarios) {
103
+ if (caseId === "PB-008" && (!scenario.decision_state_facts || typeof scenario.decision_state_facts.effective_control_state !== "string" || typeof scenario.decision_state_facts.currently_permitted_action !== "string" || typeof scenario.decision_state_facts.mutation_intent !== "string" || scenario.decision_state_facts.unresolved_target !== true)) fail(`incomplete decision-state facts ${scenario.scenario_id}`);
104
+ if (["PB-010", "PB-011"].includes(caseId) && (!scenario.task_semantics?.requested_action || !scenario.task_semantics?.semantic_effect || !scenario.task_semantics?.excluded_effects?.length)) fail(`incomplete task semantics ${scenario.scenario_id}`);
105
+ }
106
+ }
107
+ for (const caseId of ["PB-016", "PB-017", "PB-020"]) {
108
+ const pack = fixtures.evidence_packs[`EP-${caseId}`]?.bounded_change_facts;
109
+ const missingGroup = verifiedFactGroups.find((key) => !(key in (pack ?? {})));
110
+ if (!pack || missingGroup) fail(`incomplete verified-change facts ${caseId}: missing ${missingGroup ?? "bounded_change_facts"}; restore the declared facts and rerun`);
111
+ if (pack.ownership_boundary.canonical_owner_count !== 1 || pack.ownership_boundary.bounded !== true || !Number.isInteger(pack.ownership_boundary.source_path_count) || pack.ownership_boundary.source_path_count < 1 || !Number.isInteger(pack.ownership_boundary.derived_path_count) || pack.ownership_boundary.derived_path_count < 0) fail(`conflicting ownership-boundary facts ${caseId}; correct the facts and rerun`);
112
+ if (!/^[a-f0-9]{40}$/.test(pack.baseline_state.commit ?? "") || pack.baseline_state.tracked_candidate_paths_clean !== true || pack.baseline_state.untracked_candidate_paths_clean !== true || !Array.isArray(pack.baseline_state.conflicts) || pack.baseline_state.conflicts.length) fail(`conflicting baseline-state facts ${caseId}; correct the facts and rerun`);
113
+ if (pack.deterministic_controls.validation !== true || pack.deterministic_controls.propagation !== true) fail(`conflicting deterministic-control facts ${caseId}; correct the facts and rerun`);
114
+ if (pack.prohibited_impacts.complete !== true || impactFacts.some((key) => pack.prohibited_impacts.impacts?.[key] !== false)) fail(`conflicting prohibited-impact facts ${caseId}; correct the facts and rerun`);
115
+ if (!["structured_slice", "structured_delivery"].includes(pack.escalation.target) || !Array.isArray(pack.escalation.conditions) || !pack.escalation.conditions.length) fail(`conflicting escalation facts ${caseId}; correct the facts and rerun`);
116
+ }
117
+ const structuredCases = baseline.cases.filter((item) => ["structured_slice", "structured_delivery"].includes(item.expected_delivery_path));
118
+ for (const item of structuredCases) {
119
+ const facts = fixtures.evidence_packs[`EP-${item.case_id}`]?.structured_depth_facts;
120
+ if (!facts || facts.depth_policy_version !== 1 || facts.fact_state !== "complete" || !Array.isArray(facts.conflicts) || facts.conflicts.length) fail(`incomplete structured-depth facts ${item.case_id}; correct the facts and rerun`);
121
+ if (depthTriggerFamilies.some((key) => typeof facts.trigger_families?.[key] !== "boolean")) fail(`incomplete depth triggers ${item.case_id}; complete all six trigger families and rerun`);
122
+ if (depthChecks.some((key) => typeof facts.bounded_checks?.[key] !== "string" || !facts.bounded_checks[key])) fail(`incomplete depth checks ${item.case_id}; complete all seven bounded checks and rerun`);
123
+ if (semanticDepthTargets[item.case_id] && (facts.semantic_eval_target !== semanticDepthTargets[item.case_id] || facts.trigger_families[facts.semantic_eval_target] !== true)) fail(`invalid semantic depth target ${item.case_id}`);
124
+ }
125
+ if (new Set(Object.values(semanticDepthTargets)).size !== depthTriggerFamilies.length) fail("semantic depth target coverage mismatch");
126
+ }
40
127
  export function loadCorpus(repoRoot, profileId = "legacy-v1") {
128
+ const profile = getProfileDefinition(profileId);
41
129
  const root = existingInside(repoRoot, "evals/proportionality");
42
- if (profileId === "staged-v2") {
43
- const manifest = JSON.parse(readFileSync(existingInside(root, "staged-manifest.json"), "utf8"));
130
+ if (isStagedProfile(profile)) {
131
+ const manifest = JSON.parse(readFileSync(existingInside(repoRoot, profile.manifest_path), "utf8"));
44
132
  const index = JSON.parse(readFileSync(existingInside(root, manifest.scenarios_path), "utf8"));
45
133
  const fixtures = JSON.parse(readFileSync(existingInside(root, manifest.fixture_path), "utf8"));
46
134
  const baselinePath = existingInside(repoRoot, manifest.baseline_path);
47
135
  const baseline = JSON.parse(readFileSync(baselinePath, "utf8"));
48
- if (
49
- manifest.profile_id !== "staged-v2"
50
- || baseline.schema_version !== "2"
51
- || baseline.baseline_version !== manifest.baseline_version
52
- || !manifest.corpus_version
53
- || !manifest.fixture_version
54
- || fixtures.fixture_version !== manifest.fixture_version
55
- ) fail("staged profile version mismatch");
56
- if (baseline.cases.length !== 40 || index.scenarios.length !== 72 || new Set(index.scenario_ids).size !== 72) fail("staged corpus coverage mismatch");
136
+ const versionMismatch = [
137
+ ["manifest.profile_id", manifest.profile_id, profile.profile_id],
138
+ ["manifest.schema_version", manifest.schema_version, profile.schema_version],
139
+ ["manifest.protocol_version", manifest.protocol_version, profile.protocol_version],
140
+ ["index.schema_version", index.schema_version, profile.schema_version],
141
+ ["index.profile_id", index.profile_id, profile.profile_id],
142
+ ["fixtures.schema_version", fixtures.schema_version, profile.schema_version],
143
+ ["fixtures.profile_id", fixtures.profile_id, profile.profile_id],
144
+ ["fixtures.fixture_version", fixtures.fixture_version, manifest.fixture_version],
145
+ ["baseline.schema_version", baseline.schema_version, profile.schema_version],
146
+ ["baseline.baseline_version", baseline.baseline_version, manifest.baseline_version],
147
+ ].find(([, actual, expected]) => actual !== expected);
148
+ if (versionMismatch || !manifest.corpus_version || !manifest.fixture_version) fail(`staged profile version mismatch: ${versionMismatch?.[0] ?? "manifest corpus/fixture version"}`);
149
+ if (profile.strict_version_links) {
150
+ const strictMismatch = [
151
+ ["index.corpus_version", index.corpus_version, manifest.corpus_version],
152
+ ["baseline.profile_id", baseline.profile_id, profile.profile_id],
153
+ ["baseline.protocol_version", baseline.protocol_version, profile.protocol_version],
154
+ ["manifest.adapter_version", manifest.adapter_version, profile.adapter_version],
155
+ ["manifest.runner_version", manifest.runner_version, profile.runner_version],
156
+ ["manifest.report_version", manifest.report_version, profile.report_version],
157
+ ].find(([, actual, expected]) => actual !== expected);
158
+ if (strictMismatch || !manifest.history_inventory_version) fail(`staged profile version mismatch: ${strictMismatch?.[0] ?? "manifest.history_inventory_version"}`);
159
+ }
160
+ const baselineCaseIds = baseline.cases.map((item) => item.case_id);
161
+ const scenarioIds = index.scenarios.map((item) => item.scenario_id);
162
+ if (baseline.cases.length !== 40 || new Set(baselineCaseIds).size !== 40 || baselineCaseIds.some((id) => !/^PB-\d{3}$/.test(id))) fail("staged case identity mismatch");
163
+ if (!Array.isArray(index.scenario_ids) || index.scenario_ids.length !== 72 || index.scenarios.length !== 72 || new Set(index.scenario_ids).size !== 72 || new Set(scenarioIds).size !== 72 || scenarioIds.some((id) => !index.scenario_ids.includes(id))) fail("staged corpus coverage mismatch");
164
+ const pathSet = new Set(baseline.cases.map((item) => item.expected_delivery_path));
165
+ if (DELIVERY_PATHS.some((path) => !pathSet.has(path)) || [...pathSet].some((path) => !DELIVERY_PATHS.includes(path)) || baseline.cases.filter((item) => item.adversarial).length < 10) fail("staged baseline coverage mismatch");
57
166
  const expectedIds = new Set(baseline.scenarios.map((item) => item.scenario_id));
167
+ if (baseline.scenarios.length !== 72 || expectedIds.size !== 72 || baseline.scenarios.some((item) => !baselineCaseIds.includes(item.case_id) || item.scenario_id.split(":")[0] !== item.case_id)) fail("staged scenario baseline mismatch");
58
168
  if (index.scenarios.some((item) => !expectedIds.has(item.scenario_id)) || baseline.scenarios.some((item) => !index.scenario_ids.includes(item.scenario_id))) fail("staged scenario baseline mismatch");
59
169
  for (const scenario of index.scenarios) {
60
170
  if (scenario.evidence_pack_id && !fixtures.evidence_packs[scenario.evidence_pack_id]) fail(`missing evidence pack ${scenario.scenario_id}`);
@@ -64,18 +174,19 @@ export function loadCorpus(repoRoot, profileId = "legacy-v1") {
64
174
  baseline.scenarios.find((item) => item.scenario_id === scenario.scenario_id),
65
175
  );
66
176
  }
177
+ const historyProvenance = profile.history_provenance ? validateHistoryInventory(repoRoot, root, manifest) : undefined;
178
+ if (profile.semantic_fact_validation) validateV3Facts(index, fixtures, baseline);
67
179
  const cases = index.scenarios.map((scenario) => ({
68
180
  ...scenario,
69
- profile_id: "staged-v2",
181
+ profile_id: profile.profile_id,
70
182
  corpus_version: manifest.corpus_version,
71
183
  fixture_version: manifest.fixture_version,
72
184
  allowed_stages: ["ungated_execution", "ur", "brownfield_review", "prd", "sd", "tp", "brownfield_analysis", "cd_tests", "cr", "qa", "uat", "or", "blocked"],
73
185
  evidence_pack: scenario.evidence_pack_id ? fixtures.evidence_packs[scenario.evidence_pack_id] : null,
74
186
  }));
75
- return { profile_id: "staged-v2", manifest, baseline, fixtures, cases };
187
+ return { profile_id: profile.profile_id, profile, manifest, baseline, fixtures, ...(historyProvenance ? { history_provenance: historyProvenance } : {}), cases };
76
188
  }
77
- if (profileId !== "legacy-v1") fail(`unknown proportionality profile ${profileId}`);
78
- const manifest = JSON.parse(readFileSync(existingInside(root, "manifest.json"), "utf8"));
189
+ const manifest = JSON.parse(readFileSync(existingInside(repoRoot, profile.manifest_path), "utf8"));
79
190
  const provenance = JSON.parse(readFileSync(existingInside(root, "legacy-v1-provenance.json"), "utf8"));
80
191
  const index = JSON.parse(readFileSync(existingInside(root, "cases.json"), "utf8"));
81
192
  const fixtures = JSON.parse(readFileSync(existingInside(root, "fixtures/catalog.json"), "utf8"));
@@ -106,5 +217,5 @@ export function loadCorpus(repoRoot, profileId = "legacy-v1") {
106
217
  repository_context: fixture.repository_context,
107
218
  control_state_context: index.case_contexts?.[case_id] ?? fixture.control_state_context,
108
219
  }));
109
- return { profile_id: "legacy-v1", manifest, baseline, fixtures, provenance, cases };
220
+ return { profile_id: "legacy-v1", profile, manifest, baseline, fixtures, provenance, cases };
110
221
  }
@@ -1,6 +1,7 @@
1
1
  import { DELIVERY_PATHS, PATH_RANK, STAGES, fail, stable } from "./contracts.js";
2
2
  import { sourceFingerprint } from "./source-fingerprint.js";
3
- import { ADAPTER_VERSION, STAGED_ADAPTER_VERSION } from "./live-recorder.js";
3
+ import { ADAPTER_VERSION } from "./live-recorder.js";
4
+ import { getProfileDefinition, isStagedProfile } from "./profiles.js";
4
5
 
5
6
  export function classifyObservation(expected, observation) {
6
7
  if (observation.ambiguous || observation.observed_delivery_path === null) return "ambiguous";
@@ -50,22 +51,25 @@ function stagedCoverageResult(expected, rows, reason) {
50
51
  };
51
52
  }
52
53
  function evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats }) {
53
- const provenanceKeys = ["series_id", "profile_id", "protocol_version", "corpus_version", "fixture_version", "surface", "runtime_version", "model", "agdf_version", "baseline_version", "adapter_version"];
54
+ const profile = getProfileDefinition(corpus.profile_id);
55
+ const provenanceKeys = ["series_id", "profile_id", "protocol_version", "corpus_version", "fixture_version", "surface", "runtime_version", "model", "agdf_version", "baseline_version", "adapter_version", ...(profile.evidence_kind_provenance ? ["evidence_kind"] : []), ...(profile.series_profile_metadata ? ["runner_version"] : [])];
54
56
  const first = observations[0] ?? {};
55
57
  const observationIds = new Set();
56
58
  const byScenario = new Map(corpus.cases.map((item) => [item.scenario_id, []]));
57
59
  for (const observation of observations) {
58
60
  if (!byScenario.has(observation.scenario_id) || observation.case_id !== observation.scenario_id.split(":")[0]) fail(`unknown staged observation ${observation.scenario_id ?? "unknown"}`);
59
- if (observation.schema_version !== "2" || observation.evidence_kind !== "live_agent_observation" || !Number.isInteger(observation.repeat) || observation.repeat < 1) fail(`invalid observation ${observation.observation_id ?? "unknown"}`);
61
+ if (observation.schema_version !== profile.schema_version || !profile.evidence_kinds.includes(observation.evidence_kind) || !Number.isInteger(observation.repeat) || observation.repeat < 1) fail(`invalid observation ${observation.observation_id ?? "unknown"}`);
60
62
  if (!observation.observation_id || observationIds.has(observation.observation_id)) fail(`duplicate observation ${observation.observation_id ?? "unknown"}`);
61
63
  if (observation.execution_status !== "completed" || observation.redaction_status !== "pass" || observation.mutation_status !== "pass") fail(`unsafe observation status ${observation.observation_id}`);
62
64
  if (!Number.isFinite(Date.parse(observation.recorded_at))) fail(`invalid observation timestamp ${observation.observation_id}`);
63
- if (
64
- observation.baseline_version !== corpus.baseline.baseline_version
65
- || observation.corpus_version !== corpus.manifest.corpus_version
66
- || observation.fixture_version !== corpus.manifest.fixture_version
67
- ) fail(`baseline provenance drift at ${observation.observation_id}`);
68
- if (provenanceKeys.some((key) => observation[key] !== first[key])) fail(`series provenance drift at ${observation.observation_id}`);
65
+ const versionDrift = [
66
+ ["baseline_version", corpus.baseline.baseline_version],
67
+ ["corpus_version", corpus.manifest.corpus_version],
68
+ ["fixture_version", corpus.manifest.fixture_version],
69
+ ].find(([key, expected]) => observation[key] !== expected);
70
+ if (versionDrift) fail(`baseline provenance drift (${versionDrift[0]}) at ${observation.observation_id}`);
71
+ const provenanceDrift = provenanceKeys.find((key) => observation[key] !== first[key]);
72
+ if (provenanceDrift) fail(`series provenance drift (${provenanceDrift}) at ${observation.observation_id}`);
69
73
  observationIds.add(observation.observation_id);
70
74
  byScenario.get(observation.scenario_id).push(observation);
71
75
  }
@@ -74,7 +78,7 @@ function evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats }
74
78
  const rows = byScenario.get(expected.scenario_id).sort((a, b) => a.repeat - b.repeat);
75
79
  const repeats = new Set(rows.map((item) => item.repeat));
76
80
  if (rows.length < minimumRepeats || repeats.size !== rows.length) return stagedCoverageResult(expected, rows, "coverage");
77
- const fingerprint = sourceFingerprint(repoRoot, blind, corpus.fixtures, STAGED_ADAPTER_VERSION);
81
+ const fingerprint = sourceFingerprint(repoRoot, blind, corpus.fixtures, profile.adapter_version);
78
82
  const stale = rows.some((item) => item.source_fingerprint !== fingerprint);
79
83
  const invalidAxes = rows.some((item) => (
80
84
  expected.stage_required !== (item.stage_evaluability === "evaluated")
@@ -130,9 +134,9 @@ function evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats }
130
134
  ...(ambiguous.length ? ["ambiguous_or_incomplete"] : []),
131
135
  ];
132
136
  return stable({
133
- schema_version: "2",
134
- profile_id: "staged-v2",
135
- protocol_version: "2",
137
+ schema_version: profile.schema_version,
138
+ profile_id: profile.profile_id,
139
+ protocol_version: profile.protocol_version,
136
140
  evidence_boundary: corpus.manifest.evidence_boundary,
137
141
  baseline_version: corpus.baseline.baseline_version,
138
142
  corpus_version: corpus.manifest.corpus_version,
@@ -142,7 +146,13 @@ function evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats }
142
146
  agdf_version: first.agdf_version ?? null,
143
147
  adapter_version: first.adapter_version ?? null,
144
148
  runtime_version: first.runtime_version ?? null,
145
- runner_version: "2.0.0",
149
+ runner_version: profile.runner_version,
150
+ ...(profile.repository_replay_non_claim ? {
151
+ evidence_class: first.evidence_kind ?? "none",
152
+ report_version: profile.report_version,
153
+ authenticated_live_host_evidence: false,
154
+ live_host_non_claim: "No authenticated staged-v3 live-host series was executed or accepted by this repository replay.",
155
+ } : {}),
146
156
  freshness_status: scenarios.some((item) => item.blocking_reasons.includes("stale")) ? "stale" : "fresh",
147
157
  minimum_repeats: minimumRepeats,
148
158
  valid_observations: observations.length,
@@ -164,7 +174,7 @@ function evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats }
164
174
  }
165
175
  export function evaluateSeries({ repoRoot, corpus, observations, minimumRepeats = 3 }) {
166
176
  if (!Number.isInteger(minimumRepeats) || minimumRepeats < 3) fail("minimum repeats must be at least 3");
167
- if (corpus.profile_id === "staged-v2") return evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats });
177
+ if (isStagedProfile(getProfileDefinition(corpus.profile_id))) return evaluateStagedSeries({ repoRoot, corpus, observations, minimumRepeats });
168
178
  const provenanceKeys = ["series_id", "surface", "runtime_version", "model", "agdf_version", "baseline_version", "adapter_version"];
169
179
  const first = observations[0] ?? {};
170
180
  const observationIds = new Set();
@@ -3,5 +3,6 @@ export * from "./contracts.js";
3
3
  export * from "./corpus-loader.js";
4
4
  export * from "./evaluator.js";
5
5
  export * from "./live-recorder.js";
6
+ export * from "./profiles.js";
6
7
  export * from "./report.js";
7
8
  export * from "./source-fingerprint.js";
@@ -5,11 +5,31 @@ import { dirname, join } from "node:path";
5
5
  import { executeStructuredAgent } from "../live-agent/read-only-structured.js";
6
6
  import { changedPaths, snapshotWorkspace } from "../skill-evals/workspace.js";
7
7
  import { buildBlindPrompt } from "./blind-prompt.js";
8
- import { normalizeAgentOutput, normalizeStagedAgentOutput, OBSERVATION_SCHEMA, STAGED_OBSERVATION_SCHEMA, fail } from "./contracts.js";
8
+ import { normalizeAgentOutput, normalizeStagedAgentOutput, OBSERVATION_SCHEMA, fail, stagedSchemaForVersion } from "./contracts.js";
9
+ import { getProfileDefinition, isStagedProfile } from "./profiles.js";
9
10
  import { behaviorSourceText, sourceFingerprint } from "./source-fingerprint.js";
10
11
 
11
- export const ADAPTER_VERSION = "1.1.0";
12
- export const STAGED_ADAPTER_VERSION = "2.1.0";
12
+ export const ADAPTER_VERSION = getProfileDefinition("legacy-v1").adapter_version;
13
+ export const STAGED_ADAPTER_VERSION = getProfileDefinition("staged-v2").adapter_version;
14
+ export const STAGED_V3_ADAPTER_VERSION = getProfileDefinition("staged-v3").adapter_version;
15
+ export function isRetryableObservationError(error) {
16
+ return error?.code === "GENERATOR_TIMEOUT";
17
+ }
18
+ export function observationAttemptFailure(error, attemptCount, attemptLimit) {
19
+ const messages = {
20
+ GENERATOR_TIMEOUT: "read-only process timed out",
21
+ PROPORTIONALITY_OUTPUT_INVALID: "agent output failed the structured contract",
22
+ PROPORTIONALITY_REDACTION_FAILED: "agent output failed redaction",
23
+ PROPORTIONALITY_MUTATION: "agent mutated the disposable fixture",
24
+ };
25
+ return {
26
+ status: "invalid",
27
+ code: error?.code ?? "EXECUTION_ERROR",
28
+ message: messages[error?.code] ?? "agent execution failed",
29
+ retryable: isRetryableObservationError(error),
30
+ remaining_attempt_budget: Math.max(0, attemptLimit - attemptCount),
31
+ };
32
+ }
13
33
  function runtimeVersion(surface) {
14
34
  try { return execFileSync(surface, ["--version"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim(); }
15
35
  catch { return `${surface} version unavailable`; }
@@ -40,8 +60,9 @@ export async function recordObservation({
40
60
  }) {
41
61
  if (!/^[a-z0-9][a-z0-9._-]{2,79}$/i.test(seriesId) || !Number.isInteger(repeat) || repeat < 1) fail("invalid series or repeat");
42
62
  if (!surface || !model || !agdfVersion || !baselineVersion) fail("surface, model, AGDF version and baseline version are required");
43
- const staged = testCase.profile_id === "staged-v2";
44
- const adapterVersion = staged ? STAGED_ADAPTER_VERSION : ADAPTER_VERSION;
63
+ const profile = getProfileDefinition(testCase.profile_id ?? "legacy-v1");
64
+ const staged = isStagedProfile(profile);
65
+ const adapterVersion = profile.adapter_version;
45
66
  const fingerprint = sourceFingerprint(repoRoot, testCase, fixture, adapterVersion);
46
67
  const fixtureRoot = mkdtempSync(join(tmpdir(), "agdf-proportionality-"));
47
68
  let output;
@@ -55,7 +76,7 @@ export async function recordObservation({
55
76
  const before = snapshotWorkspace(fixtureRoot);
56
77
  try {
57
78
  output = await execute({
58
- surface, cwd: fixtureRoot, model, timeoutMs, outputSchema: staged ? STAGED_OBSERVATION_SCHEMA : OBSERVATION_SCHEMA,
79
+ surface, cwd: fixtureRoot, model, timeoutMs, outputSchema: staged ? stagedSchemaForVersion(profile.schema_version) : OBSERVATION_SCHEMA,
59
80
  prompt: buildBlindPrompt(testCase, behaviorSourceText(repoRoot)),
60
81
  });
61
82
  } catch (error) { executionError = error; }
@@ -63,18 +84,19 @@ export async function recordObservation({
63
84
  const mutations = changedPaths(before, after);
64
85
  if (mutations.length) fail(`agent mutated fixture: ${mutations.join(", ")}`, "PROPORTIONALITY_MUTATION");
65
86
  if (executionError) throw executionError;
66
- const normalized = staged ? normalizeStagedAgentOutput(output, testCase.requested_axes) : normalizeAgentOutput(output);
87
+ const normalized = staged ? normalizeStagedAgentOutput(output, testCase.requested_axes, profile.schema_version) : normalizeAgentOutput(output);
67
88
  const observation = {
68
- schema_version: staged ? "2" : "1",
89
+ schema_version: profile.schema_version,
69
90
  observation_id: `${seriesId}:${staged ? testCase.scenario_id : testCase.case_id}:${repeat}`,
70
91
  case_id: testCase.case_id,
71
92
  ...(staged ? {
72
- profile_id: "staged-v2",
73
- protocol_version: "2",
93
+ profile_id: profile.profile_id,
94
+ protocol_version: profile.protocol_version,
74
95
  corpus_version: testCase.corpus_version,
75
96
  fixture_version: testCase.fixture_version,
76
97
  scenario_id: testCase.scenario_id,
77
98
  lifecycle_stage: testCase.lifecycle_stage,
99
+ ...(profile.series_profile_metadata ? { runner_version: profile.runner_version } : {}),
78
100
  } : {}),
79
101
  series_id: seriesId,
80
102
  repeat,
@@ -0,0 +1,102 @@
1
+ const definitions = {
2
+ "legacy-v1": {
3
+ profile_id: "legacy-v1",
4
+ family: "legacy",
5
+ manifest_path: "evals/proportionality/manifest.json",
6
+ schema_version: "1",
7
+ protocol_version: "1",
8
+ adapter_version: "1.1.0",
9
+ runner_version: "1.0.0",
10
+ report_version: "1.0.0",
11
+ observation_key: "case_id",
12
+ fixture_strategy: "catalog_fixture",
13
+ evidence_kinds: ["live_agent_observation"],
14
+ evidence_kind_provenance: false,
15
+ history_provenance: false,
16
+ semantic_fact_validation: false,
17
+ fingerprint_profile_metadata: false,
18
+ repository_replay_non_claim: false,
19
+ strict_version_links: false,
20
+ series_profile_metadata: false,
21
+ },
22
+ "staged-v2": {
23
+ profile_id: "staged-v2",
24
+ family: "staged",
25
+ manifest_path: "evals/proportionality/staged-manifest.json",
26
+ schema_version: "2",
27
+ protocol_version: "2",
28
+ adapter_version: "2.1.0",
29
+ runner_version: "2.0.0",
30
+ report_version: "2.0.0",
31
+ observation_key: "scenario_id",
32
+ fixture_strategy: "staged_catalog",
33
+ evidence_kinds: ["live_agent_observation"],
34
+ evidence_kind_provenance: false,
35
+ history_provenance: false,
36
+ semantic_fact_validation: false,
37
+ fingerprint_profile_metadata: false,
38
+ repository_replay_non_claim: false,
39
+ strict_version_links: false,
40
+ series_profile_metadata: false,
41
+ },
42
+ "staged-v3": {
43
+ profile_id: "staged-v3",
44
+ family: "staged",
45
+ manifest_path: "evals/proportionality/staged-v3-manifest.json",
46
+ schema_version: "3",
47
+ protocol_version: "3",
48
+ adapter_version: "3.0.0",
49
+ runner_version: "3.0.0",
50
+ report_version: "3.0.0",
51
+ observation_key: "scenario_id",
52
+ fixture_strategy: "staged_catalog",
53
+ evidence_kinds: ["synthetic_replay", "live_agent_observation"],
54
+ evidence_kind_provenance: true,
55
+ history_provenance: true,
56
+ semantic_fact_validation: true,
57
+ fingerprint_profile_metadata: true,
58
+ repository_replay_non_claim: true,
59
+ strict_version_links: true,
60
+ series_profile_metadata: true,
61
+ },
62
+ };
63
+
64
+ function deepFreeze(value) {
65
+ if (value && typeof value === "object" && !Object.isFrozen(value)) {
66
+ Object.freeze(value);
67
+ for (const item of Object.values(value)) deepFreeze(item);
68
+ }
69
+ return value;
70
+ }
71
+
72
+ export const PROPORTIONALITY_PROFILES = deepFreeze(definitions);
73
+ export const SUPPORTED_PROFILE_IDS = Object.freeze(Object.keys(PROPORTIONALITY_PROFILES));
74
+
75
+ export function getProfileDefinition(profileId) {
76
+ const definition = PROPORTIONALITY_PROFILES[profileId];
77
+ if (!definition) throw Object.assign(new Error(`unknown proportionality profile ${profileId}`), { code: "PROPORTIONALITY_PROFILE_UNKNOWN" });
78
+ return definition;
79
+ }
80
+
81
+ export function isStagedProfile(profileOrId) {
82
+ const definition = typeof profileOrId === "string" ? getProfileDefinition(profileOrId) : profileOrId;
83
+ return definition.family === "staged";
84
+ }
85
+
86
+ export function observationKey(profileOrId, testCase) {
87
+ const definition = typeof profileOrId === "string" ? getProfileDefinition(profileOrId) : profileOrId;
88
+ const value = testCase[definition.observation_key];
89
+ if (!value) throw new Error(`missing ${definition.observation_key} for ${definition.profile_id}`);
90
+ return definition.observation_key === "scenario_id" ? value.replaceAll(":", "__") : value;
91
+ }
92
+
93
+ export function fixtureForProfile(profileOrId, corpus) {
94
+ const definition = typeof profileOrId === "string" ? getProfileDefinition(profileOrId) : profileOrId;
95
+ return definition.fixture_strategy === "staged_catalog"
96
+ ? corpus.fixtures
97
+ : corpus.fixtures.fixtures[corpus.manifest.fixture_id];
98
+ }
99
+
100
+ export function profileUsage() {
101
+ return SUPPORTED_PROFILE_IDS.join("|");
102
+ }
@@ -1,11 +1,20 @@
1
+ import { getProfileDefinition, isStagedProfile } from "./profiles.js";
2
+
1
3
  export function renderMarkdown(report) {
2
- if (report.profile_id === "staged-v2") {
4
+ if (report.profile_id && isStagedProfile(getProfileDefinition(report.profile_id))) {
3
5
  const lines = [
4
6
  "# AGDF Staged Proportionality Observation",
5
7
  "",
6
8
  `- Status: \`${report.status}\``,
7
9
  `- Evidenzgrenze: ${report.evidence_boundary}`,
8
10
  `- Profil/Protokoll: \`${report.profile_id}\` / \`${report.protocol_version}\``,
11
+ ...(report.evidence_class ? [
12
+ `- Corpus/Baseline: \`${report.corpus_version}\` / \`${report.baseline_version}\``,
13
+ `- Report-Version: \`${report.report_version}\``,
14
+ `- Evidenzklasse: \`${report.evidence_class}\``,
15
+ `- Authentifizierte Live-Host-Evidenz: \`${report.authenticated_live_host_evidence}\``,
16
+ `- Live-Host-Nichtbehauptung: ${report.live_host_non_claim}`,
17
+ ] : []),
9
18
  `- Serie: \`${report.series_id ?? "none"}\``,
10
19
  `- Surface/Modell: \`${report.surface ?? "none"}\` / \`${report.model ?? "none"}\``,
11
20
  `- Runtime/AGDF/Adapter/Runner: \`${report.runtime_version ?? "none"}\` / \`${report.agdf_version ?? "none"}\` / \`${report.adapter_version ?? "none"}\` / \`${report.runner_version}\``,
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { stable } from "./contracts.js";
5
+ import { getProfileDefinition } from "./profiles.js";
5
6
 
6
7
  export const BEHAVIOR_SOURCES = Object.freeze([
7
8
  "plugin/meta/agdf-agent-router.md",
@@ -24,7 +25,10 @@ export function behaviorSourceText(repoRoot) {
24
25
  }
25
26
  export function sourceFingerprint(repoRoot, testCase, fixture, adapterVersion) {
26
27
  const hash = createHash("sha256");
27
- hash.update(JSON.stringify(stable({ testCase, fixture, adapterVersion })));
28
- for (const path of [...BEHAVIOR_SOURCES, ...IMPLEMENTATION_SOURCES]) hash.update(path).update(readFileSync(join(repoRoot, path)));
28
+ const selectedProfile = testCase.profile_id ? getProfileDefinition(testCase.profile_id) : null;
29
+ const profile = selectedProfile?.fingerprint_profile_metadata ? selectedProfile : null;
30
+ hash.update(JSON.stringify(stable(profile ? { testCase, fixture, adapterVersion, profile } : { testCase, fixture, adapterVersion })));
31
+ const sources = profile ? [...BEHAVIOR_SOURCES, ...IMPLEMENTATION_SOURCES, "create-agdf/lib/proportionality-benchmark/profiles.js"] : [...BEHAVIOR_SOURCES, ...IMPLEMENTATION_SOURCES];
32
+ for (const path of sources) hash.update(path).update(readFileSync(join(repoRoot, path)));
29
33
  return hash.digest("hex");
30
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agdf",
3
- "version": "0.13.2",
3
+ "version": "0.13.3",
4
4
  "description": "Bootstrap AGDF repository-local plugin files, Copilot/OpenCode instructions, skills, control files and machine-readable checks.",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,10 +36,12 @@
36
36
  "test:package-build": "node ./scripts/package-build-test.js",
37
37
  "test:lifecycle": "node ./scripts/lifecycle-test.js",
38
38
  "test:control-state": "node ./scripts/control-state-test.js",
39
+ "test:parent-reconciliation": "node ./scripts/parent-reconciliation-test.js",
39
40
  "test:interaction-presentation": "node ./scripts/interaction-presentation-test.js",
40
41
  "test:verified-change": "node ./scripts/verified-change-test.js",
41
42
  "test:runtime-integrity-layout": "node ./scripts/runtime-integrity-layout-test.js",
42
43
  "test:runtime-integrity-negative": "node ./scripts/runtime-integrity-negative-test.js",
44
+ "test:agent-skills-conformance": "node ./scripts/agent-skills-conformance-test.js",
43
45
  "test:skill-evals": "node ./scripts/skill-evals-test.js",
44
46
  "eval:skills": "node ./scripts/run-skill-evals.js",
45
47
  "eval:skills:record": "node ./scripts/record-skill-evals.js",
@@ -48,7 +50,7 @@
48
50
  "test:proportionality": "node ./scripts/proportionality-benchmark-test.js",
49
51
  "test:release-bootstrap": "node ./scripts/release-bootstrap-smoke-test.js",
50
52
  "test:routing": "npm run sync-package-assets && node ./scripts/test-routing.js",
51
- "smoke-test": "npm run release:prepare && npm run test:cli-modularization && npm run test:local-validator && npm run test:local-marketplace && npm run test:package-build && npm run test:package-contents && npm run test:lifecycle && npm run test:control-state && npm run test:interaction-presentation && npm run test:verified-change && npm run test:runtime-integrity-layout && npm run test:runtime-integrity-negative && npm run test:skill-evals && npm run eval:skills && npm run test:proportionality && npm run test:delivery-path-search && npm run test:delivery-path-search-unit && npm run test:delivery-path-search-generator && npm run test:opencode-hardening && node ./scripts/smoke-test.js && node ./scripts/test-routing.js",
53
+ "smoke-test": "npm run release:prepare && npm run test:cli-modularization && npm run test:local-validator && npm run test:local-marketplace && npm run test:package-build && npm run test:package-contents && npm run test:lifecycle && npm run test:control-state && npm run test:parent-reconciliation && npm run test:interaction-presentation && npm run test:verified-change && npm run test:runtime-integrity-layout && npm run test:runtime-integrity-negative && npm run test:agent-skills-conformance && npm run test:skill-evals && npm run eval:skills && npm run test:proportionality && npm run test:delivery-path-search && npm run test:delivery-path-search-unit && npm run test:delivery-path-search-generator && npm run test:opencode-hardening && node ./scripts/smoke-test.js && node ./scripts/test-routing.js",
52
54
  "prepack": "npm run release:prepare"
53
55
  },
54
56
  "keywords": [