@kontourai/flow-agents 3.2.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 +173 -0
- package/CHANGELOG.md +54 -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/assignment-provider.js +10 -1
- 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-artifact-cleanup-audit.js +418 -11
- package/build/src/cli/workflow-sidecar.d.ts +310 -1
- package/build/src/cli/workflow-sidecar.js +1914 -126
- 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 +30 -3
- package/context/contracts/artifact-contract.md +16 -2
- 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 +194 -22
- 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/coordination-guide.md +370 -0
- package/docs/decisions/agent-coordination.md +26 -9
- package/docs/decisions/embeddable-engine.md +152 -0
- package/docs/decisions/index.md +5 -3
- package/docs/decisions/trust-ledger-retention.md +88 -0
- package/docs/decisions/trust-reconcile.md +42 -9
- package/docs/decisions/workflow-enforcement.md +31 -9
- package/docs/fixture-ownership.md +6 -2
- package/docs/implementing-trust-reconciliation.md +129 -0
- package/docs/index.md +23 -9
- package/docs/integrations/flow-agents-console.md +275 -0
- package/docs/integrations/index.md +4 -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-artifact-lifecycle.md +38 -1
- package/docs/workflow-usage-guide.md +10 -0
- package/evals/acceptance/prove-capture-teeth.sh +132 -0
- package/evals/ci/antigaming-suite.sh +2 -0
- package/evals/ci/run-baseline.sh +78 -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/reconcile-preflight/disputed-critique-unsuperseded.json +48 -0
- package/evals/fixtures/reconcile-preflight/standalone-disputed-session-local.json +59 -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_checkpoint_signing.sh +10 -2
- package/evals/integration/test_ci_actor_identity.sh +221 -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 +389 -2
- package/evals/integration/test_pull_work_board.sh +200 -0
- package/evals/integration/test_pull_work_provider.sh +1 -1
- package/evals/integration/test_reconcile_preflight.sh +304 -0
- 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_takeover_protocol.sh +340 -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 +121 -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_verify_hold.sh +910 -0
- package/evals/integration/test_veritas_governance_kit.sh +257 -0
- package/evals/integration/test_workflow_artifact_cleanup_audit.sh +575 -3
- 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 +37 -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/continue-work/SKILL.md +2 -0
- package/kits/builder/skills/deliver/SKILL.md +115 -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 +33 -2
- package/kits/builder/skills/release-readiness/SKILL.md +12 -0
- package/kits/knowledge/kit.json +9 -0
- package/kits/veritas-governance/docs/README.md +113 -7
- package/kits/veritas-governance/fixtures/exemption/approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/fixtures/exemption/not-approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/fixtures/exemption-review/mixed-fresh-stale.DECLARED.json +14 -0
- package/kits/veritas-governance/flows/exemption-issuance.flow.json +35 -0
- package/kits/veritas-governance/kit.json +19 -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 +214 -253
- package/scripts/hooks/codex-hook-adapter.js +77 -2
- package/scripts/hooks/evidence-capture.js +38 -5
- package/scripts/hooks/lib/actor-identity.js +82 -0
- 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 +194 -22
- 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/lib/reconcile-shape.js +381 -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/assignment-provider.ts +12 -1
- 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-artifact-cleanup-audit.ts +483 -10
- package/src/cli/workflow-sidecar.ts +1980 -119
- 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 +29 -3
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type EffectiveState } from "./assignment-provider.js";
|
|
2
3
|
type AnyObj = Record<string, any>;
|
|
3
4
|
export declare const statuses: Set<string>;
|
|
4
5
|
export declare const phases: string[];
|
|
@@ -132,6 +133,36 @@ type SurfaceModule = {
|
|
|
132
133
|
assuranceLevel: "signed";
|
|
133
134
|
} | null>;
|
|
134
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* Fold a raw command-log (command-log.jsonl entries) into a per-command classification,
|
|
138
|
+
* keyed by normalized command text (whitespace-collapsed, trimmed). Pure and side-effect-free
|
|
139
|
+
* so it is directly unit-testable (#470 iteration 2, finding #2 — HIGH: the prior inline reducer
|
|
140
|
+
* collapsed every non-"fail" `observedResult` — including "ambiguous" — to "pass", feeding a
|
|
141
|
+
* verified event + `passing:true` and reintroducing the #470 false-pass through the trust-bundle
|
|
142
|
+
* reconciliation path).
|
|
143
|
+
*
|
|
144
|
+
* Three-way classification, keyed on `observedResult` (never re-derived from `exitCode` alone,
|
|
145
|
+
* which would miscoerce the #362 grep/diff absence carve-out `ambiguous,exitCode:1` entry to
|
|
146
|
+
* `fail`):
|
|
147
|
+
* - "fail" when `observedResult==="fail"`, or (legacy, no observedResult) a nonzero
|
|
148
|
+
* integer `exitCode`.
|
|
149
|
+
* - "ambiguous" when `observedResult==="ambiguous"`, or (legacy) `exitCode` is `null` with no
|
|
150
|
+
* fail signal.
|
|
151
|
+
* - "pass" when `observedResult==="pass"`, or (legacy) `exitCode===0`.
|
|
152
|
+
*
|
|
153
|
+
* Precedence across repeated entries for the same command: fail > pass > ambiguous. A genuine
|
|
154
|
+
* exit-0 pass is positive evidence and confirms; ambiguous holds only when there is neither a
|
|
155
|
+
* fail nor a positive pass, since a "pass" always requires positive evidence.
|
|
156
|
+
*
|
|
157
|
+
* The caller (buildTrustBundle) maps "ambiguous" onto the existing canonical non-confirming
|
|
158
|
+
* status `not_verified` — consume-never-fork, mirroring record-check's identical mapping — so
|
|
159
|
+
* `checkStatusToEventStatus("not_verified")` returns null (no verification event emitted) and the
|
|
160
|
+
* evidence item is stamped `passing:false`. See Decision/finding #2 in the iteration-2 plan.
|
|
161
|
+
*/
|
|
162
|
+
export declare function reduceCaptureLogByCommand(commandLog: AnyObj[] | undefined): Map<string, {
|
|
163
|
+
observedResult: "pass" | "fail" | "ambiguous";
|
|
164
|
+
exitCode: number | null;
|
|
165
|
+
}>;
|
|
135
166
|
/**
|
|
136
167
|
* Build a Hachure trust.bundle from raw check/criterion/critique inputs.
|
|
137
168
|
* trust.bundle is the PRIMARY artifact (ADR 0010 Phase 4a producer inversion).
|
|
@@ -166,7 +197,7 @@ export declare function writeTrustBundle(dir: string, slug: string, timestamp: s
|
|
|
166
197
|
export declare function sidecarBase(slug: string): AnyObj;
|
|
167
198
|
export declare function validateEvidenceRef(ref: AnyObj, label: string): AnyObj;
|
|
168
199
|
export declare function normalizeEvidenceRefs(raw: unknown, label: string): AnyObj[];
|
|
169
|
-
export declare function normalizeCheck(raw: AnyObj): AnyObj;
|
|
200
|
+
export declare function normalizeCheck(raw: AnyObj, allowGateClaimPrefix?: boolean, existingCheckStampById?: ReadonlyMap<string, boolean>): AnyObj;
|
|
170
201
|
/**
|
|
171
202
|
* Derive kit identity from a parsed trust.bundle by structurally reading the
|
|
172
203
|
* DECLARED primary claim (kit-typed) rather than hardcoding "builder".
|
|
@@ -201,6 +232,235 @@ export declare function normalizeFinding(raw: AnyObj): AnyObj;
|
|
|
201
232
|
* Signing is ALWAYS fail-open — a signing failure never breaks the seal.
|
|
202
233
|
*/
|
|
203
234
|
export declare function sealTrustCheckpoint(dir: string, slug: string, sealedAt: string, status: string, phase: string): Promise<void>;
|
|
235
|
+
/**
|
|
236
|
+
* Distinct, identifiable error for a shape-invalid trust.bundle — NOT a generic Error, so
|
|
237
|
+
* every publishDelivery() call site (advanceState/recordRelease/promote/publishDeliveryCmd)
|
|
238
|
+
* can positively distinguish "refuses to publish an invalid bundle" (must be LOUD, fail
|
|
239
|
+
* closed, AC6) from the other failure modes those call sites already tolerate as best-effort
|
|
240
|
+
* (missing kits/ ancestor for a scratch dir, I/O errors, etc — see each catch's own comment).
|
|
241
|
+
* A bare `instanceof Error` check would not suffice since every thrown failure in this file is
|
|
242
|
+
* already an Error; `code` is the recognizable, grep-stable discriminator.
|
|
243
|
+
*/
|
|
244
|
+
export declare class InvalidBundleShapeError extends Error {
|
|
245
|
+
readonly code: "RECONCILE_PREFLIGHT_INVALID_SHAPE";
|
|
246
|
+
readonly issues: string[];
|
|
247
|
+
constructor(issues: string[]);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Distinct, identifiable error for a publish attempt by an actor who is NOT the fresh,
|
|
251
|
+
* non-superseded holder of the subject (issue #293, ADR 0021 §3) — NOT a generic Error and NOT
|
|
252
|
+
* `InvalidBundleShapeError` (#356), so every publishDelivery() call site can positively
|
|
253
|
+
* distinguish "refuses to publish because the bundle shape is invalid" from "refuses to publish
|
|
254
|
+
* because this actor no longer holds the subject" — two genuinely distinct fail-closed tiers
|
|
255
|
+
* that must never be conflated in a catch handler (a worker fixing a shape issue must not be
|
|
256
|
+
* told to "re-record evidence" when the real problem is a stale/superseded claim, and vice
|
|
257
|
+
* versa). Mirrors `InvalidBundleShapeError`'s shape exactly: same `extends Error` base, same
|
|
258
|
+
* `readonly code` discriminator convention, same doc-comment structure — only the payload
|
|
259
|
+
* differs (the effective-state/holder/reason/guidance `runVerifyHold()` computed, rather than a
|
|
260
|
+
* shape-issue list).
|
|
261
|
+
*/
|
|
262
|
+
export declare class NotFreshHolderError extends Error {
|
|
263
|
+
readonly code: "VERIFY_HOLD_NOT_FRESH_HOLDER";
|
|
264
|
+
readonly effective_state: EffectiveState | "not_evaluated";
|
|
265
|
+
readonly holder?: {
|
|
266
|
+
actor?: string;
|
|
267
|
+
assignee?: string | null;
|
|
268
|
+
idle_days?: number | null;
|
|
269
|
+
last_at?: string;
|
|
270
|
+
};
|
|
271
|
+
readonly reason: string;
|
|
272
|
+
readonly guidance: string[];
|
|
273
|
+
constructor(result: {
|
|
274
|
+
effective_state: EffectiveState | "not_evaluated";
|
|
275
|
+
holder?: {
|
|
276
|
+
actor?: string;
|
|
277
|
+
assignee?: string | null;
|
|
278
|
+
idle_days?: number | null;
|
|
279
|
+
last_at?: string;
|
|
280
|
+
};
|
|
281
|
+
reason: string;
|
|
282
|
+
guidance: string[];
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Distinct, identifiable error for a publish attempt whose resolved `repoRoot` does not
|
|
287
|
+
* positively confirm the session's sealed `trust.checkpoint.json` `commit_sha` — a FOURTH,
|
|
288
|
+
* distinct fail-closed tier (#413 Facet A), never conflated with `InvalidBundleShapeError`
|
|
289
|
+
* (bundle shape) or `NotFreshHolderError` (actor hold). This is the "refuse loudly when the cwd
|
|
290
|
+
* repo does not match the sealed checkpoint commit_sha" fallback the issue itself proposed:
|
|
291
|
+
* `publishDelivery`'s `repoRoot` is resolved by walking up from the ARTIFACT directory
|
|
292
|
+
* (findRepoRootFromDirStrict), which always physically lives under the primary checkout even
|
|
293
|
+
* when invoked from an unrelated worktree/repo — so a positively-confirmed mismatch here is the
|
|
294
|
+
* signal that this resolved repoRoot is NOT the repo the sealed checkpoint was produced against,
|
|
295
|
+
* and publishing into it would silently write to the wrong tree.
|
|
296
|
+
*
|
|
297
|
+
* #413 iteration-2 Fix 4: thrown for the ONE positively-determinable `mismatchKind` (see
|
|
298
|
+
* checkpointHeadAncestry's doc comment) — `"positive"` (repoRoot's HEAD is confirmed NOT an
|
|
299
|
+
* ancestor-or-equal of commit_sha; `headSha` is a real sha). It is intentionally NEVER thrown for
|
|
300
|
+
* `"undeterminable-shallow"` (e.g. a shallow clone missing the commit object) — that case only
|
|
301
|
+
* warns and allows the publish (see publishDelivery's own gate). A non-git `repoRoot` classifies
|
|
302
|
+
* as `mismatchKind === "none"` (no opinion — allow; see checkpointHeadAncestry's doc comment for
|
|
303
|
+
* why the iteration-2 Fix 5 refusal here was reverted in iteration-3) and never throws this error
|
|
304
|
+
* either.
|
|
305
|
+
*/
|
|
306
|
+
export declare class RepoHeadMismatchError extends Error {
|
|
307
|
+
readonly code: "PUBLISH_DELIVERY_REPO_HEAD_MISMATCH";
|
|
308
|
+
readonly repoRoot: string;
|
|
309
|
+
readonly commitSha: string;
|
|
310
|
+
readonly headSha: string;
|
|
311
|
+
constructor(repoRoot: string, commitSha: string, headSha: string);
|
|
312
|
+
}
|
|
313
|
+
export declare function runReconcilePreflight(dir: string, repoRoot: string, manifestOverride?: string | null): {
|
|
314
|
+
ok: boolean;
|
|
315
|
+
issues: string[];
|
|
316
|
+
warnings: string[];
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* The ONE hard-stop gate (issue #293, ADR 0021 §3): "is my actor the fresh, non-superseded
|
|
320
|
+
* holder of this subject (or is the subject free/self-held)?" Reuses the SAME assignment ⋈
|
|
321
|
+
* liveness join #290/#291 already built (`computeEffectiveState` + `readLocalAssignmentStatus`
|
|
322
|
+
* + `readLivenessEvents`/`freshHolders`) — no second computation is invented here. This is the
|
|
323
|
+
* mirror-image check, at the OTHER end of the session lifecycle, of
|
|
324
|
+
* `enforceEnsureSessionOwnership`'s pre-entry guard above: that guard decides whether entry
|
|
325
|
+
* should claim/supersede/refuse; this gate decides whether PUBLISH should proceed, with a
|
|
326
|
+
* different (new) per-effective-state mapping — the ownership guard's "claim"/"supersede"
|
|
327
|
+
* actions are wrong at publish time, so this is new interpretation of the existing join output,
|
|
328
|
+
* not a new join and not a new `EffectiveState` value (there is no literal `"superseded"` state
|
|
329
|
+
* — a superseded-away actor's own re-check naturally resolves to `held`(holder=successor) or
|
|
330
|
+
* `reclaimable`, never `self_is_holder`; see assignment-provider.ts's `computeEffectiveState`).
|
|
331
|
+
*
|
|
332
|
+
* Effective-state -> publish-decision mapping (the operative spec, from the plan's table).
|
|
333
|
+
* IMPORTANT (bug fix, #397): this gate fences the durable ASSIGNMENT hold, not ambient
|
|
334
|
+
* liveness — liveness is advisory everywhere else in the system, and this is the ONE hard
|
|
335
|
+
* gate, so it must never false-block on liveness alone. A subject with fresh liveness by
|
|
336
|
+
* another actor but NO durable assignment record (`held`, reason
|
|
337
|
+
* `liveness_claim_present_assignment_lagging`) therefore PASSES, not BLOCKs — there is no
|
|
338
|
+
* durable ownership conflict to protect, only ambient presence. This does NOT weaken zombie
|
|
339
|
+
* protection: a superseded zombie always has an assignment record (either its own stale
|
|
340
|
+
* assignment — `reclaimable` — or the successor's assignment-backed `held`/
|
|
341
|
+
* `fresh_liveness_heartbeat`), both of which still BLOCK below.
|
|
342
|
+
* - `free` (no assignment ever recorded) -> PASS (never false-block an untracked subject)
|
|
343
|
+
* - `held`, reason `self_is_holder` -> PASS (the caller IS the current holder)
|
|
344
|
+
* - `held`, reason `liveness_claim_present_assignment_lagging`
|
|
345
|
+
* (fresh liveness by another actor, NO durable assignment record) -> PASS (liveness alone
|
|
346
|
+
* is never a durable ownership conflict — see #397 fix note above)
|
|
347
|
+
* - `held`, reason `fresh_liveness_heartbeat`
|
|
348
|
+
* (durable assignment held by another actor + fresh liveness) -> BLOCK (a different
|
|
349
|
+
* actor durably holds this subject and is demonstrably still live)
|
|
350
|
+
* - `reclaimable` (assignment present, stale/absent liveness) -> BLOCK (not proof of
|
|
351
|
+
* self — safe default blocks; a durable assignment record exists)
|
|
352
|
+
* - `human-held` -> BLOCK (never publish over a human assignee)
|
|
353
|
+
* - no resolvable join at all (non-local-file provider
|
|
354
|
+
* with no --effective-state-json) -> `not_evaluated`, PASS (documented scope
|
|
355
|
+
* boundary, loud stderr note, never a silent block)
|
|
356
|
+
*
|
|
357
|
+
* Actor resolution mirrors `enforceEnsureSessionOwnership` EXACTLY: the bare
|
|
358
|
+
* `resolveActor(env).actor` / branchActorKey string, NEVER `serializeActor(actorStruct)`'s
|
|
359
|
+
* triple — the #291 flat-vs-triple seam. `opts.actorKey` (the CLI's --actor / FLOW_AGENTS_ACTOR
|
|
360
|
+
* override, already sanitized by the caller) takes precedence when provided.
|
|
361
|
+
*
|
|
362
|
+
* Slug/artifactRoot derivation matches `publishDelivery()`'s own `slug =
|
|
363
|
+
* path.basename(path.resolve(dir))` byte-for-byte (both must resolve the SAME assignment
|
|
364
|
+
* record) and the `artifactRoot = path.dirname(dir)` pattern already used elsewhere in this
|
|
365
|
+
* file for a `dir`-only consumer.
|
|
366
|
+
*
|
|
367
|
+
* github provider: read-only precomputed `--effective-state-json` escape hatch, matching
|
|
368
|
+
* `enforceEnsureSessionOwnership`'s existing github branch precedent exactly (render-don't-
|
|
369
|
+
* execute — assignment-provider.ts never calls `gh` directly from this CLI).
|
|
370
|
+
*
|
|
371
|
+
* Every interpolated actor/holder/reason string is sanitized via
|
|
372
|
+
* `stripControlCharsForDisplay(...).slice(0, 64)` — reusing the exact top-level helper, never a
|
|
373
|
+
* second sanitizer (AC7).
|
|
374
|
+
*
|
|
375
|
+
* SECOND CI-blocking false-block fix (this iteration): the hard gate above enforces ONLY for a
|
|
376
|
+
* STABLY-identified actor. A caller's identity is STABLE when it comes from an explicit
|
|
377
|
+
* `opts.actorKey` (a caller that hands in an actor key is asserting a stable identity — e.g. the
|
|
378
|
+
* CLI's --actor / FLOW_AGENTS_ACTOR override, or the github skill's precomputed path), from
|
|
379
|
+
* `FLOW_AGENTS_ACTOR` (`resolveActor` source `"explicit-override"`), or from a runtime-native
|
|
380
|
+
* session id (`resolveActor` source `` `runtime-session-id:${runtime}` ``, e.g. Claude Code's
|
|
381
|
+
* `CLAUDE_CODE_SESSION_ID`). It is UNSTABLE when `resolveActor` falls all the way through to the
|
|
382
|
+
* process-ancestry fallback (source `"process-ancestry"`) or fails to resolve at all (source
|
|
383
|
+
* `"unresolved"` / `isUnresolvedActor(actor)`). This mirrors `enforceEnsureSessionOwnership`'s
|
|
384
|
+
* Design Decision 4 (never hard-fail on actor ambiguity): a session that cannot stably
|
|
385
|
+
* self-identify cannot be meaningfully fenced against a durable assignment record, so hard-
|
|
386
|
+
* blocking it produces exactly the false-block CI hit (no `FLOW_AGENTS_ACTOR`/runtime session id
|
|
387
|
+
* in CI -> ancestry fallback -> a DIFFERENT ancestry-derived actor string than the one that
|
|
388
|
+
* created the claim -> `reclaimable`/not-self -> hard BLOCK of a legitimate self-publish). A
|
|
389
|
+
* real coordination participant always has a stable identity (explicit override or runtime
|
|
390
|
+
* session id), so zombie protection under a stable actor is completely unaffected — this only
|
|
391
|
+
* changes behavior for a caller that was never fenceable in the first place. When the resolved
|
|
392
|
+
* actor identity is UNSTABLE, this function short-circuits to `{ ok: true, effective_state:
|
|
393
|
+
* "not_evaluated", reason: "actor-identity-unstable-advisory-only" }` (holder included, sanitized,
|
|
394
|
+
* when one exists) BEFORE running the assignment ⋈ liveness join at all, with one loud stderr
|
|
395
|
+
* note — the gate degrades to advisory-only rather than ever false-blocking an unstable identity.
|
|
396
|
+
* When the actor identity IS stable, the effective-state -> publish-decision mapping above
|
|
397
|
+
* applies exactly as documented, unchanged.
|
|
398
|
+
*/
|
|
399
|
+
export declare function runVerifyHold(dir: string, repoRoot: string | null, opts?: {
|
|
400
|
+
actorKey?: string;
|
|
401
|
+
now?: number;
|
|
402
|
+
assignmentProviderKind?: string;
|
|
403
|
+
effectiveStateJson?: unknown;
|
|
404
|
+
}): {
|
|
405
|
+
ok: boolean;
|
|
406
|
+
effective_state: EffectiveState | "not_evaluated";
|
|
407
|
+
holder?: {
|
|
408
|
+
actor?: string;
|
|
409
|
+
assignee?: string | null;
|
|
410
|
+
idle_days?: number | null;
|
|
411
|
+
last_at?: string;
|
|
412
|
+
};
|
|
413
|
+
reason: string;
|
|
414
|
+
guidance: string[];
|
|
415
|
+
};
|
|
416
|
+
/**
|
|
417
|
+
* Render (never execute) the takeover protocol for a candidate the skill has selected. Takeover is
|
|
418
|
+
* RESUMPTION, not restart: when a subject is `reclaimable` (a durable assignment whose incumbent is
|
|
419
|
+
* no longer heartbeating), a successor must (1) grace-beat — wait one heartbeat interval and re-check,
|
|
420
|
+
* backing off if the incumbent revives — (2) supersede via `ensure-session --supersede-stale`, and
|
|
421
|
+
* (3) CONTINUE THE INCUMBENT'S BRANCH (from the incumbent's claim record), never a parallel one, and
|
|
422
|
+
* re-enter the SAME artifact dir (deterministic slug). This function computes the effective state
|
|
423
|
+
* (the same assignment ⋈ liveness join verify-hold/ensure-session use) and emits the appropriate
|
|
424
|
+
* action + the incumbent's `resume_branch`; the skill executes the beat/supersede/git steps.
|
|
425
|
+
*
|
|
426
|
+
* Race-safety is CLI-enforced at supersede time, not here: `ensure-session --supersede-stale`
|
|
427
|
+
* re-computes the state and refuses (dies on `held`) if the incumbent revived during the beat, so a
|
|
428
|
+
* successor that skipped or lost the grace race still cannot supersede a live incumbent (AC2a).
|
|
429
|
+
*
|
|
430
|
+
* ADVISORY, not a gate: the assignment ⋈ liveness JOIN is identical to verify-hold's, but this render
|
|
431
|
+
* only advises the skill which action to take — the ACTUAL enforcement is `ensure-session
|
|
432
|
+
* --supersede-stale` (re-check under a subject lock). So it deliberately does NOT replicate
|
|
433
|
+
* verify-hold's #398 `isStableActor` tiering (which exists there only because verify-hold is a hard
|
|
434
|
+
* publish BLOCK that must not false-block an unstable/ancestry identity): a wrong self-identification
|
|
435
|
+
* here yields only a wrong advisory string, never a wrong mutation.
|
|
436
|
+
*
|
|
437
|
+
* Ordering note: ADR 0021 §5's literal wording is supersede→grace→maybe-undo; this implements
|
|
438
|
+
* grace→recheck→supersede (never write until the beat confirms the incumbent stayed stale) — a
|
|
439
|
+
* deliberate, safer variant that preserves the ADR's intent ("laptop just woke resolves in the
|
|
440
|
+
* incumbent's favor") without a premature write to walk back.
|
|
441
|
+
*
|
|
442
|
+
* All untrusted fields (incumbent actor / branch / last_at, sourced from the shared multi-writer
|
|
443
|
+
* assignment+liveness stream) pass through `sanitize`/`sanitizeWide` (stripControlCharsForDisplay +
|
|
444
|
+
* the repo's 64/240 cap tiers — branch uses the 240 free-text tier so a valid long branch is never
|
|
445
|
+
* truncated into a bad checkout target) — the #287/#320/#293 injection class.
|
|
446
|
+
*/
|
|
447
|
+
export declare function runTakeoverPreflight(dir: string, opts?: {
|
|
448
|
+
actorKey?: string;
|
|
449
|
+
now?: number;
|
|
450
|
+
graceSeconds?: number;
|
|
451
|
+
}): {
|
|
452
|
+
ok: boolean;
|
|
453
|
+
action: "grace-then-supersede" | "back-off" | "claim" | "ask-first" | "proceed";
|
|
454
|
+
effective_state: EffectiveState;
|
|
455
|
+
reason: string;
|
|
456
|
+
holder?: {
|
|
457
|
+
actor?: string;
|
|
458
|
+
last_at?: string;
|
|
459
|
+
};
|
|
460
|
+
resume_branch?: string;
|
|
461
|
+
grace_seconds?: number;
|
|
462
|
+
next_steps: string[];
|
|
463
|
+
};
|
|
204
464
|
/**
|
|
205
465
|
* Publish the session's trust artifacts to the committed delivery/ path.
|
|
206
466
|
*
|
|
@@ -226,6 +486,55 @@ export declare function sealTrustCheckpoint(dir: string, slug: string, sealedAt:
|
|
|
226
486
|
* evals/integration/test_checkpoint_signing.sh TEST 2 and the WS5 session findings at
|
|
227
487
|
* .kontourai/flow-agents/ws5-governance-kit-slice1 for the root cause this fixes).
|
|
228
488
|
* Idempotent: overwrites on re-delivery to the same slug.
|
|
489
|
+
*
|
|
490
|
+
* #356 Wave 3 (AC6): Fail-CLOSED on bundle SHAPE. After the fail-soft absence guard below,
|
|
491
|
+
* runs the SAME reconcile-preflight shape check (runReconcilePreflight) the
|
|
492
|
+
* `reconcile-preflight` CLI subcommand exposes, BEFORE copying anything into delivery/. A
|
|
493
|
+
* shape-invalid bundle throws InvalidBundleShapeError (a distinct, identifiable error — see
|
|
494
|
+
* its own doc comment) rather than silently publishing a bundle CI's Trust Reconcile job
|
|
495
|
+
* would reject anyway. This is intentionally a NEW, additive fail-closed branch — it must
|
|
496
|
+
* never be conflated with the pre-existing fail-soft absence/repo-root branches above/below,
|
|
497
|
+
* which stay exactly as before (see each publishDelivery call site's catch handler for how
|
|
498
|
+
* the distinction is preserved end-to-end).
|
|
499
|
+
*
|
|
500
|
+
* #293 (THIRD, DISTINCT fail-closed gate): immediately after the shape check above and BEFORE
|
|
501
|
+
* writing anything into delivery/, runs `runVerifyHold()` — the assignment ⋈ liveness join
|
|
502
|
+
* asking "is the calling actor the fresh, non-superseded holder of this subject (or is it
|
|
503
|
+
* free/self-held)?" A not-fresh-holder result throws `NotFreshHolderError` (distinct from
|
|
504
|
+
* `InvalidBundleShapeError` — a different `code`, a different failure mode: actor hold vs
|
|
505
|
+
* bundle shape).
|
|
506
|
+
*
|
|
507
|
+
* #413 Facet A (FOURTH, DISTINCT fail-closed gate): immediately after the verify-hold gate and
|
|
508
|
+
* BEFORE writing anything into delivery/, compares the resolved `repoRoot`'s `git rev-parse
|
|
509
|
+
* HEAD` against the session's sealed `trust.checkpoint.json` `commit_sha` (via the shared
|
|
510
|
+
* checkpointHeadAncestry() helper — the SAME ancestor-check checkpointStalenessWarning already
|
|
511
|
+
* used as a non-blocking warning). Throws `RepoHeadMismatchError` (distinct from both other
|
|
512
|
+
* error tiers) instead of silently publishing into what is very likely the WRONG repo (e.g.
|
|
513
|
+
* `repoRoot` resolved to the primary checkout via findRepoRootFromDirStrict's artifact-dir
|
|
514
|
+
* walk, even though this session's checkpoint was sealed against a DIFFERENT worktree's HEAD).
|
|
515
|
+
* A session with no checkpoint yet, or a checkpoint with no commit_sha, has nothing to compare
|
|
516
|
+
* against and is unaffected (scoped strictly to the mismatch case, never a spurious refusal).
|
|
517
|
+
*
|
|
518
|
+
* #413 iteration-2 Fix 4 (see checkpointHeadAncestry's own doc comment for the full
|
|
519
|
+
* `mismatchKind` classification this gate reads): only `mismatchKind === "positive"` (a
|
|
520
|
+
* POSITIVELY-DETERMINABLE ancestry mismatch — the real wrong-tree harm case) hard refuses here.
|
|
521
|
+
* `"undeterminable-shallow"` (e.g. a local shallow clone missing the commit_sha object) must
|
|
522
|
+
* NEVER hard-refuse a legitimate publish — this branch only WARNS loudly and lets the shape +
|
|
523
|
+
* verify-hold gates above continue to stand guard. A non-git `repoRoot` classifies as
|
|
524
|
+
* `mismatchKind === "none"` (allow) — iteration-2's Fix 5 hard-refused this case too, but that
|
|
525
|
+
* regressed the SUPPORTED non-git-repoRoot scratch/checkpoint-signing flow (see
|
|
526
|
+
* evals/integration/test_checkpoint_signing.sh TEST 2) and was reverted in iteration-3. Wrong-tree
|
|
527
|
+
* protection for that case relies on the shape-check and verify-hold gates above, which correctly
|
|
528
|
+
* no-op (allow) when there is no git repo to inspect, same as this gate.
|
|
529
|
+
*
|
|
530
|
+
* There are now FOUR fail-closed/fail-soft TIERS in this function, and they must never be
|
|
531
|
+
* conflated in prose or in a call site's catch handler: (1) fail-SOFT bundle absence /
|
|
532
|
+
* repo-root resolution (silent no-op / visible warning, unchanged from before #356), (2)
|
|
533
|
+
* fail-CLOSED bundle shape (#356, `InvalidBundleShapeError`), (3) fail-CLOSED verify-hold (#293,
|
|
534
|
+
* `NotFreshHolderError`), (4) fail-CLOSED repo-HEAD-vs-checkpoint mismatch (#413 Facet A,
|
|
535
|
+
* `RepoHeadMismatchError`) — see this tier's own gate below for the undeterminable-shallow
|
|
536
|
+
* carve-out. Tiers run in this fixed order (shape, then verify-hold, then HEAD-mismatch); a
|
|
537
|
+
* bundle that fails an earlier tier throws that tier's error specifically, never a later one's.
|
|
229
538
|
*/
|
|
230
539
|
export declare function publishDelivery(dir: string, repoRoot: string | null): Promise<void>;
|
|
231
540
|
export declare function validateLearningCorrection(record: AnyObj): void;
|