5.6 KiB
Context
The platform/run architecture already separates control registration, job lifecycle calls, durable log ingest, and artifact transfer into typed routes and protocol packages. Prior changes proved those channels individually, and the lifecycle proof showed that real plugin operations can route through platform-owned lifecycle APIs into run jobs.
This change hardens the cross-channel behavior. The important failure mode is not just malformed payloads; it is starvation under concurrent work. A large artifact or file transfer must not delay control heartbeat, job acknowledgement, job result delivery, or durable log spool upload. Likewise, retry queues must stay independently bounded so a blocked artifact transfer cannot consume the execution path needed for log ingest or job completion.
Goals / Non-Goals
Goals:
- Prove run-side scheduling keeps control heartbeat, job ack/result, log upload, and artifact/file transfer on independently bounded paths.
- Prove platform APIs validate and mutate state independently when log, artifact, job, and control requests interleave.
- Add focused tests that simulate slow or large artifact/file work while verifying timely heartbeat, job ack/result, and log acknowledgement.
- Document the channel priority and non-starvation invariants in run/platform protocol docs.
- Preserve the existing channel APIs unless implementation reveals a contract gap that must be made explicit in the spec.
Non-Goals:
- Do not add new plugin-facing transport or direct run access.
- Do not add a browser UI flow unless implementation discovers an existing platform_web surface incorrectly exposes channel details.
- Do not redesign storage backends, introduce external queues, or require distributed infrastructure.
- Do not change artifact/log/job payload semantics except where needed to enforce bounded isolation.
Decisions
-
Keep isolation proof local to run/platform packages before adding broader e2e tooling.
The current risk lives in queueing, retry, route handling, and worker scheduling. Package-level tests can deterministically simulate slow artifact uploads, retryable platform failures, and interleaved requests without relying on brittle timing from a full browser stack. A later browser acceptance suite can reuse this confidence without becoming the primary proof.
Alternative considered: start with a full local platform/run/browser smoke. That gives nice operator evidence but is weaker for starvation because browser timing is noisy and harder to make deterministic.
-
Treat control and job lifecycle calls as high-priority bounded work.
Heartbeats, job claim/ack/progress/result, and cancellation/reconcile calls remain small JSON payloads. They must never carry artifact chunks, file bodies, or large inline logs. Tests should assert that delayed artifact/file uploads cannot prevent these calls from completing.
Alternative considered: one shared retry worker for all run-to-platform calls. That is simpler, but a stuck artifact transfer could monopolize retries and delay lifecycle visibility.
-
Keep log ingest durable and independently retryable.
The log spool already persists batches until platform acknowledgement. This change should assert that log batch selection, upload, ack handling, and retry bookkeeping stay independent from artifact chunk retry queues and job result submission.
Alternative considered: merge log and artifact retry state because both are upload queues. That would blur priority boundaries and make it easier for large artifact payloads to starve small log acknowledgements.
-
Verify platform state isolation with interleaved service/API tests.
Platform tests should interleave control heartbeat, job ack/result, log batch ingest, and artifact transfer requests for the same run endpoint. Success means each route validates only its own contract, mutates only its own state, and preserves idempotency when requests are retried or reordered within valid channel rules.
Alternative considered: only test run-side clients. That would miss platform-side cross-route coupling, such as artifact completion accidentally blocking log acknowledgement state.
Risks / Trade-offs
- Timing-sensitive tests become flaky -> Use deterministic fakes, channels, contexts, and bounded wait helpers instead of wall-clock sleeps wherever possible.
- Hardening may reveal that current worker scheduling is too serial -> Introduce small, explicit channel executors or queue limits rather than broad worker rewrites.
- Additional docs can drift -> Keep docs close to
run/protocol/andplatform/protocol/route contracts, and update them in the same implementation task as tests. - Full starvation proof can become too broad -> Scope the first pass to platform/run package behavior and exact commands in
tasks.md; leave browser-wide automation to the later acceptance-suite queue item.
Migration Plan
- Add failing tests for platform and run channel isolation around existing APIs and queues.
- Adjust run scheduling, retry queues, or client sequencing only where tests prove coupling.
- Update protocol documentation with the enforced invariants.
- Run platform/run tests, structure check, and strict OpenSpec validation.
Rollback is straightforward because expected changes are test and scheduling hardening around existing APIs. If a scheduling change regresses behavior, revert that implementation while keeping the new tests as the contract for the corrected approach.
Open Questions
- None currently. The implementation should stay within
run/andplatform/unless a failing test proves a shared contract needs a spec update.