v0.6.0 — per-node session reuse (T-214..T-219)#44
Merged
Conversation
Release v0.5.0 — unified ~/.forge graduation layer
…219) Open the "engine made real" trio with item 1, scoped to the safest slice: within-node session reuse. The dispatch wrapper already supports `resume=<session_id>` at RESUME_FLOOR_USD (0.01 vs FRESH 0.06) and returns each run's session_id; the engine just never captures/chains it. v0.6.0 surfaces session_id from `_attempt`, reuses a node's own session across its retry + heal re-dispatches (verifier stays fresh; cross-node deferred), with a default-off `orchestration.session_reuse` toggle and a stale-session fallback-to-fresh. Admission/estimator stay on FRESH_FLOOR so AC-WF-014 and the determinism split are byte-identical on/off. Caveman mode (prompt compression) researched and recorded as a SEPARATE measurement-gated release (srs-v0.6.0 §6, fits_v060: separate-release) — only its stdlib levers port; caveman-compress (needs a model call + pip) and caveman-shrink (Node/MCP proxy) are out per REQ-NF-024. Ref: T-214
Plumb the v0.6.0 per-node session-reuse capability without yet changing any dispatch behavior — pure inert wiring so the engine stays byte-identical to v0.4.x. - _workflow_config.py: add `session_reuse: bool = False` to OrchestrationConfig and to `_TOGGLES`, so the existing strict `is True` / fail-soft parse covers it (a stray `1`/`"yes"` stays off; absent or malformed config → off), mirroring `flows_enabled` and siblings. - _workflow.run_workflow: accept `session_reuse: bool = False`. It is unused this task (no node `--resume`s a prior same-node attempt), so output is byte-identical with it on or off. Threaded into the nested decompose `run_kwargs` for recursive parity. - parallel_build.py / _orchestrate.fan_out: thread the config value into their inner `run_workflow` calls. - workflow_loader.flow_estimate: document that `session_reuse` is deliberately NOT an admission/estimator input — admission stays on FRESH_FLOOR_USD so the estimator split equals run drops (AC-WF-014, REQ-WF-020). TDD red-first; +11 tests (6 config, 5 workflow incl. on==off byte-identical). Full unit suite 1746 pass; validate-plugin 0. Ref: T-214 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface res.session_id as a 4th tuple member from _attempt so a later same-node re-dispatch can --resume it (REQ-WF-016). The id is returned on every with-session path (status="ok" — success, non-JSON, validation-failed) and None on every no-session path (dispatch raised, non-ok status, is_error). This is the split-determinism refactor (REQ-NF-040): committed separately from any reuse behavior. All three _run_node call sites unpack the 4-tuple but IGNORE the session, so every re-dispatch stays fresh and the engine is byte-identical to v0.4.x. T-216 consumes the captured id. The full existing suite stays green and unchanged; +8 _attempt tests. Ref: T-215 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t fallback
When orchestration.session_reuse is on, _run_node now threads a node's
most-recent captured session_id into its OWN retry and heal re-dispatches via a
per-attempt copy ({**kwargs, "resume": sid}) — lowering their realized floor from
FRESH_FLOOR_USD to RESUME_FLOOR_USD. The shared kwargs dict is never mutated, so
the independent verifier (which reads it through _run_verify/_verify.run_verify's
forced resume=None) still dispatches fresh (REQ-WF-002).
A resumed re-dispatch that returns a non-ok status (stale/invalid session →
obj is None AND no new session) falls back to ONE fresh re-dispatch within the
same attempt budget (REQ-WF-018), so reuse can never turn a would-succeed node
into a drop; it never raises and adds no spurious drop reason on recovery. An
ok-but-unparseable/validation-failed reused result is a genuine retry, not a
stale session, and does not fall back.
With the toggle off (or no captured session) the original kwargs flow unchanged:
the run-level resume token is preserved and the engine is byte-identical to
v0.4.x (empty stdout; identical ordered results/drops/summary on vs off).
Admission and the estimator stay on FRESH_FLOOR_USD (AC-WF-014 untouched).
_submit threads session_reuse into _run_node; nested decompose children inherit
it via run_kwargs while the generation dispatch stays fresh.
TDD red-first. +12 tests (10 test_workflow, 2 test_parallel_build) covering
AC-WF-017/018/019. Full unit suite 1766 pass; validate-plugin exit 0;
full-pipeline 12/12 (toggles off and on).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ref: T-216
… under session reuse T-217 proves the v0.6.0 within-node session reuse changes ONLY realized cost, never the engine's admitted/dropped split, its audit fidelity, its determinism, or the stdout contract. Test-only: the optional additive `reused` audit field is deliberately NOT added — it is optional and would force a schema_version bump and risk T-203 regressions for no required benefit, so the invariants are proven on the existing schema. +6 tests in tests/unit/test_workflow.py: - estimator/run admitted-dropped split identical with session_reuse on vs off, and equal to estimate_admission's split (uncapped); - for a max_budget_usd-capped diamond the estimator split EQUALS the run drops in BOTH modes (AC-WF-014 preserved — both charge FRESH_FLOOR_USD); - a run where every node heals costs strictly LESS under reuse while completing the identical node set; - the T-203 events.jsonl workflow_run record stays exactly one schema-versioned, PII-free line per run with unchanged completed/dropped/admitted and a LOWER total_cost_usd under reuse (identical key set ⇒ schema unchanged across modes); - parallel == sequential determinism with reuse ON; - empty + byte-identical stdout with reuse ON (T-128 / AC-WF-012 lineage). A deterministic id-routed _healing_id_dispatch fake (every node heals once, routed by the node id embedded in the verifier prompt so parallel interleaving cannot scramble verdict order) keeps realized cost and the split order-independent. TDD red-first: temporarily forcing _reuse_attempt to always dispatch fresh turned the two cost-bearing tests RED (0.48 < 0.48) while the split/determinism/stdout invariants stayed green by design — proving the cost tests are non-tautological; the engine was restored byte-for-byte (no scripts/_workflow.py diff). Full unit suite 1772 pass; validate-plugin.py exit 0; full-pipeline.sh 12/12. Ref: T-217 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Document the v0.6.0 per-node session-reuse feature (shipped in T-214..T-217) so its decisions and user-facing surface are on the record before release. - ADR-010 (build/02-architecture/adr/010-session-reuse.md, matching the 008/009 path+format): within-node only, verifier never reused (REQ-WF-002), admission stays FRESH_FLOOR_USD (AC-WF-014), default-off toggle (strict is True ⇒ byte-identical to v0.4.x), fallback-to-fresh on a stale session. - references/workflow-engine.md: session_reuse row in the orchestration toggle table (now five capability toggles), a Per-node session reuse section, and a cost-economics note on the one safe within-node reuse exception. - README.md: session_reuse config line + capability bullet. - ROADMAP.md: v0.5.0 marked released; new v0.6.0 row; engine-trio section updated (within-node half shipped, per-branch deferred) + caveman mode (candidate v0.6.1, measurement-gated) sub-section. - progress.md / decisions.md: T-218 row + the ADR-010 decision entry. The DAG's literal docs/adr/ADR-010-… path was a spec typo; followed the actual repo ADR convention per "match the existing ADR path/format". Docs-only — no engine change. New tests/unit/test_docs_session_reuse.py (red-first) pins the ADR file + the toggle/README/ROADMAP wiring. Ref: T-218 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Engine made real I: capture each DAG node's first-attempt session_id and --resume it into that same node's retry/heal re-dispatches, dropping their realized floor FRESH_FLOOR_USD ($0.06) → RESUME_FLOOR_USD ($0.01). Within-node only; verifier never reused; admission stays FRESH_FLOOR so the estimator split is identical on/off (AC-WF-014); stale session falls back to fresh. Opt-in orchestration.session_reuse, default off ⇒ byte-identical to v0.4.x. bump 0.6.0; CHANGELOG [0.6.0]; ROADMAP/progress rows; manifests 0.6.0. 1776 unit tests green, validate 0, full-pipeline 12/12 (toggles off and on). Ref: T-219
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Engine made real I — per-node session reuse. Cost-reduction minor with zero default behavior change.
Captures each DAG node's first-attempt
session_idand--resumes it into that same node's retry/heal re-dispatches (same prompt + model), dropping their realized floorFRESH_FLOOR_USD($0.06) →RESUME_FLOOR_USD($0.01). Within-node only; the independent verifier is never reused (REQ-WF-002); admission stays onFRESH_FLOOR_USDso the estimator/admitted-set split is identical on vs off (AC-WF-014); a stale session falls back to fresh within the attempt budget. Opt-inorchestration.session_reuse, default off ⇒ byte-identical to v0.4.x. ADR-010.run_workflowparam · T-215 behavior-preserving_attempt4-tuple capture · T-216 within-node reuse + fail-soft fallback · T-217 admission/estimator/audit invariance proofs · T-218 ADR-010 + docs · T-219 release.SRS
build/01-srs/srs-v0.6.0.md, DAGbuild/04-plan/task-dag-v0.6.0.md.🤖 Generated with Claude Code