Interruptible Request Diagnostics Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Make the request diagnostics reload action interrupt and replace an in-flight foldkit/http request using FoldKit 0.129.0.
Architecture: FetchMetrics owns HTTP work and is registered under a fixed diagnostics-dataset key with Command.Interruptible.define. The application update owns cancellation and dispatches a replacement request only after the interrupt outcome Message, leaving Astro lifecycle and chart primitives unchanged.
Tech Stack: FoldKit 0.129.0, Effect, foldkit/http, foldkit/experimental, Vitest, Astro.
Global Constraints
- Install the locked
foldkit@0.129.0package before importing its new API. - Preserve unidirectional flow: view -> Message -> update -> Command -> Message.
- Keep
FetchMetricsas the only owner of the HTTP effect andHttp.layerprovisioning. - Use a past-tense interrupt outcome Message and a
Schema.Unknowntype override only if the outcome cannot be represented by Effect Schema. - Do not return an interrupt Command and replacement
FetchMetrics()Command in the same update batch. - Do not change public APIs of
@opsydyn/astro-foldkitor@opsydyn/foldkit-viz.
Task 1: Install and verify the FoldKit 0.129 Command API
Files:
- Modify:
node_modules/only through Bun installation; no tracked source change.
Interfaces:
-
Consumes:
bun.lockresolvingfoldkit@0.129.0. -
Produces: Installed declarations for
Command.Interruptible.defineand itsInterruptconstructor. -
Step 1: Install from the existing lockfile
Run:
Terminal window bun install --frozen-lockfileExpected: workspace
foldkitsymlinks resolve to0.129.0. -
Step 2: Inspect the installed declarations
Run:
Terminal window rg -n -C 3 'Interruptible' node_modules/.bun/foldkit@0.129.0*/node_modules/foldkit/distExpected: the exact no-argument definition and interrupt-call overloads are available before source is changed.
Task 2: Cover interrupt sequencing with failing update tests
Files:
- Modify:
apps/web/src/apps/request-diagnostics/machine.test.ts - Modify:
apps/web/src/apps/request-diagnostics/command.test.ts
Interfaces:
-
Consumes:
ClickedReload,FetchMetrics, and the new interrupt outcome Message. -
Produces: tests proving a reload in
Loadingfirst interrupts and starts replacement only after the outcome Message. -
Step 1: Add the failing loading-state test
Add a test asserting that
diagnosticsMachine.step(Loading(), ClickedReload())transitions toLoadingand returns exactly one interrupt Command, with no replacementFetchMetrics()Command in that command list. -
Step 2: Add the failing update sequencing test
Add a test that sends the interrupt outcome Message to
update(initModel, message)and asserts that it returns exactly oneFetchMetrics()replacement command. -
Step 3: Run focused tests and confirm the expected API failure
Run:
Terminal window bun run --filter @opsydyn/web test -- apps/web/src/apps/request-diagnostics/machine.test.ts apps/web/src/apps/request-diagnostics/command.test.tsExpected: FAIL because
ClickedReloadis ignored while loading and the interrupt outcome Message does not exist.
Task 3: Implement the interruptible command flow
Files:
- Modify:
apps/web/src/apps/request-diagnostics/command.ts - Modify:
apps/web/src/apps/request-diagnostics/message.ts - Modify:
apps/web/src/apps/request-diagnostics/update.ts
Interfaces:
-
Consumes: FoldKit
Command.Interruptible.defineandFetchMetrics.Interrupt. -
Produces:
FetchMetrics()for metrics work andCompletedCancelFetchMetricsas the app-owned interrupt result fact. -
Step 1: Define
FetchMetricsas interruptibleRetain the existing HTTP effect and response decoding, but use the no-argument
Command.Interruptible.defineoverload so FoldKit uses the command name as the diagnostics key. -
Step 2: Add the completion Message
Add
CompletedCancelFetchMetricsto the message schema. It carriesCommand.Interruptible.Outcome, which is directly representable by Effect Schema. -
Step 3: Sequence reload through the completion Message
Change every
ClickedReloadstate-machine transition to returnFetchMetrics.Interrupt(CompletedCancelFetchMetrics)and add theCompletedCancelFetchMetricsupdate case returning[model, [FetchMetrics()]]. -
Step 4: Run the focused tests
Run:
Terminal window bun run --filter @opsydyn/web test -- apps/web/src/apps/request-diagnostics/machine.test.ts apps/web/src/apps/request-diagnostics/command.test.tsExpected: PASS.
Task 4: Verify the full workspace and document the shipped slice
Files:
- Modify:
ROADMAP.md
Interfaces:
-
Consumes: Working interruptible reload flow.
-
Produces: the P0 roadmap item marked complete with a short pointer to the retained sequencing rule.
-
Step 1: Mark P0 complete
Mark the cancellable request diagnostics item complete and retain the constraint that a replacement starts only from the interrupt outcome Message.
-
Step 2: Run all verification
Run:
Terminal window bun run checkbun typecheckbun run --filter '*' testbun run buildgit diff --checkExpected: all commands exit
0; pre-existing lint warnings may remain. -
Step 3: Commit the slice
Terminal window git add apps/web/src/apps/request-diagnostics/command.ts apps/web/src/apps/request-diagnostics/message.ts apps/web/src/apps/request-diagnostics/update.ts apps/web/src/apps/request-diagnostics/machine.test.ts apps/web/src/apps/request-diagnostics/command.test.ts ROADMAP.md docs/superpowers/plans/2026-07-18-interruptible-request-diagnostics.mdgit commit -m "feat: add interruptible diagnostics reload"