Skip to content

flows: implement-slice.flow.ts hits kernel default step lease on npm-ci+typecheck (30s cap); adopt long-lease or split-step pattern #343

Description

@kjgbot

The dogfooded orchestrator flow ops/implement-slice/implement-slice.flow.ts runs a f.run with npm ci --ignore-scripts && npm install ./packages/surface --prefix packages/sdk --no-save --ignore-scripts && npm run typecheck. On a real slice run (slice S, run `01M28Z5VQCCHMC7P3945971KCM`), that step timed out at 30.57s while the actual work needs ~2 minutes.

Symptom

```
✗ run-5 (deterministic) 30.57s
FAILED [protocol_error] relayflowd could not complete the run request:
step_failed: journal step "run-5" completed with timeout
```

Root

Kernel default deterministic-step lease is 30s. The wrapper bounds table (SURFACE §2 rule 6) documents a 300s execution deadline for agent CLI steps, but deterministic `run` steps have their own tighter default that no header currently overrides.

Options

  1. Extend deterministic-step lease per-invocation — add `f.run(cmd, {timeout: N})` to the surface. Ergonomic and honest — the author declares expected duration. Requires a kernel field on `DeterministicStepSpec` (`lease_ms` or similar).
  2. Split into smaller steps — three separate `f.run` calls (`npm ci`, `npm install ./surface`, `npm run typecheck`). Each fits under 30s but total wall-clock unchanged. Simpler; no kernel change.
  3. Background detachment — the current workaround: `nohup bash -c '...' > log &` fire-and-forget, PR CI catches real regressions. Cheap but loses gate value.

Recommend

Option 1 (extend lease per-step) — matches the SURFACE §2 rule 6 pattern where wrappers declare their bounds. Author writes `f.run('long-cmd', {timeout: '5m'})` and the kernel journals that as the step's lease.

Files

  • `packages/surface/src/context.ts` — extend `Ctx.run` overload to accept `{timeout: string|number}`
  • `packages/sdk/src/spec.ts` — `DeterministicStepSpec.lease_ms?`
  • `kernel/relayflowd-core/src/machine.rs` — read the field; refusal if beyond a hard ceiling
  • `packages/sdk/src/authored-worker-step.ts` — thread the option

Acceptance

  • (i) `f.run('sleep 60', {timeout: '90s'})` succeeds; without the timeout arg it refuses at 30s
  • (ii) Refusal code `lease_exceeded` on timeout
  • (iii) Hard ceiling (e.g., 15 minutes) beyond which the surface refuses at check
  • (iv) Regression: existing `f.run(cmd)` (no timeout) still uses default

🤖 Filed after slice S run hit this on 2026-09-11.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions