feat: execute durable standalone Jobs through Host-owned Internal Workers (T-708)
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# T-708 implementation and validation ledger
|
||||
|
||||
Base: clean detached assigned checkout `3c424fd17d1a5e8bb5542de2d0ad88f55338e0ea`,
|
||||
also the inspected `origin/develop`. T-704 was authoritative `done` with that
|
||||
integrated source. Created `work/T-708-standalone-jobs` without overwriting an
|
||||
existing branch or discarding changes. T-709's subjektiv consumer is separate.
|
||||
The concrete SQLite placement/schema ownership was recorded in
|
||||
[the design](../design/standalone-jobs.md) before implementation; it uses the
|
||||
existing `<state_dir>/<WorkerId>` directory layout, not a new `workers` subdirectory.
|
||||
|
||||
Three scoped implementation children supplied the common contract/Backend
|
||||
projection, Worker execution adapter, and local SQLite store. Parent inspected
|
||||
committed sessions, exact source changes and concrete test results, then integrated
|
||||
Host/service ownership, live-resource ceilings, deadline fencing, independent
|
||||
acknowledgement, shared outcome projection, process-loss tests and documentation.
|
||||
Independent published-MR review is separate from these implementation children.
|
||||
|
||||
## Implemented boundaries
|
||||
|
||||
- `job`: neutral immutable request/limits/result envelope, fingerprint, strict
|
||||
registry selectors, bounded digests and read-only intent/attempt/outcome DTOs.
|
||||
No HTTP, Workspace, Runtime identity, domain grants, runner or workflow DSL.
|
||||
- Backend reuses validation/result helpers and neutral projections while retaining
|
||||
its exact request wire/fingerprint/envelope, domain grants, persistent states,
|
||||
Runtime authorization, unknown fences, resource serialization and cleanup.
|
||||
- `worker::job`: selected registry Profile/instruction/model, explicit requirement
|
||||
rejection, bounded policy, distinct ephemeral Internal Worker, result-only
|
||||
FeatureModule and Host-fenced structured acceptance. No parent filesystem,
|
||||
Workspace, Feature or domain connections; no Profile-name authorization.
|
||||
Ambiguous sink acceptance is Unknown unless the Host's durable result proves success.
|
||||
- Standalone Host owns schema-1 SQLite intent/attempt/result/ack state and a bounded
|
||||
execution service. It opens and recovers under its Worker lease; shutdown cancels
|
||||
and awaits executions, closes SQLite, then releases the lease after controller
|
||||
confirmation. Old cloned handles are closed. Drop cannot attest cleanup and
|
||||
retains the lease. Busy/unknown/cancelled/terminal work is not blindly replayed.
|
||||
- Exact immutable request resend differs from explicit bounded new-attempt retry.
|
||||
Results commit before resource release, survive model/notification failure, and
|
||||
are independently acknowledged by the consumer. Waiting does not relinquish
|
||||
Host ownership of cancellation/concurrency. Cancelling unknown intent retains
|
||||
its uncertain attempt evidence and serialization fence.
|
||||
- Optional `builtin:job` is a caller-selected compatible policy, not a fixed runner
|
||||
default. Different user registry Profiles are demonstrated in Worker fixtures.
|
||||
Existing `builtin:backend-job` retains Backend behavior; standalone rejects its
|
||||
unavailable requirements rather than silently stripping or replacing them.
|
||||
- No production Server/Runtime process, HTTP/WS listener, Worker registry,
|
||||
subprocess Worker, daemon/pool or subjektiv-specific runner is added.
|
||||
|
||||
## Validation results
|
||||
|
||||
Development began with narrow contract/module targets before full changed-crate
|
||||
validation. Final root check covers the normal default-members TUI/Server closure.
|
||||
|
||||
| Command | Concrete result |
|
||||
| --- | --- |
|
||||
| `cargo test -p job` | 9 contract tests passed; no unit/doc tests |
|
||||
| `cargo test -p standalone --lib job_store` | 19 fixtures passed: transactional replay/conflict, all limits, result fences, retry/old-attempt preservation, cancellation, concurrency races, SQL rollback, schema rejection and reopen recovery |
|
||||
| `cargo test -p standalone --lib jobs::tests` | 2 passed: Host capability binding/deadline/replay and success/cancellation/closed-handle lifetime |
|
||||
| `cargo test -p standalone --test jobs process_loss_recovers_durable_jobs_without_replaying_unknown` | Actual test-owned process exit and Host stale-lease/SQLite recovery passed |
|
||||
| Final `cargo test -p standalone` | 25 library + 10 existing Host integration + 8 Job integration passed; 1 child-process fixture entry point marked ignored in parent harness, explicitly invoked with `--ignored` by the passing process-loss test |
|
||||
| `cargo test -p manifest` | All 185 tests passed, including new optional builtin Profile catalogue resolution; no resolver/runtime/schema implementation changed |
|
||||
| `cargo test -p worker` | All 826 library + 110 integration tests passed, including 11 new Job tests and 8 existing Internal Worker substrate tests |
|
||||
| `cargo test -p yoi-workspace-server --lib backend_job` | All 38 passed: neutral adapter/wire/fingerprint, T-704 Profiles/no fallback, structured fences, unknown/recovery, resource serialization and T-690 cleanup |
|
||||
| `cargo test -p yoi-workspace-server --bins` | All 11 binary tests passed |
|
||||
| `cargo test -p worker-runtime --lib backend_job` | All 3 Job binding/dispatch regressions passed |
|
||||
| `cargo test -p server-api --features typescript` | All 77 passed, including checked-in generated/OpenAPI/TypeScript freshness; existing ts-rs serde-attribute warnings |
|
||||
| Root `cargo check` | Passed after integration and again after final local adapter/tests changes |
|
||||
| `cargo fmt --all -- --check` / `git diff --check HEAD` | Passed |
|
||||
| `cargo test -p yoi-workspace-server` | **Failed: 643 passed, 1 failed** in library; see retained anomaly below. Binary tests were therefore run separately. This is not a green full Server suite. |
|
||||
| `cargo test -p yoi-workspace-server -- --test-threads=4` | **Failed: 643 passed, 1 failed**, same unchanged checker assertion; not claimed passed |
|
||||
|
||||
Profile fixtures use two different existing user registry entries with distinct
|
||||
instructions and budgets, plus optional `builtin:job`. They prove only
|
||||
`SubmitJobResult` is exposed, selected instructions/policy are retained, scopes and
|
||||
Backend/domain tools are absent, malformed/oversized/forged results are rejected,
|
||||
uncertain sink submission permits only identical replay, final prose is not
|
||||
success, provider failure/cancellation/turn limits do not manufacture success,
|
||||
and accepted results survive later provider failure.
|
||||
|
||||
Host Job integration additionally proves explicit known-model-failure retry,
|
||||
request replay, live concurrency while a consumer waits, cancellation, timeout,
|
||||
shutdown, pending resume, consumer acknowledgement and unsupported Profile
|
||||
rejection without model calls. Direct-store fixtures prove persisted facts and
|
||||
rollback/reopen behavior, not live model or process behavior.
|
||||
|
||||
### Actual process verification versus fixtures
|
||||
|
||||
`process_loss_recovers_durable_jobs_without_replaying_unknown` starts **only a
|
||||
test-owned copy of the integration test executable**, using scripted model clients.
|
||||
The child owns a real StandaloneHost/SQLite connection/Worker lease, persists a
|
||||
reserved request, a cancelled request and an accepted result, then exits with code
|
||||
23 while a separate Internal Worker is executing. It deliberately skips destructors
|
||||
and graceful shutdown. The parent verifies that exit and restores the Host through
|
||||
the real stale-process lease path: accepted result retained/unacknowledged,
|
||||
cancelled work never resumed, reserved work explicitly resumable and interrupted
|
||||
work Unknown/no automatic retry. The helper's ignored annotation is an entry-point
|
||||
selector, not skipped semantic coverage.
|
||||
|
||||
These are real Rust test/compiler processes plus scripted in-process model
|
||||
executions and SQLite fixtures. They are **not** live-provider LLM calls, a live
|
||||
standalone CLI/TUI session, a Backend/Runtime deployment or dogfood environment
|
||||
update. No operating Yoi Worker or live dogfood process was stopped or updated.
|
||||
Production Jobs do not create the subprocess used solely by that crash test.
|
||||
|
||||
## Retained failures and evidence limits
|
||||
|
||||
Initial integrated compilation exposed `get` snapshot/Option disagreement between
|
||||
concurrently authored store/service; signatures were aligned and the subsequent
|
||||
store/Host/full standalone runs passed. A private tool-type import during child
|
||||
integration was corrected before focused/full Worker validation. No passing
|
||||
result is attributed to those initial failing builds.
|
||||
|
||||
Both full Server runs and one isolated run of
|
||||
`server::tests::ticket_checker_suppresses_stale_and_clean_results_and_diagnoses_invalid_output`
|
||||
failed the unchanged post-stale-result `assert!(execution.take_inputs().is_empty())`
|
||||
at `server.rs:44748`. All 38 Job-filter tests pass, including unchanged Backend
|
||||
envelope/fingerprint compatibility and late-result/cleanup fences. The same
|
||||
checker assertion/race was independently reproduced on the earlier original base
|
||||
in the [T-702 ledger](2026-10-06-t702-stale-checker-validation.md), and explicitly
|
||||
retained as unfixed in the [T-704 ledger](2026-10-06-t704-validation.md).
|
||||
No new isolated build of this Ticket's exact base was run, and its root cause is
|
||||
not claimed proven or fixed here. The checker implementation/test was neither
|
||||
changed nor skipped to manufacture a green suite. This validation anomaly remains
|
||||
visible for Reviewer/Orchestrator attention.
|
||||
|
||||
No whole-workspace tests, E2E, Nix/Docker builds or live-provider validation were
|
||||
claimed. Backend generated contracts were regression checked despite no wire
|
||||
change. Result-only Jobs reject unsupported Feature/authority requirements;
|
||||
subjektiv consumer capabilities/postprocessing are T-709 work, not inferred grants.
|
||||
|
||||
Publication must use only the clean committed Ticket work branch by normal
|
||||
non-force push, verified with exact provider source ref. No target/tags/unrelated
|
||||
refs, replacement MR, integration branch, merge or Ticket completion is performed
|
||||
by this Coder. Final immutable source/MR/review identities belong in the MR thread
|
||||
and approved Ticket handoff rather than being guessed in this ledger.
|
||||
Reference in New Issue
Block a user