Skip to content

fix(operations): expired-plan replay + declared lane timeouts + measured pin TTL (issue #192) - #193

Merged
rldyourmnd merged 4 commits into
mainfrom
fix/plan-expiry-replay-and-lane-timeouts
Sep 27, 2026
Merged

rldyourmnd merged 4 commits into
mainfrom
fix/plan-expiry-replay-and-lane-timeouts

Conversation

@rldyourmnd

Copy link
Copy Markdown
Contributor

Summary

Closes #192 — gds module update-pin lost three transactions to a plan TTL and per-command bound sized for a small module, applied to one whose declared verification legitimately runs longer.

  • fix(operations): Apply now answers a recorded operation from its journal before the expiry and enablement gates. A past-TTL plan replays its recorded result instead of masking it as GDS_PLAN_EXPIRY_RECORD_FAILED (issue attempt 2); a signed plan can replay even though its one-shot enablement was consumed by the recorded op; a second expired apply on an already-marked-stale plan reports GDS_PLAN_EXPIRED instead of an internal record failure. Signature verification still precedes any journal answer — a tampered record fails closed.
  • feat(verification): modules declare per-lane command budgets via verification.timeouts (schema + domain + PlanVerification + runDeclaredCommand). Precedence: operator --command-timeout > declared lane bound > engine default. The pin path passes 0 so declarations apply.
  • fix(module-pin): plan lifetime derives from measured lane duration (3x + base TTL — both apply re-runs plus retry headroom); lane command deadline default covers two full verification passes; per-command bounds still stop runaways; --timeout still wins.
  • Regenerated goldens + repository projections with the branch engine.

Test plan

  • go test ./... — all packages green (incl. new replay-after-expiry, already-stale re-apply, signed-replay-after-consumed-enablement regression tests)
  • python3 -m pytest — 70 passed (hash-locked venv)
  • scripts/validate_shell.sh, scripts/validate_go_core.sh --quick
  • gds generate repository --check clean on the committed branch
  • CI

Generated with Devin

…ent gates

A plan that already produced an operation could not answer from its own
journal in three cases: past the wall-clock lifetime it reported
GDS_PLAN_EXPIRY_RECORD_FAILED instead of the recorded result; a signed plan
could never replay at all because the one-shot enablement was consumed by
the recorded operation; and an already-marked-stale plan failed the
"planned" -> "stale" transition on a second expired apply (issue 192,
attempt 2).

Replay now consults the journal before expiry and enablement, signature
verification still precedes any journal answer so a tampered record fails
closed, and the stale mark is written as durable bookkeeping under
WithoutCancel while tolerating a mark an earlier expired apply already
recorded.
Every lane command used to run under one hardcoded 10-minute bound, so a
suite that legitimately needs longer could only report "timeout" and a pin
apply re-running the lanes failed closed as GDS_STALE_PLAN -- the
operational half of issue 192. Modules now declare their own cost:
`verification.timeouts` carries per-lane seconds through the anchor schema,
the domain type and PlanVerification into runDeclaredCommand. An explicit
operator `--command-timeout` still wins, then the declaration, then the
engine default. Regenerated goldens and repository projections record the
new canonical input.
… cost

The 15-minute plan TTL and the 20-minute lane command deadline both
expired mid-verification on a real module: apply re-runs the declared
lanes up to twice before mutating, and issue 192's first attempt died
there as a misleading GDS_STALE_PLAN. The plan now derives its lifetime
from the measured lane duration (3x plus the base TTL, covering both
re-runs and a retry), and the lane deadline default covers two full
declared-verification passes; each command stays individually bounded by
verification.timeouts or the per-command default, and --timeout still
wins.
@rldyourmnd
rldyourmnd merged commit 23c8cd5 into main Sep 27, 2026
8 checks passed
@rldyourmnd
rldyourmnd deleted the fix/plan-expiry-replay-and-lane-timeouts branch September 27, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gds module update-pin: plan TTL expires before module verification completes

1 participant