@kontourai/flow-agents 3.3.0 → 3.4.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/.github/workflows/add-to-project.yml +15 -0
- package/.github/workflows/ci.yml +161 -0
- package/CHANGELOG.md +41 -0
- package/CONTEXT.md +5 -1
- package/README.md +19 -8
- package/build/src/builder-flow-run-adapter.d.ts +80 -0
- package/build/src/builder-flow-run-adapter.js +241 -0
- package/build/src/builder-flow-runtime.d.ts +16 -0
- package/build/src/builder-flow-runtime.js +290 -0
- package/build/src/cli/builder-run.d.ts +1 -0
- package/build/src/cli/builder-run.js +27 -0
- package/build/src/cli/effective-backlog-settings.js +70 -2
- package/build/src/cli/init.d.ts +34 -0
- package/build/src/cli/init.js +341 -61
- package/build/src/cli/kit.js +55 -12
- package/build/src/cli/pull-work-provider.js +346 -5
- package/build/src/cli/skill-drift-check.d.ts +1 -0
- package/build/src/cli/skill-drift-check.js +165 -0
- package/build/src/cli/telemetry-doctor.d.ts +37 -0
- package/build/src/cli/telemetry-doctor.js +53 -6
- package/build/src/cli/validate-hook-influence.js +37 -7
- package/build/src/cli/workflow-sidecar.d.ts +93 -8
- package/build/src/cli/workflow-sidecar.js +1175 -158
- package/build/src/cli.js +5 -0
- package/build/src/flow-kit/validate.d.ts +54 -34
- package/build/src/flow-kit/validate.js +237 -26
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +1 -0
- package/build/src/lib/console-connect-options.d.ts +97 -0
- package/build/src/lib/console-connect-options.js +199 -0
- package/build/src/lib/console-telemetry-validate.d.ts +49 -0
- package/build/src/lib/console-telemetry-validate.js +91 -0
- package/build/src/lib/flow-resolver.d.ts +54 -1
- package/build/src/lib/flow-resolver.js +112 -5
- package/build/src/lib/fs.d.ts +17 -0
- package/build/src/lib/fs.js +172 -0
- package/build/src/lib/local-artifact-root.d.ts +44 -1
- package/build/src/lib/local-artifact-root.js +131 -3
- package/build/src/runtime-adapters.d.ts +39 -3
- package/build/src/runtime-adapters.js +77 -31
- package/build/src/tools/build-universal-bundles.js +40 -2
- package/build/src/tools/codex-agent-routing.d.ts +2 -0
- package/build/src/tools/codex-agent-routing.js +49 -0
- package/build/src/tools/generate-context-map.js +1 -0
- package/build/src/tools/validate-source-tree.js +27 -1
- package/context/scripts/hooks/lib/kit-catalog.js +235 -0
- package/context/scripts/hooks/lib/runnable-command.js +177 -0
- package/context/scripts/hooks/stop-goal-fit.js +278 -48
- package/context/scripts/hooks/workflow-steering.js +121 -21
- package/context/scripts/package.json +3 -0
- package/context/scripts/telemetry/install-console-config.sh +25 -4
- package/context/scripts/telemetry/lib/config.sh +102 -12
- package/context/scripts/telemetry/lib/pricing.sh +50 -0
- package/context/scripts/telemetry/lib/session.sh +3 -0
- package/context/scripts/telemetry/lib/transport.sh +87 -0
- package/context/scripts/telemetry/lib/usage.sh +205 -4
- package/context/scripts/telemetry/telemetry.conf +6 -0
- package/context/scripts/telemetry/telemetry.sh +48 -0
- package/context/settings/workspace-backlog-provider-settings.example.json +48 -0
- package/docs/agent-usage-feedback-loop.md +35 -0
- package/docs/architecture-engine-and-kits.md +110 -0
- package/docs/context-map.md +2 -0
- package/docs/decisions/embeddable-engine.md +152 -0
- package/docs/decisions/index.md +3 -1
- package/docs/decisions/trust-ledger-retention.md +88 -0
- package/docs/decisions/workflow-enforcement.md +31 -9
- package/docs/fixture-ownership.md +3 -0
- package/docs/implementing-trust-reconciliation.md +129 -0
- package/docs/index.md +19 -9
- package/docs/integrations/flow-agents-console.md +167 -0
- package/docs/kit-authoring-guide.md +52 -21
- package/docs/spec/builder-flow-runtime.md +80 -0
- package/docs/spec/runtime-hook-surface.md +45 -1
- package/docs/specs/economics-record-contract.md +270 -0
- package/docs/specs/harness-capability-matrix.md +74 -0
- package/docs/specs/learning-review-proposals-contract.md +340 -0
- package/docs/specs/routing-efficiency-review.md +59 -0
- package/docs/verifiable-trust.md +74 -25
- package/docs/workflow-usage-guide.md +10 -0
- package/evals/acceptance/prove-capture-teeth.sh +132 -0
- package/evals/ci/antigaming-suite.sh +1 -0
- package/evals/ci/run-baseline.sh +72 -4
- package/evals/fixtures/economics/acceptance.json +12 -0
- package/evals/fixtures/economics/agents/tool-worker-1/events.jsonl +2 -0
- package/evals/fixtures/economics/agents/tool-worker-2/events.jsonl +2 -0
- package/evals/fixtures/economics/agents/tool-worker-3/events.jsonl +2 -0
- package/evals/fixtures/economics/agents/tool-worker-4/events.jsonl +1 -0
- package/evals/fixtures/economics/agents/tool-worker-5/events.jsonl +2 -0
- package/evals/fixtures/economics/critique.json +22 -0
- package/evals/fixtures/economics/expected-record.json +71 -0
- package/evals/fixtures/economics/session-usage-event.json +1 -0
- package/evals/fixtures/economics/state.json +11 -0
- package/evals/fixtures/economics/transcript.jsonl +3 -0
- package/evals/fixtures/hook-influence/cases.json +7 -7
- package/evals/fixtures/learning-review-proposals/balanced/economics.jsonl +6 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/economics.jsonl +5 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/sessions/task-lr-ef-1/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/sessions/task-lr-ef-2/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/sessions/task-lr-ef-3/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/sessions/task-lr-ef-4/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/effect-follow-up/sessions/task-lr-ef-5/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/economics.jsonl +6 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/expected-aggregates.json +30 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/expected-aggregates.md +66 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-1/gate-review.inquiries.json +26 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-1/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-2/gate-review.inquiries.json +26 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-2/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-3/gate-review.inquiries.json +26 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-3/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-4/gate-review.inquiries.json +26 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-4/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-5/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/pattern-present/sessions/task-lr-pp-6/trust.bundle +21 -0
- package/evals/fixtures/learning-review-proposals/repeat-window/economics.jsonl +6 -0
- package/evals/fixtures/learning-review-proposals/under-threshold/economics.jsonl +3 -0
- package/evals/fixtures/telemetry/usage-transcript-sample.jsonl +4 -0
- package/evals/fixtures/trust-reconcile-exploits/mcp-degrade.json +42 -0
- package/evals/integration/test_builder_entry_enforcement.sh +241 -0
- package/evals/integration/test_builder_step_producers.sh +18 -10
- package/evals/integration/test_bundle_install.sh +172 -0
- package/evals/integration/test_console_tenant_isolation.sh +167 -0
- package/evals/integration/test_critique_supersession_roundtrip.sh +4 -1
- package/evals/integration/test_dual_emit_flow_step.sh +10 -4
- package/evals/integration/test_economics_record.sh +674 -0
- package/evals/integration/test_effective_backlog_settings.sh +1 -1
- package/evals/integration/test_evidence_capture_hook.sh +17 -2
- package/evals/integration/test_exemption_usage_review.sh +198 -0
- package/evals/integration/test_fixture_retirement_audit.sh +2 -2
- package/evals/integration/test_flow_kit_install_git.sh +83 -0
- package/evals/integration/test_flowdef_session_activation.sh +0 -1
- package/evals/integration/test_flowdef_session_history_preservation.sh +13 -3
- package/evals/integration/test_gate_lockdown.sh +7 -0
- package/evals/integration/test_gate_review_inquiry_records.sh +9 -1
- package/evals/integration/test_goal_fit_hook.sh +2031 -0
- package/evals/integration/test_hook_category_behaviors.sh +8 -1
- package/evals/integration/test_hook_influence_cases.sh +25 -1
- package/evals/integration/test_install_merge.sh +227 -2
- package/evals/integration/test_kit_conformance_levels.sh +6 -6
- package/evals/integration/test_learning_review_proposals.sh +329 -0
- package/evals/integration/test_liveness_conflict_injection.sh +26 -22
- package/evals/integration/test_liveness_console_relay.sh +166 -0
- package/evals/integration/test_liveness_heartbeat.sh +17 -17
- package/evals/integration/test_liveness_worktree_root.sh +575 -0
- package/evals/integration/test_phase_map_and_gate_claim.sh +6 -1
- package/evals/integration/test_publish_delivery.sh +331 -1
- package/evals/integration/test_pull_work_board.sh +200 -0
- package/evals/integration/test_pull_work_provider.sh +1 -1
- package/evals/integration/test_record_check.sh +378 -0
- package/evals/integration/test_routing_efficiency.sh +71 -0
- package/evals/integration/test_runtime_adapter_activation.sh +28 -0
- package/evals/integration/test_session_resume_roundtrip.sh +16 -19
- package/evals/integration/test_skill_drift_check.sh +870 -0
- package/evals/integration/test_telemetry.sh +445 -0
- package/evals/integration/test_telemetry_doctor.sh +66 -0
- package/evals/integration/test_telemetry_usage_pipeline.sh +228 -0
- package/evals/integration/test_trust_reconcile_negatives.sh +30 -13
- package/evals/integration/test_trust_reconcile_trailer_diagnostic.sh +247 -0
- package/evals/integration/test_usage_cost.sh +61 -0
- package/evals/integration/test_workflow_sidecar_writer.sh +1395 -0
- package/evals/integration/test_workflow_steering_hook.sh +157 -16
- package/evals/integration/test_workspace_settings.sh +176 -0
- package/evals/lib/env.sh +26 -0
- package/evals/lib/node.sh +8 -0
- package/evals/run.sh +29 -0
- package/evals/static/test_ci_integration_coverage.sh +115 -0
- package/evals/static/test_declared_scope_forms_documented.sh +114 -0
- package/evals/static/test_universal_bundles.sh +34 -0
- package/evals/static/test_validate_source_kit_asset_scope.sh +259 -0
- package/evals/static/test_workflow_skills.sh +1 -1
- package/kits/builder/flows/build.flow.json +9 -18
- package/kits/builder/flows/publish-learn.flow.json +5 -1
- package/kits/builder/kit.json +120 -0
- package/kits/builder/skills/deliver/SKILL.md +42 -0
- package/kits/builder/skills/evidence-gate/SKILL.md +12 -0
- package/kits/builder/skills/execute-plan/SKILL.md +9 -0
- package/kits/builder/skills/learning-review/SKILL.md +51 -0
- package/kits/builder/skills/plan-work/SKILL.md +17 -20
- package/kits/builder/skills/pull-work/SKILL.md +21 -0
- package/kits/builder/skills/release-readiness/SKILL.md +12 -0
- package/kits/knowledge/kit.json +9 -0
- package/kits/veritas-governance/docs/README.md +35 -7
- package/kits/veritas-governance/fixtures/exemption-review/mixed-fresh-stale.DECLARED.json +14 -0
- package/kits/veritas-governance/kit.json +14 -0
- package/kits/veritas-governance/skills/exemption-usage-review/SKILL.md +128 -0
- package/kits/veritas-governance/skills/exemption-usage-review/review-exemptions.mjs +231 -0
- package/package.json +2 -2
- package/packaging/manifest.json +29 -0
- package/schemas/backlog-provider-settings.schema.json +13 -0
- package/schemas/workflow-state.schema.json +44 -0
- package/scripts/README.md +4 -0
- package/scripts/check-content-boundary.cjs +8 -1
- package/scripts/ci/trust-reconcile.js +136 -0
- package/scripts/hooks/codex-hook-adapter.js +77 -2
- package/scripts/hooks/evidence-capture.js +38 -5
- package/scripts/hooks/lib/codex-exit-code.js +316 -0
- package/scripts/hooks/lib/kit-catalog.js +235 -0
- package/scripts/hooks/lib/liveness-write.js +28 -1
- package/scripts/hooks/lib/local-artifact-paths.js +97 -1
- package/scripts/hooks/lib/runnable-command.js +177 -0
- package/scripts/hooks/lib/skill-drift.js +350 -0
- package/scripts/hooks/stop-goal-fit.js +278 -48
- package/scripts/hooks/workflow-steering.js +121 -21
- package/scripts/install-codex-home.sh +97 -47
- package/scripts/install-merge.js +72 -14
- package/scripts/install-owned-files.js +178 -0
- package/scripts/liveness/relay.sh +84 -0
- package/scripts/telemetry/economics-record.schema.json +145 -0
- package/scripts/telemetry/economics-record.sh +331 -0
- package/scripts/telemetry/install-console-config.sh +25 -4
- package/scripts/telemetry/learning-review-decide.sh +124 -0
- package/scripts/telemetry/learning-review-proposals.schema.json +161 -0
- package/scripts/telemetry/learning-review-proposals.sh +484 -0
- package/scripts/telemetry/lib/config.sh +102 -12
- package/scripts/telemetry/lib/pricing.sh +14 -6
- package/scripts/telemetry/lib/session.sh +3 -0
- package/scripts/telemetry/lib/transport.sh +133 -15
- package/scripts/telemetry/lib/usage.sh +121 -28
- package/scripts/telemetry/routing-efficiency.sh +0 -0
- package/scripts/telemetry/telemetry.conf +6 -0
- package/scripts/telemetry/telemetry.sh +48 -0
- package/src/builder-flow-run-adapter.ts +357 -0
- package/src/builder-flow-runtime.ts +348 -0
- package/src/cli/builder-flow-run-adapter.test.mjs +495 -0
- package/src/cli/builder-flow-runtime.test.mjs +213 -0
- package/src/cli/builder-run.ts +28 -0
- package/src/cli/codex-agent-routing.test.mjs +44 -0
- package/src/cli/codex-exit-code.test.mjs +207 -0
- package/src/cli/console-connect-options.test.mjs +329 -0
- package/src/cli/console-telemetry-validate.test.mjs +157 -0
- package/src/cli/effective-backlog-settings.ts +68 -2
- package/src/cli/flow-resolver-composition.test.mjs +72 -0
- package/src/cli/init.test.mjs +161 -0
- package/src/cli/init.ts +407 -62
- package/src/cli/kit-metadata-security.test.mjs +443 -0
- package/src/cli/kit.ts +50 -12
- package/src/cli/pull-work-provider.ts +377 -3
- package/src/cli/sidecar-pure-helpers.test.mjs +64 -0
- package/src/cli/skill-drift-check.ts +196 -0
- package/src/cli/telemetry-doctor.test.mjs +53 -0
- package/src/cli/telemetry-doctor.ts +50 -7
- package/src/cli/validate-hook-influence.ts +37 -6
- package/src/cli/workflow-sidecar.ts +1150 -151
- package/src/cli.ts +5 -0
- package/src/flow-kit/validate.ts +277 -38
- package/src/index.ts +19 -0
- package/src/lib/console-connect-options.ts +261 -0
- package/src/lib/console-telemetry-validate.ts +88 -0
- package/src/lib/flow-resolver.ts +117 -4
- package/src/lib/fs.ts +160 -0
- package/src/lib/local-artifact-root.ts +129 -3
- package/src/runtime-adapters.ts +113 -33
- package/src/tools/build-universal-bundles.ts +36 -2
- package/src/tools/codex-agent-routing.ts +48 -0
- package/src/tools/generate-context-map.ts +1 -0
- package/src/tools/validate-source-tree.ts +26 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
5
|
+
|
|
6
|
+
node - "$ROOT" <<'NODE'
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const root = process.argv[2];
|
|
11
|
+
const rel = (...parts) => path.join(...parts).replace(/\\/g, '/');
|
|
12
|
+
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
|
13
|
+
|
|
14
|
+
// Baseline-red in #297: stop-goal-fit fixture still emits no disputed-claim
|
|
15
|
+
// gate hint. Do not wire until fixed by the owning gate/claim-lookup work.
|
|
16
|
+
// Reason is duplicated in the value so this machine check can fail closed.
|
|
17
|
+
const EXEMPTIONS = {
|
|
18
|
+
'evals/integration/test_claim_lookup.sh':
|
|
19
|
+
'Baseline-red in #297: stop-goal-fit fixture emits no disputed-claim gate hint.',
|
|
20
|
+
|
|
21
|
+
// Baseline-red in #297: goal-fit block streak fixture now exits 0 instead of
|
|
22
|
+
// the expected block/release sequence. This touches hook/gate behavior, which
|
|
23
|
+
// is explicitly out of scope for #297.
|
|
24
|
+
'evals/integration/test_goal_fit_escape_hatch.sh':
|
|
25
|
+
'Baseline-red in #297: goal-fit block streak fixture exits 0 instead of block/release sequence.',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function slugify(label) {
|
|
29
|
+
return label.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function integrationTestsIn(text) {
|
|
33
|
+
return [...text.matchAll(/evals\/integration\/test_[A-Za-z0-9_-]+\.sh/g)].map((m) => m[0]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const integrationDir = path.join(root, 'evals/integration');
|
|
37
|
+
const allIntegration = fs
|
|
38
|
+
.readdirSync(integrationDir)
|
|
39
|
+
.filter((file) => /^test_.*\.sh$/.test(file))
|
|
40
|
+
.map((file) => rel('evals/integration', file))
|
|
41
|
+
.sort();
|
|
42
|
+
|
|
43
|
+
const runBaseline = read('evals/ci/run-baseline.sh');
|
|
44
|
+
const checks = new Map();
|
|
45
|
+
for (const match of runBaseline.matchAll(/"([^"\n]+)\|([^"\n]+)"/g)) {
|
|
46
|
+
const [, label, command] = match;
|
|
47
|
+
checks.set(slugify(label), { label, command });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const ci = read('.github/workflows/ci.yml');
|
|
51
|
+
const ciCheckIds = [
|
|
52
|
+
...ci.matchAll(/run:\s*bash evals\/ci\/run-baseline\.sh --check ([a-z0-9-]+)/g),
|
|
53
|
+
].map((match) => match[1]);
|
|
54
|
+
|
|
55
|
+
const covered = new Map();
|
|
56
|
+
const unknownChecks = [];
|
|
57
|
+
|
|
58
|
+
for (const checkId of ciCheckIds) {
|
|
59
|
+
const check = checks.get(checkId);
|
|
60
|
+
if (!check) {
|
|
61
|
+
unknownChecks.push(checkId);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const directTests = integrationTestsIn(check.command);
|
|
66
|
+
for (const test of directTests) covered.set(test, check.label);
|
|
67
|
+
|
|
68
|
+
const suiteScripts = [...check.command.matchAll(/evals\/ci\/[A-Za-z0-9_-]+\.sh/g)].map((m) => m[0]);
|
|
69
|
+
for (const suiteScript of suiteScripts) {
|
|
70
|
+
const suitePath = path.join(root, suiteScript);
|
|
71
|
+
if (!fs.existsSync(suitePath)) {
|
|
72
|
+
throw new Error(`CI check '${check.label}' references missing suite script: ${suiteScript}`);
|
|
73
|
+
}
|
|
74
|
+
for (const test of integrationTestsIn(fs.readFileSync(suitePath, 'utf8'))) {
|
|
75
|
+
covered.set(test, `${check.label} (${suiteScript})`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const problems = [];
|
|
81
|
+
for (const checkId of unknownChecks) {
|
|
82
|
+
problems.push(`CI invokes unknown run-baseline check id: ${checkId}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (const [test, reason] of Object.entries(EXEMPTIONS)) {
|
|
86
|
+
if (!allIntegration.includes(test)) {
|
|
87
|
+
problems.push(`Exemption references missing integration eval: ${test}`);
|
|
88
|
+
}
|
|
89
|
+
if (typeof reason !== 'string' || reason.trim().length < 12) {
|
|
90
|
+
problems.push(`Exemption for ${test} must include a concrete reason.`);
|
|
91
|
+
}
|
|
92
|
+
if (covered.has(test)) {
|
|
93
|
+
problems.push(`Exempted integration eval is also CI-covered; remove exemption: ${test}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const test of allIntegration) {
|
|
98
|
+
if (covered.has(test) || Object.hasOwn(EXEMPTIONS, test)) continue;
|
|
99
|
+
problems.push(`Integration eval is not covered by CI and has no reasoned exemption: ${test}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const test of covered.keys()) {
|
|
103
|
+
if (!allIntegration.includes(test)) {
|
|
104
|
+
problems.push(`CI references missing integration eval: ${test}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (problems.length) {
|
|
109
|
+
console.error('CI integration coverage audit failed:');
|
|
110
|
+
for (const problem of problems.sort()) console.error(` - ${problem}`);
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log(`CI integration coverage audit passed: ${covered.size} covered, ${Object.keys(EXEMPTIONS).length} exempted.`);
|
|
115
|
+
NODE
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test_declared_scope_forms_documented.sh — AC8 (issue #303/#304 residue): delivery/README.md
|
|
3
|
+
# documents all four DECLARED scope forms, the compound (space-separated AND) form, and the
|
|
4
|
+
# author:/branch-prefix: combining requirement for identity exemptions.
|
|
5
|
+
#
|
|
6
|
+
# Sourced from scripts/ci/trust-reconcile.js's matchesScopeCondition()/matchesScope() (the
|
|
7
|
+
# actual implemented semantics — string equality/prefix only, never RegExp) and ADR 0022 §2 +
|
|
8
|
+
# the 2026-07-03 addendum. This is a documentation-coverage lock: if delivery/README.md's
|
|
9
|
+
# scope-forms section is ever removed or one of the four forms silently drops out, this eval
|
|
10
|
+
# fails loudly, naming what's missing.
|
|
11
|
+
#
|
|
12
|
+
# Deterministic, no model spend, no fixtures.
|
|
13
|
+
# Usage: bash evals/static/test_declared_scope_forms_documented.sh
|
|
14
|
+
|
|
15
|
+
set -uo pipefail
|
|
16
|
+
|
|
17
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
18
|
+
DOC="$ROOT/delivery/README.md"
|
|
19
|
+
|
|
20
|
+
errors=0
|
|
21
|
+
pass() { echo " ✓ $1"; }
|
|
22
|
+
fail() { echo " ✗ $1"; errors=$((errors + 1)); }
|
|
23
|
+
|
|
24
|
+
echo "=== delivery/README.md DECLARED scope-forms documentation coverage (AC8) ==="
|
|
25
|
+
|
|
26
|
+
if [[ -f "$DOC" ]]; then
|
|
27
|
+
pass "delivery/README.md exists"
|
|
28
|
+
else
|
|
29
|
+
fail "delivery/README.md is missing — cannot check scope-forms documentation"
|
|
30
|
+
echo ""
|
|
31
|
+
echo "FAIL: 1 check(s) failed"
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# --- The four single-condition scope forms --------------------------------------
|
|
36
|
+
if grep -qF 'ref:' "$DOC"; then
|
|
37
|
+
pass "documents the ref: scope form"
|
|
38
|
+
else
|
|
39
|
+
fail "delivery/README.md does not mention the ref: scope form"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if grep -qF 'commit:' "$DOC"; then
|
|
43
|
+
pass "documents the commit: scope form"
|
|
44
|
+
else
|
|
45
|
+
fail "delivery/README.md does not mention the commit: scope form"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if grep -qF 'author:' "$DOC"; then
|
|
49
|
+
pass "documents the author: scope form"
|
|
50
|
+
else
|
|
51
|
+
fail "delivery/README.md does not mention the author: scope form"
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
if grep -qF 'branch-prefix:' "$DOC"; then
|
|
55
|
+
pass "documents the branch-prefix: scope form"
|
|
56
|
+
else
|
|
57
|
+
fail "delivery/README.md does not mention the branch-prefix: scope form"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# --- commit: range form (commit:a..b), not just the bare single-sha form --------
|
|
61
|
+
if grep -qE 'commit:[^[:space:]]*\.\.' "$DOC"; then
|
|
62
|
+
pass "documents the commit:<from>..<to> RANGE form, not just a bare single-sha example"
|
|
63
|
+
else
|
|
64
|
+
fail "delivery/README.md does not show a commit:<from>..<to> range example"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# --- Compound (space-separated AND) scope form -----------------------------------
|
|
68
|
+
if grep -qiE 'compound|space-separated' "$DOC"; then
|
|
69
|
+
pass "documents the compound (space-separated) scope form"
|
|
70
|
+
else
|
|
71
|
+
fail "delivery/README.md does not mention a compound/space-separated scope form"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if grep -qiE '\bAND\b|ANDed' "$DOC"; then
|
|
75
|
+
pass "documents that compound conditions are ANDed (all must match)"
|
|
76
|
+
else
|
|
77
|
+
fail "delivery/README.md does not state that compound scope conditions are ANDed"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --- author:/branch-prefix: combining requirement for identity exemptions -------
|
|
81
|
+
if grep -qiE 'pusher-controlled|pusher-chosen' "$DOC"; then
|
|
82
|
+
pass "documents the fork-PR pusher-controlled ref/branch-prefix weakness motivating the combining requirement"
|
|
83
|
+
else
|
|
84
|
+
fail "delivery/README.md does not explain why ref:/branch-prefix: alone are insufficient for identity exemptions (pusher-controlled branch names)"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
if grep -qiE 'MUST combine|combine.*author:|author:.*combine' "$DOC"; then
|
|
88
|
+
pass "documents that an identity-binding scope MUST combine author: with a second condition"
|
|
89
|
+
else
|
|
90
|
+
fail "delivery/README.md does not state the author:+branch-prefix:/ref: combining requirement"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# --- The real worked example (release-please compound scope) --------------------
|
|
94
|
+
if grep -qF 'author:github-actions[bot] branch-prefix:release-please--' "$DOC"; then
|
|
95
|
+
pass "shows the real worked compound-scope example (release-please: author: + branch-prefix:)"
|
|
96
|
+
else
|
|
97
|
+
fail "delivery/README.md does not show the real release-please compound-scope worked example"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# --- Matching semantics: string equality/prefix only, never RegExp --------------
|
|
101
|
+
if grep -qiE 'no.*RegExp|never.*RegExp' "$DOC"; then
|
|
102
|
+
pass "documents that matching is string equality/prefix only — no RegExp is ever constructed from marker content"
|
|
103
|
+
else
|
|
104
|
+
fail "delivery/README.md does not state the no-RegExp matching-semantics note"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo ""
|
|
108
|
+
if [[ "$errors" -eq 0 ]]; then
|
|
109
|
+
echo "PASS: delivery/README.md documents all four DECLARED scope forms, compound-AND, and the identity-combining requirement"
|
|
110
|
+
exit 0
|
|
111
|
+
else
|
|
112
|
+
echo "FAIL: $errors check(s) failed"
|
|
113
|
+
exit 1
|
|
114
|
+
fi
|
|
@@ -206,6 +206,40 @@ else
|
|
|
206
206
|
_fail "Codex agent TOML required-field check failed"
|
|
207
207
|
fi
|
|
208
208
|
|
|
209
|
+
if node - "$DIST_DIR/codex/.codex/agents" <<'NODE'
|
|
210
|
+
const fs = require("node:fs");
|
|
211
|
+
const path = require("node:path");
|
|
212
|
+
const root = process.argv[2];
|
|
213
|
+
function stringAssignment(text, key, name) {
|
|
214
|
+
const matches = [...text.matchAll(new RegExp(`^${key}\\s*=\\s*"([^"]*)"\\s*$`, "gm"))];
|
|
215
|
+
if (matches.length !== 1) throw new Error(`${name}: expected exactly one ${key} assignment, found ${matches.length}`);
|
|
216
|
+
return matches[0][1];
|
|
217
|
+
}
|
|
218
|
+
const expected = {
|
|
219
|
+
"tool-planner.toml": ["gpt-5.6-sol", "high"],
|
|
220
|
+
"tool-worker.toml": ["gpt-5.6-terra", "high"],
|
|
221
|
+
"tool-code-reviewer.toml": ["gpt-5.6-sol", "high"],
|
|
222
|
+
"tool-security-reviewer.toml": ["gpt-5.6-sol", "high"],
|
|
223
|
+
"tool-verifier.toml": ["gpt-5.6-sol", "high"],
|
|
224
|
+
};
|
|
225
|
+
for (const [name, [model, effort]] of Object.entries(expected)) {
|
|
226
|
+
const text = fs.readFileSync(path.join(root, name), "utf8");
|
|
227
|
+
if (stringAssignment(text, "model", name) !== model) throw new Error(`${name}: expected model ${model}`);
|
|
228
|
+
if (stringAssignment(text, "model_reasoning_effort", name) !== effort) throw new Error(`${name}: expected reasoning ${effort}`);
|
|
229
|
+
}
|
|
230
|
+
const fallback = fs.readFileSync(path.join(root, "tool-playwright.toml"), "utf8");
|
|
231
|
+
if (stringAssignment(fallback, "model", "tool-playwright.toml") !== "gpt-5.5" ||
|
|
232
|
+
stringAssignment(fallback, "model_reasoning_effort", "tool-playwright.toml") !== "low") {
|
|
233
|
+
throw new Error("unmapped Codex agent no longer uses family fallback");
|
|
234
|
+
}
|
|
235
|
+
console.log("ok");
|
|
236
|
+
NODE
|
|
237
|
+
then
|
|
238
|
+
_pass "Codex Builder specialist roles use deterministic 5.6 models and unmapped agents retain family fallback"
|
|
239
|
+
else
|
|
240
|
+
_fail "Codex Builder specialist role routing is missing, stale, or bypasses family fallback"
|
|
241
|
+
fi
|
|
242
|
+
|
|
209
243
|
if node - "$DIST_DIR/codex/.codex/hooks.json" <<'NODE'
|
|
210
244
|
const fs = require("node:fs");
|
|
211
245
|
const hooks = JSON.parse(fs.readFileSync(process.argv[2], "utf8")).hooks || {};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test_validate_source_kit_asset_scope.sh — src/tools/validate-source-tree.ts's
|
|
3
|
+
# validateLegacyRefs() kit-owned-asset exemption stays EXACT-PATH scoped.
|
|
4
|
+
#
|
|
5
|
+
# Context (fix pass, issue #303 follow-up): a prior draft of this exemption widened it to
|
|
6
|
+
# "any file in the same directory as a registered kit.json asset" (a directory-level
|
|
7
|
+
# exemption) to make an eval's reference to a kit skill's own helper script pass
|
|
8
|
+
# validate:source. That widening was reverted — the helper is now registered as its own
|
|
9
|
+
# kit.json "assets" entry (data-driven, no validator special-casing) — but the REAL risk
|
|
10
|
+
# the reviewer flagged deserves a permanent regression lock: a directory-level exemption
|
|
11
|
+
# would silence real missing-path detection for every OTHER (bogus, typo'd, deleted) file
|
|
12
|
+
# that happens to sit in the same directory as a legitimately registered asset, not just
|
|
13
|
+
# the intended one.
|
|
14
|
+
#
|
|
15
|
+
# This eval proves the negative: a reference to a FILE THAT DOES NOT EXIST, sitting in the
|
|
16
|
+
# SAME directory as a real, registered kit.json asset (kits/veritas-governance/skills/
|
|
17
|
+
# exemption-usage-review/, which legitimately owns a registered SKILL.md AND a registered
|
|
18
|
+
# assets[] helper), IS STILL FLAGGED by validate:source as a missing source path — never
|
|
19
|
+
# silently exempted just because it shares a directory with real registered assets.
|
|
20
|
+
#
|
|
21
|
+
# Mechanism: writes a throwaway eval-shaped fixture file (self-cleaning, removed in the
|
|
22
|
+
# trap) under evals/integration/ whose CONTENT (built at runtime, not hardcoded as a
|
|
23
|
+
# literal path string in THIS file's own source — see note below) references a bogus
|
|
24
|
+
# filename in that real kit skill directory, runs the REAL `npm run validate:source`
|
|
25
|
+
# against the REAL repo tree, asserts it fails and names the exact bogus path, then
|
|
26
|
+
# removes the throwaway fixture and re-confirms the repo is clean again. Deterministic, no
|
|
27
|
+
# model spend.
|
|
28
|
+
#
|
|
29
|
+
# Self-scan hazard: validate-source-tree's legacy-ref scanner walks EVERY .sh file under
|
|
30
|
+
# evals/, including this one. If the bogus path string were written as a literal in this
|
|
31
|
+
# file's own source text, this eval would trip its own probe merely by existing. The bogus
|
|
32
|
+
# ref/probe-file path strings below are therefore assembled at runtime from parts (never
|
|
33
|
+
# written as one contiguous literal anywhere in this file) so this file's own presence
|
|
34
|
+
# never becomes a false positive.
|
|
35
|
+
#
|
|
36
|
+
# Crash-resilience hazard (fix pass, second review round): the probe fixture below MUST
|
|
37
|
+
# live in a scanned directory (evals/integration/) for the negative probe to mean anything
|
|
38
|
+
# — but a SIGKILL/OOM/CI-timeout landing between the probe's write and this script's EXIT
|
|
39
|
+
# trap would leave it behind, permanently failing validate:source repo-wide for every
|
|
40
|
+
# future run until someone manually deletes it. Two defenses: (1) a SELF-HEALING
|
|
41
|
+
# PRE-FLIGHT, at the very top of this script before anything else runs (including the
|
|
42
|
+
# positive control), that deletes any file matching this eval's own narrowly-scoped
|
|
43
|
+
# probe-name glob and logs a loud line when it heals one — this is the defense that
|
|
44
|
+
# actually matters if the crash window is ever hit; (2) the EXIT trap is kept as the
|
|
45
|
+
# normal-path cleanup, and the probe write is placed as late as possible (immediately
|
|
46
|
+
# before the validate:source call that depends on it) to narrow the window. The glob is
|
|
47
|
+
# deliberately a literal, distinctive prefix this eval alone uses (never a generic
|
|
48
|
+
# wildcard) so the self-heal can never match — and therefore never delete — any real,
|
|
49
|
+
# non-probe file.
|
|
50
|
+
|
|
51
|
+
set -uo pipefail
|
|
52
|
+
|
|
53
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
54
|
+
cd "$ROOT"
|
|
55
|
+
|
|
56
|
+
errors=0
|
|
57
|
+
pass() { echo " ✓ $1"; }
|
|
58
|
+
fail() { echo " ✗ $1"; errors=$((errors + 1)); }
|
|
59
|
+
|
|
60
|
+
# Narrowly-scoped probe-name glob prefix — every probe fixture this eval ever writes
|
|
61
|
+
# (negative-probe or self-heal-regression-test fixtures alike) MUST start with this exact
|
|
62
|
+
# literal prefix, and nothing else in the repo may. This is what makes the self-heal safe:
|
|
63
|
+
# it can only ever match files THIS eval itself creates.
|
|
64
|
+
PROBE_GLOB_PREFIX="test__scope_probe_"
|
|
65
|
+
|
|
66
|
+
# Delete any stale probe fixture(s) matching PROBE_GLOB_PREFIX under evals/integration/,
|
|
67
|
+
# logging a loud line per file healed. Called at pre-flight (below) AND directly by the
|
|
68
|
+
# self-heal regression assertion later in this file (as a lightweight in-process function
|
|
69
|
+
# call, not a recursive re-invocation of this whole script — re-running the full script,
|
|
70
|
+
# with its several npm run validate:source calls, is too heavy to use as the mechanism for
|
|
71
|
+
# a single targeted assertion).
|
|
72
|
+
heal_stale_probes() {
|
|
73
|
+
local stale_probes=("$ROOT"/evals/integration/${PROBE_GLOB_PREFIX}*)
|
|
74
|
+
if [[ -e "${stale_probes[0]}" ]]; then
|
|
75
|
+
for stale in "${stale_probes[@]}"; do
|
|
76
|
+
echo " ⚠ SELF-HEAL: removing stale probe fixture left behind by an interrupted prior run: $stale"
|
|
77
|
+
rm -f "$stale"
|
|
78
|
+
done
|
|
79
|
+
fi
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# --pre-flight-only: run ONLY the self-healing pre-flight (heal_stale_probes) and exit,
|
|
83
|
+
# skipping every npm run validate:source call in the rest of this script. Exists solely so
|
|
84
|
+
# the end-to-end self-heal assertion below can exercise the REAL pre-flight wiring at the
|
|
85
|
+
# top of this script (not just heal_stale_probes() called in isolation) as a fresh
|
|
86
|
+
# subprocess, WITHOUT paying for a full second run of this eval's several
|
|
87
|
+
# npm run validate:source builds — keeps the added runtime bounded to one lightweight
|
|
88
|
+
# glob-and-delete pass, not a second full eval run.
|
|
89
|
+
if [[ "${1:-}" == "--pre-flight-only" ]]; then
|
|
90
|
+
heal_stale_probes
|
|
91
|
+
exit 0
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
echo "=== validate-source-tree kit-asset exemption stays exact-path scoped (no directory-level exemption) ==="
|
|
95
|
+
|
|
96
|
+
# --- Self-healing pre-flight (reviewer HIGH: hard-kill/OOM/CI-timeout resilience) -
|
|
97
|
+
heal_stale_probes
|
|
98
|
+
|
|
99
|
+
# Real skill directory + its two REAL registered kit.json assets (assembled from parts —
|
|
100
|
+
# see the self-scan hazard note above; these ARE real, existing paths, so splitting them
|
|
101
|
+
# is purely to avoid THIS descriptive assertion accidentally reading as a probe target).
|
|
102
|
+
KIT_DIR="kits/veritas-governance"
|
|
103
|
+
REAL_SKILL_DIR="$KIT_DIR/skills""/exemption-usage-review"
|
|
104
|
+
REAL_SKILL_MD="$REAL_SKILL_DIR/SKILL.md"
|
|
105
|
+
REAL_HELPER="$REAL_SKILL_DIR/review-exemptions.mjs"
|
|
106
|
+
# kit.json's own "path" fields are relative to the KIT directory, not the repo root.
|
|
107
|
+
KIT_RELATIVE_SKILL_MD="${REAL_SKILL_MD#"$KIT_DIR/"}"
|
|
108
|
+
KIT_RELATIVE_HELPER="${REAL_HELPER#"$KIT_DIR/"}"
|
|
109
|
+
|
|
110
|
+
# --- Sanity: the real skill directory + its two REAL registered assets exist -----
|
|
111
|
+
if [[ -f "$ROOT/$REAL_SKILL_MD" && -f "$ROOT/$REAL_HELPER" ]]; then
|
|
112
|
+
pass "real skill directory has both registered files present (SKILL.md, review-exemptions.mjs)"
|
|
113
|
+
else
|
|
114
|
+
fail "expected real skill directory files missing — cannot run the negative probe against real fixtures"
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
if grep -qF "\"path\": \"$KIT_RELATIVE_SKILL_MD\"" "$ROOT/$KIT_DIR/kit.json" \
|
|
118
|
+
&& grep -qF "\"path\": \"$KIT_RELATIVE_HELPER\"" "$ROOT/$KIT_DIR/kit.json"; then
|
|
119
|
+
pass "both files are registered in kit.json (SKILL.md under skills[], review-exemptions.mjs under assets[])"
|
|
120
|
+
else
|
|
121
|
+
fail "kit.json does not register both real files under skills[]/assets[] as expected"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# --- Positive control: validate:source passes on the clean, real tree -----------
|
|
125
|
+
if npm run validate:source > /tmp/vskas_positive.out 2>&1; then
|
|
126
|
+
pass "positive control: npm run validate:source passes on the clean tree (no probe fixture present)"
|
|
127
|
+
else
|
|
128
|
+
fail "positive control: npm run validate:source unexpectedly failed on the clean tree — cannot trust the negative probe below"; tail -20 /tmp/vskas_positive.out
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# --- Negative probe: a BOGUS sibling filename in the SAME real directory is flagged --
|
|
132
|
+
# Assembled from parts at runtime (see self-scan hazard note above) — this exact
|
|
133
|
+
# contiguous string never appears anywhere else in this file's own source text.
|
|
134
|
+
BOGUS_FILENAME_PART1="this-file-does-not"
|
|
135
|
+
BOGUS_FILENAME_PART2="-exist-probe.mjs"
|
|
136
|
+
# NOTE: legacyRefRe (validate-source-tree.ts) matches starting at recognized top-level
|
|
137
|
+
# prefixes (skills / evals / scripts / etc — see the regex in validate-source-tree.ts),
|
|
138
|
+
# not at "kits" — so the ref as written in the probe fixture (and as reported in
|
|
139
|
+
# validate:source's failure output) is kit-directory-relative, not repo-root-relative. Use
|
|
140
|
+
# the kit-relative form here to match what the scanner actually records. Built from parts
|
|
141
|
+
# (never one contiguous literal in this file's own comments or code) for the same
|
|
142
|
+
# self-scan-hazard reason noted at the top of this file.
|
|
143
|
+
BOGUS_REF="skills""/exemption-usage-review/$BOGUS_FILENAME_PART1$BOGUS_FILENAME_PART2"
|
|
144
|
+
PROBE_FILE_NAME_PART1="${PROBE_GLOB_PREFIX}bogus"
|
|
145
|
+
PROBE_FILE_NAME_PART2="_ref.sh"
|
|
146
|
+
PROBE_FILE="$ROOT/evals/integration/$PROBE_FILE_NAME_PART1$PROBE_FILE_NAME_PART2"
|
|
147
|
+
|
|
148
|
+
cleanup() {
|
|
149
|
+
rm -f "$PROBE_FILE"
|
|
150
|
+
}
|
|
151
|
+
trap cleanup EXIT
|
|
152
|
+
|
|
153
|
+
# Content-writer for a throwaway probe fixture — factored out so the self-heal regression
|
|
154
|
+
# assertion below can plant an equivalent stale fixture without duplicating the heredoc.
|
|
155
|
+
write_probe_fixture() {
|
|
156
|
+
local target="$1"
|
|
157
|
+
{
|
|
158
|
+
echo "#!/usr/bin/env bash"
|
|
159
|
+
echo "# Throwaway probe fixture (self-removing) — exists only for the duration of"
|
|
160
|
+
echo "# test_validate_source_kit_asset_scope.sh's negative-probe assertion."
|
|
161
|
+
echo "HELPER=\"\$KIT/$BOGUS_REF\""
|
|
162
|
+
} > "$target"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Write the probe fixture as LATE as possible (immediately before the validate:source call
|
|
166
|
+
# that depends on it) to narrow the window a hard-kill could land in between write and
|
|
167
|
+
# cleanup — this is the second line of defense; the self-healing pre-flight above is the
|
|
168
|
+
# first (and the one that actually matters if this window is ever hit).
|
|
169
|
+
write_probe_fixture "$PROBE_FILE"
|
|
170
|
+
|
|
171
|
+
if npm run validate:source > /tmp/vskas_negative.out 2>&1; then
|
|
172
|
+
fail "negative probe: validate:source PASSED with a bogus sibling-file reference present — the exemption is over-wide (directory-level), not exact-path"
|
|
173
|
+
else
|
|
174
|
+
pass "negative probe: validate:source FAILS (exit non-zero) with a bogus sibling-file reference present"
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if grep -qF "references missing source path: $BOGUS_REF" /tmp/vskas_negative.out; then
|
|
178
|
+
pass "negative probe: failure output names the exact bogus path ($BOGUS_REF) — real missing-path detection is not silenced by directory proximity to registered assets"
|
|
179
|
+
else
|
|
180
|
+
fail "negative probe: expected failure output to name the bogus path — output: $(tail -20 /tmp/vskas_negative.out)"
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# --- Cleanup verification: removing the probe restores a clean, passing tree ----
|
|
184
|
+
rm -f "$PROBE_FILE"
|
|
185
|
+
if npm run validate:source > /tmp/vskas_cleanup.out 2>&1; then
|
|
186
|
+
pass "cleanup: npm run validate:source passes again once the throwaway probe fixture is removed"
|
|
187
|
+
else
|
|
188
|
+
fail "cleanup: npm run validate:source did not pass again after removing the probe fixture"; tail -20 /tmp/vskas_cleanup.out
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# --- Self-heal regression lock: a STALE probe left by a simulated hard-kill is healed ---
|
|
192
|
+
# Simulates exactly the failure mode this fix pass addresses: a probe fixture left behind
|
|
193
|
+
# by an interrupted prior run (no EXIT trap ever ran for it, since this write below is
|
|
194
|
+
# deliberately NOT wrapped in this script's own trap/cleanup — it models "the process died
|
|
195
|
+
# before its trap could fire"). Exercises heal_stale_probes() DIRECTLY (a lightweight
|
|
196
|
+
# in-process function call — NOT a recursive re-invocation of this whole script, which
|
|
197
|
+
# would be several redundant npm run validate:source builds just to prove one glob-delete
|
|
198
|
+
# works) and confirms it heals: the file is removed and a loud line names it.
|
|
199
|
+
STALE_PROBE_FILE_PART1="${PROBE_GLOB_PREFIX}stale"
|
|
200
|
+
STALE_PROBE_FILE_PART2="_simulated.sh"
|
|
201
|
+
STALE_PROBE_FILE="$ROOT/evals/integration/$STALE_PROBE_FILE_PART1$STALE_PROBE_FILE_PART2"
|
|
202
|
+
write_probe_fixture "$STALE_PROBE_FILE"
|
|
203
|
+
if [[ -f "$STALE_PROBE_FILE" ]]; then
|
|
204
|
+
pass "self-heal setup: pre-planted a stale probe fixture (simulating an interrupted prior run with no trap-driven cleanup)"
|
|
205
|
+
else
|
|
206
|
+
fail "self-heal setup: failed to pre-plant the stale probe fixture — cannot exercise the self-heal assertion below"
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
HEAL_OUT="$(heal_stale_probes 2>&1)"
|
|
210
|
+
|
|
211
|
+
if echo "$HEAL_OUT" | grep -qF "SELF-HEAL: removing stale probe fixture left behind by an interrupted prior run: $STALE_PROBE_FILE"; then
|
|
212
|
+
pass "self-heal: heal_stale_probes() logged a loud SELF-HEAL line naming the exact stale probe path it removed"
|
|
213
|
+
else
|
|
214
|
+
fail "self-heal: expected a loud SELF-HEAL line naming the stale probe path — output: $HEAL_OUT"
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
if [[ ! -e "$STALE_PROBE_FILE" ]]; then
|
|
218
|
+
pass "self-heal: the stale probe fixture no longer exists after heal_stale_probes() ran (healed, not just logged)"
|
|
219
|
+
else
|
|
220
|
+
fail "self-heal: the stale probe fixture STILL EXISTS after heal_stale_probes() ran — self-heal did not actually delete it"
|
|
221
|
+
rm -f "$STALE_PROBE_FILE"
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
# End-to-end confirmation: a FRESH invocation of this eval (its own pre-flight, not a
|
|
225
|
+
# hand-called function) also heals a pre-planted stale probe and still passes overall —
|
|
226
|
+
# proves the pre-flight wiring at the top of this script, not just the helper function in
|
|
227
|
+
# isolation. This is the one genuinely-recursive re-invocation in this file; kept to
|
|
228
|
+
# exactly one (not three, as an earlier draft did) to bound the added runtime.
|
|
229
|
+
write_probe_fixture "$STALE_PROBE_FILE"
|
|
230
|
+
FRESH_RUN_OUT="$(bash "$ROOT/evals/static/test_validate_source_kit_asset_scope.sh" --pre-flight-only 2>&1)"
|
|
231
|
+
FRESH_RUN_CODE=$?
|
|
232
|
+
|
|
233
|
+
if echo "$FRESH_RUN_OUT" | grep -qF "SELF-HEAL: removing stale probe fixture left behind by an interrupted prior run: $STALE_PROBE_FILE"; then
|
|
234
|
+
pass "self-heal (end-to-end): a fresh --pre-flight-only invocation of this eval's own pre-flight healed the pre-planted stale probe"
|
|
235
|
+
else
|
|
236
|
+
fail "self-heal (end-to-end): expected the fresh invocation to log a loud SELF-HEAL line naming the stale probe — output: $(echo "$FRESH_RUN_OUT" | head -10)"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
if [[ ! -e "$STALE_PROBE_FILE" ]]; then
|
|
240
|
+
pass "self-heal (end-to-end): the stale probe fixture no longer exists after the fresh --pre-flight-only invocation"
|
|
241
|
+
else
|
|
242
|
+
fail "self-heal (end-to-end): the stale probe fixture STILL EXISTS after the fresh invocation"
|
|
243
|
+
rm -f "$STALE_PROBE_FILE"
|
|
244
|
+
fi
|
|
245
|
+
|
|
246
|
+
if [[ "$FRESH_RUN_CODE" -eq 0 ]]; then
|
|
247
|
+
pass "self-heal (end-to-end): the fresh --pre-flight-only invocation exits 0"
|
|
248
|
+
else
|
|
249
|
+
fail "self-heal (end-to-end): the fresh --pre-flight-only invocation exited $FRESH_RUN_CODE (expected 0) — output: $(echo "$FRESH_RUN_OUT" | tail -10)"
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
echo ""
|
|
253
|
+
if [[ "$errors" -eq 0 ]]; then
|
|
254
|
+
echo "PASS: validate-source-tree kit-asset exemption is exact-path scoped (no directory-level widening)"
|
|
255
|
+
exit 0
|
|
256
|
+
else
|
|
257
|
+
echo "FAIL: $errors check(s) failed"
|
|
258
|
+
exit 1
|
|
259
|
+
fi
|
|
@@ -552,7 +552,7 @@ require_text "$WORKFLOW_STEERING_INTEGRATION" 'workflow steering hook neutralize
|
|
|
552
552
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'workflow steering hook appends context-map recovery guidance' "workflow steering integration covers context-map guidance"
|
|
553
553
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'workflow steering hook emits ambient state guidance at user prompt submit' "workflow steering integration covers ambient state guidance"
|
|
554
554
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'Claude hook adapter surfaces Builder workflow route for coding prompts' "workflow steering integration covers Claude Builder-route prompt guidance"
|
|
555
|
-
require_text "$WORKFLOW_STEERING_INTEGRATION" '
|
|
555
|
+
require_text "$WORKFLOW_STEERING_INTEGRATION" 'release-readiness and learning-review' "workflow steering integration covers full Builder lifecycle guidance"
|
|
556
556
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'does not route explicit review-only prompts into Builder workflow' "workflow steering integration covers review-only prompt suppression"
|
|
557
557
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'does not route explicit validation-only prompts into Builder workflow' "workflow steering integration covers validation-only prompt suppression"
|
|
558
558
|
require_text "$WORKFLOW_STEERING_INTEGRATION" 'does not route question-only test prompts into Builder workflow' "workflow steering integration covers question-only test prompt suppression"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "builder.build",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1",
|
|
4
4
|
"phase_map": {
|
|
5
5
|
"pickup": "pull-work",
|
|
6
6
|
"planning": "plan",
|
|
@@ -36,8 +36,7 @@
|
|
|
36
36
|
"claimType": "builder.pull-work.selected",
|
|
37
37
|
"subjectType": "work-item",
|
|
38
38
|
"accepted_statuses": [
|
|
39
|
-
"
|
|
40
|
-
"accepted"
|
|
39
|
+
"verified"
|
|
41
40
|
]
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -55,8 +54,7 @@
|
|
|
55
54
|
"claimType": "builder.design-probe.pickup-readiness",
|
|
56
55
|
"subjectType": "work-item",
|
|
57
56
|
"accepted_statuses": [
|
|
58
|
-
"
|
|
59
|
-
"accepted"
|
|
57
|
+
"verified"
|
|
60
58
|
]
|
|
61
59
|
}
|
|
62
60
|
},
|
|
@@ -69,8 +67,7 @@
|
|
|
69
67
|
"claimType": "builder.design-probe.decisions",
|
|
70
68
|
"subjectType": "decision",
|
|
71
69
|
"accepted_statuses": [
|
|
72
|
-
"
|
|
73
|
-
"accepted"
|
|
70
|
+
"verified"
|
|
74
71
|
]
|
|
75
72
|
}
|
|
76
73
|
}
|
|
@@ -88,8 +85,7 @@
|
|
|
88
85
|
"claimType": "builder.plan.implementation",
|
|
89
86
|
"subjectType": "artifact",
|
|
90
87
|
"accepted_statuses": [
|
|
91
|
-
"
|
|
92
|
-
"accepted"
|
|
88
|
+
"verified"
|
|
93
89
|
]
|
|
94
90
|
}
|
|
95
91
|
}
|
|
@@ -107,8 +103,7 @@
|
|
|
107
103
|
"claimType": "builder.execute.scope",
|
|
108
104
|
"subjectType": "change",
|
|
109
105
|
"accepted_statuses": [
|
|
110
|
-
"
|
|
111
|
-
"accepted"
|
|
106
|
+
"verified"
|
|
112
107
|
]
|
|
113
108
|
}
|
|
114
109
|
}
|
|
@@ -137,8 +132,7 @@
|
|
|
137
132
|
"claimType": "builder.verify.tests",
|
|
138
133
|
"subjectType": "flow-step",
|
|
139
134
|
"accepted_statuses": [
|
|
140
|
-
"
|
|
141
|
-
"accepted"
|
|
135
|
+
"verified"
|
|
142
136
|
]
|
|
143
137
|
}
|
|
144
138
|
},
|
|
@@ -152,9 +146,7 @@
|
|
|
152
146
|
"claimType": "builder.verify.policy-compliance",
|
|
153
147
|
"subjectType": "artifact",
|
|
154
148
|
"accepted_statuses": [
|
|
155
|
-
"
|
|
156
|
-
"accepted",
|
|
157
|
-
"advisory"
|
|
149
|
+
"verified"
|
|
158
150
|
]
|
|
159
151
|
}
|
|
160
152
|
}
|
|
@@ -183,8 +175,7 @@
|
|
|
183
175
|
"claimType": "builder.merge-ready.readiness",
|
|
184
176
|
"subjectType": "change",
|
|
185
177
|
"accepted_statuses": [
|
|
186
|
-
"
|
|
187
|
-
"accepted"
|
|
178
|
+
"verified"
|
|
188
179
|
]
|
|
189
180
|
}
|
|
190
181
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "builder.publish-learn",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1",
|
|
4
4
|
"description": "Reusable delivery closeout extension: publish the verified change, confirm merge readiness from provider/CI evidence, and record learning feedback.",
|
|
5
5
|
"steps": [
|
|
6
6
|
{ "id": "pr-open", "next": "merge-ready-ci" },
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"claimType": "builder.pr-open.pull-request",
|
|
28
28
|
"subjectType": "pull-request",
|
|
29
29
|
"accepted_statuses": [
|
|
30
|
+
"verified",
|
|
30
31
|
"trusted",
|
|
31
32
|
"accepted"
|
|
32
33
|
]
|
|
@@ -46,6 +47,7 @@
|
|
|
46
47
|
"claimType": "builder.merge-ready-ci.readiness",
|
|
47
48
|
"subjectType": "pull-request",
|
|
48
49
|
"accepted_statuses": [
|
|
50
|
+
"verified",
|
|
49
51
|
"trusted",
|
|
50
52
|
"accepted"
|
|
51
53
|
]
|
|
@@ -65,6 +67,7 @@
|
|
|
65
67
|
"claimType": "builder.learn.decisions",
|
|
66
68
|
"subjectType": "decision",
|
|
67
69
|
"accepted_statuses": [
|
|
70
|
+
"verified",
|
|
68
71
|
"trusted",
|
|
69
72
|
"accepted"
|
|
70
73
|
]
|
|
@@ -79,6 +82,7 @@
|
|
|
79
82
|
"claimType": "builder.learn.evidence",
|
|
80
83
|
"subjectType": "release",
|
|
81
84
|
"accepted_statuses": [
|
|
85
|
+
"verified",
|
|
82
86
|
"trusted",
|
|
83
87
|
"accepted"
|
|
84
88
|
]
|