Local provider-core: reusable provider runtime, with U/A acceptance criteria
Dated design and evidence record. Selected design and evidence quotations retain their source line anchors and historical identities; use the current guides for operation.
Record sections
- Current completion audit, 2026-10-23
- Phase requirements and existing evidence
- Scientific and receiving-evidence limits
- Reusable-consumer requirements and supported limits
- Packaging priority and installation defaults, 2026-10-20
- Cross-repository usability workshop, 2026-10-20
- What belongs where
- Public consumer shape
- Gaps to close before claiming peer readiness
- Tests first and replacement order
- Precise sources and rationale
- Prepared-input identity follow-up, 2026-10-19
- Decision and scope
- Evidence and rationale
- Finished ownership and enforceable invariants
- Package and composition
- Layout workshop, 2026-10-18
- Test-first implementation sequence (requires review first)
- Concrete integration acceptance contracts
- U/A conformance ledger: owner and required witness
- Resilience audit, 2026-10-22
- Implementation order after the resilience audit
- Review and completion of planning
- Peer-consumer workshop, 2026-10-18
- Planning audit completed, 2026-10-18
- Implementation: first installed input slice, 2026-10-18
- Dependency tooling slice, 2026-10-18
- Runtime dependency closure and installed lane, 2026-10-18
- Exact signing slice, 2026-10-18
- Bounded async transport slice, 2026-10-18
- TLS ownership correction, 2026-10-18
- Signed Job-input operation slice, 2026-10-18
- Upload membership and grant API slice, 2026-10-18
- Job-scoped acquisition and shared budgets, 2026-10-18
- 2026-10-18 P3 first boundary: read Attempt and Job lifecycle observations
- 2026-10-18 P3 start protocol: exact retained requests and uncertain admission
- 2026-10-18 P3 progress protocol: current observations, not execution authority
- 2026-10-18 P3 terminal wire boundary: retain and reconcile the chosen outcome
- 2026-10-18 P3 pending-start records and explicit recovery scope
- 2026-10-18 P3 owned pending-start storage
- 2026-10-18 P3 acknowledgement and durable execution entry
- 2026-10-18 P3 immutable terminal records and required evidence
- P3 publication slice (2026-10-18)
- P3 durable start slice (2026-10-18)
- P3/P4 scientific preparation boundary (2026-10-18)
- P3 execution orchestration boundary (2026-10-18)
- P3 observation during preparation and execution (2026-10-18)
- P3 retained-request recovery and inventory ownership (2026-10-18)
- P4 first scientific worker transport (2026-10-18)
- P4 released-model worker composition (2026-10-18)
- P4 exact-container retirement primitive (2026-10-18)
- P4 live host-retirement qualification (2026-10-18)
- P4 worker-observed scientific provenance (2026-10-18)
- P4 one-geometry scientific result contract (2026-10-18)
- Host retirement adapter -- contained controller connection
- Warning evidence correction -- no implicit scientific veto
- Direct-coordinate session -- core lifecycle composition
- Real scientific worker through the core lifecycle (resumed)
- Crash-durable returned evidence after interrupted acceptance
- Sibling adoption inspection: actual adaptation requirements
- Signed Job discovery -- authenticated input identity source
- Individual U/A audit of Job discovery (base b531dfa)
- Final discovery validation and review closure
- Signed in-progress Attempt inventory (after 8630d8a)
- Individual U/A audit of Attempt inventory (base 8630d8a)
- Inventory validation and review closure
- Stop observation during execution-entry persistence (after 8d2c9f5)
- Individual U/A audit of entry persistence (base 8d2c9f5)
- Entry-persistence validation and review closure
- Magnet outcome-seam adaptation fixture (after fca04e3)
- Individual U/A audit of Magnet outcome adaptation (base fca04e3)
- Magnet adaptation validation and review closure
- P5 scripted child-retirement boundary (2026-10-18)
- Individual U/A reviews of child-retirement slice (base f6ebe8f)
- P5 explicit Job-state execution policy (2026-10-18)
- Individual U/A review of execution-policy slice (base 7cfdc34)
- Next runtime slice: one selected Attempt controller
- Controller implementation and first qualification (base e3eafee)
- Controller slice review closure
- R3 source-grounded file-acquisition design checkpoint, 2026-10-22
- Awaited condition reporting qualified, 2026-10-22
- Raw streamed HTTPS file output qualified, 2026-10-22
- Verified Upload file acquisition qualified, 2026-10-22
- Immutable Upload file consumption boundary qualified, 2026-10-22
- SECS direct/ZIP receiving contract on immutable Upload bytes, 2026-10-22
- Acquired-source lifetime through a real scripted child, 2026-10-22
- Pinned API release content, signing and eleven-route contracts, 2026-10-22
- Reusable protected core failure projections, 2026-10-22
- Next U27 resource slice: confirmed-history ownership contract (planned, not implemented)
- 2026-10-22 confirmed-history storage implementation (service wiring follows)
- 2026-10-22 connected service confirmed-history renewal
- Next native renewal slice: host request-consumption protocol (plan before coding)
- 2026-10-22 host-only native-consumption implementation
- Next client slice: explicit adopted-channel retirement
- 2026-10-22 connected adopted-channel consumption
- 2026-10-22 installed image and one native capacity witness
- OOM strategy discussion and applicability
- 2026-10-22 unresolved inventory takes priority over slot-limit advice
- 2026-10-22 next recovery slices: exact START, then progress separately
- Controller START slice qualified
- Production START recovery binding qualified
- Next: elapsed input-selection limits without losing operational evidence
- Final interpreter diagnostic prerequisite qualified
- Installed recovery image checkpoint
- 2026-10-22 owned input-selection time limit and successive Jobs
- Next: phase-progress delivery resilience, before optional combined native proof
- Progress evidence predicate qualified before executor wiring
- Core phase-only continuation qualified before production binding
- Production phase-delivery continuation and recipients qualified
- Installed service-resilience checkpoint
- Condition-report recovery: settled design before implementation
- Condition API permission qualified
- Core bounded condition recovery qualified; production follows
- Production condition recovery and receiving proof
- Installed condition-recovery checkpoint
- Porting bounded native prediction recovery (2026-10-23)
- Bounded prediction recovery connected
- Real kernel OOM and installed recovery checkpoint
- 2026-10-23 native history release: source-grounded proposal, not implementation
- Existing cutpoints and owners
- What remains necessary
- Smallest proposed change
- Adjudicated bounded native end state: one existing host generation and sequence
- Confirmed Attempt retention: lifecycle obligation versus evidence policy
- Native sequence implementation, 2026-10-23
- Awaited native history release, 2026-10-23
- Confirmed evidence window and shutdown batch, 2026-10-23
- Focused launcher-check follow-through
- Installed bounded-storage checkpoint
Local provider-core: reusable provider runtime, with U/A acceptance criteria Date: 2026-10-18 Status, audited 2026-10-23: 003's scoped local/API/real-interpreter qualification complete; broader reusable-consumer limits remain explicit Current completion audit, 2026-10-23 ==================================== Current actual API caller/source:154be58af09a0d87bca566464ce6250d477ced8c; real ambiguity/format probe sourcee211390fbf1bc18d5f106f46b871f77d8008bc9a; shell-only diagnostic correction087a090. Current qualified controller image: sha256:e0c953f63a1c3ad51250aff8c5e03b40876053d6684b39beefb0e67f0a357330. 003 R52 records its build/installed proof; R53 records actual API delivery and R54 records the seven newly authorized real-interpreter cases and final handoff. This entry updates current status without recertifying earlier runs. The dated entries below retain their source identities, results and limits. The full provider-core goal retains its broader consumer-contract requirements; 003's qualified local/API scope does not imply another production integration. One full-dependency distribution remains the installation choice. Phase requirements and existing evidence ---------------------------------------- P0: concrete owners now exist for the NMRNet session, controller, transport, scoped store, exact terminal recovery and host retirement. analysis.py's AnalysisSession/PreparedAnalysis contracts and controller.py/execution.py preserve preparation, durable execution entry, science and retirement as separate operations. Peer-specific policies and recipient witnesses remain. P1: tools/provider_core_tests.py builds and installs one wheel with the locked full dependency closure, runs pip check and executes outside the checkout. tests/run_suite.py checks installed origin; contract/test_installation.py checks exact wheel contents, forbidden imports and the container marker. Python>=3.12 and the full pinned dependency closure are requirements, stated directly in packages/provider-core/README.md and requirements/provider-core.md. The maintained runtime is Python3.12.12 on Linux x86-64. Other environments are unqualified; no runtime migration or wider support is authorized here. P2: signing, bounded TLS, strict Job input, Upload membership/grant/digest checks and socket retirement have installed tests with finite local TLS peers. ProviderAPI now implements Hello, configured topology and safe request-ID correlation (api.py::publish_hello, _require_api_envelope and ApiFailure). This supersedes R2's earlier missing-feature observation. Selected release content/vector/route contracts are now qualified at37cf6a1 below. Actual peer worker integration and broader consumer/deployment compatibility remain open. P3: Starter, Executor, Publisher, AttemptStore, AttemptClaims and AttemptRecovery own durable effects and exact replay. 003 R36 records successive configured Jobs, lost completion acknowledgement, store reopen, explicit byte-identical recovery and a third Job with no repeated interpretation or science; its scientific ports are recording fixtures. R39 adds installed stopped inspection, one exact COMPLETE replay and ordinary idle restart through local TLS. It supplied no Job, model request or new science. R40 joins production stopped inspection/recovery operations to service-produced outcomes before a third Job, still with recording science; its exact evidence is in003. These owner/composition proofs are reused within003's current recorded limits; no full fault/route/model cross-product is an additional gate. P4: NMRNet interpretation/preparation/inference is connected to the core owners. process_reports.py and test_nmrnet_reports.py exercise nested owned causes, redaction and failed reporting. Note019 records the current both-stream Docker/journald path: bdc2487 removed ordinary stderr/report file dumps. Older dated file-sink evidence below describes those historical runs. The service tests deliver attributed model-input guidance through the signed failure API. 003 R44 now qualifies actual local-GUI rendering/exact download of four existing API results (pasted, SMILES N1/N3, XYZ Upload), without new Jobs or science. The dev GUI reports no source commit. R53 adds one actual API SDF ZIP Upload/Job with two native records/eight exact C shifts. The user removed browser submission as a provider qualification requirement; R54 now observes the remaining ambiguity/format decisions independently of GUI readback, using authored metadata without new Jobs or scientific work. P5: installed test bindings exercise direct/ZIP source acquisition, immutable snapshots, an awaited preparation/prediction split and a binding-only future result field. These are separate bounded test seams, not production consumer integrations. The real-child retirement fixture proves exact child stop at the core seam. These do not qualify another production scientific reader, supervisor, process tree, warm reuse or deployment. Required integration contracts remain documented; no external repository changes are authorized. Scientific and receiving-evidence limits ---------------------------------------- 003 R13b retains the four-reference population: 137 outputs (82 H/55 C), with 64 historical positions (42 H/22 C), ATOL=RTOL=0. R15b separately retains connected 128-atom capacity: all 128 H and 128 C indices and finite predictions, plus actual resource observations. Their exact source/result/manifest receipts remain in 003 R13b/R15b; reuse them only where scientific code, inputs, artifacts, runtime and enforced limits remain applicable. No denominator or tolerance is reduced. 003 R37 retains native results for nine supplied-format cases, 15 geometries and 54 ordered H/C rows. Its contained receipt review establishes case-level joins and exact retirement; both original host targets still exited 2. Scripted model choices do not qualify real-model format interpretation. R38 supplies the stopped recovery implementation and offline ambiguity-probe mechanics; R39 completes the bounded installed operator sequence described above. Their capsules and exact hashes remain in 003, with the original failures and proof limits preserved. Actual API/live-interpreter evidence also exists: 003 R24 covers pasted input, R25 SMILES N1, R28 an inspected XYZ Upload, and R32 SMILES N3. Pasted/Upload predictions match the pinned oracle; generated N1/N3 retain observed provenance without an independent numerical reference. R28's original overall target failed. R53 now adds real selection of two carbon-only SDF records inside a ZIP, using the original Upload after storage-owner-confirmed absence and renewed capability. The one API Job succeeded, both geometries/eight C predictions match R46 exactly, and all native/host work retired. Its first502, recovery, request/result/terminal identities, hashes and preservation capsule are recorded in003 R53. These bounded results alone did not establish ambiguity/MOL/PDB/MOL2 decisions. The user then authorized both probes: R54 observes4/4 ambiguity and3/3 format choices passed against the selected real endpoint, zero corrections, with all helpers retired. Those use authored metadata and establish no additional parser/scientific/API execution or universal interpretation guarantee. Browser submission is not an additional gate under the user's correction. 018 records later receiving repairs at precise commits: - af632819b75c4732a8de18843b5f84f3211d4000 retains corrected ToolRejected objects, earlier endpoint failures and bounded private parser evidence before preparation and through result evidence; public interpretation exposes correction counts. - bdd95d2e1b7ca5b65d7691942c25ab5045ec2372 adds bounded received-result metadata and preparation-diagnostic projections when evidence admission fails. Full raw payloads remain only in memory; the projection grants no salvage or replay. - 2a2f7a9a92f24761e265015352eb3190cef28ec3 repairs stale API-envelope/grant test fixtures without changing production expiry or effect rules. - f096e7cdd775adcdf45faa1a184af9c85db95a5c repairs test-input grants and preserves inspection-only correction evidence without scientific preparation authority. 018 records focused contained results and their receiving-test references for these changes. The aggregate then passed 375 tests with 11 native-runtime gates skipped. It did not execute those native witnesses. After the final helper-grant narrowing, aggregate argv was unchanged; the aggregate was not rerun. Eight launcher tests and nine dedicated inspection-probe tests passed. These repairs neither rebuilt/qualified a production image nor repeated live model/API or native science at that time. Later image and actual-API evidence is recorded in003 R52/R53. Reusable-consumer requirements and supported limits -------------------------------------------------- R1: Python>=3.12, cryptography50.0.0 and the full default installation are the supported requirements, not an unfinished compatibility migration. Installed distribution checks are recorded under P1 and in the image-refresh entry below. Do not widen metadata or downgrade dependencies to admit an unqualified runtime. R2's Hello/topology/correlation code now exists, as recorded above. Qualification of the pinned release content, its two signing vectors and selected consumed rules for all11 provider routes is recorded at37cf6a1 below. This is not complete schema, recovery-policy or live-deployment compatibility; those require evidence from the actual intended integration before a broader replacement claim. R3 remains open: immutable-byte acquisition and verified-file acquisition now share admission, grants and budgets. The raw transport port is qualified at 3cd984387cdde1889d16c24f022241cf91592a71; the private-file acquisition owner at b4b73e70d4e5e9f0733dcabdbd875393a0940218. See their dated entries below. The immutable file-snapshot primitive is qualified at 4848a4f2bfb42e11d7a8e9e38b1f8c93efb92062; see the dated entry below. The source-grounded direct/ZIP receiving fixture is qualified at8576bfb; see the dated entry below. A production scientific reader/supervisor and its advertised capacity still require their own integration evidence. NMRNet's actual native readers are now composed through R37/R46/R53; these do not qualify an additional production consumer merely because it uses this core. 7a98fff joins acquisition and an installed-core snapshot read in an actual scripted child to core cancellation/retirement and source cleanup, as recorded below. It does not qualify a production scientific supervisor or reader. R4: awaited phase-bound conditions, admission/discovery GET recovery, current Hello recovery and finite-gap active Attempt observation are implemented and locally qualified in the dated U27 entries below. Production supplies bounded exact START/ terminal recovery and protected phase-delivery continuation. Fixed phase labels may remain unconfirmed only after original retirement and before a fresh allowed observation; condition reports still require matching acknowledgement. Bounded condition recovery is implemented and locally qualified in core and production wiring, including an actual foreground receiving proof. Owned input-call/selection-time limits can fail one Job after confirmed retirement and permit later Jobs; operational/cleanup failures remain service failures. These contracts authorize no scientific retries or warm reuse. Separately authorized bounded native prediction recovery is documented in the final 2026-10-23 port entries below; it does not extend lifecycle replay or introduce warm worker reuse. R5: scoped stores/shared claims and read-only terminal reconciliation are implemented; the latter is locally qualified atac70b82/2343e63 below, separately from TerminalHeld and matching receipts. The service archives exact confirmed bytes before releasing active slots, only from a clean confirmed inventory; unresolved obligations block admission. Adopted native channels renew host capacity only after confirmed retirement/consumption, preserving original request/worker evidence. 003 R52 supersedes unlimited retained-history wording: required positive confirmed_history_records bounds confirmed terminal history; expiry follows clean archival and exact native history-release ACK. The exclusive native host lifetime uses a monotonic sequence/frontier; retired archives are removed only after the service archives its whole clean inventory. Partial/unknown/unconfirmed effects still block new admission. R53 observed release through frontier3 after one actual API Job, with empty native history and a retained confirmed terminal record. Physical disk remains finite: reserve checks do not reserve blocks against other writers or cover a separate native filesystem. Logical count bounds are not a filesystem quota or a fsynced native power-loss guarantee. Preserve useful evidence separately before configured expiry; R53 records that compact capsule. Simultaneous independent production lanes and nonempty journal cutover remain unqualified. Read-only terminal observations stay unresolved without matching receipts. R6: shared core-owned facts/causes are projected by provider_core.failure_projection atb8c3cfe below; NMRNet retains its one graph, redaction, bounds and scientific/recipient policy in process_reports.py. Protected execution reports now include the acknowledged Job/Attempt references; pre-start native setup reports include the selected Job only. Exact producer and receiving evidence is recorded at4d392fa/7c9019e below. Note019 supersedes those historical file sinks: both process streams, tracebacks and scientific failure notes go to bounded Docker journald. Ordinary failure.json, stderr dumps and normal-process shutdown-summary files are removed; functional lifecycle/science receipts remain separately owned. Journal retention/access belongs to the host; its nonblocking buffer may drop output and messages can expire. Logs confer no execution, retirement or publication authority. There is no parallel diagnostic journal/file fallback or required new post-replay lookup API. Actual recipients still receive their owned signed-API failure/result surface; R44 and R53 record their respective GUI-readback and API-result observations. Production awaited-condition recovery now retains its matching-receipt gate through temporary API outages. The earlier scoped diagnostic-history proposal is superseded by the user's current bounded-Docker-logs decision, not an outstanding package gate. Retained lifecycle evidence keeps its separate recovery authority; no second diagnostic journal or general retry framework is required. The condition-reporting slice has reached contained qualification: core retains serialized API effects and phase ordering, and the binding awaits its phase-bound callable. Repository-check follow-through is qualified at83459e9 below. Unsupported consumer policies remain explicit limits, not permission to infer readiness or introduce a new retry/lifetime framework. 003's real-model multi-geometry SDF Upload/API result is observed inR53, with reproducible source/scientific/result joins and exact retirement. Its remaining product observations were then authorized and passed inR54:4/4 selected-model ambiguity decisions and3/3 MOL/PDB/MOL2 choices. They reuse existing native/ scientific evidence rather than require another full matrix. R53/R54 preserve their compact outcomes/receipts and observed provider-description guide link; 003 is complete within its recorded local scope. The user explicitly removed browser submission from this provider qualification. Broader reusable consumer requirements stay explicit, without assuming sibling changes or integration. Current installed controller identity is e0c953f63a1c3ad51250aff8c5e03b40876053d6684b39beefb0e67f0a357330, qualified by003 R52's four installed-runtime checks and fresh required-retention staging. R53 then observed actual signed API/result delivery with the real chosen interpreter and released native model. The shell-only087a090 diagnostic fix has a separate focused proof; no new model or scientific rerun was needed. This supports the recorded local workflow, not remote/HA deployment, independent accuracy or unobserved semantic decisions. This current summary supersedes stale next-step language in dated workshops; original proposals/results stay historical. Packaging priority and installation defaults, 2026-10-20 ====================================================== Decision: retain one provider-core distribution with its full runtime dependencies. The user's final direction, "Full dep, keep it simple", closes the earlier minimal installation proposal. No minimal group, API-extra split or separate lightweight distribution is planned. Existing dependency metadata already provides the chosen behavior and is unchanged. Continue qualifying the full installed package outside the checkout, including import origins and dependency consistency. Historical feasibility research for the abandoned option, checked 2026-10-20: ordinary extras add dependencies; they cannot subtract project.dependencies. PEP 771 proposes default extras and minimal installs, but remains Draft. Reference and rationale: https://peps.python.org/pep-0771/ (Status, Abstract, Specification). Independent source review confirms the current distinction: https://packaging.python.org/en/latest/specifications/pyproject-toml/#dependencies https://packaging.python.org/en/latest/specifications/dependency-groups/#package-building The first defines runtime/extra requirements; the second excludes dependency groups from distribution metadata. uv's documented local default-groups setting (https://docs.astral.sh/uv/concepts/dependencies/#default-groups) controls its project environment, not the mandatory requirements of an installed wheel. Rationale for retaining the existing full installation: it already works with the pinned toolchain and needs no additional distribution or installation mode. The references above preserve why the minimal option was investigated and dropped; they do not establish a pending packaging task. Cross-repository usability workshop, 2026-10-20 ============================================= Decision: keep one local distribution, provider-core, with consumer-owned model bindings. Reusability means replacing an existing owner without losing its useful behavior, not importing a fourth copy or making every provider behave like NMRNet. This section revises the active adoption plan. The 2026-10-18 workshop below is historical evidence. No sibling migration, runtime upgrade or deployment is authorized or claimed by this documentation workshop. Three independent read-only reviewers inspected actual SECS, Magnet and NMRPeak code, one repository each. The coordinator checked the disputed boundaries against core and sibling source. All three sibling worktrees were clean. Exact snapshots: C nmrnet-repro ef2637f4681fbd5267f7544842e5841214826728 M magnet-deploy 600968a5fad8ad0118ea4f42cd7fc1fbfde54aaf S secs-repro 7356c354368f2355d3ab5cef00cf48c67cea9c2c P nmrpeak-repro 1697dc84dd1d76ae25b04efc8183fd80614000e5 These aliases are local to this dated section; they do not silently update the older source aliases below. Source inspection proves design constraints, not installation, cancellation, native retirement or scientific compatibility. What belongs where ------------------ Core owns API signing/wire admission, verified Job input, authenticated Upload acquisition, Attempt records/effects/reconciliation and common chat exchange. Shared diagnostic rendering and conversation bookkeeping are justified next candidates: retain safe causes, effect state, budgets and cleanup observations without importing a provider's scientific vocabulary or publication policy. Bindings own prompts/tools, interpretation decisions, scientific validation, prepared worker capabilities, model execution and result meaning. Model-reported input problems are attributed claims. NMRNet's terminal-report precedence does not become a universal core policy: NMRPeak deliberately permits another endpoint to produce an independently admitted candidate. No generic tool registry, universal worker protocol, model-input schema or exception-to-user-error rule is proposed. Composition owns endpoint/configuration loading, offering/readiness policy, scheduling, lane stores, provider-wide claims, native supervision and grants. Core should issue a Hello operation through the adopted API client; composition still decides its content, availability transitions, refresh and retry pacing. Core receives confirmed stop/quiescence observations, never engine authority. Further extraction candidates need evidence. The verified Job span selection in C:nmrnet_provider/submission.py:28-41 is generic in shape, but current peer inputs do not require that operation; keep it local until a real second consumer needs it. Likewise, NativeDiagnostic's bounded capture can be shared when used by an installed worker consumer, while RDKit labels/messages remain scientific. Moving these small helpers alone would not establish cross-repository usability. Public consumer shape --------------------- Use documented owner modules, with no startup in provider_core.__init__: - job_input: FeedInputFacts and VerifiedJobInput; original bytes remain exact. - signing/transport/api: explicit identity, TLS, bounded I/O and API operations. - uploads: one Job-scoped acquisition owner and explicitly granted storage. - analysis: AnalysisSession.prepare/execute/retire and the session-owned PreparedAnalysis carrying required opaque prepared identity. - controller/ownership/attempt_store/publication/recovery: one selected lifecycle and one retained obligation, with shared claims across independent execution lanes. - chat: one bounded Chat Completions exchange; conversation/tool policy remains explicit at the consumer boundary. The async decision stands. Do not add a synchronous lifecycle twin, nested asyncio.run, blanket to_thread adapters or automatic callable introspection. Pure verifier/codec leaf adoption may remain synchronous. Real blocking workers need owned asynchronous channels and confirmed cancellation/retirement paths. Keep prepared handles local and identity-checked; persisted identity cannot reconstruct a live handle or authorize scientific replay. Gaps to close before claiming peer readiness ------------------------------------------ R1. Installed compatibility, not matching package names. M/P use Python 3.11 and cryptography 49.0.0; C requires Python >=3.12 and cryptography 50.0.0. S advertises >=3.11,<3.13 and locks cryptography 49.0.0. These installations cannot be assumed compatible. Qualify the full dependency closure even for leaf use such as the Job verifier. The installation decision above abandons the earlier stdlib-base/API-extra proposal; compatibility qualification remains required. Qualify Python 3.11 as well as 3.12 before widening interpreter support. Preserve the reason for cryptography 50: requirements/provider-core.md:23-35 records the 2026-10-18 advisory review, selected Ed25519 scope and rejection of an unnecessary affected 49 dependency. Functional compatibility does not justify downgrading or widening that security choice. Review current exact- version advisories before a later dependency change; full API adoption needs an explicitly reconciled peer dependency lock, not two contradictory pins. Consumer locks still select exact complete closures. Do not silently upgrade sibling runtimes or relax metadata to make pip accept an untested combination. Install an exact wheel and record its hash/source revision; 0.1.0 alone does not identify bytes. Tests must run outside both checkouts, assert import origins and pip check, and require the package's own container marker. R2. Complete the common API boundary before replacing transport. At workshop snapshot C, Hello and configured Nmr-Api-Topology admission were missing. The 2026-10-22 audit above records their later implementation; peer release/vector qualification remains open. Keep HttpTransport protocol-neutral and those operations at ProviderAPI. Preserve safe X-Request-ID correlation even if body admission fails. Keep signing, endpoint authority, topology and protocol release identity distinct. P consumes release sha256:719055db7751605c0e5325ca23bcbe66cde631376d4b2b99523c8e4db75f0d01, source 12a53e720fc87e1a4144c76203f8853d5afaf753; C cites API 6a163b7a9cc1e2c7485b681c0b2b969c7c20e6c8. The coordinator found no diff in provider routes, live provider schemas, signing profile, security problem definitions or outcome service between those two API revisions. This limited comparison is useful evidence, not authentication of the released artifact inventory or all consumed rules. Qualify the pinned release/vector boundary. Keep core's strict six-field Job envelope/canonical Base64 checks. SECS's existing tolerance for a conflicting copied schema field is not a reason for a lax compatibility parser; record this deliberate stronger admission. R3. Share acquisition without forcing large Uploads into memory. Core UploadLimits can express S's 128 MiB/source and 256 MiB/Attempt limits; the problem is buffering, not a hard-coded small data ceiling. Extend the one acquisition owner with an explicitly granted verified-file destination. Verify/hash while consuming, account failed bytes, and expose no completed file before whole-transfer verification and required I/O settlement. Define whether cancellation leaves an incomplete private file and who removes it. Bind the worker's later consumption to those same verified bytes. A verified pathname alone is insufficient: use an owned immutable/read-only object or verify the opened object and consume it without reopening a substitute path. Test pathname/symlink substitution and in-place mutation between acquisition and consumption; the worker must consume the frozen bytes or refuse them. Keep the small immutable-byte result for NMRNet. Do not introduce a second downloader/cache/budget. Worker source-file lifetime, ZIP-member traversal, decompression limits and scientific parsing remain binding/composition-owned. R4. Preserve lifecycle policy without weakening effects or stop evidence. Core currently stops on any observation failure; M/S tolerate bounded outages during already-running work. Specify an explicit observation-gap/deadline policy after structured failure classification. Initial admission, mutations, malformed replies, rejected authority and actual cancellation are separate; an unknown state must never authorize fresh scientific dispatch or replay. Add a narrow awaited condition-reporting port for sessions: core still owns phase ordering and serialized API effects. A binding must not acquire a raw API client, mutate phases independently or bypass durable entry before scientific dispatch. This preserves core's existing progress-acknowledgement, entry-persistence and fresh-observation order. No unbounded event queue. Retry-safe unavailable preparation remains distinct from input failure. S currently marks execution before its worker can reject input and return to interpretation. Split real worker admission from retrieval/GA first. M E01/E02 can report runner_admission_changed after generation dispatch as a positive no-computation/refusal claim. The existing Magnet fixture does not cover it. Do not reset EXECUTION_ENTERED, infer retry safety from an exception or publish bad-input failure. Qualify an exact-input bounded live retry only if the runner contract proves no scientific effect and the same frozen input remains applicable; if re-interpretation/new prepared identity is needed, adoption stays blocked pending an explicit behavioral decision. Restart after uncertain dispatch remains observe/reconcile only. G01 is the first M lane. Healthy warm reuse needs confirmed quiescence/per-Attempt release; interrupted work needs confirmation from its actual supervisor. A closed socket or sent RETIRE is not that confirmation. Do not impose NMRNet container shutdown on every peer, and do not relabel the existing peer close method as confirmed process exit. Their distinct worker protocols remain local unless a separate shared component has a real installed consumer and preserves the protocol. R5. Reconcile existing obligations and independent lanes honestly. P HF/CHF cannot share one current core store/controller inventory unchanged: a nonterminal record blocks fresh core work and overlapping store calls are refused. Start with separate lane-scoped stores and one provider-wide claim registry, coordinating the complete startup inventory before lane admission. Keep discovery pacing, readiness and shutdown policy in composition. S's durable terminal_reconciling/read-only obligation requires the distinct TerminalReadRequired/TerminalStateObserved/TerminalReadNotVisible records, implemented and locally qualified atac70b82/2343e63 below. Preserve that obligation through the actual binding/restart; never restore permission to resend, replace terminal bytes or rerun science. Core qualification does not establish that the SECS lifecycle has moved to this owner. An Attempt-state read does not prove acceptance of the exact retained terminal command; keep matching outcome receipts and state observations distinct when deciding whether any obligation is discharged. Default journal cutover is drain under the old owner, stop/exclude it, retain historical evidence separately and admit an empty new scoped store. Refuse nonempty cutover. A necessary offline conversion must preserve exact request bytes, scope/generation, uncertainty and outstanding obligations, and refuse missing facts; P's old records lack some core acknowledgement facts. Do not fabricate them. Keep old binding resources, not old competing lifecycle owners. Define confirmed-record retention/capacity; do not copy S's journal clearing into core implicitly. Qualify complete scientific failure evidence against core's 262144-byte limit; never truncate an existing report to fit. R6. Maximum safe error information through the recipient's real channel. Core failures retain .cause/.primary/.cleanup_failures/.api_failure in addition to Python chains. P's and S's existing formatters would lose that evidence. Provide explicit projections for core-owned failures, keeping operation, phase, effect certainty, earlier failures and cleanup observations. Share credential redaction before display bounds, bounded traversal, cycle handling and explicit omission. Do not enumerate arbitrary object attributes, dump raw responses, or claim regex redaction identifies all private science. Provider event vocabularies and approved scientific explanations stay local. Extend the existing core store's serialized durable I/O with bounded, Attempt/generation-bound diagnostic history, independently retained after a replay obligation retires. Give this history explicit capacity, retention and lookup rules; it must not participate as another replay/claim authority. Preserve pre-execution interpreter-unavailable route evidence and useful post-retirement lookup. Do not keep the old lifecycle journal merely for its diagnostic methods or rely only on evidence written at execution/termination. Test developer and operator diagnostics, commissioner Attempt messages and receiver result notices separately. A stderr test is not recipient proof. Type-only errors are insufficient; raw exception text is not automatically public. Persistence/cleanup errors must preserve the primary diagnostic. Failure to persist required evidence blocks the dependent scientific or publication effect, retaining both the original and storage failure. Tests first and replacement order --------------------------------- Use focused contained targets and U26's normative/adversarial split, integration tests for real connections, contract tests for installation/wire compatibility, and scenarios for lost replies/restart. No empty Cartesian suite scaffolding. Each extraction needs a real deletion witness: the replaced analogue disappears from its selected consumer path; no old/new fallback, second signer, second downloader or journal authority is left behind. Actual sibling edits remain a separately authorized cutover; local source-grounded fixtures are not that cutover. 1. Qualify R1's controller installations; reject unsupported runtimes and mixed package origins. R2's whole-API replacement separately requires envelope/Hello/ correlation tests: wrong/missing/duplicate topology, malformed response with valid correlation and protocol drift must fail at their owning boundary. Prove installation with the full runtime dependency closure under each supported, exact locked controller environment. 2. Prove useful leaf adoption: actual SECS Job read -> installed core verifier -> unchanged instruction bytes -> existing interpreter boundary. Substitution rejects before interpretation. This leaf may retain SECS's existing single signed transport and replace only its verifier; unrelated Hello/transport work is not a prerequisite. Delete the local verifier rather than keeping fallback. For chat, keep one POST after ambiguous delivery, explicit retirement, original reasoning/tool IDs, correction context and consumer-owned endpoint/report precedence. Do not reproduce unsafe retries merely because an older adapter attempted them. 3. Add R6's core failure projections alongside 003's actual input interpreter; shared conversation mechanics must support NMRNet's multiple tools and the peer's existing report/fallback policies without changing core for chemistry. A next tool/result field changes only the binding. New budget/repair/fallback choices cannot reset elapsed work or replay a completed tool effect. Persist pre-execution unavailability, then retire the replay obligation and prove scoped diagnostic lookup still works. Exercise nested primary/cleanup causes, credential-prefix canaries, multibyte bounds and evidence-write failure through the actual consumer formatter and public result/Attempt projections. 4. Complete R2 before replacing a whole API client. Prove G01's real prepare/ predict split with its actual contracts and a controlled backend. Prove P with both installed distributions and simultaneous HF/CHF; no nested event loop or blocking runner call on the control loop. Prove S with streamed verified files and worker-side preparation before one scientific run. Include outage/recovery policy, condition messages, rejected preparation, cancellation with real stop confirmation and a lost terminal acknowledgement followed by processor-free exact replay. E01/E02 follow their R4 decision. 5. Only then cut over a peer's selected owners and remove their analogues, with explicit old-journal disposition and source/wheel/lock/runtime receipts. Numerical model qualification, workload capacity and deployed API/GUI proof remain distinct exits. No broad/costly suite is part of routine plan review. Precise sources and rationale ---------------------------- Primary peer source entrypoints: https://github.com/numpde/magnet-deploy/blob/600968a5fad8ad0118ea4f42cd7fc1fbfde54aaf/models/g_01_nmr_forward/provider/magnet_provider_bindings/g_01_nmr_forward/processor.py https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/analysis_run.py https://github.com/numpde/nmrpeak-repro/blob/1697dc84dd1d76ae25b04efc8183fd80614000e5/nmrpeak_provider/attempt_lifecycle.py For each repository alias above use https://github.com/numpde/REPO/blob/REV/PATH; the following exact revision/path/line anchors explain each decision: - C:packages/provider-core/{pyproject.toml,src/provider_core/analysis.py:52-84, src/provider_core/controller.py:102-116,src/provider_core/execution.py:237-254, src/provider_core/attempt_store.py:127-143}: actual installation/session/poll/ store constraints, rather than an assumed generic provider interface. - C:src paths below are relative to packages/provider-core/src/provider_core/: api.py:170-223; uploads.py:39-67,186-247; transport.py:109-119; attempt_record.py:162-177,247-273; recovery.py:72-104. Rationale: envelope/correlation gaps, memory handoff, evidence capacity and durable reconciliation obligations are current implementation facts. - C:requirements/provider-core.md:23-35 and requirements/provider-core-advisories.json record the dependency-selection rationale; https://github.com/pyca/cryptography/security/advisories/GHSA-g6cj-pr64-35w5 is the precise advisory cited by that dated review, not a fresh security claim. - M:pyproject.toml:7-15; containers/provider/Dockerfile:2; magnet_provider/{analysis_contract.py:167-206,analysis_execution.py:320-380, attempt_observation.py:150-190,provider_attempt_recovery.py:237-310, runner_session.py:228-260,terminal_outbox.py:71-180}. models/g_01_nmr_forward/provider/magnet_provider_bindings/g_01_nmr_forward/processor.py:170-283; models/e_01_jvae_nmrexp/provider/magnet_provider_bindings/e_01_jvae_nmrexp/processor.py:356-401; models/e_02_ch_nmrexp/provider/magnet_provider_bindings/e_02_ch_nmrexp/processor.py:378-428; models/g_01_nmr_forward/runner/serving_worker.py:104-145. Rationale: real preparation/prediction split, post-dispatch no-compute refusal, observation-gap policy, old outbox ownership and warm-worker stop boundaries. - S:src/secs_inference/provider/{config.py:29-49,http.py:294-335, job_api.py:89-103,analysis_run.py:45-137,191-206,247-275, worker_model.py:107-114,upload_download.py:87-108,199-210, execution.py:187-243,attempt_store.py:246-264,295-304,307-361, diagnostics.py:15-65, worker.py:224-245,285-295,runtime.py:39-83}; tests/provider/{test_job_input.py:82-96,test_analysis_run.py:543-574}; containers/provider/Dockerfile:7-21. Rationale: actual streaming scale, deliberate outage tolerance, admission after current execution mark, complete failure reports and durable read-only holds. - P:pyproject.toml:7-15; containers/provider/Dockerfile:2,13-19; nmrpeak_provider/{provider_http_contract.py:18-56,provider_https.py:413-425, provider_process.py:145-230,379-415,input_interpreter.py:154-203, runner_session.py:103-109,333-443,diagnostic_text.py:28-84, provider_events.py:106-141,interpreter.py:381-410, attempt_journal_store.py:27-55,110-125,attempt_lifecycle.py:890-930}; tests/unit/test_input_interpreter.py:378-397. Rationale: installed binding resources, multi-lane ownership, nested/blocking async hazards, useful error projection, report precedence and old-journal facts. Workshop acceptance: no module is moved merely because it looks generic. Close the real peer contract gaps without importing their scientific semantics or lowering their meaningful safeguards. Current installed/local NMRNet proof and the scripted Magnet adaptation remain useful, explicitly limited evidence. Review closure: all three peer reviewers challenged the synthesis against actual source and U/A intent. Revisions added consumed-file byte binding, independent leaf adoption, accurate progress ordering, the dependency security rationale, explicit scoped diagnostic lifetime and exact-receipt/state distinctions. Two subsequent unchanged-design rounds from all three returned no actionable signal. The final module-list spelling is attempt_store, matching the installed owner. No tests were added or run for this documentation workshop; runtime assertions above are source observations or explicitly future qualification obligations. Prepared-input identity follow-up, 2026-10-19 =========================================== 003's interpreted-source route needs the selected candidate identity before model dispatch, in addition to original Job identity. Core analysis.PreparedAnalysis now provides that session-owned handle with required ProtectedEvidence. The executor writes the identity through the existing execution-entry CAS and waits for settled durability and active-state observation before executing. Live authority remains in the session; restoring bytes grants no replay. A fresh store transition cannot omit identity. Historical acknowledged.v1 records remain readable and encode v1; new identity-bearing entries use strict v2, also within existing terminal envelopes. NMRNet is the actual consumer; sibling adoption fixtures were migrated without editing siblings. Required evidence bounds and future-store reservations cover both input identity and terminal evidence. See 003's dated follow-up and focused prepared-identity lanes for proof; Upload/interpreter/service composition remains open and this prerequisite does not close P4/P5 or 003. Decision and scope ================== The maintainer requests a local package named provider-core, intended eventually to replace the corresponding provider infrastructure in sibling repositories. The import namespace is provider_core. NMRNet is its first real consumer. There is no dependency on magnet-provider-core and no request to modify Magnet. The maintainer then explicitly required planning and U/A audit before building. That planning step was documentation/read-only investigation. The maintainer has subsequently authorized implementing the package tests-first; progress is below. This decision supersedes 003's proposed shared-Magnet extension. It does not cancel 003's three input routes, interpretation loop, scientific constraints, container requirements or API/GUI end-to-end completion criteria. Sibling migrations, external publication and deployment remain separate authorization. Success is not a renamed fourth copy of a provider implementation. The installed package must own the common behavior that the NMRNet workflow actually consumes, with independently checked adoption contracts for Magnet, SECS and NMRPeak. Their present implementations are evidence, not a universal behavioral template. Evidence and rationale ====================== 013 owns U01-U26, A01-A10 and the historical X01-X07 scope dispositions. Read their full intent, especially U23: useful errors must reach each authorized end-user, not merely stderr, while secrets and unauthorized scientific information do not. 014 pins the following source aliases; references here use those revisions: M magnet-deploy c5813ee35cfbb1c98a5cc5d20a94787271f26486 S secs-repro 34f5915c1534278bbf61b4c6592afa44cf94ab08 P nmrpeak-repro 1697dc84dd1d76ae25b04efc8183fd80614000e5 I nmr-api-v1 6a163b7a9cc1e2c7485b681c0b2b969c7c20e6c8 G nmr-gui-v1 d432668a137e860e1bf37bf242f792ec07f01533 Resolve paths via the exact GitHub tree URLs recorded in 014, not moving HEAD. - M:magnet_provider/{analysis_contract,analysis_execution,provider_protocol}.py: analysis outcomes and transport/commit certainty are separate responsibilities. Preserve that distinction rather than importing Magnet's scientific policies. - M:magnet_provider/job_input.py: authenticate exact Job text against feed facts before interpretation. Original instructions differ from prepared model input. - M:magnet_provider/provider_http.py and P:nmrpeak_provider/{provider_signing, provider_https,http_response}.py: signing and response ownership precedents. S:src/secs_inference/provider/socket_deadline.py: whole-exchange deadlines and retirement of deadline helpers; a library read timeout is insufficient evidence. - S:src/secs_inference/provider/{job_api,analysis_run,upload_download}.py: Job membership -> temporary read grant -> verified bytes, with no model-granted access. Keep generic source authority in core; format selection stays in binding. - S:src/secs_inference/provider/{execution,diagnostics}.py and P:nmrpeak_provider/{attempt_lifecycle,diagnostic_text,provider_events}.py: durable effects and recipient-specific diagnostics are related but distinct. Do not adopt one sibling's retries, scientific correction or journal schema merely because it contains more machinery. - I:nmr_api/provider/routes.py, provider/job_upload_set_read_response.py, operations/provider_job_upload_set_read_service.py, operations/provider_job_upload_read_capability.py and wire/upload_read_capability_response.py: existing API authority and wire shapes. G:app/src/features/workspace/ColumnExecutionAttempt.tsx and result-presentation/ ResultPresentation.tsx: actual commissioner/receiver display boundaries. M:pyproject.toml demonstrates a standalone distribution. Its dependency pins are candidates for comparison, not automatically the new package's dependency policy. S's AGPL notice must be retained if its code is actually reused; do not treat NMRNetplusplus's MIT license as licensing this new package. Record actual source adaptation and applicable notices when implementing; publication licensing is a separate explicit decision, not a reason to invent a substitute framework. Finished ownership and enforceable invariants ============================================ 1. API server owns authorization, eligibility, membership, expiry and committed Attempt state. Core authenticates exchanges and binds returned facts; it cannot create authority from text, a local flag, an interpreter decision or a receipt. 2. Core is the sole NMRNet owner of signing, bounded authenticated API transport, verified Job input, Job-bound Upload access, generic Attempt effects and exact terminal reconciliation. No second signer, downloader or replay owner in binding. 3. Binding owns scientific intent, typed interpretation tools, supported formats, geometry generation/conversion, scientific admission, model execution and result meaning. Core does not import NMRNet, RDKit, Torch, sibling packages or repo tools. XYZ and other chemistry readers do not move into provider-core. 4. Host/container composition owns actual network, filesystem, credential, resource and worker-retirement grants. Core consumes narrow execution/control ports and blocks new work when retirement is unconfirmed; it never receives an engine socket or implements a competing deployment manager. 5. Cross-module records distinguish original Job bytes, selected Upload bytes, prepared executable bytes and exact terminal bytes. Verified immutable bytes are the bytes consumed; paths do not become later unchecked authority. 6. One active Attempt per execution owner; NMRNet initially has one owner. Sibling composition may run multiple independent lanes with one shared claim authority excluding duplicate ownership and recovery races. Core adds no scheduler or process-global singleton. Determinate rejection, unavailable operation, potentially committed effect, observed committed effect, and failed cleanup are different states. No implicit queue, blind retry, science replay or generic catch-to-user- error conversion. Retry is an explicit bounded policy, not a diagnosis. 7. Errors carry the maximum safe useful cause, operation/phase, effect state and next action through the intended recipient's actual channel. Diagnostic-storage or cleanup failure cannot erase the primary cause or misreport commitment. 8. The package installs and executes independently of this checkout. Each adopted behavior has one owner and a real consumer. A sibling migration later replaces its analogue rather than wrapping old and new owners with silent fallback. Package and composition ======================= Proposed source layout: packages/provider-core/pyproject.toml and packages/provider-core/src/provider_core/. This is a separately installable local distribution, not a provider-named directory exported through root PYTHONPATH. Keep public contracts small: verified source values, Job-scoped source access, analysis outcome/effect values and an analysis processor boundary. Introduce a port only where an actual integration or alternate implementation needs one. No plugin registry, generic DAG, universal configuration language or event bus. Layout workshop, 2026-10-18 -------------------------- Extraction follow-up, 2026-10-20: provider_core.chat now owns the shared Chat Completions carrier (003 records the reviewed move and local qualification). Shared conversation mechanics belong in core as the NMRNet tool consumer is connected; prompts, tool implementations and scientific admission remain local. Worker framing/channel ownership and host receipt observation are further shared candidates, but their native installation is an unresolved part of extraction. The full-dependency decision above supersedes the earlier stdlib-only worker installation proposal. A complete worker move must install the built wheel and its full locked runtime dependencies in every consuming native runtime, update source closures/guards and qualify the changed image. Current worker images and locks are unchanged. Neither installing an incomplete distribution with --no-deps nor mounting core sources is an acceptable shortcut. Controller-only retirement can be extracted independently. Keep host engine control in tooling; do not call a relocated controller test proof of the native installed boundary. Current evidence: pyproject.toml dependency metadata; tools/provider_core_tests.py build/install lifetime; containers/{geometry,inference}/Dockerfile runtime locks; tools/worker_qualification.sh direct retirement/protocol grants; tools/baseline.sh worker-parity entrypoint. These are local repository sources, inspected 2026-10-20. The following is the intended layout as slices acquire real behavior, not an instruction to generate empty files. The earlier conversational contracts.py proposal is replaced by types beside their owning behavior. Public consumers import documented owner modules; __init__.py stays small and has no startup effects. packages/provider-core/ pyproject.toml Distribution, build inputs and runtime dependencies. README.md Public API, ownership, containment and test guidance. src/provider_core/ __init__.py job_input.py Verified Job instructions and their source identity. signing.py Signing inputs and authenticated request construction. transport.py Bounded exchanges, response consumption and retirement. chat.py Chat Completions carrier; consumer owns tools and prompts. api.py API wire operations and their explicit effect outcomes. uploads.py Job membership refresh/grants and verified consumption. analysis.py Preparation/execution boundary and outcome handoff. attempts.py Per-owner serial decisions and effect ordering. recovery.py Exact retained-terminal reconciliation policy. attempt_store.py Durable records, atomic writes and retention capacity. diagnostics.py Safe diagnostic context and recipient projections. container_guard.py Shared execution-policy guard. tests/ README.md Suite purposes, contained invocation and evidence limits. unit/normative/ unit/adversarial/ contract/ integration/ scenarios/ fakes/ Types stay local: job_input owns verified instructions; analysis owns processor outcomes; api owns wire/effect results; attempt_store owns persisted records. Do not create a central types/contracts/utils bucket or mirror those definitions in the NMRNet adapter. Extract a shared type only when it has one clear owner and actual cross-module consumers. Errors likewise start beside their operation; diagnostics preserves and projects their context, not a universal exception registry. Dependencies point from orchestration to effects: attempts uses analysis, source access, API operations and recovery; recovery uses the store and API reconciliation. API operations use signing/transport. Upload access uses API membership/grants and bounded store transport without forwarding provider credentials. The store does not call the API or decide retry policy. Signing/transport do not import lifecycle or science. Dependency cycles require correcting ownership, not deferred imports. The consumer composition supplies the processor, policy, credentials and narrow worker-control boundary. Its installed NMRNet binding imports provider_core; core never imports nmrnet_provider. No generic executable/CLI, deployment manager or plugin discovery is needed to make this library reusable. Host engine control and actual filesystem/network/resource grants stay in repository composition. The analysis boundary separates preparation from execution: binding returns an admitted execution handle; core confirms required progress and durably records execution entry before invoking that handle. Core cannot forge or reconstruct session-owned handles. A monolithic callback that marks science entered before interpretation/validation is insufficient. Binding owns generation compatibility for pre-execution recovery. Terminal replay needs neither processor nor runner. Execution-model decision, accepted by the maintainer on 2026-10-18: one async provider orchestration implementation. The application composition owns the event loop and task lifetimes. Core awaits API/store transport, interpreter/worker protocols, readiness, progress, execution and recovery. Pure parsing, validation and state decisions remain ordinary synchronous functions. RDKit and inference remain synchronous inside isolated scientific workers, never on the control loop. Rationale: cancellation, expiry and shutdown must remain observable while external operations wait. Magnet already exposes awaited ports; SECS and NMRPeak need explicit controller integration changes. Their synchronous owners may already use threads; that does not establish compatibility with async cancellation or ownership. P5 must qualify their async integration rather than merely matching data types. No sync lifecycle twin, nested event loops, callable-result introspection or automatic wrapping of arbitrary synchronous processors in threads. P0 names the task owner, stop path and confirmation evidence for every blocking effect. Inherently blocking durable storage may use a narrowly owned, serialized I/O executor if needed; this is an explicit store implementation, not a general sync-consumer adapter. Bound outstanding writes, preserve write order and await their actual completion before dependent effects or store reuse. Cancelling an await cannot cancel a filesystem write or prove that it failed. Storage failure and uncertain persistence block unsafe advancement. No untracked fire-and-forget task or thread may outlive its owning operation without retained recovery ownership. Cancellation is a request to stop, not evidence that an API mutation, worker or store operation stopped. Preserve each operation's effect certainty, execute bounded cleanup under its named owner, and await required retirement confirmation before reuse. Cleanup failure cannot replace the primary cause. Expiry/shutdown must not be mapped to bad scientific input. Independent lanes may proceed only where their claims/resources are independent; NMRNet initially admits one execution owner. The outcome handoff also distinguishes successful result bytes from a binding- classified failure projection and required protected evidence. Persist required failure evidence before publishing its terminal report; storage failure blocks that effect without hiding the primary cause. Product outcome vocabulary stays in binding, including SECS cannot_analyse and no_starting_candidates. One Job-scoped source owner refreshes authenticated membership observations, invalidates stale acquired selections and acquires bytes through fresh grants. Binding decides reinspection/reselection after an observed change; it does not own a second downloader/cache. Freeze the identity of consumed bytes. The API exposes no membership generation or atomic execution freeze: do not claim that changes after the last membership observation are atomically excluded. P2 tests removal after inspection, changed/unchanged membership after grant failure and pending-hash finalization. Defensive same-reference metadata-change fixtures do not establish that the server permits replacing finalized content. Package metadata declares its actual runtime dependency requirements; the existing repository acquisition owners maintain the separately reviewed exact core lock and advisory evidence. Do not add a package-local build/download/test shell framework. Installed tests must import the built distribution outside the checkout, with no source-path injection. Tests, fakes, credentials, retained Attempts and scientific artifacts are excluded from the runtime wheel. Required runtime resources are explicit package data and checked in installed-closure tests; no resource directory or duplicated schema/prompt is added without a real runtime consumer. In particular, NMRNet interpretation prompts and geometry fixtures remain with the binding. Evolution checks for this layout: replacing HTTP transport must not change Attempt policy; replacing durable storage must preserve exact replay semantics; adding a NMRNet format must not change core; changing an API field belongs at the wire boundary and its consumers. These are ownership review questions, not an excuse to implement multiple backends or a public interface for every internal function. Concrete modules follow behavioral owners during implementation, not an up-front empty module inventory. First useful behavior: verified Job text from exact authenticated feed/response facts, consumed by the NMRNet submission adapter. Then signed transport and complete Job-scoped Upload acquisition; then Attempt lifecycle/publication and its required durable reconciliation. Packaging alone is not completion. Do not ship an unused verifier as the finished shared package. Configuration is admitted once per run: provider/API identity, destination trust, Upload-store origin, deadlines/work limits and immutable implementation identity. The caller supplies product policy explicitly. No NMRNet limits, absent-nucleus semantics, solvent vocabulary or retry assumptions become core defaults. Credentials never cross into the analysis/preparation worker. The scoped Upload port takes an Upload reference; the interpreter cannot supply a different Job. All development, building, installing and running remains contained. Core owns a portable runtime guard rather than importing tools.container_guard; guarded entry points reject unsupported host execution. The marker checks shared containment policy; it is not proof of isolation or NMRNet-specific scientific policy. Test real container grants and denial separately. Repository tools/checks retain their current guards; new package sources enter guard, lint, cache, source and build-context inventories explicitly, without blanket exemptions. Use existing acquisition/build/test owners where applicable. Dependency acquisition requires explicit interface selection; no ambient interface fallback. Independently review current advisories for exact versions in the complete core dependency closure before installing it. Keep it separate from the qualified inference and preparation dependency locks. Test-first implementation sequence (requires review first) ========================================================== Test layout implements 013 U26, not a flat mirror of source modules. Sources: M:tests/{unit,contract,integration}/ and Makefile targets test/unit, test/contract, test/integration; P:tests/{unit,contract,integration,repository, fakes,live,model_behavior}/ and Makefile. Revisions are pinned above. The distinction keeps local behavior, external compatibility and composed lifecycle proof visible. packages/provider-core/tests/ unit/normative/ Required behavior, including specified rejection and ordering. unit/adversarial/ Malformed, hostile or fault-injected boundary challenges. contract/ API wire/signature compatibility and consumer boundary contracts. integration/ Composed source/Attempt/recovery flows, finite peers, installed use. scenarios/ Recognizable multi-step consumer workflows and recovery stories. fakes/ Shared controlled peers/stores only where tests need them. The normative/adversarial split follows I:tests/unit/{normative,adversarial}/ and G:tests/unit/{normative,adversarial}/. I also uses integration_tests/{normative, adversarial}/: these categories express test intent, not merely test granularity. S:tests/input/README.md and tests/input/{normative,adversarial,scenarios,adapters}/ provide the domain-suite precedent. In particular, adversarial/test_source_boundaries.py checks foreign references, duplicate archive members and storage faults with no downstream inference; scenarios/test_scientific_jobs.py exercises interacting inputs and corrections at a worker boundary, explicitly not an API/GUI end-to-end claim. Use these precise sources at the S/I/G revisions above. Normative is not synonymous with happy path: required refusal, precedence and atomicity are normative contracts too. Adversarial tests challenge those contracts with tampering, substitutions, exhaustion and interrupted effects. Scenario tests exercise complete meaningful stories (e.g. lost publication reply, restart, exact reconciliation without another analysis). Integration tests focus on the actual connections between owners, such as signed transport and store consumption. Place each test under its primary purpose; do not duplicate it across categories. Use normative/adversarial subgroups within other suites only where actual coverage benefits. Adapter-specific tests belong with the boundary they qualify; S's adapters directory does not require a new core adapter layer. Repo-checks, system/e2e and model-behavior lanes stay separate from these package behavior categories. Fixture data belongs beside its owning suite, with precise provenance for derived examples. Within each layer, group by behavior; do not create empty directories. Repository conventions and actual container/launcher grants remain repository-level checks. NMRNet interpretation/model behavior and live API/GUI end-to-end tests stay outside the shared package. Do not add model_behavior/live directories to core merely to copy the sibling tree. Focused contained Make targets must preserve the unit/contract/integration/scenarios distinction, allow focused normative/adversarial selection, and select provider-core explicitly. This layout clarification follows the maintainer's correction after the design audit; it changes test organization, not the behavioral acceptance obligations. P0. Freeze owner/consumer contracts from the pinned API and sibling code. Specify exact API types, bounds, state transitions and recipient projections. Specify async operation/task ownership, cancellation and shutdown ordering, aggregate deadlines and explicit treatment of blocking persistence. Choose concrete existing async-capable I/O dependencies during closure review, not an additional scheduling framework. Scientific workers remain isolated. Freeze expected populations before iteration: the retained 002 artifact's four fixture identities, 137 outputs and 64 historical positions; separately the three 003 routes (SMILES+N, one pasted geometry, instructed Upload). Missing cases fail qualification rather than shrinking its denominator. Compare differences explicitly; do not erase them into a common denominator. Exit: the end-to-end NMRNet composition names every effect owner, including host retirement and exact terminal retention, with no unowned integration seam. P1. Installable package plus exact verified Job-input behavior and NMRNet adapter. Establish U26 discovery and contained selection with the first actual tests: normative source/identity contracts, adversarial substitutions, and installed package integration. Missing selected suites/tests must fail, not pass empty. Write boundary failures first: wrong Job/schema/digest/length, duplicate JSON, invalid UTF-8/base64 and over-limit replies. Failed verification must cause no interpretation/preparation call. Preserve exact accepted instructions. Build/install offline in a clean contained prefix; run outside the checkout with isolated imports. Assert distribution metadata, complete package resources and imported origins. A source-tree import is not installed-package proof. P2. Signed exchanges and Job-bound Upload acquisition, end to end with finite peers. Exact method/authority/path/query/body signing; list membership, fresh grant, allowed store origin, no redirects or provider credentials at store, length/ digest checks, private staging and no exposure of partial bytes. Include total and per-source budgets while failed/trickling responses are consumed. Test the real transport and socket retirement, not only mocked HTTP functions. Cancel during connect/headers/body and Upload transfer; verify deadline/stop observation while a peer stalls, socket retirement and no partial-byte handoff. P3. Attempt lifecycle and terminal-effect recovery with one active owner. Start/progress/terminal/readback paths share one protocol owner. Specify durable state from exact replay obligations; reserve bounded retention capacity before accepting obligations that need it. Inject response loss before/after each commit, restart, expiry, disk failure, conflicting owner and failed retirement. Reconcile exact terminal bytes; never rerun science to resolve uncertain delivery. Include pending-start uncertainty and prepared-versus-execution-entered states. Qualify composition-supplied claim exclusion across independent lanes/recovery; NMRNet still deploys one lane. Do not impose NMRNet's lane count on core users. Inject cancellation before/after start, progress, durable execution entry and terminal publication. An unfinished write/mutation stays owned and unresolved until observed/reconciled; no duplicate write, science replay or early reuse. Check stop/expiry observation while worker I/O or persistence is delayed and verify bounded shutdown preserves retained obligations and primary diagnostics. P4. NMRNet composition and recipient-visible diagnostics. Core handles orchestration; NMRNet supplies interpretation/preparation/inference. Exercise success, user correction, unavailable service, uncertain effect, oversized reason, nested secret-bearing cause and diagnostic persistence failure. Inspect developer evidence, operator recovery output, commissioner Attempt view and receiver result/download. Rendering tests must retain safe causes and limits. Apply the interpreter and recipient contracts below, through actual bindings. P5. Reuse qualification and full 003 workflow. Build three source-grounded consumer contract fixtures: Magnet implementation binding, SECS source-driven analysis, NMRPeak direct/interpreted request outcomes. Show each can express its own product policies without importing sibling code or changing core for chemistry. Include a next-change test (new product result field or tool) that changes only the binding, and an API protocol change that fails explicit compatibility admission rather than silently dropping fields. Magnet's fixture uses awaited ports. SECS/NMRPeak fixtures must demonstrate explicit async controller/worker integration, including cancellation and retirement; synchronous source compatibility alone cannot pass this witness. These are adoption evidence, not claims that siblings have migrated. Run real NMRNet/API/GUI transactions for all 003 routes and failure/restart cases before claiming 003 closed. Later sibling migration requires an explicit consumer revision, qualification, cutover and deletion of displaced authority. Before any future cutover, explicitly drain/refuse nonempty old journals or qualify an offline conversion preserving owner, exact command, uncertainty and recovery disposition. Never start an empty new store over retained obligations or allow old and new recovery owners to run together. Reader/archive tools must change with their store. Migration is still separately authorized. Concrete integration acceptance contracts ======================================== Retirement: composition confirms that the exact owned execution has stopped after interruption, with the required grant cleanup. Successful quiescence and permitted warm reuse are distinct from stopping a worker. SECS/Magnet retain successful warm workers; a ready response is not evidence of stopping an interrupted execution. NMRNet's initial container-retirement implementation confirms its allocated exact container stopped and its grants were released. A shared name, timed-out wait or stop request is insufficient. Core receives the bounded result, never an engine handle. P0 names the controller, execution identity and actual confirmation scope; P3 injects wrong/stale identity, supervisor loss and failed confirmation. Unsafe work blocks reuse until confirmed stopped; successful warm reuse also requires observed quiescence and completed per-Attempt cleanup under explicit consumer policy. No general deployment interface is introduced. Interpreter (NMRNet binding, not core policy): preserve original Job instructions separately from admitted executable bytes. Test direct and interpreted routes, bounded endpoint/repair calls and an overall deadline; malformed direct JSON must not silently become prose. Distinguish model-reported input problems, deterministic admission rejection, endpoint failure and indeterminate execution. Interpreter egress uses an explicitly trusted destination and its own credential grant; source or model output cannot widen Upload authority. Include credential/private-data canaries and ensure rejection cannot start preparation. 003/016 own format, conversion, native-work and result-size limits; these witnesses exercise them through the real binding rather than duplicating scientific policy in core. Following 014 W03/W04, test configured endpoint order and bounded fallback; explain to operators and commissioners what request material goes to external interpreters. Fallback must not override a terminal source-problem report. Test that such a report ends interpretation without calling another endpoint or starting preparation; operational fallback must preserve the stated deadline and effect-certainty rules. Include wrong/ambiguous-unit fixtures through binding conversion, proving core neither infers nor repairs units. Account failed and partial preparation work against the same admitted work/time budget as successful preparation. Recipient projections must use actual supported channels, grounded in I and G: - Commissioner: terminal providerFailure.code/message, rendered by G:app/src/features/workspace/ColumnExecutionAttempt.tsx, carry safe useful cause and next action. In-progress providerCondition.code selects the GUI catalog's message/next_action, with observedAt; it cannot carry arbitrary per-Job detail. Do not turn uncertain delivery into a false terminal failure to get richer text. - Receiver: the authorized result/download carries scientific limitations and provenance, including the existing scaler warning. Never invent a successful result for a failed or unresolved Attempt. - Operator: protected recovery output preserves operation, causal chain, exact effect certainty and permissible retry/reconciliation action. - Developer: protected diagnostic evidence retains safe causal detail and source identity needed to reproduce the failure, without raw credentials or input dumps. P0 names concrete API wire fields, result renderer and protected diagnostic/recovery store or sink for every supported path. P4 covers normal rejection, unavailable service, uncertain delivery, cleanup failure and diagnostic-store failure on their meaningful recipient paths. Assert safe cause, effect truth, retry disposition and next action where applicable; secret canaries must stay absent. Storage/cleanup failure remains secondary evidence and cannot erase the primary cause. Do not invent a generic projection framework or a meaningless Cartesian test matrix. Reuse evidence qualifies a design for adoption. Only an actual sibling cutover, with qualification and removal of its old owner, proves shared production use. U/A conformance ledger: owner and required witness ================================================= Every row is a planned acceptance obligation, not a passing result. Core, binding and composition obligations all matter; moving a rule outside core is not exemption. U01 binding: one existing scientific callable; adapter spy plus real 003 path prove no parallel predictor or checkpoint-specific scientific implementation. U02 binding: ordered interpretation/preparation/admission/inference; a failure at each boundary proves later scientific effects do not occur. U03 core+binding: Job/source/prepared/result identities travel with their selected bytes; swap, reorder and stale-selection fixtures reject or preserve identity. U04 binding+core compatibility: scientific semantics stay in binding, wire/package compatibility in core admission; shape-compatible but wrong-schema cases fail. U05 core source owner: hash and consume identical immutable bytes; mutate/reopen fixtures prove no checked-path/unchecked-read substitution. U06 qualification: exact producer revisions, populations and installed closure; assert P0's expected fixture and route sets before iteration; portable evidence names missing cases rather than reducing a denominator. U07 composition: real signed exchange, actual worker and API/GUI route tests; component mocks cannot substitute for those completion witnesses. U08 core lifecycle: explicit uncertain/committed/rejected outcomes; response-loss, cleanup and restart fault injection preserves effect truth and safe next action. U09 core+binding: declaration/admission/acquisition/execution are separate effects; malformed input and foreign Upload cause no download or model work. U10 core contracts: named immutable cross-module values; mutation and repr canaries distinguish empty, unavailable and unresolved without exposing protected data. U11 package: installed-origin and exact-resource inventory checks, forbidden imports and blocked effect tests; passive source inspection alone does not qualify it. U12 launcher: literal hierarchical Make inputs and protected aliases; real Make hostile/ambient-value tests show no expansion or unauthorized engine call. U13 transports/preparation: consumed byte/time/work budgets include failures and retries; trickle, partial read, aggregate exhaustion and oversized body tests. U14 composition+core admission: retire exact owned worker/transport before reuse; interrupted work requires confirmed stop; successful warm reuse follows the explicit quiescence contract. Replaced identity and failed-retirement tests leave admission blocked. U15 review/checks: judge requirements by intent; focused properties cover actual effects, with no proof-token registry or implementation-shaped test substitute. U16 owner docs/code: precise revision/path/reference and adaptation rationale; reviewer traces each borrowed behavior to source and distinguishes runtime proof. U17 recipient text: plain blocked operation, safe cause and next action; independent reader explains the actual user-facing failure without internal shorthand. U18 delivery: coherent audited slices and explicit-path commits; status distinguishes implemented, installed, locally qualified and deployed; no unrequested push. U19 artifacts: keep exact reproducibility evidence and enduring rationale; retention disposition identifies why each bundle remains and when scratch can be removed. U20 package acquisition: review full dependency lock/advisories; no automatic lock refresh treated as deterministic regeneration or unreviewed producer update. U21 qualification: version-matched independent observations; changing dependency, implementation or protocol version blocks stale-reference qualification. U22 notes/guide: supersede active Magnet-reuse instructions and mark historical observations; review finds no mixed current architectures in 003/016/README. U23 diagnostics: safe causes reach actual developer/operator/commissioner/receiver channels, including nested causes and delivery failure; secret canaries never leak, safe useful context remains, uncertainty and retry disposition stay distinct. U24 accepted limitations: maintain explicit executable cases for known limitations; NMRNet's scaler warning reaches its result/diagnostics, not just a local log. U25 test lanes: focused cheap checks routinely; expensive real-capacity and full workflow witnesses in explicit contained lanes and run before their claims. U26 package test organization: normative/adversarial unit tests, contract, integration and scenario suites preserve their distinct purposes; repository checks and live/scientific proof stay in their owning lanes. Verify focused contained discovery includes the intended tests and rejects empty selections. Shared fakes and provenance-bearing fixtures serve tests, never runtime imports. U27 service+operation+resource owners: transient outages recover automatically with configurable capped backoff, bounded exchanges and responsive shutdown; exact replay/reconciliation preserves uncertain effects without repeating science. Ordinary throughput stays within a stated unattended envelope through owned retention/allocation renewal. Focused scenarios distinguish automatic recovery from justified operator intervention; no new generic retry framework is required. A01 evidence: package import/health/receipt never means science or workflow passed; completion report labels each proof layer and retains failed results honestly. A02 binding: preserve exact identities and independently chosen numeric tolerances; loaded-state/reference tests survive package integration without tuned goldens. A03 diagnostics: bounded useful reasons, no raw-input dump or broad ValueError-to- user-error conversion; oversized/nested/private-cause fixtures preserve semantics. A04 packaging: complete imported/resource closure, not just hashes of a subset; missing resource and forbidden ambient import tests fail installed qualification. A05 ownership: one local core for shared behavior, existing operational owners; consumer/import review rejects duplicate signer/downloader/journal and silent old/new fallback. Future migration must remove the displaced implementation. A06 binding: three sibling contract fixtures retain their different scientific semantics; core contains no peaks/solvent/nucleus/atom-map policy or schema. A07 binding/result: preserve coordinate/stereo limits through publication; renderer tests prevent stronger stereochemical claims than the scientific result supports. A08 binding/source: explicit units and conversion evidence; core passes bytes and provenance without inferring units; wrong/ambiguous-unit cases cannot be repaired by transport, source parsing or implicit core defaults. A09 capacity: execute actual maximum advertised workload and result envelope; synthetic admission and a healthy core cannot certify native/model capacity. A10 retention: durable notes and identified evidence, no raw transcripts or abandoned compatibility trees; cleanup preserves the only supporting observations. A11 service/composition: a documented safe stop is not unattended resilience; review rejects routine manual restart, repeated limit increases or fresh-root replacement as normal recovery/throughput, and rejects blind workflow retries. Resilience audit, 2026-10-22 --------------------------- Source review against new U27/A11; no tests or live outages were run for this audit. This is an implementation assessment, not a new qualification campaign. Gap 1: nmrnet_provider/service.py::ProviderService.run/_watch stops the service when work or Hello raises, and _work_loop has no transient-outage recovery loop. Its class contract explicitly stops on outages. docs/provider.md describes this honestly, but temporary dependency failures still require operator restart or recovery. SECS runtime.py::run_execution at 7356c354368f2355d3ab5cef00cf48c67cea9c2c shows the relevant narrower backoff precedent. Correction belongs at the operation and service owners, with distinct read, definite-refusal and uncertain-write dispositions; do not retry an entire Attempt or rerun science. Gap 2: docs/provider.md, "Retained history and a full store", specifies keep-all retention: confirmed successes/failures consume maximum_records forever. Normal throughput eventually stops and requires an operator to raise the limit and restart. tools/provider.sh::provider_host_monitor also stops at native request capacity and asks for a fresh installation root. These are separate resource owners and both constrain unattended operation. Define the intended operating envelope and owned safe retention/renewal behavior before choosing a mechanism. Increasing limits, dropping unresolved evidence or blindly recycling allocations is not a fix. Existing strengths: configurable exchange, preparation, polling and settlement budgets; explicit retained terminal requests and read-only reconciliation states; separate scientific execution and publication; exact host-owned retirement; original and independent cleanup causes retained in protected diagnostics. These support resilience but do not establish automatic recovery. Commissioner/receiver delivery is a separate claim from operator failure.json. Required follow-up should address the concrete recovery and resource-lifetime gaps, reusing existing focused tests. Implementation order after the resilience audit ---------------------------------------------- The maintainer's unattended-operation requirement supplies the concrete consumer need missing from the earlier status-only assessment. U27/A11 supersede that assessment: supported stop behavior must remain honestly reported until repaired, but documenting it is not closure. No scientific work needs repeating for these control-loop changes. Runtime checkpoint for this design:7c9019e. 1. Retry reviewed startup-admission and idle-discovery GET outages in the existing service task. Keep admission.py's bounded one-shot walks. Retire original API I/O before classifying its final evidence; no replacement transport or detached retry task. The API owner permits safe GET repetition after selected gateway failures and explicitly recognized network/timeouts. This does not establish transience or admit an error body: proxies may return HTML during maintenance. Certificate, authentication, explicit wrong environment, malformed success, capacity and ownership failures still refuse. Status supplies no mutation permission or authoritative API observation. Re-enter the whole admission/discovery cycle, including local capacity and cursor=None, without carrying a selection across an outage. Allocation, controller.run and all mutations remain outside this retry scope. Configure capped exponential delay, jitter and stop-responsive waits. Reset backoff only after the complete read cycle succeeds. Keep constant-size current outage context separate from terminal failures, and use the existing protected process renderer for retry/recovery notices. A reporting or retirement failure retains the original outage. Tests first in the existing API/service/process lanes: recover and execute once; restart pagination; stop during backoff; held cleanup forbids another request; permanent failures do not loop. 2. Address initial/periodic Hello independently. Its current task still stops the service on outage, so step1 cannot establish general outage survival. Recompute the current complete announcement after confirmed retirement; no blind replay of a stale announcement or use of GET retry permission for a POST. 3. Give active execution an explicit finite observation-gap policy. No new phase, execution entry, accepted result or publication follows without fresh observed authority. Grace expiry/observed stop retires the original session; never restart interpretation or science. Uncertain START/terminal writes keep their existing replay/reconciliation paths. Uncertain progress remains with its original API/executor owner; do not replay obsolete progress or route mutations through the read-retry loop. Separately classify per-Job budget exhaustion at its owning binding. Return a legitimate terminal failure, not a catch-all bad-input result, only after the original work can be confirmed stopped. Continue fresh service admission after confirmed publication and complete retirement; unresolved effects or cleanup still hold it. No whole-Attempt retry converts a budget failure into another scientific execution. 4. Define the unattended history/disk and native-request envelope at their current owners before changing retention or renewal. Preserve unresolved obligations, exact replay and required scientific/operator evidence. No implicit deletion, root rotation or process replacement hides an unsettled owner. Implement the resulting owned retention/renewal policy; defining an envelope alone does not close U27/A11 or establish unattended ordinary throughput. This is a phased implementation plan, not proof of these behaviors. Two independent read-only owner/design reviews informed step1; both identified Hello as a separate service-fatal path and required fresh complete reads plus settled original I/O. Re-use the maintained focused lanes; no new harness or exhaustive outage campaign. X01 now applies: persistent provider and terminal reconciliation in P3; explicit outcome precedence for unordered event batches and uncertain replies. X02 applies as serial admission per execution owner/no implicit queue. Composition may schedule independent owners; duplicate-claim exclusion is required. Model RNG and daemon scheduling frameworks remain outside provider-core's initial contract. X03 applies to required durable terminal obligations, not a new general task queue; bounded record growth and atomic replacement capacity tested before admission. X04 applies at actual API/store/control transports: full exchange deadlines and released sockets/helpers, including trickle and interrupted-response tests. X05 preparation is required by 003 but stays outside core. Core must preserve its provenance/limits and cannot claim native-reader qualification from wheel hashes. X06 ensemble/GPU/precision/performance campaigns remain outside this package change; no core device or averaging policy. Existing scientific distinctions survive. X07 sibling instructions are evidence, not imported authority. This checkout's containment, permission and explicit-path commit rules remain in force. Review and completion of planning ================================= Peer-consumer workshop, 2026-10-18 -------------------------------- One read-only agent per M/S/P inspected its pinned checkout and discussed adoption with the coordinator. Findings were checked against source; no sibling tests ran. The package is potentially usable by all three after these concrete corrections; source review is not installed-consumer or migration qualification. M:provider_process.py:200-267 (under magnet_provider/) shares claim authority across lanes and recovery; provider_attempt_recovery.py:97-115 excludes claimed/retained Attempts. Its :156-191,237-310 inventory recovery is not merely replay of local terminal records. Keep inventory scheduling/abandonment disposition/pacing in composition; core supplies bound API inventory/read and one adopted-candidate terminal/reconciliation path. Completed/expired/missing/outage observations must not become blind failure reports. Retain one claim and replay owner. Witness the shared-owner behavior in tests/integration/test_provider_process.py:1208 and add same-key competition versus distinct-key progress. runner_session.py:152-209 uses warm success/retirement on failure. terminal_outbox.py:73-180 explains why migration must preserve owner/state/uncertainty as well as command bytes. M:magnet_provider/analysis_contract.py:197-206 and models/g_01_nmr_forward/provider/magnet_provider_bindings/g_01_nmr_forward/processor.py:182-231 require awaited processor/progress ports; source-contract compatibility alone does not qualify an alternative synchronous runtime for Magnet. S:src/secs_inference/provider/analysis_run.py:121-145,191-205 owns changing Upload observations; move that common source authority, not scientific reselection, into core. I:nmr_api/operations/provider_job_upload_set_read_service.py:54-57 and provider_job_upload_read_capability.py:98-145 define observation/grant authority; I:nmr_api/provider/job_upload_set_read_response.py:19-32 contains no generation. S:runtime.py:44-75 and worker.py:207-245,268-295 (under the same provider directory) distinguish warm success from supervisor-confirmed child termination. Do not claim container shutdown or mount revocation from that acknowledgement. S:execution.py:99-138 and attempt_store.py:246-264 retain unsuccessful scientific reports before publishing bounded failure; tests/provider/test_execution.py:139, 169,180 cover replay and evidence-write failure. Keep outcomes/interpretation, archive/member decoding, retrieval, GA and worker implementation in SECS. SECS does not already satisfy the new prepare/execute split: analysis_run.py:201-206 marks execution before worker analyse, which may still return input_rejected and resume interpretation. Its future adapter must expose admission before that mark; wrapping current run_analysis as execute is insufficient. P5's SECS witness must show preparation rejection/reselection without execution entry or inference, followed by admitted execution, durable entry and one scientific invocation. P:nmrpeak_provider/provider_process.py:145-230 serves HF/CHF concurrently; attempt_journal_store.py:225-245, attempt_inventory.py:130-183 and generation_runtime.py:76-95 bind claims/restore to the correct lane and generation. Local process locks do not establish distributed exclusivity. Tests must reject wrong-lane restore and incomplete/duplicate inventory before either feed starts. attempt_lifecycle.py:695-772,1153-1203 and runner_session.py:102-107,333-393 require preparation and session-owned admission before confirmed progress/durable execution entry. attempt_lifecycle.py:1502-1539,1646-1678 and attempt_journal.py:534-579 require generation-sensitive pre-execution recovery and processor-free exact terminal replay. Port those behaviors, not HF/CHF schemas. runner_session.py:395-411 closes/retires channels without claiming process exit; stronger retirement proof remains a future consumer qualification obligation, not an already-satisfied sibling property. Future adoption replaces common signing, HTTP/wire, source and lifecycle/store owners, splitting mixed files rather than deleting scientific policy. M's existing distribution also contains retained Magnet behavior; P's nmrpeak-provider-core contains binding resources. Do not delete those whole distributions blindly. P:containers/provider/Dockerfile:13-19 and tests/repository/test_package_install.py:13-84 ground a two-distribution installation witness. S:containers/provider/Dockerfile:16-21 currently copies controller sources; its adoption must instead qualify installed core origins without scientific dependencies. Installed sibling composition fixtures must cover these boundaries; neither importing sibling source nor retaining a competing old implementation qualifies adoption. After the revisions, Magnet and NMRPeak reviewers found no further source-level adoption mismatch. SECS confirmed its findings were represented and identified the additional admission split above as a future adapter qualification requirement. The subsequent maintainer decision selects async orchestration as recorded above. P0 now fixes concrete ownership/integration details, not the sync/async choice. That decision and its cancellation witnesses postdate these peer reviews; the earlier review results do not establish runtime compatibility or re-review of it. Audit architecture, every U/A row and X applicability against the actual sibling and API sources. Challenge whether the proposed owner is needed, whether a normal consumer evolution requires mirrored edits, and whether a failure can lose truth or expose secrets. Revisions must include the affected acceptance witness, not just another promise. Track concise findings/dispositions here, not raw agent logs. Require two unchanged-plan review rounds without new actionable findings before calling the plan settled. Planning completion authorizes no implementation/build. Present the settled plan to the maintainer before beginning P0/P1 implementation. Initial design dispositions: rejected product-prefixed package names (the requested name is provider-core); rejected moving XYZ into core (wrong responsibility); rejected wholesale sibling lifecycle copying and thin wrappers that leave dual authority. Retained standalone installed-origin proof and shared Job/source/effect contracts. Planning audit completed, 2026-10-18 ---------------------------------- Three context-isolated Luna-low reviewers covered U01-U12/A01-A04, U13-U25/A05-A10, and architecture/X01-X07 respectively. Revisions added exact population checks; actual recipient channels and error projections; interpreter ordering, disclosure and terminal-source-problem precedence; explicit unit and failed-preparation budget witnesses; exact worker retirement; and honest adoption claims. Each reviewer then returned no new actionable findings in two passes of the unchanged substantive plan. One proposed restriction was rejected after checking 003's recovery policy: bounded repeat interpretation before inference remains permitted under the declared Attempt policy. The prohibition on rerunning science after inference may have begun must not be broadened into an invented interpreter retry ban. This is design conformance review, not passing package or runtime qualification. The later maintainer-directed layout workshop and U26 additions are coordinator revisions; the preceding independent audit did not cover these later additions. All acceptance witnesses above still require implementation and contained proof. No package code, build, installation or sibling migration was performed in this planning step. The maintainer subsequently authorized tests-first implementation. Implementation: first installed input slice, 2026-10-18 ----------------------------------------------------- Implemented standalone provider-core 0.1.0, its portable execution guard and exact Job-input verifier. Frozen feed identity and immutable source bytes cross the boundary; payloads are excluded from repr and parser failures do not echo private values. NMRNet's direct adapter consumes verified bytes through existing geometry admission, without a second scientific parser or malformed-input reinterpretation. This internal binding is not a live API submission route or Attempt controller. Tests were written and run red before each implementation: missing job_input module first, then missing submission adapter. The installed tests now pass: make test/unit/provider-core: 9 tests, including normative/adversarial subcases. make test/contract/provider-core: 4 tests (installed files/imports, guard, empty suite). make test/integration/provider-core: 3 real NMRNet adapter tests. make test/unit/provider: 22 existing/new input and launcher tests. make test/repository/provider-core: 36 focused convention/inventory/guard tests. All ran in offline containers. Build/runtime environments are separate, source and dependency mounts read-only, wheel installation hash-checks the retained setuptools input, and runtime imports are outside the checkout. Current build dependency advisory observations and limitations are in requirements/provider-core.md. Package/runtime/test roots enter the existing source, guard, lint and cache checks. The normal test aggregate includes the new unit, contract and consumer lanes. Independent reviews covered input ownership/privacy, U/A evidence and contained lane grants. Corrections included reaching actual decoded-payload hashing in a test, capturing live traceback privacy, exact installed file inventory, and rejecting intermediate symlinked consumer-test directories. Focused lint/format was applied in the existing checker image. A temporary focused-check script was replaced, at maintainer direction, with test/repository/provider-core and removed. Adding actual-source assertions exposed 14 pre-existing broad import-order findings in test_prediction_model.py/test_prediction_release.py. The broad assertion remains unchanged; the core lane selects its actual package/tool/adapter import-order check and all three real source visibility/tree/mount assertions, not just detector fakes. No broad aggregate, network authentication, async lifecycle, live API/GUI or new scientific qualification is claimed by this slice. Those remaining P2-P5 contracts stay open; installed Job-input consistency does not authenticate a network peer. Dependency tooling slice, 2026-10-18 ----------------------------------- The existing lock/capture/apply and wheelhouse owners now accept a separate provider-core profile. Candidate direct dependencies follow Magnet's async client; they are intent, not reviewed/installable runtime evidence yet. Core acquisition may write only .work/provider-core; inference and preparation locks, reports and wheels retain their separate authorities. The new profile regression ran red before implementation; make test/unit/packages now exercises the lock, wheelhouse and guarded launcher tests offline. Three independent reviewers found no remaining ownership/capture/isolation defect; a preparation-output preservation witness was added alongside the existing inference witness. Actual staging must follow this slice's commit because package_capture_inputs uses HEAD execution blobs. Resolution, exact-version advisory review and acquisition are the next separate effects. Runtime dependency closure and installed lane, 2026-10-18 ------------------------------------------------------- Resolved and retained the separate 11-package provider-core closure and hashes. The initial cryptography 49.0.0 candidate had two records for one PKCS#7 advisory; 50.0.0 is the maintainer's patched version. Selection rationale and precise source are in requirements/provider-core.md; the replacement exact-version PyPI report has no reported entries. This is not a complete security audit. Acquisition used the explicit interface-bound container lane; all 11 wheels passed inventory/hash verification before publication. No scientific dependency closure was changed. Installed tests now verify the wheelhouse before pip, install only hashed offline wheels, and check installed dependency consistency. Native cryptography requires executable mappings: the disposable installed runtime gets its own 128 MiB tmpfs, while source/build scratch remains on 64 MiB noexec /tmp. Five installed contract tests passed, including real Ed25519 signing and verification within these bounds. Launcher tests ran red for missing mounts before implementation; 23 input/launcher and 36 focused repository checks pass. Independent review caught the need to reuse the existing wheelhouse member verifier, rather than relying only on pip hashes. Source and dependency mounts remain read-only. The next signed-request tests are separate work; no authenticated API exchange is claimed by this closure slice. Exact signing slice, 2026-10-18 ------------------------------ Added the pure RFC 9421 request constructor, deriving parameters/components from the pinned API profile and adapting Magnet's exact-target signing precedent. The package README links both owners precisely. No client, clock, nonce generator or retry policy is hidden in signing; the eventual API operation owner supplies time and a fresh nonce. Body None and empty bytes remain distinct. Identity repr does not reveal credentials or key material, and HTTPX target rewriting rejects. Tests ran red with the missing signing module before implementation. Independent verification reconstructs signature bytes and checks actual emitted headers; three reviewers covered protocol, privacy/admission and contained installation. Review found IPvFuture bracket syntax could become a different DNS destination; its regression ran red, then admission was corrected while retaining IPv6 support. The installed unit suite now has 15 passing tests, with five contract and 36 focused repository checks passing. This qualifies local request construction, not server acceptance, transport retirement or any API mutation. Bounded async transport slice, 2026-10-18 ---------------------------------------- Added a serial HTTPS exchange owner using one fresh client per exchange. This removes pooled-connection reuse ambiguity without adding a scheduler. Composition supplies verified TLS trust, exchange duration and a separate finite retirement grace; ambient proxies/auth and redirects are disabled. Raw response bytes are bounded before handoff. Success requires response/client closure. Failed or unfinished retirement retains its task and prevents another exchange; an explicit retire operation observes later closure without losing the original failure. Server mutation certainty remains the API operation owner's responsibility. Tests ran red for the absent transport, then reproduced three review findings: cleanup timeout hiding a read failure, repeated retirement erasing prior evidence, and cancellation before the worker's first instruction leaving ownership stuck. All were corrected. Original private causes, interruption and cleanup evidence remain distinct; public exception rendering does not contain request/secret text. Controlled cancellation-resistant I/O proves bounded return and retained ownership. Initial focused evidence: 23 installed unit tests, 7 integration tests (four finite-loopback TLS cases plus three real NMRNet adapter cases), five installed contracts and 36 repository checks passed before extending connection coverage. TLS tests cover successful closure, no redirect follow, headers/body stalls, trickle deadline, cancellation and incomplete-response failure. Peer-side closure and exact failure causes are asserted; unexpected fixture task errors propagate. These are offline contained tests, not deployed API proof. The next functional slice must join signing/transport to the real Job-input and Upload contracts, after the unresolved transport defect below is corrected. Current checkpoint: NOT qualified for transport use. Added TLS-handshake stall cases reproduce two failures in test/integration/provider-core: cancellation and deadline return without the peer observing socket closure. httpcore 1.0.9's _backends/anyio.py::AnyIOStream.start_tls catches Exception, excluding cancellation; _async/connection.py registers its connection only after TLS completion. Thus HTTPX client closure is insufficient evidence for a pre-handshake raw stream. Exact retained wheel sources support this diagnosis; current upstream source: https://github.com/encode/httpcore/blob/1.0.9/httpcore/_backends/anyio.py https://github.com/encode/httpcore/blob/1.0.9/httpcore/_async/connection.py The fixture initially obscured this with teardown waiting for active connections before cancelling handlers; teardown now closes handlers before waiting for the server and has finite waits. The two actual socket regressions remain red. No backend workaround has been implemented. Proposed correction is explicit stream ownership through httpcore's public network-backend/pool interfaces, avoiding private HTTPX pool mutation or an untracked patched wheel. The maintainer requested this checkpoint commit before the exhaustive U/A audit and revision. TLS ownership correction, 2026-10-18 ----------------------------------- The red checkpoints e34540c and 5bbc586 are superseded by an explicit stream owner using HTTPcore's public AsyncNetworkBackend/AsyncNetworkStream interfaces. A TCP stream is retained before TLS upgrade and released only after successful closure. Interrupted upgrade therefore leaves the raw stream available to final cleanup. The earlier description of pool registration was imprecise: the pool registers its connection wrapper before TLS; the wrapper does not retain the raw stream when TLS upgrade is interrupted. The exact 1.0.9 sources above explain why closing the HTTPX client alone did not suffice. HTTPX still constructs the signed buffered request. Its method, raw URL target, headers and content pass to a fresh HTTPcore pool with no retries or keepalive. HTTPcore is now an explicit package dependency; the exact 1.0.9 wheel already belongs to the reviewed locked closure. No dependency bytes changed. Native I/O errors remain private causes; the public failure contract is ExchangeFailed. Focused contained evidence: test/unit/provider-core passes 24 tests, including raw-stream retention across cancelled TLS and failed closure; actual loopback TLS cancellation and aggregate-deadline regressions now observe peer closure. The integration lane additionally verifies an Ed25519 signature from the GET request received by the TLS peer, including escaped query and Host authority. This does not establish deployed API acceptance or body-digest wire coverage. Installed-contract coverage now imports all operational modules outside the checkout and excludes scientific/repository/test modules. The 36 focused repository checks and package Ruff checks pass. Independent read-only review found no runtime defect; its source-description correction was applied, followed by a second review with no new actionable findings. U/A audit disposition for this correction: U07 gains actual TLS retirement and composed-signature evidence; U08/U14/U17/U23/A01 gain socket ownership through handshake cancellation. U09/U18/U22/U19 status prose now distinguishes implemented transport from unfinished API/lifecycle work. A04 gains clean installed imports of every operational module. Scientific behavior, upstream code and sibling repositories remain untouched. Total Upload work budgets (U13), recipient-visible scientific warnings (U24), and consuming protected transport causes in recipient projection (U23) remain obligations of their later owning slices. This correction does not close the package or note 003. Final focused rerun: test/integration/provider-core passes eight tests (including the composed signature), and test/contract/provider-core passes five tests. Signed Job-input operation slice, 2026-10-18 ------------------------------------------ ProviderAPI now owns one signed, bodyless Job-input GET. It validates the catalog key before any exchange, uses a fresh nonce/time, admits the exact success HTTP headers, and delegates byte binding to verify_job_input. Feed authentication is an explicit caller precondition; FeedInputFacts alone proves shape, not authority. Composition retains transport retirement authority. No retries or scientific work are introduced. The API routes.py::JOB_INPUT_READ_ROUTE and security/ analysis_kind_refs.py at I govern the target, ceiling and catalog-key grammar. Package README links these exact sources and explains their role. ApiFailure keeps operation/status and private original response/cause. Cancellation remains CancelledError and leaves operation context in last_failure. Review caught that HTTP-number-only errors lost useful API meaning. A regression ran red before adding a bounded known-problem projection: reviewed type/status/code combinations map to local explanations, while arbitrary title/detail remain protected. Server request IDs remain structured correlation, not interpolated public text. Unknown, malformed, duplicate or mismatched problem documents retain the original private response and a generic HTTP explanation. Sources: I:security/problems.py and request_ids.py; the 4096-byte bound and grammar belong to that API boundary. This is not yet the recipient-rendering completion required by P4. Tests ran red for absent api.py, then green; the diagnostic regression separately ran red for missing structured problem facts. Final focused contained lanes: 31 unit, 9 integration, 5 installed contract and 36 repository checks pass; package Ruff passes. The finite TLS peer now accepts a response payload so integration can exercise correct and substituted Job identities through real transport. It observes socket closure and exact transmitted route; signature-presence checking here is not cryptographic server verification. The separate transport signature test supplies that local witness; neither establishes deployed API acceptance. Independent protocol/error reviews found no further actionable runtime findings after the diagnostic correction. A separate full U01-U26/A01-A10 scope review required an explicit feed-authentication precondition and current package guidance; both were corrected. U05/U07-U11/U13-U15/U23/U25/U26 and A01/A03-A05 have local behavioral evidence; U16-U18/U22 have source/intent/status documentation. Scientific U01-U04/U06/U24 and A02/A06-A09, Make U12, dependency U20/U21 are unchanged by this slice. U19/A10 preserve purposeful history without raw run-log retention. This review does not waive those requirements for later scientific or lifecycle work. Membership/grant operations, total Upload budgets, durable Attempt effects, recipient projections and adoption/end-to-end qualification remain unfinished. Upload membership and grant API slice, 2026-10-18 ----------------------------------------------- ProviderAPI now exposes uploads(job_ref) and read_grant(job_ref, upload_ref), using its existing signer/transport owner. Both are bodyless; membership GET has no query, and grant POST has no Content-Type or Content-Digest. The route-owned response ceilings are 2097152 and 65536 bytes. upload_response.py owns exact wire admission and immutable Job-bound membership/grant observations. It preserves pending hashes, full ordered descriptions and resource identity independently of content identity. Grant Job context comes from the request, not an echoed field. Wire sources at I: provider/routes.py::JOB_UPLOAD_SET_READ_ROUTE and JOB_UPLOAD_READ_CAPABILITY_ROUTE; provider/schemas/job_upload_set_read_response.v1. schema.json; wire/upload_read_capability_response.py; wire/upload_transfer_schemas.py; json_datetime.py; upload_store_target.py. These own membership limits, exact fields, nullable hash, 359-character URL bound, 2048-character bearer and canonical UTC expiry. The named records are inert observations: no store request, current-source freeze, configured-origin admission or byte-verification claim is made here. Those effects belong to the next Job-scoped acquisition slice. The grant POST may extend retention before its reply is lost. ApiFailure retains issuance_may_have_committed and a safe note on uncertain failures, including cancelled/failed transport and malformed replies. No implicit retry occurs. This is evidence about this call only, not reconciliation of an earlier grant. Reference validation and signing failures precede transport handoff. A busy/locally refused transport is conservatively uncertain; API code does not inspect transport internals to manufacture dispatch certainty. Review corrected overly broad uncertainty and useful-reason loss. Pinned I: security/problems.py::_PROBLEM_SEND_EFFECT_DEFAULTS establishes no domain change for recognised authentication failures, but explicitly makes no assertion for generic authorization/not-found/conflict categories. I:operations/errors.py:: ProviderJobUploadReadNotFinalized and ProviderJobUploadReadPurgeInProgress explicitly promise no new link; provider_job_upload_read_capability.py raises those before issuance. Only these admitted exact 409 meanings and reviewed 401 meanings narrow this grant's uncertainty. Local explanations tell the caller to finalize the existing Upload, or seek another authorized source after Project purge. Arbitrary server detail stays private. A review suggestion to treat all 403/404 replies as no issuance was rejected against the exact source; the reviewer corrected it. Tests-first evidence: missing Upload methods failed before implementation. The reviewed-refusal test then failed before certainty/409 diagnostics were corrected. Focused contained lanes pass: 39 unit, 11 integration, five installed-contract and 36 repository tests. Actual TLS tests cover membership/grant observation and cancelled grant with one received request, retained uncertainty/transport cause and peer-side closure. Maximum membership exercises all 64 full descriptions; pending hashes, ordering, duplicates, foreign identities, invalid scalar/date/number/schema, malformed/oversized JSON and secret-safe failures are covered. Installed inventory includes the wire module. These remain local tests, not deployed API/store proof. Independent protocol, failure and full U/A reviews found no further actionable code/test issue after correction. Applicable U05/U07-U11/U13-U17/U23/U25/U26 and A01/A03-A05 have explicit boundary witnesses; U18/U22 public guidance is updated. Scientific scope, Make, dependency and preservation dispositions are unchanged from the preceding slice. Total transfer budgets, membership refresh/invalidation, store target admission, expiry and exact downloaded-byte verification remain next; Attempt lifecycle, recipient projections and P5 qualification remain unfinished. Package Ruff and the affected eight-test normative rerun also pass after replacing an ambiguous Unicode fixture character with an unambiguous Unicode character. Final documentation recheck found no new actionable issue. Job-scoped acquisition and shared budgets, 2026-10-18 --------------------------------------------------- JobUploads is the sole source-session owner: inspect current membership, select a reference, admit source size, refresh the whole observation, obtain fresh access, bind grant facts and destination, then verify the complete bytes. Per-source size and remaining total byte allowance are admitted before grant issuance. Observed membership changes or any failed acquisition invalidate selection; explicit inspection is required before another attempt. No byte cache, retry loop or parallel source worker is introduced. Pending hashes may finalize through the grant; changes observed in refreshed membership require reselection. The API does not supply an atomic freeze after the last observation, and this code makes none. Explicit UploadLimits bound each source, total consumed store-body bytes, request count and session duration. Inspection/refresh/grant/store calls share the request and time limits from source-owner construction. Metadata retains its route-specific body ceiling; it is bounded in aggregate by request count, not charged to the store-body byte counter. HttpTransport accepts one synchronous byte-accounting callback, invoked before rejecting an oversized chunk. Failed/cancelled consumed bytes remain charged. An offending chunk can take the counter over the allowance; it is recorded and rejected, not forgotten. This is application-body accounting, not an OS traffic quota. No late verified-byte handoff is permitted after deadline. Hashing remains synchronous under the per-source byte bound; the final clock check rejects its late result rather than claiming preemptive CPU interruption. All returned bytes are immutable and length/SHA-256 verified. Private intermediate bytes remain in bounded session memory; no plaintext staging files are created. Configured canonical store origin and exact API Upload path must match before the bearer is attached. Store requests contain no provider signature, request body, content headers or Range. HTTP 200 and singleton no-store/octet-stream/exact-length/ Content-Digest headers are checked independently of actual byte hashing. Original private response/cause evidence is retained for diagnostics; public errors do not render bearers or source bytes. API/store transports stay independently supplied and composition-owned. The transport's retirement_confirmed property reports its actual unresolved task/cleanup state; source work refuses unresolved store cleanup. Provenance/rationale: I:upload_transfer_http.py::_read_response_start and upload_transfer_http_contract.py own the exact store method/path/header contract. S:src/secs_inference/provider/{job_api,upload_download}.py at the pinned S revision is the source-ordering precedent. The local implementation does not import or copy sibling code; it adds explicit async session accounting and existing transport retirement composition. Exact links and public method contracts are in package README. Neither tokens nor a metadata receipt establish membership freshness or actual bytes; this separation motivates the ordering and independent checks. Tests-first failures: absent uploads.py; verification completing after the session deadline; and missing confirmed-issuance evidence after a successful grant followed by a failed local/store check. Review found the latter two, regressions reproduced them, and fixes now reject late results and retain grant_issued plus safe context. Caller cancellation stays CancelledError, with protected original evidence retained. A grant-time timeout keeps ApiFailure's possible-issuance fact without claiming confirmed issuance. A later failed transfer cannot erase successful issuance. Focused contained evidence covers exact-byte success and pending-hash finalization; foreign target refusal before bearer dispatch; changed observations; failed grants with changed/unchanged explicit reinspection; expired/mismatched grants; same-length hash corruption; shared request budget; overlap refusal; retirement gating; final verification deadline; and consumed failed bytes. Separate real TLS API/store peers prove signed API calls, bearer-only store calls, socket closure, partial transfer cancellation/deadline accounting and oversized-chunk charging. These establish local composition, not deployed API/store availability or an actual sibling migration. Installed inventory/import checks include uploads.py; shared test doubles remain in fakes, successes in normative, faults in adversarial and sockets in integration. Independent protocol/failure/full-U&A reviews converged after the deadline and issuance-evidence corrections. U05/U07-U11/U13-U17/U23/U25/U26 and A01/A03-A05 have behavioral witnesses; U18/U22 documentation is current. Scientific, Make, dependency and preservation dispositions remain unchanged. P3 Attempt persistence/recovery, P4 recipient delivery and scientific composition, and P5 adoption/deployed end-to-end qualification remain unfinished; local acquisition completion does not close them. Final focused validation: 53 unit tests (44 adversarial and nine normative), 14 integration, five installed-contract and 36 repository checks pass; package Ruff passes. Only affected lanes were rerun after the final corrections. 2026-10-18 P3 first boundary: read Attempt and Job lifecycle observations ----------------------------------------------------------------------- ProviderAPI.read_attempt(execution_attempt_ref, job_ref=...) now performs the bodyless signed read, admits the exact five-field/65536-byte response and binds both identities to the caller's retained obligation. It returns immutable named states without folding Job cancellation/closure into Attempt terminalization. Authority: I:nmr_api/provider/routes.py::EXECUTION_ATTEMPT_READ_ROUTE and I:nmr_api/provider/schemas/execution_attempt_read_response.v1.schema.json, at the I revision pinned above. Their rationale matters: in_progress may coexist with closed/cancelled, and the response has no terminal content identity. A read cannot establish which result/failure bytes committed or whether science ever started. Generic bounded JSON decoding moved from upload_response.py to response_json.py, shared by the two actual schema owners. ResponseRejected replaces the Upload-only exception name throughout core; no unused compatibility alias was retained. Domain fields, identity checks and state meanings remain in their schema modules. Tests first failed with the missing read_attempt method. Focused installed tests then admitted all 12 independent state combinations and rejected foreign identity, unknown/missing/duplicate fields, malformed/oversized JSON, invalid states and request target injection. Transport and cancellation failures retain protected evidence and do not retry. A finite verified TLS peer confirms exact GET routing and socket retirement. These are local boundary proofs, not deployed API proof. Independent wire, failure and all-U/A disposition reviews found no actionable implementation issues. Scientific/Make/dependency/preservation scope is unchanged. This is only the read boundary: start/progress/terminal mutations, durable recovery, P4 composition/recipient delivery and P5 qualification remain open. Validation: 58 package unit tests, five installed-contract tests and 15 integration tests pass in the offline contained lanes; package Ruff passes. No broad repository or scientific suite was run for this read-only protocol slice. 2026-10-18 P3 start protocol: exact retained requests and uncertain admission -------------------------------------------------------------------------- start_body(Job, key) builds immutable request bytes with an explicit caller key. ProviderAPI.start_attempt accepts retained bytes, validates the 4096-byte exact request schema before dispatch and sends those same bytes with fresh signing. Expected Job/kind/provider bind the returned AttemptAdmission. Terminal replay states are admitted as observations, never a trigger to run scientific work. Persistence before first send and before execution is the lifecycle owner's next obligation; this protocol layer does not itself provide durable recovery. Authority and rationale: I:nmr_api/provider/schemas/execution_attempt_start_request. v1.schema.json and execution_attempt_start_response.v1.schema.json specify wire facts; I:nmr_api/provider/routes.py::EXECUTION_ATTEMPT_START_ROUTE and I:nmr_api/operations/execution_attempt_start.py specify unchanged replay and replay-before-new-admission ordering. Generating a new key can create a different logical start; retaining the original body prevents reconstruction from changing its facts. Fresh request authentication must not change those facts. All I references use the previously pinned 6a163b7 revision, with complete links in the package README and source ownership comments. ApiFailure.attempt_mutation_may_have_committed preserves uncertainty for this send on transport/cancellation/envelope/parser failures. I:nmr_api/security/problems.py marks admitted401 and the selected409 start codes as no_domain_change for THIS send: provider_attempt_key_conflict, job_provider_attempt_limit_reached and job_attempt_limit_reached. Generic403/404/503 and other409 remain uncertain. A later refusal cannot clear the retained uncertainty of an earlier failed send. Grant issuance evidence remains separate. Original response and cause stay protected. Tests first failed on the missing start API/request module. The contained package lanes now pass 64 unit, five installed-contract and 17 integration tests; Ruff passes. Exact legal whitespace/order survive explicit replay; real TLS tests independently verify received body bytes, SHA-256 and Ed25519 signatures, fresh authentication, terminal replay and cancellation/socket closure. Invalid requests send nothing; malformed/foreign success and failed exchanges cannot imply absence of an admitted Attempt. No broad scientific/repository suite was run. Independent protocol, failure and full-U/A disposition reviews found no actionable implementation issues. This closes only start's protocol boundary. Progress and terminal publication, persistence/recovery, NMRNet composition, recipient delivery and deployed/adoption qualification remain open under the unchanged full goal. 2026-10-18 P3 progress protocol: current observations, not execution authority --------------------------------------------------------------------------- ProviderAPI.progress_attempt now signs a single PUT with the current phase and public condition code. The immutable acknowledgement binds Attempt/phase/code and preserves the original observed timestamp. Both phases may be first. A repeat of stored facts may succeed after terminalization; it proves neither process liveness nor scientific execution. No historical queue, automatic retry or work restart is introduced. Composition still owns observation freshness and safe code vocabulary. Sources: I:nmr_api/provider/schemas/execution_attempt_progress_request.v1.schema.json and execution_attempt_progress_response.v1.schema.json; I:nmr_api/provider/routes.py ::EXECUTION_ATTEMPT_PROGRESS_ROUTE; I:nmr_api/operations/execution_attempt_progress.py and errors.py::ExecutionAttemptProgressTerminal/ExecutionAttemptProgressRegression. All use pinned I revision 6a163b7; complete links are in package README. The shared HTTP effect table omits these progress codes, but their explicit operation errors and pre-write refusal branches establish no change for this update. Review caught this distinction before implementation closure; the client uses that more precise fact without resolving prior uncertainty. Interrupted/malformed replies remain uncertain, and original response/cause evidence stays protected. Tests first failed on missing progress_attempt. Focused offline installed-package lanes now pass 68 unit and 19 integration tests, including signed PUT body/digest, both phases, null/maximal conditions, original repeated timestamp, foreign replies, known refusals, cancellation and socket closure. Ruff passes. The shared Attempt timestamp helper retains start's validation; its existing tests also passed. No new runtime modules or dependencies were added; the unchanged inventory contract and broader repository/scientific lanes were not rerun for this change. Independent protocol, failure and full-U/A reviews found no actionable source findings; documentation closure preserves these scope and evidence limits. Outcome publication, durable lifecycle/recovery, NMRNet recipient composition and deployed/adoption qualification remain open. Local progress transport is not proof of any of those end-to-end requirements. 2026-10-18 P3 terminal wire boundary: retain and reconcile the chosen outcome ------------------------------------------------------------------------- complete_body/fail_body build exact terminal requests; complete_attempt/fail_attempt validate retained bodies before dispatch and send them unchanged. Completion binds the returned Attempt/schema/hash/length to decoded opaque result bytes; failure binds exact code/message. Separate result-reference validation does not confuse resource identity with content hash. Both acknowledgements preserve committed time and boolean replay status. Allowed scalar text, controls and whitespace are not normalized. Shape validation does not decide which diagnostic text is publishable; composition must protect confidential evidence before building a failure request. Authority: I:nmr_api/provider/schemas/execution_attempt_{complete,fail}_{request, response}.v1.schema.json, I:nmr_api/provider/routes.py terminal route declarations, I:nmr_api/operations/canonical_content.py and execution_attempt_outcome.py. All refer to pinned I 6a163b7; package README links each exact schema. The service's exact existing-result/failure comparison explains the retention/replay choice. I:nmr_api/security/problems.py explicitly assigns current-send no change to outcome expiry, opposite-outcome and terminal replay mismatch codes. The client admits those precise meanings but never clears earlier uncertainty from them. Unknown, malformed, interrupted or cancelled publication remains uncertain with protected original evidence. No operation retries, switches terminal choice or runs science. Tests first failed on missing terminal builders. Focused installed-container lanes pass 76 unit and 21 integration tests. Unit cases include opaque non-UTF8 results, canonical-base64 pad bits, exact scalar preservation, invalid/oversized retained requests, foreign acknowledgements and earlier uncertainty followed by refusal. Review identified a maximum-payload witness gap in the builder-only test. Added real TLS cases now send/replay the maximum 786432-byte result and 1024 supplementary Unicode failure scalars through admission/signing/acknowledgement. They also verify SHA-256 and Ed25519 from received requests, fresh signing on explicit identical resend after connection loss, and cancellation/socket closure for both operations. The scripted peer does not implement database commits; its replay acknowledgement is client-handling evidence, not proof of server idempotency or durable recovery. Independent protocol, failure and full-U/A reviews found no runtime defect; the identified U07 evidence gap is closed by composed tests. No new runtime files or dependencies were added. Package Ruff passes; final independent documentation reviews found no residual actionable signal. Durable retention/capacity, claim exclusion, recovery and execution-entry ownership are still P3 work. NMRNet/recipient integration and P5 qualification remain open; finishing the wire operations does not close the goal. 2026-10-18 P3 pending-start records and explicit recovery scope ------------------------------------------------------------- Inspected P:nmrpeak_provider/attempt_journal.py and attempt_journal_store.py; S:src/secs_inference/provider/attempt_state.py; M:magnet_provider/terminal_outbox.py. P's admit/replace/_replace_record/_require_recovery_space establish the intended next storage ordering: private bounded reads, expected-record comparison, staged write, file fsync, atomic replacement and directory fsync, plus retained uncertainty after failures. Free-space arithmetic is not physical reservation against other disk writers. M's owner binding separates API/provider identity from record bytes. Use these behaviors, not a sibling-specific journal schema or sync control loop. Design review narrowed the first implementation to pending starts rather than freezing all future lifecycle records before their consumers exist. StartPending retains exact start body, input identity and expected analysis kind. RecoveryScope adds canonical API origin, provider, consumer/lane and generation identity; restore requires an explicit matching scope. No credential, live handle or prepared-input fingerprint is serialized. Future prepared state is historical evidence only; repreparation requires explicit source/generation policy and a fresh admitted handle. Terminal records must preserve execution-entry/retirement facts and keep request/evidence through confirmed publication. These remain required next slices. The new bounded codec rejects missing/unknown/duplicate/malformed fields, foreign scope, noncanonical base64 and body/Job mismatch. Encoding preserves the exact request, including legal whitespace/order. Reviews found an actual closure defect: unbounded origin text could encode beyond the 65536-byte decode ceiling. A focused regression reproduced it; encoding now checks actual serialized size before emitting bytes. No arbitrary DNS-length rule was added. The redundant state field was also removed because the pending-start schema already identifies this single state. Contained installed validation passes 83 unit tests and five contract tests; Ruff passes. Contract checks establish installed module inventory/import independence. The final bound correction reran the affected unit lane; unchanged inventory was not retested. Independent wire/failure/all-U&A reviews found no residual source findings after correction. No filesystem durability, cancellation ownership, claim exclusion or restart proof is claimed by this pure codec. Full-sized retention capacity, owned async file I/O, later lifecycle states, recovery and P4/P5 remain open under the original goal. The 65536-byte pending-record ceiling must not become the future terminal retention reservation. 2026-10-18 P3 owned pending-start storage --------------------------------------- AttemptFiles owns blocking private-directory operations; AttemptStore owns one submitted worker future on the async control loop. Admission uses bounded reads, same-key comparison, exclusive staging, file fsync, exclusive publication and directory fsync. Identical requests preserve the original obligation; conflicting facts cannot overwrite it. Local flock excludes cooperating processes using the same directory inode, not other hosts or directory-path substitution. The source docstring and package README identify P's precise storage precedent and the intentional difference: retain cleanup failures rather than suppress them. Cancellation/timeout leaves the original operation owned. New work and close are refused until explicit settlement; no second write is submitted. Publication failure preserves staging and any visible target and poisons further use. Visibility does not imply durability. Reopening validates and syncs the retained inventory; unknown staging requires explicit reconciliation. Slot/headroom arithmetic covers supplied full-record budgets, but does not reserve physical disk against unrelated writers. Full terminal record sizing remains part of the later lifecycle qualification. Tests first failed for the missing store. Independent audits then found a real U14 defect: only directory-close failure recorded uncertain retirement. A reproduced regression showed that failed record/staging closure could be hidden by successful directory closure. All owned close paths now retain sticky uncertainty, never retry a detached descriptor number, and still attempt remaining directory cleanup. Primary errors and cleanup evidence remain separately available for protected use. Focused installed-container validation: 93 unit tests and 22 integration tests pass. Five installation contracts passed for the new module inventory. Tests cover short writes, file/directory fsync, link/unlink and write failure, preserved cleanup evidence, visibility versus durability, duplicate/conflicting keys, headroom refusal, cancelled/expired waits and settlement of the original write. A separate-process integration test proves lock exclusion and successful readback after owner closure. These are local filesystem/runtime witnesses, not power-loss or cross-host proof. Applicable U07/U08/U11/U13 fault evidence and U14 retirement findings are resolved; independent wire, failure and full-U/A source reviews found no residual actionable issue. This slice admits pending starts only. Active/terminal states, replacement, execution-entry ownership, recovery policy, NMRNet composition, recipient diagnostics and end-to-end/sibling qualification remain required under the active goal. Final documentation review corrected stale future-owner wording; the existing file owner checks composition-supplied capacity. Ruff and the final affected adversarial lane (73 tests) pass after binding test fault callbacks explicitly. 2026-10-18 P3 acknowledgement and durable execution entry -------------------------------------------------------- AcknowledgedAttempt nests the original StartPending and admitted start response, plus LocalExecutionPhase.NOT_ENTERED or EXECUTION_ENTERED. Both server and local facts survive restart independently. Terminal start replays remain representable but cannot construct or transition to execution-entered state. Preparation remains a live, session-owned handle, not a serialized prepared flag. Source/README cite P:attempt_journal.py::bind_started_attempt/mark_execution_entered and P:attempt_lifecycle.py::PreparedForExecution at the established pinned revision. The retained terminal replay is an intentional extension of P's active-only record. AttemptStore.replace compares the entire expected retained record and permits only implemented forward transitions. Original start bytes and acknowledgement facts cannot change. Replacement stages, syncs, atomically replaces and syncs the directory; one existing slot suffices, with headroom for growth and staged replacement. A failed replacement preserves the old or installed new record and blocks further work. Cancellation retains the original worker result for explicit settlement. The read and minimum-capacity bounds grew together to cover the bounded pending document, bounded acknowledgement and envelope; pending encoding retains its 65536-byte cap. Tests first failed for missing transitions. The first implementation exposed a classification error: invalid pre-effect transitions became StoreFailed through the async boundary. They now produce StoreRefused before storage mutation. Review found the same inconsistency for oversized initial admission; its regression also failed before correction. Neither refusal poisons storage or writes staging data. Focused contained validation passed 102 unit and 23 integration tests before that final admission-classification correction. Replacement tests cover staging write, file sync, atomic replace and post-replace directory-sync failure, original-future settlement after cancellation, exact headroom limits, stale/foreign/backward refusal, and a maximum pending record through acknowledgement/entry encoding and decoding. A child process exits without cleanup after durable entry; the next owner reads the entered record and cannot mark another entry. This establishes local process restart retention, not power-loss proof or a complete scientific recovery workflow. Independent wire, failure and applicable-U/A reviews resolved the replacement fault evidence gap. NOT_ENTERED remains historical state, never proof of a prepared handle. This slice does not invoke science: lifecycle claim checks, fresh server observations, preparation/generation policy and ordering the actual handle call remain required. Terminal retention/evidence, publication replay, inventory recovery, NMRNet binding, recipient diagnostics and P5 qualification remain open under the original goal. The final affected adversarial lane passes all 80 tests after the admission fix; package Ruff passes. Final independent wire, failure and full applicable-U/A reviews report no residual actionable source or documentation finding. 2026-10-18 P3 immutable terminal records and required evidence ------------------------------------------------------------- TerminalPending retains the acknowledged Attempt, COMPLETE/FAIL operation, exact request and required ProtectedEvidence. TerminalConfirmed adds only a receipt validated against that exact request. TerminalHeld retains an operation-specific expiry, opposite-outcome or replay-mismatch conflict and optional request ID. CAS cannot replace the chosen outcome/evidence, reverse a hold or return to execution. These are record semantics; the actual claimed publisher/recovery loop is next. Evidence uses a binding-owned schema and immutable 1..262144 bytes. The ceiling is grounded in P:nmrpeak_provider/attempt_diagnostic.py::MAX_DIAGNOSTIC_BYTES at the established pin; its history-trimming behavior is intentionally not copied. Required evidence is rejected when oversized, never silently shortened. S:execution.py's record_report-before-publication ordering grounds the evidence-first obligation. Binding owns necessary causal/retirement facts, content meaning and secret removal. Core owns exact private retention and bounds, not automatic secret detection. Review clarified that unresolved worker cleanup must remain retainable: requiring retirement before saving an outcome could lose primary evidence when cleanup fails. Receipt and retirement are independent. This slice does not release claims, delete records or reuse workers. Typed execution identity/retirement authority belongs with the real preparation/handle owner, not an invented boolean in a byte codec. Opaque evidence and a matching server receipt must never become resource-release proof. The maximum retained record derives from bounded start/admission, the full 2 MiB completion request (including legal whitespace), request/evidence base64 expansion, schema metadata and a bounded receipt. Read and minimum StoreLimits capacity share that bound, checking configured headroom for full outcome capacity before initial admission; physical blocks are not reserved. Actual encoded length is checked. Request JSON is never normalized; nested records stay JSON objects rather than recursively base64-expanding the entire envelope. Tests first failed for missing terminal records. The unit lane then passed 109 tests. Added composed cases pass all 24 integration tests: maximum completion/failure bodies, maximum evidence and supplementary-Unicode schema/message text, maximum pending-start envelope, matching receipt, exact minimum record budget, actual storage and reopen. The final affected adversarial lane passes 88 tests: foreign/corrupt nested records, canonical-base64 rejection, wrong receipts/hold metadata, safe rendered tracebacks, full-capacity admission, immutable outcome/evidence and held-state reopen. Evidence sync failure preserves the prior acknowledged record and exact staged evidence while blocking reuse. Package Ruff passes. No dependency/module-inventory change occurred. Source references/rationale are recorded in attempt_record.py and package README. Publication send ordering, exact replay after lost acknowledgement, durable receipt failure, held-conflict dispatch prevention, execution/claim ownership and real recipient delivery still require orchestration witnesses. No scientific or deployed recovery claim follows from these storage tests; P3/P4/P5 remain open under the full goal. Final independent wire, failure and applicable-U/A reviews found no residual source issue. Documentation review corrected reservation wording to describe headroom checks. P3 publication slice (2026-10-18) ------------------------------------------------------------------- TerminalPublisher now observes the exact durable pending record before sending, then retains the matching receipt or reviewed operation-specific conflict. It never retries implicitly, changes the original outcome, or releases worker/lifecycle ownership. Actual TLS reply loss plus store close/reopen proves explicit unchanged resend and durable confirmation; the previous pending record cannot be sent again. AttemptClaims shares one local registry across lanes/recovery, keyed by API origin, provider and remote Attempt. Consumer/generation labels cannot partition a remote Attempt's ownership. The precedent is Magnet revision M's magnet_provider/provider_attempt_recovery.py::ProviderAttemptOwnership; exact replay follows P's nmrpeak_provider/attempt_journal.py::prepared_terminal_replay and required report retention follows S's src/secs_inference/provider/execution.py::_publish (pins above and source/README; paths and symbols checked against pinned Git trees). This is local exclusion, not distributed locking or proof that a scientific worker has stopped. Independent review caught two concrete defects and both received regressions: - Settlement previously retired whichever API exchange was active. Transport now records its admitted caller and refuses foreign retirement; publisher settlement touches only its own network/storage operations. Foreign activity neither loses its result nor pins this publisher's claim after its own work has settled. - Cancelled settlement previously replaced the original publication failure. Protected evidence now preserves the original cause and ordered subsequent settlement failures/cancellations, while CancelledError still propagates. Tests-first witnesses failed before the fixes. Measured contained lanes: 123 unit, 25 integration and 5 installation-contract tests pass; the final affected adversarial rerun passes 96 tests and package Ruff passes. Reviews cover wire/failure and applicable U/A items, particularly U05/U07-U11/U14/U15/U17/ U18/U22/U23/U25/U26 and A01/A03-A05/A10. Other scientific/runtime adoption items are outside this slice, not certified by these tests. No dependency acquisition, sibling change, upstream change, worker execution or deployed-service claim. Still required for the full goal: start/recovery orchestration and generation policy, live execution-handle/retirement authority, recipient diagnostics and NMRNet composition, sibling reuse and end-to-end qualification. Receipt-storage failure pins an unretained confirmed outcome for reconciliation; no automatic rewrite or worker-release policy is implied. P3/P4/P5 remain open. Final independent wire, failure and applicable-U/A re-reviews report no remaining actionable finding in this slice. Reviewers inspected sources; the coordinator ran the contained tests above. The scripted TLS peer proves client replay behavior, not deployed server idempotency. No full-package completion is claimed. P3 durable start slice (2026-10-18) --------------------------------- AttemptStarter now owns initial pending retention or explicit existing-record replay, one exact signed start, synchronous reference binding, and durable server acknowledgement. It returns only the retained AcknowledgedAttempt; execution remains NOT_ENTERED even for a replay. Terminal start acknowledgements are preserved too. No preparation callback, execution permit or worker-release grant is introduced. Before a remote reference exists, AttemptClaims.claim_start excludes the provider attempt key across Jobs, lanes and generations. Binding adds the received remote reference to that same handle without releasing the key; explicit release removes both. A conflicting remote owner preserves its authority, while the starter retains the received admission privately and remains pinned for reconciliation. Recovery of already acknowledged records must acquire both identities in the forthcoming lifecycle owner; remote-only claim() is not a substitute for pending-key exclusion. Sources, checked in the pinned Git trees and linked in package README: - I:nmr_api/operations/execution_attempt_start.py:396-412 reserves provider keys across Jobs. Key ownership therefore excludes Job/lane/generation partitions. - P:nmrpeak_provider/attempt_lifecycle.py:442-508 retains initial admission; :648-695 consumes the retained start and binds server acknowledgement; :1636-1664 checks generation before pending-start replay. Review corrected the earlier attribution of retention to :648-695 alone. Start and terminal publication keep separate owners: start binds two identities, whereas publication classifies terminal conflicts. Review rejected a generic transaction framework as unnecessary. Both use exact owner tags for asynchronous storage and API settlement. Initial-retention settlement sends nothing and returns no acknowledgement; interrupted acknowledgement replacement returns only its original completed write. Neither path silently repeats work. Failed replacement or alias binding preserves protected admission and primary cause; settlement adds secondary failures without replacing the primary. Reconciliation remains explicit. Tests first failed for absent start ownership and starting module. The first unit run then passed 126 tests. Added adverse witnesses pass 104 adversarial tests: initial-retention failure sends nothing; cancellation before start preserves foreign API activity; acknowledgement-write failure/cancellation retains identity and claims; reference conflict preserves both owners; stale/absent/wrong-generation recovery sends nothing; same key across Jobs/lanes remains exclusive. The 26 integration tests include real TLS response loss, original pending retention, store close/reopen, explicit byte-identical replay and durable acknowledgement, with no third stale send. Five installation contracts and package Ruff pass. These are contained client-side proofs with scripted peers, not deployed server idempotency or scientific execution. Independent source/failure/wire and applicable-U/A reviews found no behavioral finding after the source-reference correction. Relevant dispositions: U05/U07-U11/ U14/U15/U17/U18/U22/U23/U25/U26 and A01/A03-A05/A10; science, deployment, dependency and Make policies remain unchanged. Remaining full-goal work: claimed recovery of later states and inventory candidates, preparation/live handles, progress and durable entry ordering, actual retirement authority, recipient diagnostics, NMRNet binding, sibling reuse and complete 003 qualification. P3/P4/P5 remain open. P3/P4 scientific preparation boundary (2026-10-18) ------------------------------------------------- Source inspection before connecting core execution found a real integration gap: prepare_direct_job supplies geometry, but dictionary admission and tensor-derived input rejection still occurred inside the direct inference path. A prepared-data record is not a live execution handle. Existing inference_native retirement also explicitly covers local client processes only, not the scientific container. PredictionSession now provides the synchronous scientific side of that boundary. It parses and dictionary-admits the request, then composes every required H/C tensor before returning a private, opaque current handle. This includes centered-coordinate and pairwise-distance finite checks, not only syntactic/dictionary admission. Replacing preparation invalidates the old handle even if the replacement fails. Execution accepts only the current object, consumes it before the first model load, and cannot be retried after a partial head or loader failure. Prepared tensors and dictionary remain private. A serial isolated worker must own this session; there is no claim of thread safety, asynchronous cancellation or engine-side retirement. Identity precedent verified in pinned P:nmrpeak_provider/runner_session.py:333-350, generate: current request object and state are checked before entering generation. The link/rationale appear in README and predict.py. NMRNet model/scaler calculation was extracted unchanged into predict_composed_element; predict_element calls it after composition, while the new session calls it with already admitted tensors. The direct predict_request entrypoint preserves its existing ordering and behavior, sharing source admission and result aggregation. Scientific units, selected release, head selection, atom ordering, scaling and numerical tolerances are unchanged. Both prepared tensor sets now coexist (bounded by the existing 128-atom limit); model/scaler references still remain scoped to one H/C head at a time. Tests-first session tests failed for the absent PredictionSession, then passed. Measured contained lanes: test/unit/prediction-input passes 37 tests; prediction/tensor-parity passes 26 tests. New cases prove invalid/stale/foreign/None handles cannot execute, rejection revokes old preparation, model failure consumes execution, later-head failure returns no partial result, real tensor overflow fails before model loading, and execution does not recompose input. A deterministic real Torch forward and scaler give exactly equal direct/session outputs. This is synthetic model composition evidence, not qualification of the new session with released weights. Existing reference tensor comparisons still pass. No upstream or sibling code changed. Runtime-source Ruff passes. Direct Ruff over the two legacy test files reports 29 pre-existing findings; the same 29 were confirmed against exact HEAD copies. Unrelated formatter changes were removed, leaving the new tests and intended source edits only. Independent failure, scientific/mechanical and applicable-U/A reviews found no actionable behavior defect; reviews explicitly corrected the tensor-lifetime and scientific qualification descriptions. U01-U05/U07-U11/U13-U19/U21-U23/U25/U26 and A01/A03/A05 remain distinguished from unexecuted deployment/science claims. Next integration remains required: a real asynchronous worker/controller owning exact execution identity and confirmed container/grant retirement; core preparation, progress and durable execution-entry ordering; subsequent recovery and recipient projections. The session alone does not make provider-core or 003 complete. P3 execution orchestration boundary (2026-10-18) ----------------------------------------------- AttemptExecutor now connects retained admission, verified input, preparation, execution entry and terminal retention under one continuous lifecycle claim. AnalysisSession names the binding-owned asynchronous preparation/execution/retirement contract; core does not manufacture or serialize its live handle. Session ownership transfers only after local admission and claim acquisition. Preparation failures classified by the binding may produce a retained failure without entering science. Unexpected binding or encoding exceptions retain their original cause instead. Source: P:nmrpeak_provider/attempt_lifecycle.py::execute_prepared, lines 1130-1240, verified at 1697dc84dd1d76ae25b04efc8183fd80614000e5 (README links exact revision). Confirmed running progress precedes durable execution entry; fresh server readback then precedes handle invocation. Readback is a snapshot, not atomic exclusion against later cancellation. The outcome is held before encoding/persistence, so failure cannot silently replace it or authorize another execution. TerminalPending and its required evidence are retained before retirement and subsequent TerminalPublisher handoff. Retirement must confirm stopped work and released grants. Python cancellation is not that proof. Failure paths attempt retirement; a failed normal retirement is not retried implicitly while handling its own exception. Explicit settlement attempts independent session/API/storage cleanup even when another cleanup fails, retaining primary and ordered secondary evidence. It never resumes preparation or invokes science. Claims remain pinned for uncertain writes, unretained outcomes or unconfirmed retirement. Tests first failed for the absent execution modules. Contained focused lanes then passed: normative 30, adversarial 112, integration 27, installation contracts 5. Package Ruff passes. New adverse cases cover failed running confirmation, oversized observed outcomes, cancellation during entry/terminal writes, stopped Job readback, failed terminal retention and failed retirement. An independent review found that a known StoreRefused incorrectly left prospective write uncertainty: a regression failed before correction, then passed. Unretained outcomes remain a separate obligation. Repeated independent failure, wire and applicable-U/A reviews found no remaining behavior defect in this slice; broader missing lifecycle behavior remains listed below. The new TLS integration performs start -> prepare -> execute -> terminal publication using the real client/store and a recording session. It observes seven requests and retained TerminalConfirmed under one claim. This proves composition and ordering; it does not qualify real NMRNet execution, worker retirement or deployed API behavior. Remaining P3/P4/P5: observe stop/expiry while preparation or execution is pending; implement actual asynchronous NMRNet worker/controller ownership and bounded, authoritative container/grant retirement; recover later records with both claim identities; project recipient diagnostics; qualify sibling reuse and full 003 paths. The package and full provider remain incomplete. P3 observation during preparation and execution (2026-10-18) ------------------------------------------------------------ AttemptExecutor now owns the original asynchronous task for each session phase. While it remains pending, sequential owner-tagged reads check Attempt/Job state. A final read admits successful returns; an already failed binding needs no further acceptance read. No watcher, scheduler, task replacement or automatic science retry was introduced. Explicit positive finite poll_seconds controls cadence, while each read retains the API exchange deadline. Session I/O must use a separate transport. Precedent verified at P 1697dc84dd1d76ae25b04efc8183fd80614000e5: nmrpeak_provider/attempt_lifecycle.py::execute_prepared, lines 1287-1340, polls generation and observes again before accepting candidates. README links the exact source. Preparation monitoring here extends that precedent. The scientific session still owns aggregate operation deadlines; polling does not bound science. A stop, failed poll or caller cancellation requests task cancellation only once. Session retirement and bounded task_settle_seconds observation are independent: either unconfirmed condition pins ownership. Settlement observes the same task, never resumes preparation or executes a handle. Task exceptions are retrieved to avoid leaking private causes through event-loop warnings; original and secondary failures remain available through protected ExecutionFailed evidence. The task captures an execution result or classified preparation failure before any acceptance read. A result arriving during a failed read or after initial cleanup times out updates the protected failure evidence and keeps the claim held. It is not replaced by a fabricated scientific failure or automatically published after stop. This is in-memory retention, not crash-durable suppressed-result recovery; that durable reconciliation remains required in the full lifecycle work. Tests-first observation cases failed on absent executor timing arguments before implementation. Independent review then found a failure-ordering issue: a newly started acceptance read could supersede an already completed binding exception. Retrieving that exception before any acceptance read fixes it; regressions cover both preparation and execution. Additional witnesses cover stop during each phase, a cancellation-resistant task with confirmed retirement, repeated settlement with no second cancellation, final stop after completed science, result during failed in-flight poll, late execution result after cleanup timeout, and caller cancellation during a pending owned read. These are recording-port race proofs; actual scientific container retirement remains unqualified. TLS lifecycle composition now performs nine requests including the two final acceptance reads. Measured contained lanes: normative 30, adversarial 119, integration 27; package Ruff and diff whitespace checks pass. Independent failure, applicable-U/A and wire reviews converged with no residual actionable finding after the exception-ordering correction and race witnesses. Relevant U07/U08/U13/U14 ownership and transparency claims are limited to these observations. P3 still needs delayed-persistence stop handling and durable recovery/reconciliation; P4/P5 still need actual worker/binding, recipient diagnostics and full scientific/sibling qualification. Goal remains open. P3 retained-request recovery and inventory ownership (2026-10-18) ---------------------------------------------------------------- AttemptClaims.claim_records now reserves all start-key and known remote aliases of a selected inventory atomically. Any existing owner or repeated identity refuses the complete selection before installing claims. claim_record provides the same behavior for one record. API origin and provider identify the ownership domain; consumer/lane and generation do not partition it. Storage still requires its explicitly opened recovery scope. The shared record accessor acknowledged_attempt exposes the existing admission without copying facts. AttemptRecovery owns one selection: StartPending delegates exact resume to the existing starter; TerminalPending delegates exact publication; acknowledged state only yields identity-bound readback with its unchanged local execution phase; confirmed/held state returns unchanged without API I/O. Each path checks current durable state. Child operations retain their own owner tags and settlement. Recovery never resumes a scientific handle, synthesizes an interrupted failure, deletes an obligation or releases the lifecycle claim. Selection/reservation is not proof that an old controller or worker stopped. Composition must exclude its mutation authority before replay and separately confirm worker/grant cleanup before reuse. Source verified from P 1697dc84dd1d76ae25b04efc8183fd80614000e5: nmrpeak_provider/attempt_journal.py:534-579, decide_restart/_terminal_restart. The precedent distinguishes exact start/terminal replay and bound observation; its consumer-specific preparation resumption, interrupted failure and deletion policies are deliberately not copied into core. README links the precise lines. Existing publisher conflict/receipt handling remains the single replay authority. Tests first failed on the missing recovery module. New cases cover atomic rollback on existing or duplicate remote identities across inventory, stale acknowledgement zero-send, entered-state readback without science, confirmed/held zero-send, and cancelled original inventory/readback settlement. Independent review found cancelled readback dropped current API diagnostic evidence: the fix captures it only around the actual API await, preserving it through settlement while excluding stale API failure during inventory cancellation. Paired regressions verify that distinction. The acknowledgement-write cancellation witness now runs through recovery and proves original-child settlement, one write and no resend. Existing lost-reply TLS tests now reopen storage, reserve the inventory, and replay exact start/terminal bytes through AttemptRecovery; this qualifies the dispatcher with real client/storage effects. Measured contained qualification: normative 32, adversarial 125, integration 27, installation contracts 5. These establish retained-request recovery and observation, not complete lifecycle recovery. Suppressed/in-memory outcomes, delayed-persistence stop handling, actual worker retirement, NMRNet composition/recipient diagnostics and full sibling/scientific workflow qualification remain required. No upstream or sibling code changed. Independent failure and wire rereviews found no residual behavior defect after the diagnostic correction; applicable-U/A closure is limited to the exercised ownership/replay/evidence boundaries. Final documentation review corrected the ownership-domain wording: API/provider remain part of exclusion identity; consumer/lane/generation do not split it. Package Ruff and diff whitespace checks pass. P4 first scientific worker transport (2026-10-18) ------------------------------------------------ Added a private, single-connection transport around the scientific preparation/ execution seam: asynchronous PredictionClient and serial serve_connection. The worker retains the actual prepared object; a random 32-hex wire token only correlates that preparation on the admitted allocation/connection. Client handles remain local objects, consumed before execution. Replacement preparation revokes previous handles, including locally rejected replacement. There is no reconnect, retry, multiplexing, queue, warm-worker policy or worker-issued retirement acknowledgement. Source verified at S 34f5915c1534278bbf61b4c6592afa44cf94ab08: src/secs_inference/provider/worker.py::_send/_receive/_exact, lines 348-374, uses four-byte network-order length framing with a 2 MiB ceiling. Its _child_loop at line 298 separates scientific work from supervisor authority. README links the framing source. This implementation adds strict duplicate/nonfinite JSON rejection, exact fields and allocation correlation, and asynchronous bounded controller I/O; it does not import SECS's warm-worker supervisor or synchronous controller waits. Exact request bytes are base64 transported after the existing 1 MiB scientific input bound is checked. Frame prefixes are admitted before payload reads. Aggregate client deadlines include explicit elapsed checks before dispatch and after decoding, so buffered/non-yielding completion cannot hand off a late result. Worker I/O uses bounded whole-frame reads and sendall timeouts; synchronous science requires external termination authority. Full worker exception chains travel only as private diagnostic payloads. Frame overflow refuses a diagnostic rather than truncating it; the eventual host owner must retain stderr for abnormal exits and failed diagnostic transport. The existing contained test/unit/provider lane now tests the transport. The first run failed because worker modules were absent. Real process/socket witnesses use recording science; the child explicitly closes the inherited controller endpoint, so socket closure is not distorted by forked descriptor ownership. Cancellation closes the client while the blocked worker remains alive until the fixture releases it. Other witnesses cover maximal admitted request bytes, fragmented/truncated/ oversized frames, wrong allocations, stale wire tokens, repeated/foreign handles, private diagnostic rendering, partial reply timeout, explicit-close/late-reply races, nonfinite JSON, pre-encoding size admission and buffered deadline expiry. Independent review found and corrected: result-send failure could attempt another frame on a corrupted stream; request size was checked after encoding; buffered completion could miss elapsed timeout; rejected local replacement left an older handle executable. Regression tests cover each. One maximal-input test initially failed because its synthetic hex result itself exceeded 2 MiB; the corrected fixture checks received bytes directly with a small result, preserving both real limits. This is a transport library, not a deployed worker binding. Allocation/connection identity does not yet bind Attempt/generation; actual PredictionSession/model loading through this transport, host-owned exact-container/grant retirement, private stderr retention and controller/API composition remain required. No worker stop receipt or retirement claim is fabricated. The recording-process tests prove neither model accuracy nor credential isolation. Existing direct inference is unchanged. Measured qualification: test/unit/provider passes 37 tests in the existing offline container lane. Focused Ruff and whitespace checks pass. Repeated independent failure, wire and applicable-U/A reviews found no residual actionable finding after the corrections. No image, dependency, upstream or sibling change was required. The full package/provider goal remains open; this does not close P4/P5. P4 released-model worker composition (2026-10-18) ------------------------------------------------ serve_released_connection now composes the existing SelectedReleaseModels and PredictionSession with serve_connection. Allocation paths are local configuration, never fields admitted from scientific requests. Model selection, byte verification, tensor preparation and calculations remain owned by their existing modules. Added prediction/worker-parity through the existing baseline.sh launcher, sharing model-parity's admitted immutable image, offline/read-only posture, release mounts, 2 CPU/4 GiB/no-swap/64-PID limits. The only added mount is read-only nmrnet_provider; there are no engine sockets, credentials or writable host outputs. The launcher regression compares exact mount sets and inherited flags, selects the intended test, and verifies missing binding source refuses admission. Make help and the existing prediction/qualify aggregate include the new hierarchical lane. Tests first failed for the missing lane and launcher action. The launcher lane then passed 18 tests. The scientific test authenticates the same four retained source records through test_prediction_release.reference_requests and the pinned reference packet hash. It sends identical label-free bytes through direct inference and the asynchronous client to a fresh spawned real worker, loading models sequentially to respect the existing budget. It compares complete ordered results exactly and all 64 original reference positions independently, with zero absolute/relative tolerance. Worker graceful exit and bounded joining are required; forced cleanup fails the qualification. These are spawned-process facts, not container-retirement proof. The emitted NMRNET_WORKER_OBSERVATION record retains mounted source hashes, immutable image identity, selected release member identities, request/result hashes, observed cgroup limits/peak and exact numerical policy. No coordinates are published. The public artifact prediction-worker-cpu-float32.json and artifacts/SOURCES.md preserve this scientific evidence without retaining raw logs in the repository. Parent HEAD is recorded separately from actual executed dirty source hashes. Existing scikit-learn scaler-version warnings remain visible; this test establishes fixture agreement in the pinned runtime, not compatibility with arbitrary library versions. Independent scientific/failure and applicable-U/A reviews found no new behavioral finding. Two early model runs passed; final evidence was rerun after source-format and import-annotation corrections so the retained hashes match the final files. Attempt/generation binding, separate worker-container authority and host-confirmed retirement, full API/interpreter composition, recipient diagnostics and sibling qualification remain required. P4/P5 and the full goal remain open. Final worker-parity run passed in 38.475 seconds: 137 complete H/C predictions over four fixtures (41, 35, 39, 22), with all 64 historical positions equal. Observed memory.peak=2149867520 bytes under memory.max=4294967296; cpu.max=200000 100000, memory.swap.max=0, pids.max=64. All 17 recorded executed-source hashes were checked against current files after capture. Focused new-source Ruff and whitespace checks pass. The retained artifact is the successful final run, not either earlier capture. P4 exact-container retirement primitive (2026-10-18) -------------------------------------------------- Added source-only tools/worker_retirement.sh. The host allocation owner supplies its admitted full CID, private worker.cid receipt/directory and scrubbed engine argv. The helper refuses entry after unconfirmed local-client retirement, checks the CID receipt byte-for-byte, and exclusively creates a retirement receipt directory. It stops that ID once, admits an exact exited/no-PID/not-restarting observation, then removes that ID without force. Only successful removal returns success. Each engine call has a ten-second local-client budget; stop has a five-second engine grace. These are local policy choices, not scientific execution deadlines. Provenance: tools/docker.sh at parent 362c7c2 supplies the byte-exact CID and bounded metadata precedent; tools/inference_native.sh at that same revision supplies the local-client owner. The existing source links there retain the underlying Magnet precedents. We do not source docker.sh because it is an executable acquisition launcher. The new helper composes the existing native owner without claiming that its client-process termination establishes engine-side termination. Failure/cancellation stops the sequence, retains private receipts and does not overwrite them on a later invocation. A failed stop may have committed; this primitive deliberately leaves reconciliation to the allocation owner rather than retrying. Engine diagnostics remain in private bounded files; controlled public text names the failed operation, status/cancellation and receipt location. Review identified that zero exit alone cannot prove complete capture: both files must now be regular, nonsymlink and strictly below 4096 bytes before advancing. Tests first failed without the helper. test/unit/provider now passes 45 tests, including eight retirement tests using a recording engine inside the offline container. Witnesses cover exact-ID ordering, malformed/still-running observations, nonzero PID/restart, extra/NUL/oversized bytes, failed stop/inspect/remove, cancellation during each command, refusal to overwrite uncertain work, and zero-success at-cap diagnostic capture. Focused Ruff, Bash syntax and whitespace checks pass. Repeated independent failure, mechanical and applicable-U/A audits found no residual issue after capture-completeness and cancellation witnesses were added. This is not yet a live-engine or complete retirement qualification. Exclusive allocation ownership and create admission are caller preconditions; spelling an ID is not ownership. Host supervisor integration, separate controller/worker grants, private scientific stderr retention, grant release and owner-issued acknowledgement remain required before AnalysisSession.retire can use this result. No production entrypoint is enabled by this helper alone. P4/P5 and the full goal remain open. P4 live host-retirement qualification (2026-10-18) ------------------------------------------------ Added make test/integration/provider-worker, an executable consumer of the retirement primitive. tools/worker_qualification.sh owns the scrubbed Docker client, exact create/CID admission, detached startup, private files and all engine operations. tests/integration/provider_worker/retirement_probe.py runs only inside the existing pinned Python image. The lane inspects the locally present digest reference and uses its immutable image ID; it cannot pull images or access the network. Source/rationale: Docker-client and local-process ownership reuse their existing tools directly. Create admission follows tools/docker.sh at e845c5a797082ac4fd8d840a1b656847e868d7a1: full CID and complete stdout must agree. worker_retirement.sh owns the actual stop/inspect/remove sequence. Scientific baseline image/artifact admission is deliberately not extracted into this probe: the boundary being measured is engine retirement, independently of model loading. The preceding real-model worker-parity evidence remains separate. The worker has its own IPC and capped diagnostics mounts. It sets TERM to ignored, publishes readiness, then blocks. The host independently observes that exact CID running before starting the contained controller. The controller can request only retirement of this allocation; it has no engine socket, CID receipt or owner files. The host's response directory is mounted read-only into the controller, and an attempted write is required to fail with EROFS. The worker has no control mount. Neither probe receives credentials. This is a concrete grant inventory and receipt write-denial observation, not a general hostile-code isolation claim. Three fixed live cases now pass: unstarted: create an admitted container without starting it, then remove it; success: stop/remove the blocked worker, remove its IPC files/directory, then atomically publish the allocation-bound retired receipt accepted by controller; grant-failure: after worker removal, a fixture-owned retained entry makes actual rmdir fail. The host publishes unconfirmed, never retired, and the controller requires that disposition. Fixture residue is removed only after both endpoints have retired. This fault injection is not a production configuration option. Every endpoint uses network none, nonroot UID/GID, read-only root, dropped caps, no-new-privileges, init, no restart, 1 CPU/128 MiB/no swap/32 PIDs and 8 MiB noexec temporary space. Probe stdout/stderr have separate 64 KiB file limits, with no daemon log driver; engine metadata uses the existing strict sub-4096-byte receipts. Successful qualification removes private allocations and Docker client state before reporting success. Unexpected failure preserves allocation evidence; ambiguous create/retirement cannot cause automatic replay or deletion by name. General startup reconciliation and recovery of an unadmitted CID remain outside this fixed probe. Review exposed a real startup-cleanup omission: a container whose start never ran can be in created, not exited. Retirement now accepts exact created false 0 false as well as exact exited false 0 false, with recording-engine and live evidence; running/restarting/nonzero-PID or malformed observations remain rejected. Review also corrected final housekeeping so it cannot replace the original failure status or print qualification success before cleanup finishes. Final focused validation: test/unit/provider passes 46 tests (2.385 seconds); test/integration/provider-worker passes all three real-engine cases. Focused Ruff, Bash syntax and whitespace checks pass. Independent failure, mechanical and applicable-U/A reviews found no residual actionable issue after revision. This closes the missing live proof for the fixed retirement primitive and disjoint host/controller confirmation channel. It does not implement the production supervisor, AnalysisSession binding, scientific stderr ownership, durable restart reconciliation, API/interpreter composition or full P4/P5 qualification. These remain part of the unchanged package goal. No upstream or sibling was edited. P4 worker-observed scientific provenance (2026-10-18) -------------------------------------------------- The complete result binding needs evidence from the scientific owner, not a copy of the controller's selected-model configuration. SelectedReleaseModels now exposes independent snapshots of the decoded dictionary and successfully loaded model/scaler pairs. It records identities already compared with the actual decoder input bytes; it does not reopen artifacts. Unloaded heads and pairs whose scaler decoding failed are absent. Observations accumulate over one loader lifetime; each released worker creates its own loader, preventing cross-execution attribution. ReleasedPredictionSession wraps the existing PredictionSession without changing tensor composition, model/scaler decoding or prediction calculation. Its private worker result contains prediction, provenance and private_warnings. Runtime Python and installed torch/numpy/scikit-learn/joblib distribution versions are collected during preparation, before model execution. Missing metadata fails preparation without loading models. Installed metadata is explicitly not an imported-code or image-identity attestation; host composition still owns runtime/source admission. The scaler decoder's actual warning emissions are retained on the private worker channel and forwarded through the original warning hook. Filters remain untouched: ignored warnings remain ignored, errors still raise, and default-policy repetitions remain suppressed. A first implementation used catch_warnings; review and a focused regression showed its filter-version changes could re-emit a previously suppressed warning. The final serial-worker hook uses try/finally restoration without changing filter state. Raw messages and source paths are not approved receiver/public text. The existing bounded frame still rejects overflow rather than truncating evidence. This hook is for the documented serial scientific worker, not concurrent loaders. Provenance/rationale: nmrnet_inference/release.py remains the byte-verification owner introduced for 002; load_scaler_from_bytes retains its exact upstream decoder link at NMRNetplusplus 3ba8b9c2f3d0a390d00685d238618345c6ab24d7. The composition adapts those existing owners to note003's result-reproduction requirements, rather than introducing a second model declaration or trusting qualification fixtures at runtime. The private transport's existing result field carries this internal envelope; core does not interpret it and no public result schema is claimed by this slice. Tests first failed for missing observed-artifact access. Final lightweight test/unit/prediction-input passes 43 tests in 0.100 seconds, including successful pair observations, failed scaler exclusion, snapshot independence, warning emission, ignore/error/default policies, hook restoration and missing runtime metadata. prediction/worker-parity passes two tests in 41.496 seconds. All 137 predictions across the four release fixtures remain exactly equal to direct prediction; all 64 historical reference positions remain equal. Returned member identities match the verified declaration, and the actual 1.5.2-to-1.8.0 scaler warning is retained. The context-only fixture returns empty predictions and element observations while retaining the dictionary identity and no scaler warnings. Refreshed artifacts/prediction-worker-cpu-float32.json captures the final source, per-fixture worker observations and only warning category names; artifacts/SOURCES.md records the evidence scope. All 17 recorded source hashes were checked against the files after capture in an offline container. Repeated independent failure, mechanical and applicable-U/A audits found no residual issue after revision. Focused Ruff reports no findings in changed production sources or worker-parity tests. The input-test file retains ten pre-existing findings (mutable class fixture, nested contexts and omitted subprocess check); comparison with its committed parent confirmed no new findings. Unrelated test cleanup was not included. The next binding requirements remain real: pre-execution capacity for the full scientific envelope, exact Attempt/generation/input binding, the production host retirement adapter, recipient-safe warning/error projections and API/GUI qualification. The API's 786432-byte decoded result ceiling and GUI's 65536-UTF-16-unit preview budget are different limits; a final envelope must respect both storage admission and honest preview/download behavior. Full P4/P5 and the original goal remain open. Limit sources: nmr-api-v1 6a163b7a9cc1e2c7485b681c0b2b969c7c20e6c8, nmr_api/provider/schemas/execution_attempt_complete_request.v1.schema.json (1048576 canonical-base64 characters = 786432 decoded bytes); nmr-gui-v1 d432668a137e860e1bf37bf242f792ec07f01533, app/src/features/workspace/result-presentation/generic-result-preview.ts and ResultPresentation.tsx (bounded preview, original-byte download). These are reviewed consumer constraints, not evidence that the forthcoming NMRNet envelope passes them. P4 one-geometry scientific result contract (2026-10-18) ---------------------------------------------------- nmrnet_provider/result.py now owns nmrnet.coordinate_shifts.result.v1. A ResultPlan freezes the complete invariant envelope before inference: binding-admitted Job/Attempt/input identities, host execution identity, model selection and runtime expectations; original source record/positions; preparation method and declared-unit conversion; prepared coordinates and separately labelled float32-admitted values; exact executed-request digest; scientific limits. Model centering/padding occurs later and is not misrepresented as those coordinate arrays. Original whitespace is not needed for reproduction, but its exact request identity remains retained. This is one geometry inside an ordered geometries collection, not enabled batch execution. Supported preparation labels describe the existing direct-JSON, table and XYZ readers. No invented RDKit producer/seed fields or arbitrary preparation metadata were added; the generated-geometry route must supply its own real variant. The binding still has to authenticate/configure the supplied identity facts and retain this plan with its exact live worker handle. Planning grants no execution, retirement, publication or replay authority. The released worker now includes the SHA-256 of its admitted request bytes. Completion requires this exact digest, exact observed dictionary/required head pairs and runtime metadata, ppm, and one finite numeric prediction at every eligible H/C position in original order. Missing/extra/reordered predictions, element changes, boolean indices, nonfinite/unrepresentable numbers and provenance substitutions refuse the whole result. Empty eligible output requires no loaded heads. Model selection is labelled separately from per-geometry loaded elements. Only the known InconsistentVersionWarning receives fixed safe receiver wording. Raw warning messages, paths and line numbers remain with the private worker outcome; unclassified warnings prevent publication pending review, rather than disappearing or entering public text. This is projection policy, not a claim that all future warnings are harmless. The caller remains responsible for protected evidence and recipient-specific failure delivery. The pre-execution capacity calculation serializes the complete invariant envelope with all punctuation/escaping, the admitted warning and a conservative quoted 32-character allowance per finite binary64 prediction. The final normalized numeric spelling fits that allowance. Plans above 786432 bytes fail before model work; completion rechecks the actual result against its reservation without truncation. That ceiling comes from the pinned API schema documented immediately above. Core's existing complete_body independently enforces the same opaque-byte bound; this module does not replace API admission. GUI preview/download qualification remains required and is separate from storage capacity. Tests first failed for the missing planner. Final test/unit/provider passes 55 tests in 2.432 seconds. New tests cover immutable snapshots, coordinate rounding/mapping, missing/duplicate/reordered/wrong-element rows, integer overflow and inexact binary64 integers, boolean provenance substitutions, private-text canaries, unknown warnings, empty eligible output and pre-execution size refusal. A 128-eligible-atom fixture uses extreme finite/subnormal shifts and an admitted warning with escape-heavy metadata less than one escape unit below the API ceiling; actual bytes fit, and one extra unit rejects planning. These synthetic limits are not model-capacity proof. Real prediction/worker-parity now builds each plan before any model run and uses the actual returned worker evidence to assemble the final result. Both tests pass in 43.391 seconds: all 137 predictions and 64 historical values remain exactly equal, and context-only input still produces no predictions. The four final envelopes are 13703, 12757, 13324 and 10662 bytes against reservations 14380, 13334, 13964 and 11023. No source coordinates were published in the qualification artifact. Its retained scientific_result fields contain size/digest/reservation; all 19 executed-source hashes were checked after capture. Final artifact SHA-256: 48b5e734372ff95ce728a217b24ef4b7b2d1258539335f51e2b7f19ca62f1345. Focused changed-source Ruff and whitespace checks pass. Repeated independent failure, mechanical and applicable-U/A audits found no residual actionable issue; the requested near-ceiling capacity witness was added. The first real run passed; the final run followed the explicit strict-zip lint correction so recorded source hashes match the committed implementation. No model arithmetic or tolerance changed. The production AnalysisSession/host-owner composition, full interpreted/generated/ uploaded routes, durable publication through that binding, recipient rendering, API/GUI transactions and sibling reuse qualification remain open. This is an actual real-worker result consumer, not completion of P4/P5 or the package goal. Host retirement adapter -- contained controller connection --------------------------------------------------------- The controller now uses nmrnet_provider/retirement.py in the existing real-engine qualification. HostRetirement publishes one allocation-specific request and returns only after the host's exact confirmation and completed local receipt I/O. Its protocol source is tools/worker_qualification.sh at 1de1074; the host still owns exact-CID retirement and grant cleanup. The controller receives only its request mount and the read-only receipt mount, never engine access. The qualifier adds two exact read-only Python source mounts and uses an allocation name admitted by the existing worker protocol. Cancellation and timeout retain the original filesystem task. Repeated calls await that task; only a completed failed observation permits another read, never another request. Failed publication refuses adoption even if matching host evidence later exists. Failed descriptor cleanup is similarly retained for recovery. Filesystem causes remain chained privately behind safe caller text. Receipt reads reject symlinks, nonregular files and malformed/wrong-allocation bytes. This does not claim that a timeout stops a blocked filesystem operation or that socket closure retires scientific work. Focused contained validation: test/unit/provider passes 63 tests in 2.500 seconds; test/integration/provider-worker passes unstarted, success and grant-failure against real containers with the actual adapter. Focused changed-source Ruff and whitespace checks pass. Independent mechanical, failure and applicable-U/A reviews found a post-open private-error escape and unresolved-close gap; both were corrected with regressions. Subsequent failure and mechanical review found no residual issue. The initial adapter existed before this turn's tests; tests preceded subsequent corrections and integration, so this is not claimed as wholly tests-first work. This closes the contained controller's stop-confirmation connection, not the production AnalysisSession, API publication or complete package qualification. Warning evidence correction -- no implicit scientific veto --------------------------------------------------------- This supersedes the earlier blanket refusal of unclassified warnings. A valid warning does not itself establish invalid predictions. Decoder exceptions and existing structural/numerical admission remain authoritative failures; unknown emitted scaler warnings instead produce one bounded public review notice naming the affected heads. Original messages, categories, filenames and line numbers remain in protected worker evidence, without copying arbitrary text into results. Known compatibility warnings now capture the H/C scaler head and structured original/current versions where emitted. Source: the pinned scikit-learn 1.8.0 wheel admitted by requirements/inference.lock, SHA-256 a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a, member sklearn/exceptions.py:160-180 (warning attributes) and sklearn/base.py:459-469 (serialized _sklearn_version versus runtime __version__). The latter uses pre-0.18 for a missing serialized version. This inspection was read-only against the local wheel; no warning-message parsing or new dependency was introduced. The existing filter and forwarding policy is unchanged. Public version facts accept bounded release identifiers and that legacy sentinel. Missing, unsupported or conflicting facts are explicitly unavailable; raw evidence is retained. Repeated observations collapse into at most one compatibility notice per head and one additional-warning notice. The full maximum representation is reserved before inference. Warning heads must occur in the admitted loaded-head set; a warning for an absent scaler is contradictory protocol evidence, distinct from an unfamiliar warning about an actually loaded scaler. Tests were added first: the original policy failed three projection tests; the absent-head regression independently failed for both H-only and context-only inputs before correction. Final contained provider tests: 65 in 2.618 seconds; input/ decoder tests: 44 in 0.114 seconds. The near-capacity fixture now includes both head notices with 32-character versions and the additional-warning notice. Real worker parity: 2 tests in 43.990 seconds, unchanged predictions, structured 1.5.2 -> 1.8.0 observations. The refreshed public record includes the admitted warning projection and was extracted only after all executed-source hashes matched. Focused changed-source Ruff and whitespace checks pass. Three independent reviews found no residual issue after the absent-head correction. No API publication or complete AnalysisSession qualification is claimed by this correction. Direct-coordinate session -- core lifecycle composition ------------------------------------------------------ nmrnet_provider/session.py implements the existing provider_core.analysis session port for direct JSON only. It delegates preparation to submission.py and result admission to ResultPlan. Core still owns current server observations, durable execution entry, terminal retention and publication. The session receives no API credentials. Composition must supply the allocation-bound worker/host ports and admitted execution/model/runtime facts; this slice does not implement startup. Preparation binds the verified input to an active unexecuted acknowledgement and creates the complete result plan before worker preparation. One session accepts one preparation, and its exact handle is consumed before execution awaits. Known InputRejected failures become explicit invalid_input outcomes. Worker/transport exceptions retain their original identity. If science returns but result/evidence assembly fails, ResultAssemblyFailed retains the exact received outcome and cause; evidence overflow never truncates diagnostics or reruns science. Retirement independently requests local close, awaits host confirmation and observes local closure. The client retains/shields its original close observation across timeouts. The session preserves the earliest failure and all later cleanup failures; cancellation propagates while combined evidence stays attached and retained. A failed host stop cannot skip local observation, and a local failure cannot skip host cleanup. No socket-close claim substitutes for host retirement. Source rationale: provider_core.analysis.AnalysisSession, execution.AttemptExecutor and publication.TerminalPublisher own the reused lifecycle contracts; their pinned sibling citations remain in those modules. The integration fixture follows packages/provider-core/tests/integration/test_execution.py but uses NMRNetSession rather than the generic recording session. Signed TLS and durable storage are real within the isolated test; science and host retirement are explicitly recording ports. Its completion response acknowledges the exact retained scientific result's schema, size and digest, and the emitted request equals the retained bytes. Tests first failed because the session module was absent. Regressions cover exact handle consumption, substituted input, rejected preparation, cancellation, assembly failure, evidence overflow, retained local close observation, simultaneous cleanup failures and cancellation with a prior error. Review found the original finally cleanup ordering could replace an earlier error and skip local observation; the three explicit cleanup phases correct both issues. Independent failure/mechanical re-reviews found no residual issue. The initial signed-publication fixture used the generic result receipt; it was corrected to acknowledge the actual NMRNet bytes. Real released-model and host-container proof remain separate from this synthetic science integration. Production allocation/startup, all interpreted/generated/ uploaded routes, recipient rendering, external API/GUI and sibling reuse closure remain open. Do not mark the package goal complete from this slice. Final validation for this slice: test/integration/provider-core passes 37 tests in 2.926 seconds; test/unit/provider passes 66 tests in 2.571 seconds. Focused Ruff and whitespace checks pass. The final failure-order test initially matched the ordinary word 'private' in safe text; it now checks the actual private messages. User requested pausing at an opportune boundary; pause after this coherent commit, before production host composition or another implementation slice. Real scientific worker through the core lifecycle (resumed) ---------------------------------------------------------- The resumed slice joins the existing owners in one fixed, offline qualification: test/integration/provider-scientific-worker. The existing worker_qualification.sh owns the two exact container IDs; worker_retirement.sh owns their removal. Its scientific scenario admits the inference image's exact identity/upstream label and compares its embedded dependency declarations before importing scientific code, following baseline.sh. No second production launcher or scientific implementation was introduced. Existing retirement-only scenarios retain their original resource and wait budgets. The worker receives read-only release inputs/code and one private Unix-socket directory. It receives no API signer, host control mounts or engine access. The controller receives installed provider-core through the existing offline build/ installation lane, binding code, its private store, and disjoint request/receipt mounts. It sees no checkpoint root and cannot write the host's receipt. Both containers use network none. The controller's 64-MiB file allowance supports the native-wheel installation; worker diagnostics keep the original 64-KiB limit. The live test uses actual PredictionClient, NMRNetSession, HostRetirement, AttemptStarter, AttemptExecutor and TerminalPublisher. A local TLS peer validates request signatures/digests and routes by operation, permitting variable polling during inference. Its wire authority remains the API revision cited in core's api.py/attempt_response.py. It supplies observations and receipts, not deployed API authorization/state semantics. The test geometry is explicitly self-authored chloromethane for wiring, not an experimental structure or accuracy reference. The witness checks durable execution entry at the actual worker execute call; exact geometry and complete finite H/C output; loaded model/runtime identity; terminal retention before host retirement; exact worker removal and IPC cleanup before publication; exact retained request bytes; and confirmed state after the store is closed/reopened. One scientific invocation and one terminal send occur. The successful fixture does not claim the full fault/restart matrix. Component fault proofs remain separate, and the next combined adverse case is still useful. Tests first failed for the absent routed-peer capability and unsupported host scenario. The first real run failed at the missing private store directory. Independent audits also found missing worker tool imports, omitted PUT body components in signature verification, and observation assertions that could veto host cleanup. Corrections preserve primary and later independent cleanup failures. A new cancellation regression failed before its correction: cancellation of the retention observation must still attempt real host retirement. A repeated review found no residual failure, mechanical or applicable-U/A issue in this bounded slice. Final contained validation: normal core integration runs 40 tests in 3.204 seconds (one intentional live-case skip); installed-package contracts run 5 in 1.266 seconds. The separate live lane passes all three selected tests, including one real-model lifecycle. Focused changed-Python Ruff and whitespace checks pass. The three original real-engine retirement scenarios also pass unchanged. No scientific arithmetic or tolerance changed and no new dependency was acquired. Selected public evidence is artifacts/provider-lifecycle-cpu-float32.json; exact producer, scope and rationale are recorded in artifacts/SOURCES.md. All 70 source hashes match the final checkout, including installed core, copied test helpers, binding/worker sources and host ownership scripts. HEAD identifies the parent revision, not those dirty bytes. The 13702-byte result is represented by its digest; no coordinates, signing key, raw warning or private journal is in the artifact. Successful runs retain a selected summary under .work/qualification; unexpected failures keep their complete private allocation receipts and journal. This follows U06/U16/U19: preserve exact useful evidence without committing transient logs. The original goal remains open: production allocation/service startup and feed, all interpreted/generated/upload routes, recipient projections, combined adverse/ restart cases, external API/GUI transactions and sibling reuse closure. This slice connects real science/host retirement to local signed publication, rather than treating the earlier separate component proofs as full workflow completion. Crash-durable returned evidence after interrupted acceptance ---------------------------------------------------------- This resolves the earlier P3 in-memory-only outcome limitation for admitted, bounded AnalysisSuccess/AnalysisFailure values. SuppressedOutcome retains an exact TerminalPending candidate and a closed reason category: server stop, failed observation or caller cancellation. The candidate reuses existing request/evidence admission and capacity; the outer record is never a pending publication. Only the exact AcknowledgedAttempt -> SuppressedOutcome transition is admitted. There is no transition back to publication or execution, including extraction of its nested candidate: the publisher's existing exact-current-record check refuses that too. Recovery returns the original suppression unchanged without any API/science call. AttemptExecutor.retain_suppressed_outcome() is an explicit persistence operation, after the original task and API/storage I/O settle. It writes the already returned outcome once under the existing claim/CAS owner. It does not change settle()'s observation-only write contract. A cancelled write remains owned and is observed by settle(), never redispatched. Successful retention cannot release unconfirmed worker retirement. Omitted retention continues to block claim release; eligible settlement diagnostics name the operation and require remaining original work to settle first. Primary failure remains authoritative when this later persistence/cleanup fails. Source/rationale: the existing core execution.py observation owner captures results before acceptance reads, based on the pinned NMRPeak generation-observation source cited there. Core therefore owns this race and its durable disposition; pushing it into each binding would duplicate lifecycle authority. TerminalHeld remains reserved for reviewed API conflict receipts. No scientific policy, exception pickling, second journal, automatic retry or publication override was introduced. Tests first failed for the absent record and absent executor method. Normative witnesses cover exact byte/evidence round trips, pre-entry failures, maximum wire body/evidence within existing reserved capacity, and close/reopen recovery with zero sends. Adversarial witnesses cover immutable suppression, malformed reasons, wrong acknowledgement, final stop, result during failed poll, late result, caller cancellation, original-write cancellation/settlement, disk failure and unconfirmed retirement. One retention write and one science call remain the observed counts. Independent reviews found the eligible action missing from settlement diagnostics, then found advice that omitted its pending-I/O prerequisite; both were corrected. Durability scope is precise: candidate scientific bytes/evidence and the suppression category survive restart. The full original API/acceptance exception chain remains in memory, not this record. Arbitrary ResultAssemblyFailed.worker_result objects, unencodable outcomes and unresolved earlier writes are outside this serializer and remain held for explicit binding/storage reconciliation. This does not close the remaining recipient diagnostics or full package goal. Final focused contained checks: normative 35 tests in 0.259 seconds; adversarial 131 in 1.206 seconds; integration 40 in 3.041 seconds (one intentional real-worker skip). Changed-source Ruff and whitespace checks pass. Repeated independent failure, mechanical and applicable-U/A reviews found no residual actionable issue after the diagnostic prerequisite correction. The preceding real-model artifact continues to identify its exact historical source hashes; it is not recast as a real-model qualification of this subsequent core change. Sibling adoption inspection: actual adaptation requirements --------------------------------------------------------- Read-only inspection of the pinned siblings found concrete work before any full adoption claim. M:analysis_contract.py:145-206 distinguishes authorized/held classified failure, retry-safe unavailability and indeterminate execution. M:models/g_01_nmr_forward/provider/magnet_provider_bindings/g_01_nmr_forward/ processor.py:182-255 interprets, reports running and predicts inside one process() call. An empty prepare() plus wrapping that whole call as core execute() would record entry before interpretation/admission. A real split is required; a suspended progress callback is not a prepared scientific handle. S:src/secs_inference/provider/analysis_run.py:201-210 marks execution then permits input_rejected and reselection. Its future binding similarly needs actual prepared admission before entry. P:nmrpeak_provider/runner_session.py:395-443 explicitly retires a channel without claiming process exit; that alone cannot satisfy core's retirement port. S:src/secs_inference/provider/worker.py:207-245,268-295 has an existing supervisor/join acknowledgment usable by an explicit async binding, with its actual child-stop scope and per-Attempt source cleanup. No sibling was edited. These are pinned source findings, not evidence of sibling migration. A narrow outcome/publication/claim compatibility witness remains useful; full processor adoption must also qualify these phase and retirement differences. Signed Job discovery -- authenticated input identity source --------------------------------------------------------- ProviderAPI.jobs reads one page from the pinned API's GET /provider/v1/jobs. job_feed.py records exact route/schema/request/service sources and their rationale. The caller explicitly supplies analysis kind, provider-attempt presence view, limit and cursor. The response echoes kind/view, carries at most the requested count and 100 items, and obeys the 65536-byte route ceiling. Immutable items reuse existing FeedInputFacts; no second input identity/verifier was introduced. Canonical UTC date parsing now has one shared wire-primitive owner in response_json.py; Attempt admission uses the same unchanged algorithm. False presence means selected open Jobs with no prior Attempt by this provider; true means any prior Attempt state, not active-work inventory. The cursor remains opaque; only canonical unpadded base64url encoding is checked. Core does not page, select, schedule, start or retry from discovery. The separate in-progress Attempt inventory operation and production service composition remain open. Tests first failed for the absent discovery module. Focused witnesses cover exact signed/bodyless query construction, explicit view/page choices, schema drift and kind/view substitution, input identity/type/range checks, invalid calendar/encoding, cursor canonicalization, requested count, private error evidence and immutable empty/nonempty pages. A real TLS witness verifies both received signatures and passes the discovered identity into the existing exact-input read; a second one cancels discovery and observes retirement of the original transport without retry. The installed wheel inventory explicitly admits the new core module. No new dependency, downloader or sibling change was introduced. Individual U/A audit of Job discovery (base b531dfa) -------------------------------------------------- Each U01-U26 and A01-A10 received a separate read-only agent review. These are source/test reviews, not independent runtime execution. The coordinator ran the contained lanes recorded below. Each entry distinguishes this slice from the whole package; no aggregate green result closes an unimplemented obligation. Code names below resolve under packages/provider-core/src/provider_core and test names under packages/provider-core/tests, unless a repository path is explicit. U01. Slice: job_feed adds no scientific implementation and reuses FeedInputFacts. Package: nmrnet_inference/model.py::predict_composed_element remains the one calculation owner; full 003 input-route integration is still open. U02. Slice: api.jobs admits the query, awaits exchange, then admits the complete page. Package: execution.AttemptExecutor orders preparation before entry; the actual sibling preparation splits recorded above remain to be qualified. U03. Slice: integration/test_job_discovery now checks two distinct Jobs in both orders, carrying the chosen identity into exact bytes. The reviewer rechecked this correction without residual signal. Other 003 routes remain unqualified. U04. Slice: kind/view/item identity and calendar admission add semantic checks, not just shape checks (job_feed.read_jobs_page/_read_job). Package: model semantics and runtime/result compatibility remain binding-owned; full routes and independent sibling consumer contracts are not established by discovery. U05. Slice: discovery feeds the existing exact-byte verifier. Package: tools/baseline_prepare.py::verified_member_bytes and release.py pass the same immutable verified buffers into decoders; test_prediction_input.py covers corruption-before-decoder and actual decoder arguments. A proposed current-boundary gap was withdrawn after inspecting those owners. U06. Slice changes no scientific qualification population and needs no second evidence registry. Package: the four fixtures/137 outputs/64 historical positions remain the fixed scientific population; source-hashed artifacts retain historical scope. The three-route/full-workflow population is open. U07. Slice: integration/test_job_discovery uses real TLS, received-signature verification, identity handoff and cancellation retirement. Package: real science/host retirement has a separate local witness; deployed API/GUI, complete adverse/restart cases and input routes remain open. U08. Slice: discovery is nonmutating; cancellation retains its original transport cause. Package: uncertain mutations and suppressed outcomes have distinct owners/records. Delayed-persistence stop handling and full composition faults remain open; a successful read is never a computation or mutation receipt. U09. Slice: a page describes Jobs; api.job_input separately acquires/verifies bytes. Package: typed interpretation, scientific admission and all source routes still require their actual binding; discovery does not perform those effects. U10. Slice: frozen DiscoveredJob/JobPage carry tuple items and existing immutable input facts. Package: lifecycle/Upload/analysis values already have named owners. No additional wrapper or current U10 defect was identified. U11. Slice: adversarial no-dispatch/substitution/privacy checks and signed TLS handoff test real boundaries. The installed probe now explicitly imports job_feed and asserts forbidden packages are unavailable before import. This strengthens negative proof; api already imported the module transitively. Whole-package sibling consumer qualification remains open. U12. Slice changes no Make input or target. Package: existing override export, unexport gates and the literal-alias/sentinel regression remain authoritative; no new Make defect was identified and no unrelated rerun was required. U13. Slice: transport charges received chunks before overflow rejection; discovery caps one exchange at 65536 bytes and one page at 100/requested items. Package: aggregate discovery/input/pagination work budgets belong in the still-open production composition; this primitive does not claim a traversal budget. U14. Slice: original API/transport ownership survives cancellation and is retired through the same owner. Package: host-confirmed exact-container retirement remains distinct from socket closure; production shutdown/restart faults and sibling retirement integration remain open. U15. Slice preserves the meaning of both presence views and exact input identity; no check was weakened for convenience. Package: active inventory must remain a separate operation, not a reinterpretation of the prior-Attempt boolean. U16. Slice: job_feed's pinned route/schema/request/service references and README explain both authority and reuse rationale. Existing attempt_response/uploads headers already contain their references and rationale; an absence claim was retracted after reading them. No current U16 defect was established. U17. Slice: public operation/rejection text is bounded and concrete, with purpose and limitations documented. Package: useful recipient projections through actual operator/commissioner/receiver channels remain unfinished. U18. Slice follows tests-first discovery, independent review and explicit-path delivery. This record accompanies the coherent commit after focused checks. Package remains in progress; P4/P5 and its open work are not called complete. U19. Slice keeps source, focused tests and rationale, not raw run transcripts. Package: artifacts/SOURCES.md identifies selected scientific evidence; successful/private failure retention has a stated purpose. Discovery adds no new artifact store or requirement to commit transient logs. U20. Slice changes no dependency/build lock or dependency version. Package: tools/package_lock.py owns reviewed lock production; observed qualification records remain observations, not deterministic generated dependency locks. U21. Slice uses the already pinned API revision; no reference implementation pin changed. Package: older scientific artifacts continue to identify their exact executed source bytes and are not re-labelled as current full-package proof. U22. Slice updates active package guidance and this note's status. Package: historical stages remain historical; standalone core supersedes the old Magnet-reuse proposal, and remaining production/input/reuse work stays open. U23. Slice: ApiFailure retains private response/cause while safe str/repr/traceback exclude the canary (adversarial/test_job_feed). Package: actual developer, operator, commissioner and receiver delivery/rendering is still a P4/P5 gap; preserving an exception object or writing stderr does not close it. U24. Slice's one-page/no-auto-follow limit is executable in normative/test_job_feed and explained to callers. Package: suppression/unconfirmed-retirement gates are behavioral; other route limits still need their complete input bindings. Opaque cursor semantics belong to the server, not a new client decoder. U25. Slice uses cheap normative/adversarial/contract/TLS lanes. Package: real model and host-container witnesses stay in explicit selected lanes; this change introduces no costly diagnostic into routine correctness discovery. U26. Slice separates normative, adversarial, integration, contract and shared fake responsibilities without empty directories. Package scenario/adoption lanes should appear with actual consumer stories; absence of an unused scaffold is not a defect or evidence of scenario completion. A01. Slice proves signed local discovery-to-input behavior, not deployed visibility or science. Package: the real-science local witness and external full-workflow obligations remain explicitly different; no receipt closes P4/P5. A02. Slice changes no numeric tolerance and retains exact identities. Package: strict CPU float32 comparisons remain scoped to the qualified population; broader chemical/ensemble accuracy is not inferred or tuned into agreement. A03. Slice retains bounded field-specific reasons and private raw evidence; rendered canary checks now include str, repr and traceback. Package: actual downstream recipient delivery remains open under U23, not solved by redaction. A04. Slice is included in the exact wheel inventory and imports in an isolated runtime with scientific/repository packages unavailable. Package has no hidden runtime asset to excuse a missing-resource check; future resources must enter installed closure. Hashes alone are not the installation proof. A05. Slice reuses the signer/exchange/input owners and adds only necessary local wire admission; no parallel cache, downloader, launcher or journal exists. Package sibling cutovers must replace their old owners, not wrap both. A06. Slice carries no scientific semantics. Package: result.py preserves supplied atom indices and H/C/context behavior; other models' projection/absent-nucleus rules must remain their own. Three sibling adoption fixtures remain open. A07. Slice infers no molecular features. Package: atom/distance input and result limitations do not establish charge, bonds or stereochemical discrimination. Format/interpreter scientific qualification remains open; no new claim was made. A08. Slice passes opaque exact input bytes without unit interpretation. Package: explicit unit conversion and the adopted angstrom model convention are distinct from archive-wide producer provenance. External input interpretation must preserve the declared units and conversion evidence through its binding. A09. Slice now exercises 100 items and the exact 65536-byte boundary, with one-more refusals. This is discovery capacity, not model capacity. Package's existing real 128-atom case remains separately scoped; conformer/routes/full envelope qualification is still required for their eventual advertised limits. A10. Slice adds maintained code, focused tests and this compact decision record; no raw transcript or abandoned entrypoint was added. Package preservation follows U19's purpose/lifetime rule; this review did not justify indiscriminate removal of retained failures or a new proof framework. Final discovery validation and review closure -------------------------------------------- All executed through existing offline contained lanes, against the installed package where the lane requires it: make test/unit/provider-core/normative: 38 tests, 0.289 s, passed. make test/unit/provider-core/adversarial: 136 tests, 1.270 s, passed. make test/integration/provider-core: 43 tests, 3.360 s, passed; one intentional live-worker skip (that selected lane was not requested for this wire change). make test/contract/provider-core: 5 tests, 1.134 s, passed. make test/repository/provider-core: 36 tests, 0.694 s, passed. Focused Ruff on the nine changed Python files and git diff --check passed. The first repository-check invocation could not access the engine from the sandbox; the same existing offline lane passed with the required engine access. No dependency acquisition or scientific rerun was needed. Independent rechecks accepted the corrected reordered-identity, installed-import, private rendered-error and maximum-page witnesses. Protocol and practices reviewers found no residual source defect or U/A overclaim; the latter requested the explicit measured results above. This closes the discovery slice only. Signed in-progress Attempt inventory (after 8630d8a) ================================================== Purpose: production recovery needs the API's provider-wide live inventory, separate from Job discovery's any-prior-Attempt view. ProviderAPI.execution_attempts requires state="in_progress", limit and cursor explicitly, issues one signed bodyless GET, and returns one immutable fully admitted page. It does not page, claim, resume, abandon or publish work. An inventory row contains no Job state; a selected identity can feed the existing read_attempt for an independent fresh observation. Neither inventory nor that point read supplies local execution history. Exact authority: I:nmr_api/provider/routes.py:350-365, provider/execution_attempts_list_request.py, provider/execution_attempts_list_cursor.py, provider/schemas/execution_attempts_list_response.v1.schema.json and operations/provider_execution_attempt_list_service.py:38-108. The server restricts the view to its authenticated provider principal, in-progress Attempts and visible Jobs across analysis kinds. Cursors are provider/view-bound opaque data. This is a live traversal, not an atomic snapshot or proof that absent work never existed. Request/time budgets across pages remain the caller's responsibility. Implementation keeps schema admission in attempt_inventory.py and reuses signing, exchange ownership, identity validators and read_timestamp. With two actual page callers, paging.py now owns their common canonical cursor and 1-100 limit grammar; there is no generic paginator or policy dispatcher. The start-key grammar has one neutral require_provider_attempt_key owner in attempt_request.py, used for start and inventory. Only its operation-specific wording changed. Installed-wheel inventory and isolated imports include both new modules. Tests first: normative discovery initially failed with ModuleNotFoundError for attempt_inventory, before implementation. The new normative/adversarial/TLS tests exercise exact signed query/no implicit continuation, immutable mixed-kind rows in both orders, selected identity-to-current-read handoff, complete eager admission, malformed/private wire refusal, exact route bytes/items, and owner cancellation. Both existing Job discovery witnesses run unchanged after paging extraction. Review corrections: fixed the service citation end from 119 to its actual 108. A proposed capacity concern was measured rather than accepted: 100 rows with maximum kind/Job/key field lengths serialize to 64,200 bytes with our fixture, so they fit. Their admission is now tested; the 65,536-byte route ceiling remains independent of row count and is tested at and one byte above its boundary. The foreign-retirement test now acts while the original exchange is pending; completed cleanup correctly leaves no foreign-owned outstanding obligation. These are local wire/ownership witnesses, not deployed filtering, a production recovery decision, scientific capacity, full workflow or sibling adoption proof. Individual U/A audit of Attempt inventory (base 8630d8a) ------------------------------------------------------ Each ID has its own independent read-only auditor. These dispositions distinguish the changed boundary from the unchanged package obligations; an open obligation is not evidence that already-qualified components are absent. Paths below use packages/provider-core/{src/provider_core,tests} unless stated otherwise. Runtime results are coordinator-run; auditors inspect source and tests, not claimed runs. U01. Slice adds no scientific callable. Package retains the existing predictor; complete interpreted/generated/upload route qualification remains open. U02. Slice admits query before GET and all rows before return. Package's actual scientific preparation/entry order still needs the remaining route bindings. U03. Slice's mixed-kind/two-order TLS test binds the selected Attempt/Job pair to current readback. Package recovery selection and all input routes remain open. U04. Slice's exact schema/state/kind/identity checks are core wire admission; no scientific interpretation moved into core. Other model semantics remain binding-owned and require their adoption witnesses. U05. Slice passes the same immutable HttpResponse.body into admission, without checked-path/reopen substitution. Full source consumption obligations remain with each binding; existing exact verified-byte paths were not changed. U06. Slice pins I's exact sources and includes both modules in installed closure; scientific populations are unchanged. Full route population remains open, not a reason to repeat or discard already-qualified scientific fixtures. U07. Slice verifies received Ed25519 signatures over real loopback TLS with synthetic replies. Existing real-worker proof remains historical evidence; deployed API/GUI and complete workflow qualification remain open. U08. Slice's cancellation preserves the original cause, nonmutating truth and single request. Package's uncertain mutations/suppressed outcomes already have owners; delayed-persistence stop/full production restart coverage remains open. U09. Slice's invalid query sends nothing; full response admission precedes exposure, with no acquisition/science. Full interpreted/Upload entry bindings remain open. U10. Slice returns frozen named values/tuples; empty page differs from ApiFailure, key/cursor repr is suppressed. Package recipient diagnostics remain separate. U11. Slice updates exact installed payload and isolated imports; blocked dispatch has adversarial witnesses. A proposed per-module-origin registry was retracted: the isolated regular package's existing directory authority already confines submodule loading. Complete workflow proof remains independently required. U12. Slice changes no Make input/target. Existing literal selectors/protected aliases remain authoritative; future service targets must retain that contract. U13. Slice bounds each page's bytes/count/time and performs no implicit continuation. Shared transport counts chunks only when a byte-accounting callback is supplied; discovery does not expose an aggregate consumed-byte counter. Production traversal/request/time and any required aggregate accounting remain open. U14. Slice forwards the exact operation owner and refuses foreign retirement while pending; cancellation then settles original I/O. Existing exact-container proof is distinct from socket closure; production shutdown/restart and sibling retirement integration remain open. No warm-reuse claim was added. U15. Slice extracts common grammar for two actual callers, retaining behavior tests rather than a proof registry. Production recovery policy remains unimplemented. U16. Slice records pinned route/parser/schema/cursor/service authority and purpose in place; corrected the service endpoint line. Deployment proof is separate. U17. Slice keeps useful bounded field constraints and named list-operation context. The neutral key validator follows existing shared field validators; adding start-only catch/rethrow wrappers was retracted as duplicate context after tracing callers. Actual downstream recipient delivery remains open. U18. Slice is a coherent tested wire operation with its docs; explicit-path commit follows review. Installed/local proof is distinguished from unfinished P4/P5. U19. Slice retains code, focused tests and rationale, no transcript/log/download. Broader retained evidence keeps its existing purpose/lifetime; no purge follows. U20. Slice changes no dependency input/lock/advisory receipt or third-party import. Future dependency changes still require reviewed acquisition and advisories. U21. Slice uses I's exact revision and adds no scientific recertification claim. Existing artifacts retain their executed-source identity; deployed protocol acceptance remains a separate required observation. U22. Slice guidance matches local provider-core; superseded shared-Magnet proposals remain labelled historical. Remaining implementation and qualification stay open. U23. Slice retains safe reasons and private original response/cause, with rendered canary tests. Actual operator/commissioner/developer/receiver delivery remains a package obligation; local exception preservation does not close it. U24. Slice's fixed view/count/bytes/no-auto-follow limits have executable witnesses. Existing result.py and tests/test_provider_result.py already exercise scaler warning projection/privacy/capacity; an absence claim was corrected. Actual API/GUI warning delivery remains unqualified, distinct from that local evidence. U25. Slice uses existing cheap contained lanes; no model or download rerun is needed for this protocol-only change. Real-capacity/full-workflow claims need their respective selected witnesses before being made. U26. Slice places units, adversarial cases, contracts, real TLS and shared fakes in their owning suites; empty selections fail. Consumer scenarios should gain their own lane with actual stories, not an empty or duplicate scaffold. A01. Slice explicitly separates installed/local TLS evidence from deployed visibility, science and production recovery. Existing local scientific proof is preserved; complete API/GUI workflow qualification remains open. A02. Slice relaxes no identity rule or numeric tolerance; protocol fakes introduce no tuned scientific golden. Broader scientific acceptance is unchanged. A03. Slice uses bounded field-specific reasons and private original evidence; str/repr/traceback canaries cover local rendering. Full recipient delivery remains open, with primary/secondary cause relationships still required. A04. Slice includes both modules in exact wheel inventory and isolated imports; regular-package directory authority already confines imported closure. No new runtime resource exists. Complete future binding resources need their proof. A05. Slice reuses signer/exchange and extracts only shared grammar for two callers; no second downloader/journal/launcher/fallback. Sibling adoption must replace displaced owners rather than retain parallel recovery authority. A06. Slice contains no peak/solvent/nucleus/atom-map policy. Magnet/SECS/NMRPeak adoption fixtures remain open and must retain their distinct scientific rules. A07. Slice changes no coordinates or result discrimination claim. Scientific input and rendering limits still require the complete binding/workflow witnesses. A08. Slice performs no unit inference or conversion. Existing angstrom convention and distance evidence remain scoped; remaining external-input bindings must preserve declared units/conversion evidence rather than guess from magnitudes. A09. Slice witnesses 100 rows, maximal item fields and exact byte ceiling/+1. The earlier unsupported maximal-row estimate was retracted after measurement. This is wire capacity; scientific/model capacity and deployed acceptance remain separate qualification obligations. A10. Slice adds maintained implementation/tests/rationale only, with no raw logs, abandoned helper or compatibility tree. Unique private failures were not removed; this slice does not authorize broad workspace cleanup. Inventory validation and review closure -------------------------------------- Coordinator-run existing offline contained lanes: make test/unit/provider-core/normative: 43 tests, 0.307 s, passed. make test/unit/provider-core/adversarial: 140 tests, 1.373 s, passed. make test/integration/provider-core: 45 tests, 3.147 s, passed; one intentional selected-live-worker skip. This wire change makes no new model-run claim. make test/contract/provider-core: 5 tests, 1.270 s, passed. make test/repository/provider-core: 36 tests, 0.709 s, passed. Focused Ruff on all ten changed Python files and git diff --check passed. Final nonbehavioral corrections sorted one import and used the lint-required list construction syntax. No dependency, network acquisition or scientific rerun. All 36 individual reviews above were actually inspected; an initial U06 response without file inspection was rejected and the agent redid the audit. Reviewers' unsupported extra-origin/wrapper/warning-absence/capacity claims were challenged, checked and withdrawn, as recorded at U11/U17/U24/A09. Wire, failure and practices reviewers independently rechecked their owning boundaries after corrections. No residual source defect was found. This closes the one-page inventory slice; production composition, recipient delivery, remaining input routes and actual sibling qualification remain required work under the package goal. Stop observation during execution-entry persistence (after 8d2c9f5) ================================================================= Problem: AttemptStore already runs filesystem work outside the event loop, but AttemptExecutor awaited its entry replacement without observing current server state. A prepared session could therefore remain live until disk completed or the store's wait expired after cancellation/expiry on the server. The existing fresh read after successful persistence prevented later execution; it did not provide prompt retirement during the delay. This slice closes that entry-specific gap. Authority/rationale: execution.py's pinned NMRPeak execution ordering and generation observation references remain its behavioral precedent; AttemptStore._observe owns the existing cancellation-without-cancelling-filesystem contract. The new entry waiter combines those existing owners rather than introducing a second store or general supervisor. It polls through the same owner-tagged API and interval, cancels only the async wait on interruption, then attempts session retirement. Original filesystem work remains owned. Settlement observes that waiter before settling original storage; an unresolved waiter blocks both competing storage settlement and claim release. A completed write cannot override a pending poll's stop/failure. Cleanup keeps late disk failures secondary to the original cause. Successful entry still requires the existing fresh state read before execution. Tests first: holding the real os.replace behind EntryWriteBarrier produced three expected adverse failures: run did not return/retire before disk release on server stop, failed poll, and expiry with failed retirement. New tests now require: - stop/failed observation retires preparation before the blocked disk is released; no execute/send, held claim, one original write, explicit late settlement; - expiry plus unconfirmed retirement and late disk failure retains the primary stop and independent protected cleanup/storage evidence, with reuse blocked; - caller cancellation while both poll and disk are pending retains both owners, retires preparation, then settles the originals without another write/request; - disk completion before a held poll returns stop or failure retains durable entry, prevents execution and preserves exact primary/secondary cause ordering; - an active poll followed by persistence still reaches the fresh state check, executes once and retains the terminal outcome before retirement. The race test observes completion at the public store.replace port before releasing the poll, rather than inspecting a private task or assuming scheduler order. Scope deliberately remains execution-entry persistence. Terminal/suppressed-evidence writes keep their existing behavior. A terminal CAS already submitted can finish as TerminalPending, which existing settlement/recovery can publish; cancellation cannot revoke it. TerminalPublisher gates exact durable identity and ownership, not a fresh Job-state observation. A promise of durable suppression at that later boundary needs its own explicit disposition/transition design. Terminal-write stop responsiveness, production startup/restart, all input routes, recipient delivery and actual sibling qualification therefore remain open under the package goal. Individual U/A audit of entry persistence (base 8d2c9f5) ----------------------------------------------------- Each ID again has an independent read-only review of the actual dirty slice. These are source/test assessments; execution results below are coordinator-run. The earlier package obligations remain acceptance requirements, not discarded work. U01. No new scientific callable; the existing one remains the owner. Full route binding qualification is still required. U02. Preparation, running progress, durable entry, fresh read and execution remain ordered; stop/failure during entry cannot advance. Other route transformations still need their complete ordered witnesses. U03. The exact acknowledged identity travels through the original retained intent and settled record. Binding selection/substitution cases remain independent. U04. Lifecycle observation does not move scientific meaning into core. Full consumer semantics/startup/recipient qualification remains open. U05. One immutable record encoding feeds one original staged replacement; no reopen substitution or resubmission. Other source-to-science byte contracts remain. U06. Scientific populations and installed closure are unchanged. Full route coverage remains required; existing qualified scientific fixtures are not absent. U07. Real store/rename barriers prove local control-flow ownership with fake API and session ports. Historical real-worker proof retains its narrower source scope; this slice does not establish deployed stop latency or full workflow. U08. Original stop/poll/cancellation stays primary and late writes/errors remain owned. Terminal persistence/disposition and production restart remain open. U09. Durable entry and fresh admission still precede execution; interrupted entry cannot start science. Full input-route acquisition/admission remains open. U10. The separate observer and filesystem operation have distinct owners; pending, failed and completed persistence stay distinct. No new payload rendering. U11. Tests block the real store port and inspect later effects, with installed core discovery. No new runtime resource or origin assertion is needed. U12. No Make/config change; literal selectors/protected aliases remain unchanged. U13. One write, bounded poll exchanges and bounded observer settlement; no retry. This is not a total lifecycle/aggregate work budget. Terminal polling and complete composition deadlines/accounting remain open. U14. Retirement, observer completion and original I/O settlement are independent requirements; failed retirement or unresolved owners keep the claim held. Existing exact-container proof is distinct from production shutdown/restart. U15. Real-port races protect meaningful stop/reuse effects; the observer state is earned, without a general supervisor or proof-token framework. U16. Existing exact NMRPeak ordering/observation references remain the precedent; docs identify this local extension and its original-storage ownership rationale. U17. New failures name the blocked wait/settlement and next action with safe text; useful underlying causes remain protected. Actual recipient delivery stays open. U18. One entry-specific behavior change with focused tests/docs; explicit-path commit follows review. No package-completion/deployment claim. U19. Maintained rationale and reproducible test barrier, no raw transcript or scratch artifact. Existing unique failure evidence was not deleted. U20. No dependency/acquisition/lock/advisory change. Future changes retain that review. U21. No producer/reference version change or artifact recertification; source pins and historical observations remain accurately scoped. U22. Active local-core guidance now describes entry monitoring and expressly leaves terminal/production/input/delivery/adoption work open; old proposals stay dated. U23. Primary and late errors survive safely in distinct protected evidence; local exception retention does not discharge actual recipient-path obligations. U24. Entry limitations are behavioral in stop/failure/cancellation/race tests. Terminal semantics retain their existing witnesses and explicit separate scope. U25. Focused cheap unit/integration lanes serve this control-flow change; no new scientific/host-run claim justifies an expensive model rerun here. U26. Normative success and adversarial races remain separate; the fake blocks a real filesystem port. Installed discovery includes both and refuses emptiness. A01. Local filesystem/ownership proof is distinct from science and deployment; earlier real-worker evidence remains historical, full workflow still open. A02. No numeric tolerance/golden/identity relaxation; exact original command and one-execution policy remain. Scientific acceptance is unchanged. A03. Bounded safe text and protected primary/cleanup evidence remain separate; this local boundary does not prove recipient-specific delivery. A04. No new runtime module/dependency/resource; existing installed inventory remains complete for this delta. Test files are excluded from runtime packaging. A05. The overlap observer has a real different lifetime from the store future; no second persistence, transport or retirement owner. Future sibling cutovers must still remove displaced owners. A06. No chemical policy moved into core; actual Magnet/SECS/NMRPeak adoption fixtures remain required, preserving their different science and retirement contracts. A07. No coordinate/stereochemical discrimination claim or rendering behavior changed; full binding/renderer acceptance remains independent. A08. No unit inference/conversion changed; existing angstrom evidence is preserved. External input must still retain explicit units/conversion provenance. A09. The held-disk ordering assertions use correctness watchdogs, not elapsed-time performance claims. A suggestion to move them to another lane was withdrawn; their guards were broadened from 0.3 s to the adjacent tests' 1 s for scheduler tolerance. Causal stop/ownership/error assertions remain unchanged. No new model-capacity or deployed-latency claim is made. A10. Only maintained implementation, test barrier/cases and rationale were added; no raw log, abandoned runner or compatibility tree. Unique evidence stays put. Entry-persistence validation and review closure --------------------------------------------- Existing offline contained lanes, executed by the coordinator: make test/unit/provider-core/normative: 44 tests, 0.389 s, passed. make test/unit/provider-core/adversarial: 144 tests, 1.435 s, passed. make test/integration/provider-core: 45 tests, 3.269 s, passed; one intentional selected-live-worker skip. No new scientific/host witness is claimed. Focused Ruff on the four changed Python files and git diff --check passed. The scenario helper was separated from its subtest loop to avoid implicit loop captures. An indentation error during that refactor was caught by the contained lane and corrected; final discovery includes all four adverse cases and the normative case, rather than hiding a failed import or reducing the denominator. Installed integration still builds and loads the changed core; unchanged wheel inventory and heavyweight model lanes were not repeated for this behavioral fix. Three independent code reviews requested decisive disk-completes-during-poll and simultaneous-API/disk-cancellation witnesses. Those tests were added, executed and rechecked with no residual source issue. All 36 individual U/A reviews inspected the actual slice; the timing-lane suggestion was adjudicated by its causal intent, then the watchdogs were broadened without changing the behavioral obligations. This closes execution-entry responsiveness only. The terminal and full-package obligations in the scope paragraph above remain required work. Magnet outcome-seam adaptation fixture (after fca04e3) ================================================== Peer-source inspection, with one read-only investigator for each sibling, confirmed the actual adaptation constraints recorded above. It did not authorize sibling edits. This first contract slice exercises Magnet's outcome distinctions through the installed core without importing Magnet or executing its scientific code. It is a proposed post-split adaptation fixture, not qualification of the current monolithic processor, a production adapter or a sibling migration. Authority: M:magnet_provider/analysis_contract.py:77-94,145-206; models/g_01_nmr_forward/provider/magnet_provider_bindings/g_01_nmr_forward/ processor.py:182-283; models/g_01_nmr_forward/magnet_runner_contracts/ runner_g_01_nmr_forward/session.py::encode_model_input; and the scripted rows in tests/unit/test_g01_provider_processor.py::_response. Exact pin and rationale are also in tests/fakes/magnet.py. Authored decimal strings, synthetic projection and noncontiguous atom indices are contract sentinels, not scientific observations, validated atom-map correspondence, probability normalization or G01 accuracy. The scripted interpreter supplies already-admitted candidate data; the real capability's rejection of malformed/unsupported interpretations is not executed or qualified here. Copying its validator/vocabulary would create another owner. Three cases in tests/integration/test_magnet_adaptation.py: - await interpretation of exact verified source bytes before returning a live prepared handle; forward unchanged SMILES whitespace and one shared solvent to both model heads, then publish exact opaque product bytes, including a future binding field and high-precision decimal strings; - a binding-certified retry-safe interpreter failure before entry remains the exact ExecutionFailed.cause with durable NOT_ENTERED. An explicitly selected new session may retry that identical admitted request; core does not retry it; - an indeterminate prediction after entry retains the exact exception and durable EXECUTION_ENTERED through store close/reopen. Recovery observes; another executor refuses re-entry, so the prediction is never repeated. The fixture uses g01_local_fixture, not the NMRNet analysis-kind value. This is local contract input, not a claim that a public API catalog advertises that key. An initial suggestion that core needed extra availability/indeterminate outcome types or a readiness port was retracted after tracing the actual owner chain: binding exceptions plus durable phase already express these distinctions, and composition can await readiness before starting an Attempt. This fixture adapts Magnet's returned outcome meanings into binding-owned exceptions; it does not claim exact source-interface compatibility or implement readiness ordering. Tests first failed on the absent fixture module in the contract lane. Review moved the cases to integration: they connect actual runtime owners for a proposed adaptation rather than verify the current external Magnet interface. Review also found the first result expectation reused the fixture's own builder: field loss could change both sides and go unnoticed. That oracle state was removed from the session. The test now independently declares the expected envelope/model-input keys and computes its receipt bytes, then compares decoded content and exact publication bytes. The shared authored worker payload is source data being preserved, not an independent scientific prediction oracle; duplicating those sentinel values adds no authority. No production-core change, new dependency, launcher or scientific implementation. Open P5 obligations remain: Magnet readiness, cancellation/retirement and classified publication policy; actual required preparation/prediction split; SECS/NMRPeak async worker/confirmed-stop fixtures; protocol-change/next-change qualification; all remaining NMRNet input routes and deployed API/GUI/recipient qualification. These three local outcome cases close none of those additional obligations. Individual U/A audit of Magnet outcome adaptation (base fca04e3) --------------------------------------------------------------- Each ID reviewed the actual fixture, its source references and claim scope. The scope paragraph above records unchanged package obligations; no row means that current Magnet or the complete package has been qualified. Runtime results below are coordinator evidence, not a claim that read-only auditors executed tests. U01. No scientific callable or production predictor added; three scripted cases exercise the proposed seam. Real route/single-predictor acceptance remains. U02. Interpretation precedes a live handle, durable entry precedes prediction; actual monolithic G01 still requires the documented split. U03. Exact verified source, shared solvent, input whitespace, key and opaque result reach independent envelope/byte expectations. Broader selection cases remain. U04. Fixture science policy stays outside core; shape/field preservation is not scientific validity, calibration or current-processor compatibility. U05. Original immutable verified bytes reach the scripted interpreter directly; no source path/reopen or new acquisition authority exists. U06. All three authored cases run against installed core. No scientific population was changed or denominator reduced; full route qualification stays required. U07. Real core/store with scripted API/interpreter/worker proves local composition; earlier real-worker evidence and deployed-workflow obligations stay separate. U08. Exact causes and durable NOT_ENTERED/EXECUTION_ENTERED distinguish explicit retry from indeterminate no-replay across reopen. Actual policy remains binding. U09. The already-admitted-candidate assumption is now explicit. No general malformed interpretation admission was qualified; copying its real validator is avoided. U10. Core receives immutable product/evidence bytes and typed causal distinctions; mutable fixture dictionaries are not a new public runtime contract. U11. Installed-origin tests and blocked-worker/replay assertions give runtime effect evidence. No sibling source is imported into the fixture. U12. No Make/config or literal selector boundary changed; existing lane is reused. U13. Retry is an explicit new session choice. This fixture makes no aggregate acquisition/interpreter/work-budget claim; those obligations remain open. U14. Scripted retirement clears fixture state only. It proves no real worker exit, grant cleanup, warm reuse or production stop; those remain required. U15. The result oracle no longer calls the fixture's builder. Independent envelope expectations catch serialization/field loss; shared authored payload values correctly serve as data being preserved, not duplicated scientific authority. U16. Full pinned source paths and rationale are in place. Test rows are now called an example layout, not scientific schema/cardinality authority. U17. Plain docs explicitly scope the adaptation and its missing admission/readiness/ worker proofs. No actual recipient-delivery claim was added. U18. One coherent test-only slice, with explicit-path commit after review. P5 stays unfinished; these cases are not current Magnet adoption or migration. U19. Maintained source references/rationale and reproducible sentinels only; no raw run transcript, irrelevant evidence or cleanup was introduced. U20. Dependency inputs/locks/advisories and acquisition remain unchanged. U21. The exact Magnet pin supports source-grounded semantics; historical scientific observations are untouched and not relabelled as new qualification. U22. Active docs describe local core and proposed adaptation honestly, leaving current-processor, other siblings and full-workflow work explicitly open. U23. Exact binding causes and durable phases survive; unavailability/indeterminacy do not become false terminal input failures. Actual recipient paths remain. U24. The three stated outcome/byte-preservation claims have behavioral witnesses; absent admission/readiness/real-stop cases stay excluded from their claims. U25. Cases now use the existing cheap integration lane; no new model/host claim justifies repeating heavyweight scientific qualification. U26. Review moved the proposed semantic-adaptation cases from contract to integration; they connect runtime owners, not the unchanged external Magnet interface. Shared fake remains outside the installed wheel. Recheck found no issue. A01. Synthetic installed-core proof remains distinct from real producer/science/ deployment evidence; missing package witnesses remain requirements. A02. No tolerance/golden change. A proposed duplicate sentinel-oracle requirement was withdrawn: preservation tests correctly share their authored source data, while the expected envelope is independent of the emitting builder. A03. Exact typed causes/phase preserve safe retry/effect distinctions; local tests do not claim real recipient rendering, nested-secret or delivery qualification. A04. Only tests/fakes/docs changed; runtime module/resource/dependency closure is unchanged and existing installed core remains the tested implementation. A05. Existing infrastructure owners compose without new outcome enums/readiness interfaces, parallel signers/stores or copied scientific validators. A06. Authored G01-shaped fields/decimal strings survive opaquely; actual scientific rules, SECS/NMRPeak fixtures and current-source adoption remain unqualified. A07. Synthetic projection/indices establish no atom-map correspondence, chemical discrimination or stereochemical behavior. No such claim is made. A08. No unit inference/conversion changed; decimal strings are contract sentinels, not scientific referencing or a new external-input convention. A09. No native/model-capacity or performance claim; scripted data serves only the stated installed-core composition proof. A10. Focused maintained fixtures/docs preserve decisions, not raw logs, abandoned scripts or duplicate production owners. Unique failures were not removed. Magnet adaptation validation and review closure --------------------------------------------- Final owning lane: make test/integration/provider-core -- 48 tests, 3.109 s, passed with one explicit selected-live-worker skip. The suite includes all three new cases. During initial tests-first work the then-contract selection failed because the fixture module was absent; its later eight-case passing runs are historical development observations, not the final suite placement. Focused Ruff on both new Python files and git diff --check passed. No production core, dependency, source pin, model artifact, public endpoint or sibling repository changed. Independent reviews corrected the coupled result oracle, fixture placement and source-authority wording. Rechecks accepted the narrowed admission assumption and rejected a duplicate synthetic-value oracle after tracing its actual purpose. These are the first three Magnet semantic adaptation cases only; all explicitly open P5/003 requirements above remain part of the package goal. P5 scripted child-retirement boundary (2026-10-18) ------------------------------------------------ This slice adds no production owner or supervisor. It exercises the installed AnalysisSession/AttemptExecutor seam using one fixed authored subprocess inside make test/integration/provider-core. Source rationale is recorded beside the fixture: NMRPeak 1697dc84dd1d76ae25b04efc8183fd80614000e5, nmrpeak_provider/runner_session.py:395-443 closes/retires a channel without claiming process exit; SECS 34f5915c1534278bbf61b4c6592afa44cf94ab08, src/secs_inference/provider/worker.py:251-295 reserves stop acknowledgement for the supervisor that confirms the retained child exited. Merely awaiting a cancelled Python task or receiving EOF cannot satisfy that ownership contract. One private peer script and one test session exercise four cases: 1. Scripted preparation completes before a live handle. Generation sees durable EXECUTION_ENTERED, runs once, and its expected result reaches the saved terminal request. The executor returns only after that exact child exits/is reaped and its owned pipes are closed/drained. 2. Scripted preparation rejection selects failure before entry. No generation occurs, and the child is still stopped/reaped before the returned failure. 3. A real generation acknowledgement precedes caller cancellation. The exact retained child stops, no result/publication candidate is produced, and saved execution-entry history survives. Claim release then succeeds. 4. A peer deliberately closes stdout but remains alive, independently of stdin. EOF and retirement failure retain the claim; failed settlement does not run another generation. Explicit cleanup of that same process still cannot release the claim until the original executor settles. No replacement child is started. The tests first failed on the absent child_session module: 49 discovered cases, one import error and one explicit live-worker skip. The initial implementation passed all four new cases. Independent review found an unbounded cancellation observation could prevent unconditional child cleanup on regression. Cleanup now uses AsyncExitStack and bounded task observation; child cleanup and store closure are attempted even if earlier cleanup fails. Executor watchdogs retain their original task instead of relying on wait_for to finish cancellation indefinitely. Review also added independent expected-result fields and a claim-release refusal between physical process cleanup and explicit executor settlement. The fixture is not a SECS/NMRPeak protocol replica or a scientific validator. Its preparation acknowledgement establishes order only. It neither qualifies process startup interruption, descendant processes, resource grants, native inputs, selection/reselection, real model outcomes, readiness, warm reuse nor production isolation. Those remain binding/composition obligations. This is additional core retirement-contract evidence, not closure of either sibling adoption or P5/003. Source inspection also identified two separate future SECS adoption obligations: its analysis_run.py:180-218 records entry before worker input_rejected/reselection, so adoption needs a real prepare/admission split; its existing closed-Job policy (analysis_run.py:248-265 at the same pin) continues an in-progress Attempt while the current core executor requires an open Job. This policy difference needs explicit composition design/tests before claiming compatibility. SECS outcomes.py:16-51 permits completion only for analysed; no_starting_candidates remains a failure with the worker's caveat, not a successful analysis. These source facts are not implemented or qualified by this child test. Final child-retirement validation after cleanup/watchdog, lint corrections and removal of the unused source field: make test/integration/provider-core -- 52 tests, 3.393 s, passed with the existing one explicit selected-live-worker skip. All four new cases ran. Focused contained Ruff on the three new Python files passed; git diff --check passed. Production core, dependency locks, scientific artifacts, launchers and siblings are unchanged. Read-only auditor observations below are source review, not additional test runs. Final simplicity pass removed the unused base64 source field from the scripted peer request. The fixture tags replies with the admitted fingerprint for ordering; it does not consume scientific source bytes or establish source-consumer identity. Actual byte-consumption qualification remains with the binding and its own tests. Individual U/A reviews of child-retirement slice (base f6ebe8f) ------------------------------------------------------------- Each U01-U26 and A01-A10 had its own read-only auditor inspect the actual changed files against its recorded obligation. No row below closes the whole-package item. U01-U07/U09-U11: scripted ordering/identity and installed-core evidence only; actual scientific admission, byte consumption and sibling routes stay open. U08/U13/U14: real exact-child/EOF/cancellation and held-claim witnesses accepted; startup interruption, descendants, grants and warm reuse remain unqualified. U12/U20/U21: launcher, dependencies and scientific producer/artifacts unchanged; existing source pins ground rationale, not new scientific observations. U15/U16/U17/U23: independent result expectation, precise rationale and safe typed cause/cleanup distinctions accepted; real recipient delivery remains open. U18/U19/U22/U24/U26: coherent maintained integration fixture with explicit limits, preserved rationale and no raw logs; no sibling or package-completion claim. U25: requested final post-correction lane evidence; result above now records it. A01-A10: no incremental issue within the stated non-scientific retirement boundary; real science/capacity, source/unit/stereo, recipient and adoption proof stay open. Three independent code reviewers rechecked the cleanup and assertion corrections without residual findings. The final unused-field deletion was separately checked under U03/U05/A08 and by the simplicity/ownership reviewer, with no regression. All new Python files passed final contained Ruff. Repeated source rechecks found no remaining actionable signal for this bounded slice; P4/P5/003 remain open. P5 explicit Job-state execution policy (2026-10-18) -------------------------------------------------- Source inspection found a concrete shared-core incompatibility: SECS 34f5915c1534278bbf61b4c6592afa44cf94ab08, src/secs_inference/provider/analysis_run.py:260-265 deliberately continues an in-progress Attempt when its Job is closed, but stops for cancellation. The core executor had required an open Job at every observation, imposing one consumer's choice on the others. A callback/strategy framework is unnecessary for this finite state choice. AttemptExecutor now requires an explicit immutable allowed_job_states frozenset from the existing response owner's vocabulary. All previous callers, including NMRNet composition tests and the scientific-worker lane, explicitly choose {open}; the SECS-shaped policy test chooses {open, closed}. There is no fallback/default. An Attempt that is no longer in_progress always stops, even when its Job state is allowed. Science and wire ownership remain unchanged. Tests first failed on the absent paused-session fixture, then on the missing allowed_job_states keyword (45 normative cases, two failing phase subcases). After the explicit choice was implemented, normative tests passed. New cases observe closure during both paused preparation and paused execution, rather than assuming an initial snapshot proves monitoring behavior. Closed Jobs continue under the SECS-shaped choice and stop under the previous open-only choice; cancelled Jobs stop under the SECS-shaped choice. Every terminal Attempt state crossed with every Job state stops before input/preparation even when closed Jobs are explicitly permitted. Configuration rejects mutable/empty/unknown/cancelled choices, including mixed known/unknown sets, before acquiring a claim. Independent tests-first review found two useful corrections: bound observation of paused executor tasks so a missing poll cannot hang the suite, and test a mixed known/unknown policy so nonempty-intersection validation cannot pass. A shared test-only watchdog retains/cancels/observes the original task. Moving the known Job-state vocabulary to a frozenset also requires checking raw response types before membership; malformed list/dictionary observations have explicit API tests, preserving rejection/evidence instead of leaking a hashability error. Scope: this corrects the finite Job-state policy only. Failed observations still stop/retire the core executor. SECS analysis_run.py:252-259 separately tolerates ApiUnavailable under its existing work deadline; that remains a policy/adoption obligation. Unit tests use a direct observation port to isolate policy and do not qualify closed-Job publication or deployed API behavior. No source-only reference is promoted to such runtime evidence. The already-qualified open-only integration and real-worker lanes now choose their former behavior explicitly; historical scientific artifacts are not recertified by this source change. Full sibling adoption, all input/recipient routes and P4/P5/003 closure remain required. U02 review rejected an unneeded first-version option to include cancelled in the permitted Job states. No current consumer needs continued work after cancellation. Configuration now refuses cancelled alone or in a mixed set; every observation therefore stops cancelled Jobs. Consumers choose closure behavior only. This removes an unsupported policy choice instead of adding a new strategy interface. Post-correction execution-policy validation: make test/unit/provider-core -- 192 tests, 1.871 s, passed, including all four new policy methods and their phase/state/configuration subcases. Earlier split runs were 45 normative tests and 147 adversarial tests; the final combined run follows the cancellation-policy correction. make test/integration/provider-core -- 52 tests, 3.535 s, passed with the existing selected-live-worker skip. No actual scientific-worker/model rerun is claimed; its constructor now explicitly selects the former open-only behavior. Dependency closure and model computation did not change. Focused lint/diff review covers the source changes and affected callers. Individual U/A review of execution-policy slice (base 7cfdc34) ------------------------------------------------------------ Each U01-U26 and A01-A10 independently inspected the actual diff against its own recorded concern. U02 identified the unsupported cancellation-continuation option; the code/test correction and its recheck are recorded above. Other ID reviews found no incremental issue within their scope. U01-U07/U09-U11/A01/A02/A04/A06-A09 explicitly retained missing scientific/source/deployed/recipient adoption evidence; U08/U13/U14 retained lifecycle/budget/retirement obligations beyond this choice; U12/U20 found no new launcher, dependency or acquisition authority; U15-U19/U21-U26 and A03/A05/A10 accepted the finite policy, safe diagnostics, precise source rationale, maintained test placement and honest preservation/evidence limits. These are source reviews, not additional runtime runs or whole-package qualification. Three ordinary code reviewers inspected the integrated slice. Their tests-first findings (watchdog and mixed known/unknown case) and U02's policy finding were fixed; rechecks found no residual actionable signal. Final contained Ruff covered all 17 changed/new Python files, and git diff --check passed. P4/P5/003, actual SECS unavailable-observation policy, closed-Job publication and sibling adoption remain open. No upstream or sibling checkout changed and nothing was pushed. Next runtime slice: one selected Attempt controller ------------------------------------------------- The next runtime owner is provider_core.controller.AttemptController: all proposed behavior is generic lifecycle orchestration over an injected AnalysisSession, with the already explicit consumer Job-closure policy. NMRNet supplies allocation, scientific session and host-retirement ports. Its existing live-worker witness must invoke the new owner; an unused orchestration facade is not acceptance. Controller ownership transfers only after synchronous configuration validation. The accepted session then belongs to this single-use owner, including before any start is sent. The controller retains a private claim from the composition's shared registry, and the actual current core operation. A read-only observation of the claim's existing operation owner supports exact settlement; no copied pending flag or parallel journal/schema is added. Transport/store lifetime stays with composition. A held controller cannot start another Attempt. The bounded inventory read is controller-owned. Unresolved retained records require explicit recovery before fresh work; confirmed records do not globally block admission. Existing store admission still owns exact duplicate/conflict and retention-capacity rules. Timed-out/cancelled inventory reads remain owned until observed; a late read never sends a start. Session cleanup is attempted even when starting fails or the server returns an already terminal start admission. That terminal replay returns the original acknowledgement without science or a new publication choice. No queue, polling service or automatic recovery is added. The normal path joins existing Starter -> Executor -> Publisher and returns the existing durable record. Failure preserves the actual operation and primary cause, plus independent cleanup failures. Explicit settlement observes only original I/O/work and confirms session retirement before releasing the private claim. A late acknowledgement cannot enter science; a late TerminalPending cannot trigger publication. Suppressed-outcome persistence remains an explicit executor operation. Recovery remains the existing AttemptRecovery owner, after allocation retirement. Tests first cover success and terminal replay; failed-start cleanup and failed retirement holding exclusion; cancelled inventory/acknowledgement persistence; uncertain terminal delivery without rerunning science; unresolved-inventory refusal and confirmed-inventory admission. Focused installed core lanes precede real NMRNet/TLS and released-worker/host-retirement composition. This is a finite runtime step toward a provider; feed scheduling, continuous service, remaining input routes, recipients and deployed API/GUI qualification still remain open. Controller implementation and first qualification (base e3eafee) -------------------------------------------------------------- The installed AttemptController now owns one accepted AnalysisSession, private claim lifetime and the actual current core operation. Its own lifetime distinguishes new/running/held/settling/released; it does not reconstruct the children’s pending state. The claim exposes its existing operation owner read-only, with normal active/loop admission. Configuration is validated before ownership transfer using the executor's shared validator. API/store shutdown remains composition-owned. Six initial tests followed the absent-module tests-first failure (194 discovered cases, two import errors). The first implementation passed 198 unit tests. Source review then found two real retirement defects: non-None return values were accepted as cleanup confirmation outside Executor, and confirmed retirement could be repeated after publication failure. New tests reproduced all three failing subcases. The shared analysis.retire_session check now owns result admission; Executor exposes confirmation directly from its existing enum. Controller records only its own pre-execution cleanup confirmation and consults the executor's confirmation/ordered publication prerequisite after handoff. It never repeats a confirmed retirement, even when the binding permits only one successful call. Rechecks found those defects resolved without another lifecycle framework. Current cheap proof: make test/unit/provider-core passed 205 tests in 1.994 s; make test/integration/provider-core passed 52 tests in 3.550 s with its explicit live-worker skip; make test/contract/provider-core passed five tests in 1.239 s. The exact wheel inventory includes controller.py and cold-import qualification covers it without consumer dependencies. Focused contained Ruff passed, including the last test-only suppression case; the provider-core repository lane passed 36 checks in 0.752 s. The controller witnesses cover normal completion and claim release, terminal start replay without science, constructor refusal before ownership, failed-start cleanup, failed retirement retaining exclusion, invalid retirement result holding ownership, confirmed records permitting admission, and active claim-owner readback. A real store-thread inventory barrier and the actual acknowledgement rename prove caller cancellation retains original I/O; late completion cannot start science. A one-shot retirement session plus lost-publication reply proves explicit recovery replays exact terminal bytes with one execution/retirement. A completed-but-stopped result keeps the controller held until its retained original executor explicitly persists SuppressedOutcome; settlement never publishes it or invokes science. NMRNet's maintained cheap TLS and released-worker scenarios now invoke this runtime controller rather than assemble the three effects in test code. The real-worker lane passed with host-confirmed stop/grant cleanup and reopened terminal receipt: make test/integration/provider-scientific-worker. Portable evidence is separately preserved as artifacts/provider-controller-cpu-float32.json, SHA-256 e1a058c70c4f0fc881b101a1baf3640a1ac7ea264bf1812b254d071b46198d30. It records source parent e3eafeeaef45f745f316e7762fb552ab574c1476 and 81 executed source hashes, all verified against this checkout after the run. One scientific execution and one completion dispatch occurred; 30 current-state reads monitored work. Result size was 15279 bytes, SHA-256 d20ed5a618da8cc77363e96f52394c8b975259975629065acd645ec636834ce5. The larger envelope includes current execution provenance; no changed scientific accuracy or population is inferred from comparing these bytes to prior evidence. The earlier provider-lifecycle-cpu-float32.json remains unchanged as historical proof of its own source set. Private allocation receipts/logs remain under .work; they are not copied into the public repository. This is a finite explicitly selected lifecycle owner, not feed scheduling, continuous-service/startup orchestration, a deployed API/GUI transaction or full 003 closure. It requires existing unresolved inventory to be recovered explicitly; confirmed records still consume store capacity under the existing retention rules. ControllerFailed preserves protected original/cleanup causes; it is developer lifecycle context, not completed recipient rendering. All input-route, recipient, capacity and sibling-policy/adoption obligations already recorded remain open. Review corrected a misleading duplicate-run instruction: a second call cannot settle a still-running invocation. Its error now says to retain the original invocation and controller for settlement/recovery. Unit qualification and the real-worker witness above were rerun after that source change; all 81 source hashes in the final artifact match the executed checkout. The unresolved-inventory gate is local to the supplied store's RecoveryScope, which binds consumer/lane and generation. Independent execution lanes share the claim registry and use separate scoped stores; the gate does not impose NMRNet's single lane on other consumers. This preserves 017 P3 and X02's existing ownership contract without adding a scheduler or another store/claim authority. Controller slice review closure ------------------------------- Each U01-U26 and A01-A10 had its own concern-specific auditor inspect the actual diff, including untracked code/evidence. Final integrated code, contract/mechanics and documentation reviews found no residual actionable issue in this finite slice. The retirement admission/repetition defects and duplicate-run instruction above were corrected and rechecked. Active package-guide statements left over from earlier stages were also corrected: implemented recovery/execution/publication and worker integration now name their owners; unfinished startup scheduling, complete restart coverage, service/routes, recipient delivery and deployed qualification remain explicit. The documentation reviewer and U22 reviewer accepted that repair. U01-U11/U13-U16/U24-U26 and A01/A02/A04-A09 retain distinct installed, fault, local signed-wire and actual released-worker evidence. None discharges the missing scientific populations, routes, recipients, capacity or sibling cutovers. U12/U20 change no launcher/dependency/acquisition authority; U17/U23/A03 preserve safe context and protected exact causes without claiming recipient rendering. U18/U19/ U21/U22/A10 preserve coherent scope, exact final-source evidence and current status without public raw logs or private receipts. Final contained Ruff and diff whitespace checks passed. No upstream/sibling checkout changed or push occurred. R3 source-grounded file-acquisition design checkpoint, 2026-10-22 -------------------------------------------------------------- Design only: no R3 implementation, consumer migration or capacity proof follows. SECS source inspected at HEAD 7356c354368f2355d3ab5cef00cf48c67cea9c2c; its worktree was clean. Core uploads.py, transport.py, attempt_store.py and attempt_files.py were unchanged from HEAD 96a1c48568369af0eab46353a8ee182924be9d6b. Keep JobUploads.acquire's immutable-byte result. Add an explicit private-file option through the same membership, grant, budget and HttpTransport exchange owners; do not buffer the whole Upload in the controller. Composition supplies the private destination. Charge every consumed chunk before refusal or disk write, including failed transfers; changing output must not reset any budget. Permit one bounded outstanding file write, owned across cancelled/expired waits. Reuse AttemptStore._run/_observe's original-future settlement pattern narrowly; do not create another downloader, cache, journal or general executor framework. No successful file receipt before whole-transfer header/length/SHA verification, file finalization and required network/file I/O settlement. Retain incomplete private files when writes or closure remain unresolved; settle before unlinking. Successful-file cleanup belongs to composition after reader quiescence or actual supervisor-confirmed interrupted-work stop, never merely socket closure. SECS sources below are relative to src/secs_inference/provider/: - upload_download.py::download_upload/_copy_verified streams, hashes and closes before handing off a path; analysis_run.py::AttemptSources retains source files on WorkerStopUnconfirmed; worker.py::WorkerClient.stop requires supervisor proof. - analysis_run.py::_worker_request currently sends paths only; worker_model.py::ScientificHandler.__call__ constructs SourceAccess from them. - source_access.py::SourceAccess.scope_reader/open/_archive/_preflight_archive currently reopens paths; _read_stream already returns immutable ReadSource bytes with their digest. input_adapter.py::InputAdapter._verify_components retains verified component bytes; input_formats.py::prepare_representation consumes them directly or creates controlled scientific temporary files. Carry authoritative expected Upload length/hash and granted locator to the worker. Open with O_NOFOLLOW, require a regular file, and verify a bounded immutable byte snapshot from that opened object before parsing. Path substitution must refuse or yield the same verified bytes; inode identity grants no scientific authority. Adapt ZIP sniff/preflight/ZipFile to BytesIO over that snapshot; never reopen the original path after verification. Hash -> seek -> parse on a mutable descriptor is unsafe against in-place mutation. Existing worker byte materialization makes this a local adaptation; sealing, memfd paths and new IPC are not justified here. Worker memory is not constant: compressed snapshots and expanded member bytes remain bounded but coexist. Actual worker capacity still needs qualification. Focused tests first: shared failed-byte budgets; streamed file success; digest, length/header/write/finalization refusal; cancelled pending write before cleanup; primary plus cleanup failure; pathname/symlink/in-place substitution before or during snapshot; immutable consumption afterward; ZIP limits and stop-held files. Awaited condition reporting qualified, 2026-10-22 ================================================ Commit 3b21d8f6599f5818b76172d2312196f950a1d90d implements the R4 condition port and supersedes the earlier design-only status. This is a narrow shared lifecycle capability; observation-gap policy, peer admission/refusal, warm reuse, full R4, P4/P5 and 003 remain open. AnalysisSession.prepare and execute now require the keyword-only report_condition callable. The binding calls it with a reviewed public condition code, or None to clear it, and awaits the acknowledgement. It receives no raw API client or phase selector. Core binds the Attempt and current phase. It serializes reporting with observation/progress API operations and admits the acknowledgement before the await returns. Running-progress acknowledgement, durable execution entry and fresh observation still precede science. The callable expires when its session phase returns or core stops observing it; a report waiting behind an API operation rechecks that lifetime before sending. Calls are sequential and awaited; detached/concurrent reporting is unsupported. A failed or cancelled report cannot be ignored to authorize the next phase or publication, even if the binding catches it. Existing first-owned failures and independent causes remain preserved; this does not give a report precedence over an earlier observation or server-stop failure. A later binding failure survives as context without replacing the report's original transport/cancellation cause. A returned outcome can still exist in memory without a durable terminal record or confirmed API effect. The actual operator stderr and failure.json now say outcome_in_memory/unconfirmed_record_in_memory; they make no durable-retention claim. Receiving tests preserve useful primary, later-context and independent cleanup causes while excluding credential canaries and scientific payloads. Those tests do not qualify commissioner GUI or requester API error delivery. Exact implementation/test references at that commit: - packages/provider-core/src/provider_core/analysis.py::ReportCondition and AnalysisSession; execution.py::_ConditionReporter, _api, _call_session, _monitor, _prepare_session and _execute_session. - packages/provider-core/tests/unit/{normative,adversarial}/ test_execution_conditions.py covers set/clear, acknowledgement waiting, poll serialization, expired/queued reporters, invalid codes and swallowed failures. - packages/provider-core/tests/integration/test_execution.py:: test_start_prepare_execute_retain_and_publish_under_one_claim sends phase-bound conditions over actual signed local TLS through durable completion. - nmrnet_provider/process_reports.py::_safe_owner_details and tests/integration/provider_core/normative/test_nmrnet_reports.py:: test_returned_outcome_in_memory_does_not_claim_durable_retention_or_publication, test_failed_condition_and_later_binding_error_keep_both_receiving_causes. The source rationale retains Magnet 600968a5fad8ad0118ea4f42cd7fc1fbfde54aaf, magnet_provider/attempt_progress.py::AttemptProgressReporter.report_condition and magnet_provider/analysis_execution.py:307,379,393; its retry/duplicate suppression is not imported. Final focused unit qualification passed 77 tests in 1.166 s. Final installed-core aggregate integration passed 377 in 44.818 s, with the same 11 native-runtime gates skipped. The earlier 31-test focused integration result is intermediate. Pinned lint/format completed successfully. Ephemeral local logs and SHA-256: - /tmp/condition-reporting-final-unit.log 881d5b5f31c54efc53d57ef388e1ec86df58f3535695648e787153b3ab16dd19 - /tmp/condition-reporting-aggregate.log 65b542b01bc70387a8d4350d32bdfc9c11533791123b635d6b556137001fc837 - /tmp/condition-reporting-style.log 1bcb7cfcfd89c456b7599560f0cd9b3ac5da58e0074c239a8ceba047b3b55649 The focused repository lane exposed three failures: its documentation grant was missing, the checker misread six valid GNU multi-target rules, and two real help entries were missing. Repair 83459e9a3016e9c0d2c4a0b5cfd5e4c0efc04633 changes only Makefile, tools/container.sh, repository_checks/quality/test_make_hygiene.py and repository_checks/test_conventions.py. It grants the existing docs read-only, adds the two help entries and counts each target name while preserving all six valid rules. Focused fixtures retain duplicate, stale-help and PHONY refusals and exclude assignments/recipes; no requirement was weakened. The final maintained make test/repository/provider-core passed 41 tests in 1.418 s. Ephemeral receipt: /tmp/repo-check-repair-final.log, SHA-256 11a47d03050a75b62a57b3d9139c20c61a5e1f738aa9e42433c6b255521a159e. Pinned Ruff 0.15.15 lint/format for the two Python files, Bash syntax and diff checks passed. Independent code/recipient and checker reviews found no actionable issue after corrections. This checker-only repair required no full integration or native rerun; the condition implementation and its 77/377 results are unchanged. No production image, native science, external model, new actual API transaction or GUI proof was produced by these slices. This documentation entry records existing results without new runtime qualification. Full provider-core, R1/R3, R4's remaining contracts, R5/R6, P4/P5 and 003 remain open. Raw streamed HTTPS file output qualified, 2026-10-22 =================================================== Commit: 3cd984387cdde1889d16c24f022241cf91592a71. This closes the transport portion of R3, not verified-file acquisition or consumer qualification. Exact implementation: packages/provider-core/src/provider_core/transport.py, HttpTransport.exchange_file/_exchange/_perform and private _FileBody. The byte exchange API stays intact. No dependency, grant, retry or scientific policy changed. exchange_file borrows an exclusively used writable regular-file descriptor without append mode, at the caller's current position. Its HttpFileResponse contains status/headers and received body count/SHA-256, without a buffered body. Those are raw response observations, not whole-file, future-path, verified Upload or durability facts. Failed cleanup can leave even all response bytes written without permitting handoff. The caller owns descriptor closure and path cleanup and must preserve them until transport retirement is confirmed. One concrete per-exchange executor validates the descriptor before any network owner is created, then writes at most 65536 bytes per submitted operation. It handles short writes; no progress refuses. Each received chunk is charged before limit refusal or writing. There is one outstanding original future, no queued write backlog; the next network chunk cannot be consumed until the write settles. On interruption, network cleanup precedes original-future settlement; a blocked inspection/write keeps the existing transport owner held. Late disk errors and independent network cleanup errors remain protected evidence alongside cancellation/deadline causes. Rationale/provenance: the preceding R3 checkpoint cites the inspected SECS stream and source-consumption owners at 7356c354368f2355d3ab5cef00cf48c67cea9c2c. Original-future settlement adapts this package's attempt_store.py::_run/_observe at parent 36eddeb485697a845ff445e5e0fbd950a52177ef; the journal itself is not reused as an acquisition owner. Borrowing the already-open descriptor keeps file creation, grant admission and reader-safe cleanup with their actual owners. Separate raw file facts avoid pretending an empty HttpResponse.body contains transferred bytes. Tests-first: initial absent-port RED ran 22 tests (1 failure/6 errors); descriptor preflight RED then ran 29 tests (5 failing descriptor subcases). A fresh independent audit identified that valid-integer closed/read-only descriptors could otherwise cause network work first. The repair checks regular/writable/nonappend state in the same original-future owner. Explicit EBADF and read-only/append/pipe fixtures prove zero backend/client creation. Held fstat tests cover cancellation and expiry, then successful original inspection: no late request starts. Held real write tests cover repeated cancellation, one write/no read-ahead, late ENOSPC with clean or failed network cleanup, owner exclusion and protected cause rendering. The real local TLS stalled-body test observes an actual byte on disk while the response cannot finish, then verifies cancellation and socket retirement. This causally rules out whole-body buffering. A complete TLS transfer checks exact bytes/count/hash. Current-offset fixtures distinguish body facts from existing file prefix/tail contents. Tests live in package tests/unit/{normative,adversarial}/ test_transport.py and tests/integration/transport/normative/test_response_file.py. Final maintained contained lanes: transport/network unit 31 tests in 1.925 s; transport local TLS 8 tests in 0.654 s; existing immutable-byte Upload acquisition 18 tests in 0.084 s. Ruff 0.15.15 lint/format on the four changed Python files and diff whitespace passed. Private ephemeral receipts and SHA-256: /tmp/file-output-unit-final.log 371b3a71335850a26bb32c3c11886b2e2b878fb1fd16f9320cee2d1bc3fb035c /tmp/file-output-tls-final.log 4fd56fbb6c7159101d0a51434de9d942d778eb3038d9515bb33f1c61299cfe1d /tmp/file-output-style-final.log fe000c25495ebef359f77007c122e787c45497623f438f663063b546043fa887 /tmp/file-output-uploads-final.log 3aeff1bf11016228aaa735a78f5af54b4e7ce1bbf4f174ec50926164532ba646 Independent boundary/code and fresh Luna-low reviews found no further actionable signal after corrections; the final pass included applicable U/A concerns from013. R3 still requires JobUploads' shared verified-file acquisition/finalization owner, bounded immutable worker consumption with substitution/ZIP proofs, reader-safe cleanup and actual consumer/capacity qualification. No upstream/sibling edit, production image refresh, new science, external model/API transaction or GUI proof was produced. The full provider-core and003 goals remain open. Verified Upload file acquisition qualified, 2026-10-22 ===================================================== Commit b4b73e70d4e5e9f0733dcabdbd875393a0940218 adds uploads.py::JobUploads.acquire_file/settle_file and VerifiedUploadFile. This closes R3's acquisition owner, not worker consumption or the user's remaining003 gates. The byte and file paths share selection, fresh membership/grant, exact store request, digest/length/header verification and cumulative byte/request/deadline accounting. No second downloader, cache, automatic retry or budget reset exists. Composition lends an open, exclusively controlled effective-user-owned0700 directory. Before grant issuance, acquisition creates one exclusive0600 leaf; restrictive umask does not change its intended mode. Success follows verified transfer, confirmed close and a final source-deadline check. The receipt binds Job/Upload/length/hash to that transfer, not future pathname contents or durability. Successful ownership leaves the acquisition owner; composition must wait for reader quiescence before deleting the source. Worker snapshot verification remains required before parsing; no consumer migration is claimed. One original create/close/remove future is retained through cancellation/expiry. Cleanup uses its explicit grace without granting more source-work budget. A late successful operation can finish abort cleanup only, never issue a late grant or receipt. Pending transport writes must retire before descriptor closure/unlink. A close error is not retried by descriptor number, even after descriptor reuse. Unknown original inode identity and observed replacement have distinct refusals; neither permits guessed deletion. Trusted directory-owner inspection/removal can allow later confirmed-absence settlement. This relies on exclusive directory control, not atomic conditional unlink against concurrent same-user mutation. Rationale/source: the inspected SECS source-consumption precedent remains pinned in the preceding R3 checkpoint at7356c354368f2355d3ab5cef00cf48c67cea9c2c. The local original-future and non-retried-close precedents are attempt_store.py::_run/_observe and attempt_files.py::_close_descriptor at parent a11b4d2ef5108b136985e9de05bf9614feb25f33. The existing bounded exact-owner process_reports.py traversal now carries Upload operation, independent cleanup, interruption and grant-issued evidence to stderr and protected failure.json. It does not stringify arbitrary filesystem messages or expose private pathnames. Historical cleanup evidence can survive later settlement; it is not ownership state. Tests-first refusal/interruption witnesses were red before their respective repairs. Final focused maintained contained lanes, against the committed runtime source: - make test/unit/provider-core/uploads:45 tests,1.378s, passed; - make test/integration/provider-core/uploads:17 tests,0.515s, passed,1 existing native-reader gate skipped; - make test/integration/provider-core/process:48 tests,25.029s, passed; - make test/repository/provider-core:49 tests,1.820s, passed. The Upload integration lane now includes actual signed local TLS API-to-bearer store file transfer. It verifies exact bytes/hash/length/private closed output and credential separation. Existing launcher tests verify exact focused discovery; the repository/core lane now owns those tests. No check was weakened. Ruff0.15.15 lint/format on8 changed Python files, Bash syntax and diff whitespace passed. Independent ownership, simplicity and fresh Luna-low U/A reviews found no remaining concrete issue after corrections. Private ephemeral logs and SHA-256: /tmp/upload-file-unit-final.log 0785e7264fbaeedd74d47f59f9a186499438e2449c6d1f0f5a364657c1cd6e27 /tmp/upload-file-integration-final.log 4150d53faaef3cb252a9b955bae5312b7f3e3cf046845f6bd2e6538ae5e6b244 /tmp/upload-file-receiving-final.log f9bab605998f93c709d0638f5eee45dc55418a7ed7d48ec5edce69dc074947c6 /tmp/upload-file-repository-final.log 7670402de216d99306b38abed3336ed6768484e051b573385b4f0d34abb81d56 /tmp/upload-file-style.log d1a1322e6e6cbfd62e936fc12af366a3bd22e945892558e89be8512194dd3803 No native science, production image refresh, external model/API Job, sibling edit or GUI qualification occurred. Worker snapshot/substitution/ZIP, actual peer consumer/capacity and the other current R1-R6/P4/P5/003 requirements remain open. Immutable Upload file consumption boundary qualified, 2026-10-22 =============================================================== Commit4848a4f2bfb42e11d7a8e9e38b1f8c93efb92062 adds uploads.py::read_upload_file/_read_upload_snapshot and UploadFileReadFailed. It accepts VerifiedUploadFile, an explicit borrowed directory descriptor and an explicit worker byte ceiling, returning the existing VerifiedUpload byte result. It opens one non-dot basename with O_NOFOLLOW/O_NONBLOCK/O_CLOEXEC, requires a regular file, reads chunks <=65536 bytes and no more than expected length+1, then uses VerifiedUpload's existing length/hash verifier once. Observed close precedes return. It neither parses nor unlinks the source. Changed paths after open cannot redirect consumption; mutation during copying refuses unless the returned bytes still exactly match the transfer receipt. Later changes cannot alter immutable data. This is not an atomic filesystem snapshot or constant-memory/durability proof. The synchronous function belongs inside an already supervised reader. Its unit interruption witness injects cancellation from the read operation; it does not prove an awaiting controller's cancellation reaches synchronous I/O or that a worker stopped. Worker supervision and source lifetime remain binding obligations. No new executor, IPC variant, archive policy or grant authority was introduced. Existing NMRNet readers already receive immutable bytes; they were not migrated. Precise source/rationale: the preceding R3 checkpoint inspects SECS at 7356c354368f2355d3ab5cef00cf48c67cea9c2c. Paths relative to src/secs_inference/provider: source_access.py::_read_stream establishes immutable ReadSource contents; input_adapter.py::_verify_components and input_formats.py::prepare_representation consume retained bytes. Current SECS path reopenings in scope_reader/open/_archive/_preflight_archive and its path-only worker request are the concrete future adaptation seam. This implementation copies no archive/scientific policy into core and edits no sibling. Basename admission protects dirfd authority, not inferred molecular identity or a new file-mode rule. A separate read failure is necessary: acquisition owns grant issuance; this reader cannot report grant_issued=false for an already acquired file. Exact-owner process_reports.py admission now renders UploadFileReadFailed's safe read reason, protected cause, independent cleanup and interruption, without acquisition facts. The pure byte verifier maps its constructor-owned safe reason at the read boundary; its translated refusal is raised outside that handler so no synthetic acquisition context survives. Global context traversal is unchanged. Actual filesystem causes remain private under .cause, suppressed from ordinary tracebacks; no generic exception stringify was added. A close error is never retried by fd number and refuses handoff. Operation and cleanup remain independently visible. Cancellation raised within the worker stays the original object, retaining previous cause and close failure through the existing owned-link pattern. Unconfirmed closure requires supervisor retirement before source release; the primitive grants no stop proof. Tests-first: absent-port RED47tests/2import errors; initial57 passed. Reviews then identified ordinary-traceback leakage and cancellation replacement: focused RED 59tests/3failures/1error reproduced them. After correction59 passed. The first receiving run50tests/1failure caught implicit acquisition __context__ still emitting grant facts; the local pure-translation correction removed that false projection. Final maintained contained lanes against the committed source: - make test/unit/provider-core/uploads:59 tests,1.446s, passed; - make test/integration/provider-core/process:50 tests,25.065s, passed; - make test/repository/provider-core:49 tests,1.779s, passed. Ruff0.15.15 lint/format on7 changed Python files, Bash syntax and diff whitespace passed. Independent byte/ownership, simplicity and fresh Luna-low U/A reviews found no remaining actionable issue after corrections. Final private ephemeral logs: /tmp/upload-snapshot-unit-final.log fc5f6ad44bd23c2d4b2ad24388f4ffef6107c19ec5942e9c11fdc91b928ab1e5 /tmp/upload-snapshot-receiving-final.log 09ce80e4d444c67cdaa563c01f17316468396695ffcf29adf9b0a11cf909ddd6 /tmp/upload-snapshot-repository-final.log 7df3fc014080eaa56c26221e61d13d345c56b6cae913ff91b5dfaa8aaa98de73 /tmp/upload-snapshot-style-final.log 0a5671adb76d036729af9ca6f25a6d525450d97d8fb533d7c26439c0d88d4fe8 R3 remains open: source-grounded direct/ZIP consumer adaptation must keep sniffing, preflight, member parsing and expanded-byte limits on the verified immutable copy; actual worker integration, reader-stop/source retention and capacity still need qualification. The other R1-R6/P4/P5/003 gates remain open. No native science, production image refresh, external model/API Job, upstream/sibling edit or GUI run occurred. The pending paid ambiguity batch was not retried. SECS direct/ZIP receiving contract on immutable Upload bytes, 2026-10-22 ====================================================================== Commit8576bfb adds a proposed, test-owned SECS receiving adapter in packages/provider-core/tests/fakes/secs_sources.py, with structured normative and adversarial integration tests. It replaces acquired-path reopenings with one read_upload_file snapshot per operation. ZIP sniffing, preflight, index and member reads use views of those same immutable bytes; direct scope reads retain them too. Fresh independent operations still verify their own snapshots. No async wrapper, SDK archive policy, extraction, scientific decoder or lifecycle registry is added. Inspected source: numpde/secs-repro7356c354368f2355d3ab5cef00cf48c67cea9c2c, paths relative to src/secs_inference/provider: - source_access.py, SHA-256 04911c122000b0246b844ef3b2567d4e5647effabef4eb0809b2b7bbfa62ef86; - input_operations.py::SourceRef, SHA-256 da2a00dda71ab0b314e38c538c0083c9e8e1bc1f2dbf5d65b4b41dbd4e4dac6b; - input_formats.py discovery helpers, lines143,161,249,287, and prepare_representation, lines374,386,407, consume access.directory for fixed-name decoder temporaries. Source links: https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/source_access.py https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/input_operations.py https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/input_formats.py The source header and package README record this provenance in place. The candidate keeps the separate scratch-directory grant needed by that actual format consumer; its test uses fixed-name materialization without claiming scientific decoding. The candidate uses the source directory descriptor only for verified reads; an O_RDONLY directory descriptor does not itself prevent relative writes. Preserved donor behavior includes preflight before loading a >4096-member central directory, ZIP64 preflight/count checks, multidisk refusal and duplicate/encrypted/nonregular member refusal, 262144-byte listing, 128MiB member and256MiB scope limits, one scope index, shared expanded-byte charging and narrow decoder-error classification. Failed work is not refunded. Filesystem errors and consumer defects remain operational. Unknown Upload selection is correctable; a receipt assigned to the wrong Upload label is an operational composition error before parsing. The supplied Job-associated receipt map remains composition's authority; this leaf fixture does not admit Jobs. Tests-first: the new absent adapter produced19tests/2import errors/1existing skip. That is an absent-port RED, not reproduction of a donor defect. After the first green, a separate read-only source probe reproduced the pinned original's direct scope reopening: admit b'original', overwrite the same-length path with b'replaced', then read the scope; observed b'replaced', expected b'original', exit1. The candidate counterexample retains b'original'. The probe hashes four donor files before import; it mounts only those files and its script into the existing offline checker image sha256:9164d380c00bf0e013d44357cafb03d4b1f64570a93105f74ac4b85b66cf1b49. It used python3 -I -B, the existing60s native command owner, read-only root, caller UID/GID, network none/pull never, cap-drop/no-new-privileges and finite resources. It imported no scientific runtime, used no credentials and edited no sibling. This causal source probe is retained evidence, not a new maintained qualification lane or proof that the current sibling has adopted the proposed adapter. Final maintained focused contained results against8576bfb: - make test/integration/provider-core/uploads:38 tests,0.664s, passed,1 existing native-reader gate skipped; - make test/unit/provider-core/uploads:59 tests,1.438s, passed; - make test/repository/provider-core:49 tests,1.731s, passed. The existing Upload integration target now selects the new test filename; its exact launcher contract and help were updated together. Ruff0.15.15 lint/format passed for9 Python files; the existing strict default detector passed for5 selected changed Python files. This was not a full repository/default-detector aggregate. Bash syntax and diff whitespace passed. Three independent source/ownership, simplicity and fresh U/A reviews found no remaining concrete issue after the scratch-grant test correction. Two SDK changes are rationale comments only. Private selective evidence: .work/qualification/secs-source-snapshot.HCHDd209, 9 files including inventory, root0700/files0600. inventory.sha256 SHA-256: 11902315d41f6c955ce5a4c436787bd8f5586f7686d0e6cb7eea8dc7242748ee. It retains the original probe/script, absent-port RED and final focused/style logs; tracked commits and the locked maintained lanes remain required for reproduction. Retain through package/003 review and handoff, then reassess under scratch policy. This qualifies a source-grounded proposed receiving contract against installed provider-core. R3 and P5 still require actual supervised-reader retirement/source retention, async preparation/prediction and capacity witnesses. R1's peer lock/Python compatibility and the remaining R2/R4-R6/P4/P5/003 requirements remain open. No native science, production image refresh, external model/API Job, sibling edit or GUI run occurred. No paid ambiguity retry was attempted. Existing scientific and successive-Job/stopped-recovery results remain unchanged and are reused. Acquired-source lifetime through a real scripted child, 2026-10-22 ================================================================ Commit7a98fff4905c9f36dcab05f3489d3ae87503abc8 joins previously separate acquisition/snapshot and async session-retirement proofs. Existing integration/test_child_retirement.py now acquires one real private file through JobUploads.acquire_file, lends its directory descriptor to the existing child using pass_fds, and runs installed read_upload_file inside that child. A completed snapshot's JSON marker comes from snapshot.data; its Upload digest remains distinct from the Job input fingerprint. No molecular decoder, weights or prediction runs. The test-owned UploadChildSession variant retains its original shielded launch Task, receipt and borrowed directory until exact-child retirement and source cleanup. It checks the receipt's Job association before launch. The existing AttemptExecutor, store, claims, private-file acquisition, ScriptedChild and finite contained test owner remain responsible; no second supervisor or SDK protocol is introduced. The child's extended payload is a concrete private test fixture. Three maintained witnesses: - An actual os.read inside read_upload_file consumes its first chunk, emits a reading acknowledgement, then blocks before the snapshot returns or closes its source descriptor. Caller cancellation joins/stops/reaps that same child and settles pipes before source removal. No prepared handle, execution entry, generation or outcome exists; the record remains NOT_ENTERED. This is active reader cancellation, not cancellation after a completed preparation. - After completed snapshot/preparation, EOF in the existing close_output mode leaves the exact child alive. Source and claim remain held across refused retirement/settlement. Explicitly stopping that child alone does not remove the source. A subsequent injected unlink failure remains an independent cleanup cause, keeping both file and claim. Later settlement removes the source once; only then may the claim release. No source reacquisition or generation replay occurs. A second post-settlement call is correctly refused by the existing executor contract; no new idempotence behavior is claimed. - A Job/source mismatch before launch cleans the already-owned file in both ordinary and close_output modes. It claims neither child exit nor science. Test teardown joins the retained launch and stops the child before the lent source-directory context can close its descriptor or remove its private tree. Rationale/source: SECS7356c354368f2355d3ab5cef00cf48c67cea9c2c, src/secs_inference/provider/worker.py::WorkerStopUnconfirmed/WorkerClient.stop and runtime.py::run_execution reserve source cleanup until worker exit or observed healthy idleness. These are the same inspected sources recorded above; exact links: https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/worker.py https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/runtime.py The local fixture applies that ownership requirement without copying the production supervisor. Its docstring records the pin and its exclusive source-leaf ownership assumption. It does not qualify concurrent path replacement during cleanup. Tests-first: absent-port RED28tests/1import error. The first integrated run had 33tests/1error because its test wrongly expected a second completed executor settle to succeed; the existing production refusal was retained. Reviews corrected a prelaunch cleanup assumption and fixture teardown's late-launch ownership. An initial generation-stage cancellation case was replaced with the in-read barrier above; generation-stage cancellation is not presented as reader interruption. Final focused maintained contained lanes against7a98fff: - make test/integration/provider-core/prepared-identity:34 tests,4.696s, passed; - make test/repository/provider-core:49 tests,1.697s, passed. Ruff0.15.15 lint/format passed for4 changed Python files. The existing strict Python default detector passed for those4 files; no global detector/aggregate pass is claimed. Diff whitespace passed. Independent boundary and fresh U/A reviews found no remaining concrete issue after the corrections. Selective private evidence: .work/qualification/upload-reader-lifetime.BK67TC9u, 8 files including inventory, root0700/files0600. inventory.sha256 SHA-256: 38b26aa667825bb374a967c33a21218b9c7bb9ecb26a6a810b38807e81410661. It retains absent-port RED, first failure and final focused/style logs. Tracked source and locked maintained lanes remain necessary for reproduction. Retain through package/003 review and handoff, then reassess under scratch policy. This qualifies a proposed binding's acquired-source lifetime through installed core and an actual scripted subprocess. It does not qualify SECS/NMRPeak's real supervisor/protocol, scientific reader cancellation, process-tree retirement, async capacity, warm reuse or a live subprocess-creation cancellation race. Actual peer integration and P5 remain open, as do the other current R1-R6/P4/003 requirements. Production source and images were unchanged. No sibling checkout was modified; no native science, external model/API Job or GUI was run. The paid ambiguity batch remains pending explicit destination approval; no external retry occurred. Pinned API release content, signing and eleven-route contracts, 2026-10-22 ======================================================================== Commit37cf6a15cdd58de7bd2ec0a02b33442a2c14f032 adds structured normative and adversarial contracts to the existing test/contract/provider-core lane. The full public release is test data: manifest plus17 inventoried artifacts (OpenAPI and16 schemas), excluded from the runtime wheel. No runtime release loader, schema engine, dependency, sibling import or new launcher/target is introduced. Help and the package README now name this existing lane's expanded contract coverage. Exact release: sha256:719055db7751605c0e5325ca23bcbe66cde631376d4b2b99523c8e4db75f0d01. Copied from numpde/nmrpeak-repro1697dc84dd1d76ae25b04efc8183fd80614000e5, contracts/upstream/nmr_api_v1; byte-identical to the API's existing archive at nmr_api/provider/contract_releases/v1/<release digest>. Declared source revision 12a53e720fc87e1a4144c76203f8853d5afaf753; archive commit daec9d978dacfd11b85ef96496dfd2e977e8142a. Manifest SHA-256: dda8dc36db963f85ec9105567342dae4ba680476c7ab1114bd1e33acba65474b. OpenAPI SHA-256: 0d8939625504e5fd1706e9e9325a2abbc9684087678e6c2b8daca5cb36fa46cc. Precise source links and rationale are beside the test artifacts in packages/provider-core/tests/fixtures/README.txt; test access is in contract/api_release.py. Signing test precedent is the same peer revision's tests/unit/test_provider_signing.py; inventory/hash rules come from its nmrpeak_provider/provider_http_contract.py. Source links: https://github.com/numpde/nmrpeak-repro/blob/1697dc84dd1d76ae25b04efc8183fd80614000e5/tests/unit/test_provider_signing.py https://github.com/numpde/nmrpeak-repro/blob/1697dc84dd1d76ae25b04efc8183fd80614000e5/nmrpeak_provider/provider_http_contract.py Fixture admission checks the exact manifest SHA-256, canonical inventory-derived release digest, complete file inventory, every artifact's byte length and Git blob SHA-1, without symlinks/special files. Only then are artifacts interpreted. This binds selected content, not a publisher. source_revision is excluded from the release digest and is not cryptographically attested. At inspected API source e7790cf6a922c39261fe736d5a23d17a9a5ea322, contract_releases/checks.py explicitly selects no supported historical baseline. No live server's support is inferred. Concrete installed-core coverage: - Both released signing vectors: exact Signature-Input, content type/digest, target and transmitted body; emitted signatures verify with a fresh test key against RELEASED signature_base bytes, not a base reconstructed by core/tests. Released signatures separately verify with their released SPKI public keys. No vector private key exists in the fixture or is invented for the test. - All11 ProviderAPI operations, including both Upload routes: actual dispatch method/verbatim path, exact body handoff, query names/required query fields and query/response/request byte ceilings. Response and constructed request top-level fields/schema identities are checked against released closed schemas. Hello/ progress body-builder reuse proves dispatch handoff; it is not an independent byte-serialization oracle. Retained start/terminal bytes are compared directly. - Released topology vocabulary; Hello supplementary-Unicode scalar and64-offering limits with overflow refusal; exact Job input bytes at1/65536 and over-limit refusal; noncanonical Base64 pad bits refused even when decoding yields the original byte. The same invalid encoding fails the released schema pattern. - Future schema versions and added response fields refuse for all11 operations, without returning admitted facts or exposing private response canaries. Missing, changed, extra or symlinked release files refuse fixture admission. These are selected consumed-rule checks, not complete nested-schema validation, every OpenAPI/recovery/send-effect rule, peer lock compatibility, authenticated server release discovery or actual consumer/deployment qualification. Tests-first: missing-fixture RED10tests/5errors; initial10 passed. Independent review identified a linked file with unchanged bytes escaping fixture closure; its counterexample produced13tests/1failure before the pre-read refusal fix. Fresh review also tightened transmitted-body assertions without changing runtime behavior. Final make test/contract/provider-core:13tests,1.196s, passed. make test/repository/provider-core:49tests,1.684s, passed before that final body assertion refinement; discovery/grants were unchanged and this lane was not rerun. Ruff0.15.15 lint/format passed for6 new Python files; the existing strict defaults detector passed for4 nonempty new Python files. Diff whitespace and byte-for-byte comparison to the pinned peer bundle passed. Independent source/boundary and fresh U/A reviews found no remaining concrete issue after both proof corrections. Private selective evidence: .work/qualification/provider-api-release.K0tSlIVx, 7 files including inventory, root0700/files0600. inventory.sha256 SHA-256: 143e2481e0cae80fad1fff0ccf4a29b9ed55cff24bb7cb186ce03879946e84c1. It retains both RED records and final contract/repository/style/default logs. Tracked source, complete pinned fixture and locked maintained lane remain required for reproduction. Retain through package/003 review/handoff, then reassess under scratch policy. Production source/dependencies/images were unchanged. No native science, external model/API Job, sibling edit or GUI run occurred. No paid ambiguity retry was attempted. R1/R3-R6/P4/P5/003 and broader R2 adoption obligations remain open; this entry closes only the precise selected-release proof described. Reusable protected core failure projections, 2026-10-22 ====================================================== Commitb8c3cfe02be298b7ce9ac53d8a4874bf3cd99de0 adds provider_core.failure_projection.owned_details/owned_relationships and changes NMRNet's existing process_reports.py to consume them. This is an actual deletion witness: the reporter's duplicate core error imports, type lists, fact branches and nonstandard cause-edge branches are removed. Core gains no scientific type, recipient sink, graph walker, registry, formatter or diagnostic journal. Precise source: numpde/nmrnet-repro37cf6a15cdd58de7bd2ec0a02b33442a2c14f032, nmrnet_provider/process_reports.py::_owned_relationships/_safe_owner_details, SHA-256 ee13ebc042ba407d957608477f3343a084cc7ce0143f84ed6971371468e25f7b. https://github.com/numpde/nmrnet-repro/blob/37cf6a15cdd58de7bd2ec0a02b33442a2c14f032/nmrnet_provider/process_reports.py The new module docstring records this provenance and the disclosure contract. Rationale: core owns these failure classes and their effect/cleanup meaning; consumers should not maintain parallel inventories that drop fields when core changes. NMRNet's scientific vocabulary and recipient policy remain with NMRNet. The donor graph-traversal precedent remains the pinned SECS diagnostics.py already cited at the top of process_reports.py; no second traversal is copied into core. Both functions expose PROTECTED, UNREDACTED data, never a public report: - owned_details returns fresh scalar facts for exact reviewed core types. Unknown types/subclasses acquire no text or attribute access. No raw response body, unrelated headers, terminal bytes or scientific payload is serialized. - owned_relationships borrows original protected cause/cleanup/interruption references, preserving labels, order, repeated references and absent causes. Standard __cause__/__context__/groups, cycles, node/display limits and redaction remain with the caller's existing mixed graph. - Received status/request IDs use the existing correlation owner, including its single visible-ASCII header/128-byte admission. Chat keeps complete-response precedence over a transport head and reads late received metadata at projection time. There is no copied/stale header authority. - Grant issuance is an acquisition fact, absent on reader failures. In-memory outcome/record presence, received start acknowledgement, held refusal and matching terminal receipt remain separate facts. No flag grants resend, scientific repetition or durable-acceptance authority. NMRNet's existing walker still redacts every selected string before bounding it, walks the one mixed graph and applies its scientific summaries and actual sinks. No previously unreviewed core exception vocabulary is added by this extraction. New maintained lane: make test/unit/provider-core/diagnostics. It uses the existing offline installed-package runner, selects only test_failure_projection.py and adds no selector/configuration framework. Make help/.PHONY, both container dispatch cases and the real launcher-argv contract agree. Exact wheel-content/import-origin and missing-container-marker tests include the new module. Existing production image input capture already globs all core Python modules; no image was built. Tests-first absent-module RED2tests/2import errors; after extraction8 passed. Final focused maintained contained results: - make test/unit/provider-core/diagnostics:8tests,0.001s, passed; - make test/integration/provider-core/process:50tests,25.146s, passed; - make test/contract/provider-core:13tests,1.212s, passed; - make test/repository/provider-core:49tests,1.911s, passed. The receiving lane exercises actual protected stderr/file rendering, including broken sinks, nested owned primary/cleanup causes, interrupted model effects, credential canaries, late heads and scientific diagnostics. Eight direct core checks add hostile unknown/subclass refusal, original reference identity, edge order, distinct effects, received-head precedence and fresh result dictionaries. The receiving/contract/repository runs preceded final whitespace formatting and an explicit builtins.ExceptionGroup import in the new unit test; the unit lane then passed against that final file. No runtime semantics changed in that final format/import correction, and those other lanes were not repeated. Ruff0.15.15 lint/format passed for6 changed Python files; the existing strict Python defaults detector passed for3 new files. Bash syntax and diff whitespace passed. Three independent source/boundary, simplicity and fresh U/A reviews found no remaining concrete issue; source comparison confirmed parity with the old reporter and the core/NMRNet exact-type sets remain disjoint. Private selective evidence: .work/qualification/core-failure-projection.DDmWvzNz, 8 files including inventory, root0700/files0600. inventory.sha256 SHA-256: 6053750d635a0d8e4c53fd06d030f2a290733bebc768582c97c49a7377c77131. It retains absent-module RED and final unit/receiving/contract/repository/style/ default logs. Tracked source and locked maintained lanes remain necessary for reproduction. Retain through package/003 review/handoff, then reassess under scratch policy. R6 is not closed: independent Attempt/generation-bound diagnostic history, pre-execution unavailability retention and lookup after replay retirement, required-evidence write gates, and actual commissioner/receiver delivery remain. R1-R5/P4/P5/003's other requirements also remain open. No native science, production image refresh, external model/API Job, sibling edit or GUI run occurred. No paid ambiguity retry was attempted. Existing science/recovery evidence is reused. 2026-10-22 R5a: durable read-only terminal records (operational wiring follows). TerminalReadRequired preserves the exact pending command/evidence plus its HTTP 404/409 response/correlation. TerminalStateObserved retains an identity-bound Attempt read; TerminalReadNotVisible retains a verified resource_not_found read (not proof of deletion or nonexistence). State succeeded is never a matching terminal receipt. Only pending -> read-required -> observed/not-visible transitions exist. All states remain unresolved, block fresh admission, and reject nested pending publication. No new journal, deletion, scientific replay or retry authority. Source/rationale: inspected SECS7356c354368f2355d3ab5cef00cf48c67cea9c2c, src/secs_inference/provider/execution.py::_publish_terminal/_reconcile_terminal, lines187-245; attempt_store.py's terminal_reconciling encoding/restore. Exact links: https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/execution.py#L187-L245 https://github.com/numpde/secs-repro/blob/7356c354368f2355d3ab5cef00cf48c67cea9c2c/src/secs_inference/provider/attempt_store.py#L313-L355 Core reuses read_attempt admission, existing scope/claim helpers and reserved record capacity. Tests cover exact round trips, all observed states, maximum body/evidence, closed schemas, foreign scope/identity, invalid correlation and reverse transitions. Tests-first focused contained lane: missing-type RED67tests/2import errors; make test/unit/provider-core/prepared-identity GREEN80tests/1.137s. Ruff0.15.15 lint/format and diff whitespace pass. Independent boundary and fresh U/A reviews found no remaining concrete issue. This records/codec slice does not yet dispatch state reads; no source/image refresh or scientific rerun was required. R5 remains open, including publication/recovery wiring and installed lane qualification. 2026-10-22 R5b: explicit read-only recovery, qualified at2343e63. TerminalRefusalPolicy.READ_STATE is an opt-in consumer choice on controller, publisher and pending-command recovery. After a terminal HTTP404/409 that does not establish an operation-valid TerminalHeld, the publisher durably records TerminalReadRequired before returning; it performs no GET. Verified404 already has resource_not_found, so 'unclassified' here means no valid operation hold, not problem_code=None. Reviewed conflicts retain TerminalHeld. The existing RETAIN_PENDING default and other statuses/transport failures without404/409 heads are unchanged; NMRNet has not silently acquired the SECS no-resend policy. Explicit AttemptRecovery on the read-required record performs one GET, then retains an identity-bound state observation. Only the existing API owner's fully admitted404/resource_not_found Problem permits TerminalReadNotVisible; bare404, malformed replies and mismatched identities preserve the read-only obligation. Reopening already-observed/not-visible states performs no request. Nested pending commands cannot publish. Even observed succeeded still blocks fresh admission; no GET result confirms the exact original terminal bytes or authorizes science. The precedent/source rationale and exact SECS links are in R5a above and the new record docstring. No second URL/Problem parser, journal or scheduler was added. Observed-but-not-durable records keep their claim and original write until settlement. Failed writes and unexpected storage defects retain the original cause plus observed record. Settlement observes original API/storage work only; it neither repeats GET/POST/write nor appends synthetic failures on repeat polls. The publisher retains the original failed send in last_failure even when returning its durable read-only disposition. A received404/409 head with held transport cleanup raises that protected failure before controller claim release; later cleanup failure preserves its disposition/primary/API evidence. This is in-memory protected evidence, not a durable diagnostic history or discharge of R6. Tests-first missing-policy RED78tests/1import error; integrated owner run83tests passed before the fault expansion. Independent audits found/corrected lost send and settlement-disposition evidence, repeated synthetic settlement failures, and unexpected-storage-defect retention. A cancellation witness was renamed to its actual scope (cancelled GET plus same-owner retirement; no late reply is produced). The first stopped-command run23tests/1failure assumed the wrong route in its new test. The test now requires the established GET /provider/v1/execution-attempts/REF route; production routing was unchanged. No expected scientific data was changed. Final focused contained evidence: - make test/unit/provider-core/recovery:66tests/0.600s, passed; - make test/integration/provider-core/recovery:23tests/5.536s, passed; - make test/integration/provider-core/process:51tests/25.777s, passed; - make test/repository/provider-core:49tests/1.991s, passed. The last two receiving/integration runs precede a behavior-preserving failure- history assembly simplification and comment/default-intent edits. The66 owner run follows those edits; unchanged receiving/scientific boundaries were not rerun. Ruff0.15.15 lint/format passed for12 selected changed Python files; no whole-tree format claim. Strict default-contract detection passed for publication.py, recovery.py and controller.py. Existing owner-absence cases are explained in place; no detector was weakened. Bash syntax and diff whitespace passed. The final source change after validation narrows a docstring's transport-head qualification only. Independent boundary and fresh U/A reviews found no remaining behavior defect. Maintained unit recovery target has help/.PHONY and exact offline launcher coverage; the existing stopped integration target now also selects terminal-store and TLS publication witnesses. Stopped CLI tests seed these new records, then execute through the real signed local TLS/Unix route and receiving result.json, preserving unresolved status. Unit controller/publisher tests establish the originating refusal transition. This is composed local evidence, not one migrated SECS production run, external deployment or a claim that a state read settles a receipt. Selective private capsule: .work/qualification/terminal-read-only.vpus2BTP, 9files, directory0700/files0600. EVIDENCE_SHA256 SHA-256: 8806973150b26f3fceef93d4ef82533eb4f4c2d4334db069779f6e79f38fb17a. It retains missing-policy RED, focused owner/recovery/recipient/repository logs, style/default checks and exact final source hashes. No model calls/API Jobs or native science were repeated. R5's installed HF/CHF sharing, actual SECS adoption, retention/cutover and all other R1-R6/P4/P5/003 obligations remain explicit/open. 2026-10-22 runtime-requirements scope clarification. Document the supported package requirements directly; no compatibility migration is authorized. packages/provider-core/README.md and requirements/provider-core.md now state Python>=3.12, the maintained Python3.12.12 Linux x86-64 runtime, four mandatory direct dependencies, complete hash-locked closure, setuptools84 build, contained-launcher marker/isolation distinction and one-event-loop lifecycle/store/ claim ownership. Package metadata and runtime behavior are unchanged. Python3.11 support and other unqualified environments must not be claimed or silently enabled. The current support limit is a reported requirement, not a trigger for another compatibility campaign. Source facts and links were checked; this text-only change required no runtime test or scientific rerun. 2026-10-22 current retention/capacity contract and operator guidance. The supported policy is keep-all within maximum_records: confirmed completions and failures retain their requests, receipts and protected evidence and still occupy slots. AttemptFiles._require_new_record_capacity refuses fresh admission at the limit; no expiry, automatic reclamation or record deletion is implemented. This is a finite operating limit, not an unfinished requirement for a new archive or diagnostic journal. Broader diagnostic-history behavior remains separate. The full-store StoreRefused now explains that finished Attempts count and tells the operator to preserve records, stop/settle, then increase maximum_records with enough disk space before restarting. docs/provider.md's full-store procedure specifies retained scope/files, stopped inspection, a fresh INSTALLATION_ROOT, and normal startup's unresolved-obligation/API/disk checks. Raising the slot limit neither resolves retained work nor reserves physical space. The recovery guide also explains read-required versus already-observed/not-visible records: no terminal resend, no matching receipt inferred from a read, unresolved remains so. Authority: packages/provider-core/src/provider_core/attempt_files.py:: _require_new_record_capacity/_require_capacity; nmrnet_provider/config.py::_lifecycle; nmrnet_provider/admission.py::require_admission_ready; ProviderService._work_loop; provider_core.recovery.AttemptRecovery. Existing regressions: packages/provider-core/tests/unit/adversarial/test_admission_inventory.py:: test_confirmed_records_still_fill_durable_slots_and_remain_unchanged and tests/integration/provider_core/normative/test_nmrnet_service.py:: test_confirmed_record_saturation_prevents_another_allocation_without_deleting_history. Focused contained make test/unit/provider-core/admission passed17tests/0.197s; no new test framework, archive, runtime policy, scientific work or external calls. Source-aware review found no semantic/privacy mismatch. Diff whitespace passed. 2026-10-22 direct Job/Attempt correlation in protected execution failures. Concrete gap: a pre-science process failure retained the model/transport cause, HTTP status and correlation, but failure.json omitted the affected Job/Attempt IDs. An operator could recover those IDs by inspecting the retained store; the report itself did not identify the work. No reason-loss or scientific replay was inferred. The existing real-process SIGTERM-after-model-headers regression, with and without independent native cleanup failure, demonstrated both omissions. ExecutionFailed now borrows the existing AcknowledgedAttempt from the executor's record through acknowledged_attempt. Its required constructor argument is passed by the one producer; two direct test constructors were updated. The existing exact-owner projection exposes only admission.job_ref and execution_attempt_ref. No phase/durability inference, copied identity authority, store lookup or additional history/registry is introduced. Existing cause/cleanup/interruption and redaction owners are unchanged. Before-acknowledgement setup failures remain a separate reporting boundary; no Attempt ID is fabricated there. Authority: provider_core.execution.AttemptExecutor.run/_remember; provider_core.failure_projection.owned_details; receiving regression tests/integration/provider_core/adversarial/test_nmrnet_process.py:: test_sigterm_after_model_headers_retains_effect_uncertainty_and_independent_cleanup. RED: existing process lane51tests/2subtest failures (missing IDs). After correction, make test/integration/provider-core/process passed51tests/25.495s; make test/unit/provider-core/diagnostics passed8tests/0.001s. Existing receiving assertions retain actual status/request-id, causes, configured secret-canary omission and zero scientific dispatch. Ruff0.15.15 lint/format passed for the five changed Python files; diff whitespace passed. The final source edit after these checks changes docstring wording only. Independent boundary and fresh U/A reviews found no remaining defect. No new lane, scientific run, API Job or model call. 2026-10-22 selected-Job correlation before an Attempt exists. Concrete gap: prediction allocation/assembly may fail after Job selection but before the API start. No retained Attempt then exists for lookup, and the setup failure/report omitted the selected Job. NativeSetupFailed now carries job_ref from the supplied StartPending through _open_role/_raise_setup and held cleanup settlement. Source-only allocation explicitly supplies None. No factory current- Job mirror, service wrapper, registry, durable record or Attempt ID is introduced. The exact-owner NMRNet projection emits only a known string Job reference and uses the existing redaction/receiving path. Existing causes/interruption and successful ownership-transfer release are unchanged. Authority: nmrnet_provider/native_factory.py::NativeAttemptFactory.__call__, _source, settle, _open_role and _raise_setup; process_reports._safe_owner_details. The existing native-factory test ports now accept the named Job context and use real StartPending values instead of object placeholders. Cancellation/held settlement retains the known Job. The receiving regression is tests/integration/provider_core/normative/test_nmrnet_reports.py:: test_pre_start_native_failure_identifies_selected_job_without_an_attempt. It invokes the real factory with an injected host allocation permission failure, then reads actual protected stderr/file output: Job+errno, no Attempt reference, private path omitted, empty store, zero API calls and retired allocation. A later source-only failure has no stale Job reference; the earlier exception still does. This is factory/report behavior with a test host port, not a native host failure qualification or an external model/API transaction. Tests first: existing process lane RED52tests/1failure (missing selected Job). Focused contained make test/integration/provider-core/process passed52tests/25.994s; make test/integration/provider-core/native-factory passed8tests/0.037s. Ruff0.15.15 lint/format passed for the five changed Python files; diff whitespace passed. Independent boundary and fresh U/A reviews found no remaining defect. No new qualification lane, scientific work, API Job or model request. Production image refresh follows this coherent runtime change; no refreshed-image proof is claimed by the source/wheel receiving tests alone. 2026-10-22 committed controller image refreshed after the reporting/recovery batch. Source checkpoint:7c9019eb404a3421471becf22f0b907cbe79e442. make provider/image/build succeeded offline with the retained full runtime closure. Recorded controller image: sha256:55771f0978c9c3de823091d93b13e9d58f32129a557d9783fb41ba4fef2bcd68. The admitted Git input-tree identity (io.nmrnet-repro.provider-inputs) is sha256:4a5111f1aeb7a8ac872434d35d15bbe1cee98e94f00de60ff1ec6933587381b1. Runtime lock SHA-256 remains 79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. The image-id record SHA-256 is 927b93a9223ca306bc786d6f472e5ba4fcd9ec927683bbba5b2393190be40efa. make test/integration/provider-runtime passed4tests/0.713s on that actual image: complete installed distribution inventory, retained dependency inventories/native Ed25519 signing, isolated image-owned imports, and foreground help unaffected by ambient current-directory/PYTHONPATH modules. Image admission checked its immutable ID and committed input-tree label. The unchanged source/wire scientific matrix was not repeated. These packaging/runtime observations are separate from the source/wheel receiving regressions above; they are not an actual model/API Job, external deployment, GUI proof or scientific prediction. No credentials or native scientific workers were supplied. No image was published or pushed. This refresh makes the coherent committed changes available to the maintained production launcher. It does not close the remaining full017/003 requirements. The pending paid ambiguity batch still requires the previously requested explicit external-destination authorization; no paid request was retried. Other unqualified contracts and supported limits remain reported above rather than inferred from this image check. 2026-10-22 safe-read outage disposition at the existing API owner. ProviderAPI.can_retry_read consumes only this API's current ApiFailure, a GET method supplied by its signed-exchange owner, and confirmed original retirement. It re-reads late causes/headers rather than caching an earlier decision. Reviewed timeouts/native connection errors and temporary DNS failure qualify; certificate, unknown/protocol/local permission failures, failed cleanup and all mutations do not. The native/httpcore cause walk is bounded; unknown wrappers refuse. 502/503/504 may permit another safe read without claiming transience or parsing the error body as API authority. This deliberately includes HTML maintenance responses and unknown/malformed error Problems, including an edge's expected topology marker. Wrong/duplicate explicit topology still refuses. Requiring a verified JSON Problem here would turn an ordinary proxy outage into a manual restart. Read-retry permission grants no receipt, mutation replay, scientific dispatch or automatic exchange. Service pacing/diagnostics are the next slice. Sources: provider_core/api.py::_exchange/_remember_failure/can_retry_read and transport.py::retirement_confirmed/retire; pinned httpcore1.0.9 httpcore/_exceptions.py::map_exceptions and its concrete I/O exception classes. The existing service_unavailable Problem vocabulary is unchanged (API pin at this module's introduction, security/problems.py::service_unavailable_problem_spec). Tests first: the new API unit file initially failed for the absent classifier; the error-response contract was then refined as above. Focused contained make test/unit/provider-core/api passed57tests/0.227s. Ruff0.15.15 lint/format passed for the two changed Python files. Independent owner/U&A reviews caught a duplicate Problem key in the first draft; it was removed without changing the existing diagnostic. Fresh review found no remaining effect/authority bypass. No service retry loop, production image refresh, external request, API Job or scientific run is claimed by this owner slice. 2026-10-22 U27 first service slice: recover admission/discovery reads. The service now uses API090f6ea's settled GET disposition in its original startup or work task. A failed page abandons the complete admission/discovery cycle: retry rechecks local capacity and live inventory before walking discovery from cursor=None. It never wraps allocation, controller.run, mutations or science. Original API retirement precedes the retry decision; failed retirement preserves the original read and cleanup failure and dispatches nothing further. ServicePolicy/config require read_backoff_max_seconds>=idle_seconds. The nominal delay starts at idle_seconds, doubles to that cap, and each actual wait draws uniformly from half to all of the nominal delay. Only a completed whole read cycle resets it. Requests retain their configured deadlines; the outage itself can wait until recovery or stop. The existing stop event interrupts backoff. Startup I/O already in flight remains subject to its exchange/retirement bounds. Process-supplied callbacks project the original failure through failure_evidence before emitting api_read_retry/api_read_recovered notices. One nonblocking stderr write restores the original descriptor flags before yielding. FIFO notices cannot exceed PC_PIPE_BUF: refusal happens before any bytes, preserving the next JSON record. DiagnosticOutputRefused exposes only code-owned numeric/reason text. The latest failed notice's event, outage and output cause remain bounded in memory and reach private result.json as api_notice_failure on released shutdown. A notice sink failure alone does not stop service or alter science's outcome. If a separate operation fails, its report includes that same notice evidence. Independent review found two necessary output corrections: direct stderr.write could block on pipe backpressure, including the final failure-report path, and a large nonblocking notice could leave partial JSON. The existing _failure_report now shares nonblocking stderr output while still attempting independent file publication; no new logging task, store, journal or lifecycle owner was added. Captured text-sink tests explicitly adapt the owned byte-writer; their diagnostic, redaction and held-ownership assertions are unchanged. The held subprocess's old stderr.write fault injection also moved to that actual writer after a rerun showed it no longer intercepted the effect. No assertion was weakened. Authority: nmrnet_provider/service.py::ProviderService._read_until_available, _select_after_admission/_startup/_work_loop and ServicePolicy; config.py::_service; process.py::_write_stderr/_write_api_notice/_failure_report/run_provider; process_reports.py::DiagnosticOutputRefused/_safe_owner_details. Existing narrow precedent remains SECS7356c354368f2355d3ab5cef00cf48c67cea9c2c, src/secs_inference/provider/runtime.py::run_execution; async task ownership, explicit jitter, retired I/O and protected receiving policy are implemented here. Tests first: new service cases failed before the callback/recovery contract existed. Final focused contained results: make test/integration/provider-core/service:29tests/7.349s; make test/integration/provider-core/process:56tests/26.972s; make test/integration/provider-core/config:30tests/2.970s; make test/integration/provider-core/interpreter:24tests/0.626s. Ruff0.15.15 lint/format passed for all15 changed Python files; diff whitespace passed. The49 provider-core repository checks passed before the final reporter- local output correction; those unchanged convention boundaries were not rerun. The existing service tests exercise four actual signed local-TLS startup503s, capped waits, recovery before one allocation/generation/prediction, second-page failure followed by fresh complete admission and first page, stop during backoff, permanent refusal and no next read after failed retirement. Process tests exercise actual subprocess notices, a genuinely full pipe through healthy shutdown, full pipe plus a later operational failure with independent failure.json publication, and oversize refusal followed by an intact next record. Existing lost-completion and stopped-recovery assertions still forbid repeating science. These are local control/receiving tests with recording scientific ports, not native accuracy or real-model/API deployment qualification. Independent owner, U/A and fresh design reviews found no remaining concrete defect after the output corrections. Selective private capsule: .work/qualification/service-read-recovery.GHB33UZr (10files,112KiB; directory0700/files0600). It retains focused logs, commands and the16 consumed source hashes; it is not a complete build/source closure. Inventory SHA-256:3973084f9af2cbd0c95ea81db2175e980c40e224fbf395330afa36bcdca94764. Tracked source/locks/maintained lanes remain required for reproduction. Keep through 003 review/handoff, then apply the existing scratch-evidence retention policy. Hello and active Attempt failures still stop service; history/native allocation renewal and per-Job budget isolation are not closed. No API Job, paid call, native scientific work or image refresh occurred. Refresh the controller after the coherent outage-handling batch; the earlier image receipt is not a claim about this source. U27/A11 and full017/003 remain open. 2026-10-22 U27 Hello permission, before service wiring. ProviderAPI now retains the signed request target alongside its existing method on the original ApiFailure. can_refresh_hello requires this API's current, retired failure, POST and the exact /provider/v1/hello target without query, then applies the same reviewed availability disposition as safe reads. It permits a caller to construct its latest complete announcement; it grants no old-body replay or receipt and authorizes no other mutation. The service must still rebuild current state on each attempt. No automatic Hello recovery is claimed by this slice. Tests first: focused API lane initially failed for the absent permission method; make test/unit/provider-core/api then passed58tests/0.317s. The actual request tests exclude grant reads, Attempt START/progress/COMPLETE/FAIL and queried Hello, and reject an old GET failure and unretired Hello. Ruff0.15.15 lint/format passed for both changed Python files. Independent owner and U/A diff reviews found no concrete defect and explicitly checked the caller-owned fresh-body obligation. Logs: /tmp/nmrnet-hello-recovery-api-{red,green,style}.log; transient local proof, not deployed runtime evidence. Authority: provider_core/api.py::_exchange, _remember_failure,can_retry_read,can_refresh_hello,_retryable_failure; Hello wire contract remains the pinned API route cited in the package README. No image refresh, external request, API Job or scientific work occurred. 2026-10-22 U27 Hello service recovery. Initial/periodic Hello now use037fd97's exact-operation permission after original transport retirement. The service's one private pacing owner serves two fixed callers: complete admission/discovery GET cycles, and newly constructed current Hello snapshots. There is no retained-body replay, general mutation retry policy, new scheduler or journal. Each send calls the existing snapshot supplier again, so an outage cannot force an old offering to be republished. The first accepted Hello still gates on_started/discovery/allocation; a periodic outage leaves the already owned scientific task running. Permanent protocol/authentication errors, failed retirement and active Attempt failures retain their existing stop policy. The required cap is now service.api_backoff_max_seconds, shared by both operation kinds with independently reset outage waits; no old-key alias was added. All maintained config/test callers were changed. Each request still has finite exchange/retirement limits, backoff is stop-aware, and outage duration itself has no retry-count ceiling. This change is source/local qualification; the previously captured controller image does not contain it. Unconfirmed Hello evidence is captured at _publish_current itself, including initial startup before a Hello task exists. A later failed/cancelled send replaces earlier outage evidence; only a receipt for the latest sent snapshot clears the slot. The old periodic-cancellation copying branch was removed. Protected shutdown result.json now calls this unconfirmed_hello, covering backoff and interruption; failure.json includes it if another operation/reporting sink fails. api_hello_retry and api_hello_recovered use the existing bounded, redacted, nonblocking notice sink. Review corrected current_announcement_confirmed to latest_hello_send_confirmed: the receipt confirms the sent snapshot, without attesting to later supplier or directory state. Its preceding-failure evidence remains explicitly separate. Authority: service.py::ProviderService._until_api_available/_hello_until_available/ _publish_current/_startup/_hello_loop and ServicePolicy; config.py::_service; process.py::run_provider/report_api_retry/report_api_recovered. Permission/wire provenance remains037fd97 and the pinned API/SECS sources cited in the package README. The nested observer callbacks classify notice context, not API authority. Tests first: the three new service behavior cases failed before wiring (32tests, 3errors). Final focused contained proof: make test/integration/provider-core/service:33tests/8.161s; make test/integration/provider-core/config:30tests/4.170s; make test/integration/provider-core/process:59tests/31.480s. The process lane was rerun only after the reviewed notice-field correction and a new successful recovery receiving witness; unchanged service/config were not repeated. Ruff0.15.15 lint/format passed for12 changed Python files. Logs remain /tmp/nmrnet-hello-recovery-service-{red,green,style}.log, /tmp/nmrnet-hello-recovery-config.log and /tmp/nmrnet-hello-recovery-process-final.log (temporary focused-test evidence). Witnesses use actual signed local TLS and the existing recording science ports: new startup snapshot after503, periodic withdrawal while original prediction is blocked, initial-backoff stop without admitted marker/discovery/allocation, failed original retirement forbidding another send, and SIGTERM after a newer Hello200 head replacing a prior503's diagnostic. Receiving output verifies the new receipt flag, safe status/request ID, secret exclusions, clearing on recovery and retaining uncertainty on stop. Existing malformed200 Hello refusals and successive-Job/exact-terminal recovery assertions remain intact. Independent owner and U/A reviews found no remaining concrete effect/retirement defect after the notice naming correction. No external request, API Job, paid model, native science, expected-output regeneration or image refresh occurred. Active-Job outage handling, per-Job budget isolation and resource-owned retention/renewal remain substantive U27/A11 work; full017/003 is not closed. 2026-10-22 U27 bounded active-observation owner, before production wiring. Core now accepts an optional ObservationRecovery(gap_seconds,backoff_max_seconds, on_retry,on_recovered), passed unchanged by Controller to Executor. None retains core's fail-stop contract. The aggregate groups the one finite recovery behavior and its required protected observers; it adds no supervisor, journal, scheduler, dependency or alternate lifecycle. Production NMRNet must explicitly supply it from required configuration and its existing notice sink in the next slice. The original executor owns the complete read window and its retained observation task. Its existing API lock stays held through failed-read retirement, reviewed GET permission, capped jittered pacing and fresh read; queued progress cannot overtake unresolved I/O. New phases, execution entry, accepting a handle/outcome and terminal choice still require a fresh allowed identity-bound observation. Only that GET can repeat. START/progress/terminal mutation and science behavior are unchanged. Unexpected observer errors retain the original API cause through the existing ExecutionFailed field; ordinary sink failure handling stays with the process callback owner, not a new core catch-all. Initial timeout-context draft was rejected in review: cancelling the awaited HTTP read can wait through its separate transport-retirement grace and delay science's stop. The final code uses asyncio.wait on the retained original observation task, cancels it once at expiry, and retires science before bounded joining of read cleanup. A pending waiter blocks claim release, suppressed-outcome retention and parallel API retirement. Settlement never sends another GET or resumes science. Cancellation with an independent read-retirement cause remains protected cleanup evidence. Expiry is ObservationGapExpired, not a bad-input result or permission to fail/restart an Attempt. Existing OBSERVATION_FAILED suppression can preserve a completed result without publication after original tasks/I/O settle. Review also rejected borrowing executor-lifetime last API failure: after recovery, a later lock-wait expiry could blame an earlier503. Current-window failure/read- started facts now belong to the actual observation; its expired exception borrows that owner for late-arriving read evidence. A lock-wait expiry invents no read or read cause, while independently interrupted progress keeps its own PUT evidence. Monotonic checks before GET, after response and parent acceptance refuse late authority even when event-loop timeout callback delivery is delayed. Error text says after starting a read, covering subsequent retirement/backoff as well. Established sources, consulted2026-10-22 at the user's request: Python3.12 asyncio Task documentation, Timeouts and Waiting Primitives: https://docs.python.org/3.12/library/asyncio-task.html#timeouts https://docs.python.org/3.12/library/asyncio-task.html#waiting-primitives The timeout primitive requests cancellation; wait returns pending tasks without cancelling them. We adapt these primitives to existing executor/task ownership, rather than treating elapsed wait or requested cancellation as native retirement. Marc Brooker, Timeouts, retries, and backoff with jitter, AWS Builders' Library, published2019-12-05; Retries and backoff / Jitter sections: https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/ (redirects to https://builder.aws.com/content/3EumjoZascWd1oZiEgL8ORlv3qE/timeouts-retries-and-backoff-with-jitter) Adaptation: one operation-owned retry layer, capped jitter and explicit deadlines; timeout is not evidence that side effects did not occur. Mutations therefore retain their exact owner-specific replay/reconciliation contracts. Authority: provider_core/execution.py::ObservationRecovery/ObservationGapExpired, AttemptExecutor._observe_active/_observe_until_available/_settle_observation_wait/ _retire_after_failure/settle/retain_suppressed_outcome/_finish_if_settled; controller.py::_run_effects and failure_projection.py::owned_details/relationships. Tests first: the focused lane initially failed for absent policy imports (90tests, 2errors). Final make test/unit/provider-core/prepared-identity passed95tests/2.017s; it is the maintained lane owning test_execution*.py. Ruff0.15.15 lint/format passed for all5 changed Python files. Logs:/tmp/nmrnet-observation-recovery-{red,final,style}.log. New witnesses cover one settled503 with already completed science and fresh read, in-flight expiry, deliberately delayed cancellation cleanup with earlier scientific retirement and held ownership, recovered503 then lock-wait expiry with actual PUT cause, nested interrupted retirement cause, and valid late reply while timeout delivery cannot run. Independent owner/U&A re-review found no remaining concrete defect after the three corrections above. These are installed-core recording-port tests, not deployed API, native accuracy or production enablement. No image refresh, external request, paid model call, API Job or scientific rerun occurred. Focused make test/repository/provider-core also passed49tests/1.802s; log:/tmp/nmrnet-observation-recovery-conventions.log. 2026-10-22 U27 active-observation production binding. NMRNet now requires finite positive lifecycle.observation_gap_seconds, admitted by the same core scalar owner as ObservationRecovery. Process construction supplies that gap, the already admitted service API-backoff cap, and its existing protected notice sink. NativeAttemptFactory requires an enabled policy before allocation; runtime assembly passes that identical policy through to the core controller. The duplicated NMRNet enabled-policy rule was removed from runtime assembly: factory owns the production effect boundary, while core retains public constructor validation. No disabled fallback, second policy or second retry owner was added. api_observation_retry/recovered carry only the actual acknowledgement's Job and Attempt references plus existing bounded/redacted API evidence. The same nonblocking notice writer and latest failed-output fallback handle them; a sink failure alone does not terminate science. Recovery does not establish terminal publication or override an observed server stop. Existing direct factory/runtime/scientific fixture callers now explicitly supply policies; unchanged native accuracy work was not repeated. Tests first: the new signed local-TLS active-read503 witness failed before binding was enabled. That first34-test run also exposed two unrelated fast-periodic-Hello shutdown races: one peer had received a head but not its full body when strict request/body pairing was inspected, and another Hello's cleanup was unconfirmed. No receiving/retirement assertion was weakened. ServicePeers now defaults to a 30s Hello cadence outside the finite tests; the four dedicated periodic-announcement tests explicitly retain50ms cadence and their original assertions. This isolates the intended cause without hiding genuine periodic cleanup failure tests. Final focused contained results: make test/integration/provider-core/service:34tests/7.068s; make test/integration/provider-core/config:30tests/3.295s; make test/integration/provider-core/native-factory:8tests/0.041s; make test/integration/provider-core/process:61tests/34.771s; make test/integration/provider-core/runtime:14tests/1.878s. The actual signed-TLS service recovers during the one blocked prediction, retains one model request/one allocation/one execution and confirms its original result. The actual foreground subprocess recovers a signed read while its model request is still in flight, delivers both notices with correct IDs/status/request ID and secret exclusions, and does not resend the model request. Its later intentional SIGTERM retains the separate model-effect uncertainty through existing failure reporting; this is not a successful completed-science API deployment witness. Required missing/zero/infinite/boolean gap configuration refuses before effects. Ruff0.15.15 lint/format passed for20 changed Python files. Logs remain /tmp/nmrnet-observation-wiring-{service-final,config,factory,process-final,runtime,style}.log; earlier RED/source-wiring logs remain identified by their lane suffixes. Independent owner/U&A review found no new concrete effect or authority defect. Receiving privacy review identified a necessary correction after the first60-test process pass: the new reference facts bypassed failure_evidence's known-secret scrubber, including private failed-notice fallback. The existing redaction closure was extracted unchanged as process_reports.operator_redactor; both failure graphs and observation references use it. IDs are scrubbed before either notice output or retention. The new receiving-port regression runs the real process owner with synthetic acknowledged references that exactly equal configured keys, covering a real pipe and deliberately failed sink/private result.json. Both redact the refs; no API request occurs in that narrow privacy witness. The separate real signed- TLS active-process test remains unchanged. Only the affected process lane was repeated after this repair; independent review confirmed closure. Authority: config.py::LifecycleSettings/_lifecycle, process.py::run_provider/ report_observation_notice, native_factory.py::NativeAttemptFactory, runtime.py:: assemble_attempt; core policy/waiter/cause rationale and precise research sources are recorded in5e37ac6 above. No dependency, image refresh, paid model, external API Job, native scientific rerun, expected-output regeneration or sibling edit. Transient START/progress/terminal effects still need their own automatic exact reconciliation policy. Per-Job budget isolation and resource-owned history/native renewal remain U27/A11 work; safe reads alone do not establish minimal babysitting. 2026-10-22 one controller refresh after the read-recovery batch. Committed source:d80e24d822d80e04ea6f0ffa1c74c5c7bf706430. make provider/image/build succeeded offline, using the existing captured-input, native-client and pinned dependency owners. Resulting installed controller: sha256:5e6b5d416f3d00902b5e49138a438fef201a906373265909d74c7fd4ddf69cd2 Committed input-tree SHA-256: 2e43bc955bc9033e1d54aa5e6414dc87694da105c623a8a2837e9512f2998120 make test/integration/provider-runtime passed4tests/0.958s (installed package, locked dependencies, isolated imports and real foreground help). This refresh contains startup/discovery, Hello and active-observation recovery; it does not qualify an external API/model, GUI, new native accuracy or future source changes. Image-ID file SHA-256:8b2d0118f7e24294938b98db80513cb928e63bbaeba7e4619643bf4309831aa5. Unchanged runtime-lock SHA-256:79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Logs:/tmp/nmrnet-outage-recovery-image-build.log and /tmp/nmrnet-outage-recovery-runtime.log. No scientific/API Job/model call repeated. 2026-10-22 U27 exact terminal replay permission, before controller wiring. ProviderAPI.can_replay_terminal admits only its current retired failure from the exact unqueried POST COMPLETE/FAIL route. Reviewed availability follows the same owner classifier as safe reads. Additionally, an exact httpcore.RemoteProtocolError without any observed response head permits exact terminal replay: this is an unverified response, not proof of EOF, transience or absence of server effects. GET/Hello permissions remain unchanged. Received malformed receipts, explicit refusals, wrong topology, certificate faults, cancellation and failed cleanup do not gain permission. The publisher must still verify the unchanged durable body; this API permission alone neither runs a loop nor authorizes another mutation. Authority: retained release sha256:719055db7751605c0e5325ca23bcbe66cde631376d4b2b99523c8e4db75f0d01, packages/provider-core/tests/fixtures/nmr_api_v1/openapi/openapi.v1.json, JSON pointers /x-nmr-attempt-recovery/terminal and /paths/~1provider~1v1~1execution-attempts~1complete/post/x-nmr-recovery, /paths/~1provider~1v1~1execution-attempts~1fail/post/x-nmr-recovery. Declared source12a53e720fc87e1a4144c76203f8853d5afaf753: https://github.com/numpde/nmr-api-v1/blob/12a53e720fc87e1a4144c76203f8853d5afaf753/nmr_api/provider/routes.py#L572-L579 https://github.com/numpde/nmr-api-v1/blob/12a53e720fc87e1a4144c76203f8853d5afaf753/nmr_api/provider/routes.py#L601-L608 https://github.com/numpde/nmr-api-v1/blob/12a53e720fc87e1a4144c76203f8853d5afaf753/nmr_api/provider/http_contract.py#L1020-L1023 Rationale: the immutable command's explicit replay contract supplies effect safety; adding transport EOF state would not establish absence of effects or improve that contract. Each actual send still receives a fresh signature. Tests first: absent-method RED, then make test/unit/provider-core/api60 tests pass in0.279s; both terminal operations and exact target/current-failure/retirement gates are covered. Offline Ruff0.15.15 passes for both changed Python files. Temporary logs:/tmp/nmrnet-terminal-permission-{red,green,style}.log. Two independent diff reviews found no remaining issue after correcting a stale test module description. Production is not wired for automatic terminal replay yet; full017/003 remain open. Terminal-only HTTP500 adjudication in that same permission slice: the pinned OpenAPI's two terminal POST /responses/500/description fields explicitly require retaining request_id/operator diagnosis and permit unchanged replay with fresh signature/nonce. A received500, or a partial500 head with reviewed I/O failure, therefore also permits terminal replay under the same topology/retirement gates. This does not assert transience or noncommit; GET/Hello retain their narrower 502/503/504 availability policy. Source at the declared12a53e7 revision above: nmr_api/provider/http_contract.py:198,284-295. Focused API final log: /tmp/nmrnet-terminal-permission-final.log. Independent source-contract review confirmed this terminal-specific distinction; no universal retry-status table. 2026-10-22 U27 controller-owned exact terminal recovery, before product wiring. AttemptController accepts explicit TerminalRecovery(window_seconds, backoff_max_seconds,on_retry,on_recovered); None preserves core fail-stop behavior. The existing controller repeats only the same TerminalPublisher.publish with the same immutable TerminalPending. Scientific retirement was already confirmed by the executor before this seam. The publisher retains durable-before-send equality checks, exact body bytes, fresh signing and receipt-before-confirmation storage. No controller.run, START, interpreter, geometry or prediction is restarted. Only an actual PublicationFailed whose primary cause is its API send failure, with no received outcome or independent settlement failure, enters consideration. The original publisher settles its own claim-borrowed I/O first; API eligibility is then re-read, including late evidence. A receipt-storage error cannot borrow a previous send's availability classification. Failed retirement preserves the send as primary and its real cleanup failure independently, even if the retry window has expired. Explicit refusals/holds and malformed received receipts remain under the existing publisher dispositions; they do not enter recovery. Window meaning is deliberate: from the first candidate send failure, include retirement, bounded synchronous observers and capped jittered backoff; begin no new publisher invocation after expiry. An already admitted invocation may finish its existing bounded storage/HTTPS/retirement later. No second timeout task or lifetime registry was added. The post-observer deadline is checked again before sleep and retry, so an observer cannot add another full wait after expiry. TerminalRecoveryExpired exposes the last PublicationFailed through the existing exact-owner protected projection and keeps the pending command unchanged. Callbacks borrow the actual acknowledgement and protected API failure; successful recovery identifies the original outage while each retry reports its actual send. Tests first: missing policy imports RED. Final maintained make test/unit/provider-core/recovery:74tests/0.963s; focused contents include existing terminal/store/recovery/claim tests plus the new structured normative and adversarial controller files. These prove repeated exact bytes, one science execution/retirement, original retirement exclusion, late certificate evidence, independent cleanup despite expiry, receipt-storage refusal, cancellation context, retry expiry and a valid admitted invocation completing after the retry window. An early run exposed the fixture's accidental1ms observation polling interleaving with its fixed lifecycle reply script; restored the established1s observation cadence while retaining millisecond publication backoff caps. Expected scientific events, call counts, refusal checks and payload identities were unchanged. Repository package checks49tests/1.913s; offline Ruff0.15.15 passes4changedPythonfiles. Logs:/tmp/nmrnet-terminal-controller-{red,green,final,style,conventions}.log. Independent reviews prompted the post-observer deadline check and confirmed the failure/retirement separation. No native accuracy, paid model/API Job or GUI run; production binding, connected successive-Job automatic replay and installed-image qualification are still separate pending steps. Full017/003 remain open. Final review refinement: expiry now borrows the exact pending acknowledgement and projects Job/Attempt IDs, including when retirement consumes the whole window before any retry notice. Structural retry admission requires exact PublicationFailed. The final rerun is74tests/0.992s (same scope); this supersedes the0.963s timing above. The original retired-send cause and independent cleanup remain distinct. 2026-10-22 U27 terminal recovery production binding and successive-Job witness. The foreground configuration now requires finite positive lifecycle.terminal_retry_window_seconds. Its scalar validator is the same owner used by core TerminalRecovery; configuration rejects absence/zero/nonfinite/bool before effects. process.run_provider constructs the enabled policy using this window, the existing service.api_backoff_max_seconds and protected Attempt notice callbacks. NativeAttemptFactory requires that concrete policy before allocation; runtime.assemble_attempt passes it unchanged to the existing controller. The same report_attempt_notice redactor/output/fallback serves observation and terminal recovery. New events are api_terminal_retry and api_terminal_recovered, with actual Job/Attempt IDs and safe original API evidence. Recovery follows durable receipt retention, not merely receipt arrival or a successful-looking HTTP status. Tests-first connected proof: existing service lane's35 tests initially had exactly one new error because assembly did not accept the policy; final35 pass/7.018s. SuccessiveServiceRecoveryTests.test_lost_second_receipt_recovers_automatically_before_third_job_without_repeating_science uses the existing signed local TLS peer: Job2 commits its outcome and drops the first reply. The same live controller sends its unchanged retained body again, retains the replayed receipt, then starts Job3 only after that confirmation. Three START keys/allocations/model conversations, one generation/prediction/retirement per Job, four COMPLETE sends (Job2 twice), matching source/result identities and unchanged records after reopen are asserted by existing owners. This is recording science/local scripted model/API proof; no released-model accuracy, deployed API, paid-model interpretation or GUI claim is made. Core's explicit None fail-stop contract remains available to direct lower-level callers. An initially proposed production-factory None exception to preserve old qualification was rejected and removed before commit. The native SERVICE manual recovery witness instead supplies an enabled policy and intentionally propagates the actual API failure from its named test-owned retry observer before any resend; its pending record, original science and exact replay assertions remain. The separate direct-core manual native fixture explicitly selects core None. The unchanged scientific matrix was not rerun for these orchestration-only controls. Focused final results: - config30tests/3.278s, including required window admission/refusal; - native factory9tests/0.040s, including disabled-policy refusal before allocation; - process/receiving61tests/33.961s; actual run_provider callbacks reach protected stderr and failed-output result fallback for both observation/terminal policies, with configured secrets equal to valid Job/Attempt refs redacted in both paths; - runtime14tests/2.006s; existing input-format and same-conversation controls; - offline Ruff0.15.15 passes all17 changed Python files. Logs:/tmp/nmrnet-terminal-binding-{red,service,config,factory,process,runtime,style}.log. Two independent final diff reviews found no remaining actionable issue. The public operator required-field table, terminal semantics/notices and package status were updated. No sibling/upstream changes, external calls, new journal or dependency. The currently retained controller image still predates these terminal slices; refresh once with the next coherent runtime qualification batch. START/progress availability, per-Job operational-budget isolation and cumulative resource renewal remain U27/A11 work; full017/003 is not closed. Shared-validator follow-up: make test/unit/provider-core/recovery74tests/0.985s passes after extracting require_terminal_window for configuration admission. Log:/tmp/nmrnet-terminal-binding-core.log. The operator guide states present START/progress/budget failure behavior and recovery action; roadmap stays here. 2026-10-22 installed controller terminal-recovery refresh. Built once for committed source1307ca1ffccbaec26d4c8d9f7a5182b3b514b4d1: image sha256:f16cdf2480198352e48b489f3a0414d1f0dce80f49193f532b070075811c3b66, committed image-input tree SHA-256 5a3f658ba3eb96018e9b520c0b765b34543bc44e794fbff36def1dc223b2dd9e; requirements/provider-core.lock SHA-256 unchanged 79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. .work/provider/image-id SHA-256 422a667ca82bcc2e384a4351c023c44c8d7ea4f90de6a97fcd0220f180cbe051. make provider/image/build and make test/integration/provider-runtime passed; installed runtime4tests/0.728s check admitted immutable image/input-tree identity, installed distributions, native signing, isolated imports and foreground help. Logs:/tmp/nmrnet-terminal-image-{build,runtime}.log. No scientific matrix, external model, API Job, GUI, push or publication was repeated. Later source edits require the normal source/image admission; this record describes this specific image only. 2026-10-22 U27 per-Job input-worker call limit. InputPreparation now raises its owned InputWorkerCallLimit at max_worker_calls, before another Upload grant or reader/generator allocation. The facts are the configured maximum and actual calls already started; rejected input consumes calls, while local argument refusal does not. No budget resets during correction. NMRNetSession maps only that reviewed type to the existing AnalysisFailure path, code input_worker_call_limit. Public guidance describes attempts to read/generate coordinates, gives the limit and asks for checked input/operator review. It does not label capacity exhaustion invalid input. Protected evidence keeps counts and already retained interpreter diagnostics. The exact-owner process renderer keeps these facts if independent cleanup prevents normal AnalysisFailure persistence. The existing core/session retirement and durable FAIL publication gates are unchanged. No service catch/restart, timeout conversion, worker reconnect, new journal or alternate renderer was introduced. Failed chooser/source/native retirement, unrelated RuntimeError/TimeoutError, API/storage faults and elapsed-time budget expiry remain operational; this slice does not claim their isolation. Tests first: the new connected case was the sole error among36 service tests before implementation. The three-Job owner was reused: strict existing COMPLETE checks remain, per-Job retirement checks share their old owner, and a FAIL hook rejects by default. The fixed budget fixture alone permits Job1's owned limit: one recording reader rejection, another same-conversation model call, no second reader/generator allocation, no prediction, actual resource retirement, exact retained FAIL bytes, matching public receipt and protected counts/diagnostics. Only after that FAIL is durable may Jobs2-3 start. They each generate/predict once; Job2 still loses its first receipt and replays only its exact terminal bytes. Three STARTs, four model exchanges (Job1 twice), one FAIL, three COMPLETE sends (Job2 twice), final immutable records and reopen equality are asserted. The reader/model/science are explicitly recording ports, not native or semantic interpretation qualification. An intermediate fixture reused its synthetic tool call ID on correction and correctly hit the existing carrier refusal. The fixed budget fixture now emits distinct call IDs and requests its declared nm unit; no product carrier guard, expected science or tolerance was relaxed. Focused results: service36tests/7.066s; interpreter25tests/0.572s, including a call-limit-plus-chooser-retirement failure that retains both causes, refuses a scientific handle and redacts configured-key/credential canaries; smiles38tests/ 0.173s (one existing native-host qualification skip); pasted7tests/0.086s. Offline Ruff0.15.15 passes all9 changed Python files. Logs: /tmp/nmrnet-call-budget-{service-red,service-green,service-final,interpreter,smiles,pasted,style}.log. Both independent final diff reviews found no remaining actionable issue; the operator guide now states actual call-cap versus elapsed-time behavior. No source scientific oracle, upstream/sibling, model dependency or paid/API Job changed. The retained image at d7e0f4e still describes the terminal-recovery batch; this later source change has not yet been refreshed there. Full017/003 remains open, including aggregate-time isolation with full effect diagnostics, other mutation recovery and resource-owned history/native allocation renewal. Next U27 resource slice: confirmed-history ownership contract (planned, not implemented) ==================================================================================== Current source checkpoint:d97bfaf. Owners: provider_core/attempt_files.py:: AttemptFiles._inventory/admit/_publish/_require_capacity; attempt_store.py:: AttemptStore._run/settle; nmrnet_provider/service.py::_work_loop/_admission. Current maximum_records counts finished records forever. Separately, tools/provider_workers.sh::provider_workers_service counts retired request leaves forever. Neither counter is a sustained-Job retention policy; increasing limits or fresh-root rotation is not the proposed repair. Preservation/envelope decision before coding: - Keep every confirmed record's ORIGINAL bytes, including private scientific and diagnostic evidence, inside the existing private scoped storage grant. A terminal receipt is not permission to discard evidence. No TTL, deletion, offload endpoint, external upload, new retention journal/index or secret-bearing metadata is added. - Reuse active slots by explicitly archiving only exact TerminalConfirmed records. Other terminal/held/suppressed/read-required/unresolved records stay active. Archival itself releases no lifecycle claim and proves no native retirement. Composition may request it only after its original controller has released work, or while reconciling an already clean scoped startup inventory; normal remote admission gates still run before fresh allocation. records/admission_inventory remain read-only; no hidden archive mutation belongs in those APIs. - Logical active slots and historical diagnostics are different resources. All history is retained, so physical usage grows. Existing actual filesystem headroom/filesystem_reserve_bytes remains the envelope: stop safely before its floor if evidence cannot be retained. A free-space check is not a reservation against other writers. No indefinite throughput, automatic historical disposal, dedicated-volume quota or bounded total history size is claimed. Retention/offload beyond that requires a real policy/destination rather than invented authority. Store mechanism to implement/tests first: - Add explicit archive_confirmed(expected,owner=...) through the SAME original-future worker/settlement gate. Timeout/cancellation retains that operation, not a replay. - Keep current active filenames/codecs. One private history-<scope digest> directory uses canonical existing RecoveryScope facts, mode0700/same UID/same filesystem, nofollow and the root's existing flock. Its exact name keeps an otherwise empty active root bound to its original scope. Foreign history names hold startup. This is local scope metadata, not authentication of unscanned history. - Reuse original-file admission to obtain decoded record AND the raw bytes actually read. Copy those bytes, not encode_record(expected). Reuse the existing durable file publisher with an explicit destination directory; history staging has a deterministic record-key name so active/reused-key point checks can detect an interrupted copy without scanning all historical files on each Job. - Sync the copied file, confirm descriptor close and sync history BEFORE retiring the active entry; then sync the active directory. Preserve stage/copies on any uncertain effect. Identical completed duplicates can be finished by another explicit archive operation; partial/conflicting/invalid counterparts hold. - Before new admission, check the archived provider-attempt-key filename and refuse reuse, including identical old start facts. Archived confirmation is not an executable replay obligation. Root scope and key checks survive restart even when active inventory is empty. Current active inventory remains bounded; arbitrary history corruption is not silently advertised as fully audited. - Test exact noncanonical raw-byte/max-evidence preservation, more Jobs than active slots, archived-key reuse refusal, changed-scope and permission/symlink refusal, copy/sync/unlink uncertainty, identical duplicate restart, and held original archive I/O. Keep useful phase diagnosis through StoreFailed and the existing protected receiving projection; preserve both primary and independent close. - Document actual historical file locations/lookup and the active-only recovery view; preserve portable standalone records. Do not add a new operator command or general history-query framework merely for this slice. Native request renewal is a separate following owner change. Only AFTER the controller has consumed exact host retirement and settled original setup I/O may it acknowledge that token as consumed. Host must independently know its exact worker is retired before moving that token's retained request/receipt/diagnostic files into private history and releasing active maps/slots. Publishing a retired receipt alone is too early: the original client may still need it. Archive rather than erase evidence, refuse old-token reuse, retain unresolved native leaves, and reuse the same physical disk envelope. No second lifetime registry/recycler or scientific rerun is planned. These are designs, not passed qualification claims. Pre-implementation mechanism refinement, after independent design challenge: Use an exclusive DIRECT final history leaf, not generalized _publish/history staging. Share only the existing bounded write-all/file-fsync loop. A partial copy is then found by the same active-key point check and holds storage while the complete original remains active. A complete identical active/history duplicate can be resynced and finished by explicit archival. There is no extra staging namespace or stage/target hard-link pair to reconcile. Same-filesystem linking was considered. Current original-file admission requires st_nlink==1 to reject aliases outside the private namespace. A crash after linking active into history and before unlinking active creates nlink2, so the shortcut would require a second paired-path/inode admission rule or block reopening a valid interrupted archive. Retain the singly-linked invariant and copy the bounded raw record instead. This also avoids a staging-link intermediate state inside history. One full temporary body copy is already covered by _require_capacity(inventory, additional_records=0); staging/final directory names would alias, not consume two body copies. Never weaken ordinary hard-link admission for this optimization. This refinement supersedes the planned deterministic staging/generalized-publisher bullets above. Source: current AttemptFiles._read/_publish and StoreLimits. 2026-10-22 confirmed-history storage implementation (service wiring follows) =========================================================================== AttemptFiles.archive_confirmed and AttemptStore.archive_confirmed preserve exact TerminalConfirmed bytes, using the original private-file admission and serialized I/O worker. Scoped history is mode0700; each original record remains mode0600 and singly linked. File sync, confirmed close and history-directory sync precede active unlink; active-directory sync confirms the slot release. Cancellation retains the original future and owner. Partial/conflicting/aliased copies hold storage. Complete identical duplicates can finish explicitly after reopening. History-only roots retain scope binding and old keys cannot become new Attempts. records/admission_inventory remain read-only active views, not full history audits. Two independent reviews found the same capacity defect: reconciling an already complete duplicate incorrectly required another copy's free-space headroom. Fixed at the copy owner: only new copies require that capacity. The restart witness now finishes an identical duplicate at zero available blocks; the causal new-copy control refuses before creating history. Reviewed record_visible documentation now means an observed target entry, which can be partial or pre-existing; it proves neither admitted bytes, durability nor active-slot release. Archive failures retain useful copy/removal/sync phase messages plus original/independent causes. Both final independent code reviews reported no new actionable finding. Focused offline qualification: - make test/unit/provider-core/admission:28tests/0.395s. Includes maximum evidence, exact noncanonical bytes, three archived keys through one active slot/reopen, old-key/scope/permissions/symlink/hard-link refusals, unsettled original I/O, copy/file-sync/history-sync/unlink/active-sync faults and both close failures. - make test/unit/provider-core/recovery:74tests/1.003s; verifies existing terminal publication/recovery behavior after sharing only bounded file-write/file-sync. - Repository launcher checks retain exact offline/grant expectations and now include test_attempt_history.py in the existing admission lane. No new lane. make test/repository/provider-core:49tests/2.258s. - Ruff0.15.15 format/lint passed for the storage files and launcher expectation. Logs: /tmp/nmrnet-history-core-{red,green,final,recovery,style,conventions}.log. This change adds explicit storage archival, not service/native renewal. NMRNet service still requests no archive at this checkpoint. No historical evidence is discarded; physical disk growth/reserve remains a real operating envelope, not a claim of indefinite capacity. Existing installed-image evidence predates this source change. No API Job/model request or scientific matrix was rerun. 2026-10-22 connected service confirmed-history renewal ===================================================== Source basis:7447357 storage operation; current service._startup/_work_loop and admission.require_admission_ready. Before fresh admission, the service explicitly archives a clean, entirely confirmed active inventory. Startup and each new work cycle call admission.archive_confirmed_history outside every API read-retry loop. A previous controller.run returning successfully is the existing claim-release authority; no parallel released flag, settlement task or new lifecycle registry was added. Context admission shares the existing config/API identity/topology and store-scope checks BEFORE reading or changing storage. Any unresolved neighbor prevents the entire archival pass. Admission still rechecks capacity and a complete remote live view before discovery/allocation; archive success is no API authority. Stop is checked before each archive submission, including after the awaited inventory read. Already-submitted I/O stays with owner=service and shutdown joins the original store future; shutdown submits no archive. A stop after the last terminal receipt may leave that confirmation active for the next clean startup. No archival failure/cancellation is wrapped in an API retry or scientific rerun. The successive-Job peer now admits confirmations from actual retained historical bytes as well as active records. Each known archived filename must match its decoded record key and EXACT recorded START body, preserving durable-before-next- START checks rather than deleting them. Recovery inspection remains active-only: Job1's archived confirmation is preserved unchanged while only Job2's pending lost-ACK command is selected for explicit replay. No expected scientific result bytes, metrics or tolerances changed. Focused offline evidence: - make test/integration/provider-core/service:40tests/10.747s. Three Jobs fit ONE active slot; Job2's lost ACK recovers exact terminal bytes; three allocations, three interpreter conversations and three scientific executions. Two confirmations are archived and the stopped final confirmation remains active; all three survive reopening. The call-limited Job1/FAIL then Job2/replay and Job3 path also passes. - Restart/full-confirmed-store witness archives original bytes then STILL refuses remote in-progress ownership before another allocation. Mixed unresolved local inventory remains byte-identical with no API calls. Wrong identity/topology/scope refuses before any new inventory/archive operation. - Real filesystem-worker barriers prove stop during inventory submits no archive, and cancellation during archive retains the exact original future/service owner, prevents dependency closure and further admission, then settles one write only. - Independent U/A/boundary and design/proof reviews found a stop-after-read race and missing historical filename/START-body checks in the fixture. Both were repaired with causal witnesses; final reviews found no new actionable issue. - Ruff0.15.15 passed for seven changed service/fixture/test files. Logs: /tmp/nmrnet-history-service-{red,green,final,admission,style}.log. This connects Attempt-store capacity renewal. Native request-leaf renewal remains a separate host/client ownership change. Retained history still grows physically; neither unlimited disk nor completed full003/017 is claimed. No external API Job, paid model exchange, new native inference or unchanged scientific matrix was run. Next native renewal slice: host request-consumption protocol (plan before coding) ============================================================================== Owners: tools/provider_workers.sh::provider_workers_service/retire/publish and nmrnet_provider/allocation.py::WorkerAllocation._retire; retirement.py:: retire_worker_channel. Exact retirement currently leaves requests and host maps counted forever. A consumed TOKEN request is a separate client acknowledgement, not a second retirement or permission to rerun science. The client may publish it only after original setup I/O, exact host retirement and channel closure settle. Host-only support is the first bounded slice; client handoff follows separately. Keep receipts/TOKEN at its current stable read-only grant, including result and resources.json. Move owned/TOKEN then requests/TOKEN into private history/TOKEN, using same-filesystem directory renames after their writers stop. This preserves all original diagnostic/request bytes and the resources.json hardlink without a recursive copy/delete, new controller grant or second lifetime registry. Confirmed never-dispatched tokens have no owned tree; host's existing retired state plus empty ID/role proves that case. Absence of a tree alone proves nothing. Only exact consumed bytes and independently known retired state permit this move. After both namespace transfers succeed, publish archived TOKEN at the existing stable receipt path, then release the existing maps before servicing another request. Process eligible consumed leaves before counting active capacity. Old receipt/history tokens are refused before any new create/map initialization. Any partial move/publication error preserves remaining paths and held maps; subsequent service must refuse unresolved transfers, not recreate or silently discount them. A missing/mismatched resource-report receipt for an otherwise admitted final report prevents renewal, preserving the earlier retention error. Durability scope: the current Bash host request/receipt protocol confirms observed filesystem effects; it has no directory-fsync primitive. These renames preserve observed namespace/content during the installation, not power-loss durability. Do not claim durable native history or substitute broad syncfs. The core Attempt record remains separately fsynced/durable. Restart still refuses reuse of a prior native installation root and requires explicit stopped reconciliation. This bounded host capability does not yet enable automatic client consumption. Native history can reside on a different filesystem from store_root. Its retained disk usage has no independently configured native free-space reserve in the current Bash owner. Do not imply AttemptStore's fstatvfs/reserve covers that mount. An actual native write/rename/receipt error holds renewal with every remaining path and existing map retained; no quota, offload or implicit cleanup is invented. Tests first in existing test/unit/provider/allocation: more completed role tokens than the active request bound; exact retained request/diagnostic/report bytes and private modes; retired-but-unconsumed retention; malformed/premature consumption; old-token reuse; partial rename/marker publication and resource retention failures hold accounting without engine re-execution. No paid/native science rerun needed. 2026-10-22 host-only native-consumption implementation ===================================================== provider_workers_archive now requires exact consumed/retired bytes and the host's independently retained physical-retirement disposition. It preserves the original owned/request trees under private history/TOKEN via same-filesystem renames, leaves original receipts/resources at their existing stable grant, publishes archived TOKEN, then clears existing active maps. Completed handoffs are processed before active counting. Old-token receipt/history reuse and any held map missing its active request path refuse service before another create. No second registry, recursive cleanup, source-copy framework or new grant exists. Independent reviewers found retirement arriving between first-pass admission and the final pre-create check retained a role despite no create. That branch now records the SAME empty ID/role never-dispatched disposition; allocate retains its original requested role. Three timing witnesses (retire-only, before admission, during admission) prove request-only archival and zero engine operations. Required device/size observations now check stat's exit status explicitly; two failed device observations cannot compare as equal empty strings and permit a move. Focused contained make test/unit/provider/allocation:39tests/16.256s. Eight role allocations fit a three-active-request bound; exact request/native diagnostic bytes, engine retirement receipts, resource-report hardlinks and private history modes survive. Retired-but-unconsumed leaves still count. Malformed/premature consumption, failed device observation, old-token reuse, owned/request/marker transfer faults and the earlier resource-report retention failure hold renewal without another engine execution. Existing allocation/retirement tests remain. Ruff0.15.15 passed for both structured test files; bash -n and git diff --check passed. Two independent final reviews reported no new actionable finding. Logs: /tmp/nmrnet-native-history-host-{red,green,final,style}.log. This is host protocol support only. Production clients do not yet publish consumption, so automatic native capacity renewal is not claimed. Observed native history is not fsynced power-loss evidence, has no native reserve/quota and may reside outside the Attempt-store filesystem. Real transfer/write failures hold the installation with its evidence. No API Job, paid model or native science run. Next client slice: explicit adopted-channel retirement ==================================================== Add retire_channel(worker) to NMRNet's retirement port: fixed HostRetirement reuses the existing close/retire/wait_closed sequence; WorkerAllocation adds consumption only after that full sequence has no failures. Session/input owners call that explicit port. No optional-method lookup, callback or generic receipt framework is needed. The private consumption method additionally requires the original allocation/setup and exact retirement tasks to have completed cleanly. One shielded publication/observation task publishes consumed once; completed absence/deadline observations can later read again, while publication, malformed receipt or descriptor-cleanup failures remain held. Keep the completed staging link because the host may rename the whole request tree immediately after the exclusive consumed link becomes visible; no post-visibility unlink is safe. Deliberately limit automatic consumption to adopted channels. Factory failure and unadopted-writer cleanup keep their existing complete failure set/settlement path and leave host request/receipt evidence unconsumed for stopped inspection. Those operational setup failures already end service; they are not successful throughput whose slots need renewal. Do not broaden consumption from _retire's local empty failure list when outer close/setup failures remain. Correctable source input rejections still use adopted channels and can consume after their clean retirement. 2026-10-22 connected adopted-channel consumption =============================================== WorkerAllocation.retire_channel reuses the existing close/retire/wait_closed sequence, then owns one shielded consumption publication/archive observation. Session/input owners call that explicit port. Fixed prestarted HostRetirement delegates to the same old sequence with no capacity registry. Factory failed or unadopted setup cleanup remains unchanged and unconsumed. A consumed marker is published by exclusive link only after its private staging file closes; the staging link remains because the host can immediately rename the whole tree. No operation touches request paths after that visibility point. Pending waits retain their original task. A completed missing-receipt deadline permits only another bounded read; publication, malformed receipt and receipt- descriptor errors latch the original protected failure, even if a later marker appears. This distinguishes confirmed physical retirement from unconfirmed capacity renewal. Never-started allocation cleanup publishes no marker. Authority/simplicity adjudication: the original _retire already joins publication, exact host retirement and setup observation before helper success. Removed new private-task/owns_leaf revalidation from _confirm_consumed rather than mirroring that authority. Also removed an advisory client receipt-exists precheck: exclusive request mkdir owns leaf freshness, old retired receipts refuse adoption, and the host independently refuses old receipt/history tokens BEFORE another create. Existing malformed/adoption tests remain; no fixture was weakened for the check. The receiving renderer already follows __cause__ AND __context__, so dual receipt read/close failures use their original exception context, not a new aggregate. An actual operator stderr/file regression proves both EIO5 and EBADF9 arrive, while PRIVATE cause text remains excluded. No arbitrary exception stringify. Focused contained evidence: - test/unit/provider/allocation:48tests/18.502s. Includes actual Python allocation owner against real Bash protocol with recording engine: FIVE adopted channels through THREE active request slots; exactly five creates/removals, all original history retained and no active maps. This is protocol proof, not native science. An initial fixture incorrectly emitted prediction-only metadata for reader channels; real unknown-IPC refusal exposed it. Corrected the fixture's role files without loosening cleanup or increasing its two-second operation budget. - Same lane proves host receipt precedes channel observation; consumption stays absent until closure succeeds; immediate host tree rename is safe; cancellation preserves original publication; late receipt never resends; publication/read/ close/malformed failures remain held; no-marker never-started behavior. - test/integration/provider-core/service:40tests/10.693s. - test/integration/provider-core/native-factory:9tests/0.039s, preserving original failed/unadopted setup/cancellation/closure ownership without consumption. - test/integration/provider-core/uploads:38tests/0.763s, skipped1 existing native witness. Its stale call-budget wording assertion now checks the existing exact InputWorkerCallLimit and (maximum_calls,calls_started)==(1,1); acquisition and scientific assertions remain unchanged. - test/integration/provider-core/lifecycle:33tests/0.276s, skipped3 existing fixed native witnesses. PDB/SDF correction fixtures use the explicit retirement port. - test/integration/provider-core/process:62tests/36.560s, including both actual protected receiving sinks for original read/close evidence and secret canaries. - test/unit/provider/host:24tests/9.630s. Ruff0.15.15 on changed Python files, bash -n on the qualification helper and git diff --check passed. Logs: /tmp/nmrnet-native-history-client-{red,green,final,service,factory,uploads, lifecycle,process,host,style}.log. Independent ownership, simplicity and privacy/ recipient reviewers plus final deletion/proof review found no new actionable issue. The native qualification now verifies each adopted token's exact archived receipt and retains COMPLETE native history before deleting successful scratch. Its old active-map iteration would omit newly archived diagnostics; it now reads stable receipt tokens and their archived owned trees. Actual native/installed-image qualification follows this commit; source/unit proof is not claimed as that run. Physical native-history growth, lack of native reserve and lack of native fsync remain explicit. No external API Job/paid model or unchanged science matrix ran. 2026-10-22 installed image and one native capacity witness ========================================================= Source:ee9707731af9b377764a7f80880393f2ed1dc053. One offline provider image build: sha256:7f75c0dc70328cf3617a046d5325cca95b5fec64f2758aa5e2df9a11f2aff81b. Committed provider-image input tree: sha256:69c7453838dfb69060fa829a9a25d97f9925e10d58e942e9d6feec7d18466d0d. requirements/provider-core.lock remains: sha256:79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Image-ID record hash: sha256:a1d4dcf362074bed637068cddb8c6d333897a28722ade965591c8aec007b157a. make test/integration/provider-runtime passed4tests/0.868s for installed isolated imports, native signing and complete consumed dependency inventory. Logs: /tmp/nmrnet-capacity-image-{build,runtime}.log. make test/integration/provider-service/pasted exited0. This existing minimal native supplied-input witness used the production factory/worker entrypoints and captured source closure, with local scripted TLS API/model peers. Its controller is the maintained checker image, NOT the freshly built installed provider image: sha256:9164d380c00bf0e013d44357cafb03d4b1f64570a93105f74ac4b85b66cf1b49. Scientific image:sha256:cabb4fe3e36541b0fefe54ca7c16fb21f9a60112a1e3d47992d4aa18343ecd08. Geometry image:sha256:be4358dd385b280723831950e527e44a87de4ee49afa9020ef8e7e8929bd3bb3. These installed-image and native-source claims remain separate. Private retained receipt relative to repository: .work/qualification/provider-service-nmrnet-native-service-vmKbLUqA/ summary.json SHA256:3e57b1003e91eb73ec6f5b2d95ff97cf14bf99f927d4baef18a97087e06c3877 scientific-result.json SHA256:ac8f0f2af56f133e7024ac6d5e40e59c4e1b719822eba9cdc71f83e5a5ba9420 sources.sha256 SHA256:4c1cc7e7628bb34e0ca8d41ccf646ef3fbcbfb83d2817ca6db02f99b8cd59b22 Pinned supplied-geometry oracle SHA256: 1686803ac341e8502fbc9eaba71dccc1a6ebc04f121af4b0ba513e11e312d5b7. The existing independent binary64 nm/angstrom error bounds were retained. Observed: one START, one acquired Job input, one reader call/record1, one preparation and one scientific execution. COMPLETE was sent twice: original lost-ACK send plus exact replay after store reopening, with no science repeat. Both prediction and reader show host_retired=true AND capacity_renewed=true from exact archive receipts. Complete requests, native diagnostics/engine-retirement receipts and resource snapshots survive under native-history and host-receipts. Receipt root mode0700; summary/manifest mode0600; metadata scan found no group/ other permission bits in this retained receipt. Snapshot memory peaks: prediction 2971234304bytes within4294967296, reader17051648bytes within536870912. These are sampled per-container peaks for this fixture, not serving-limit/OOM qualification. Log:/tmp/nmrnet-capacity-native-pasted.log. No broad scientific matrix rerun, external API Job, paid model call or GUI qualification was performed. OOM strategy discussion and applicability ======================================== magnet-deploy@b1b5e410aa75192b05e347576b3c137ca3363934: - models/e_01_jvae_nmrexp/provider/magnet_provider_bindings/e_01_jvae_nmrexp/ unix_runner_backend.py:80-125: at most two generation executions, preserving typed input, Attempt-derived seed and implementation-owned decoding; the retry is scoped to pure generation, not interpreter/API lifecycle replay. - magnet_provider/single_runner_boot_owner.py:51-115,185-242: owned ready boot, detach/retirement and operation ordering. - magnet_provider/owner_session_supervisor.py:64-126,193-242,255-289,338-361: process observation/reaping, lock/socket ownership and WorkerTerminationTimeout. These are inspected checkout source references, not claims of external deployment or of native NMRNet OOM behavior. Rationale retained from discussion: a fresh READY or released flock alone is not proof that an unreaped old worker is gone. Replacement requires the actual configured composition's container/PID-namespace retirement fence. A future model-specific pure-compute retry must keep frozen input/Attempt/seed/decoding, bounded executions and original/second protected causes, distinguish definite failure from lost response, and leave cancellation/protocol/rejection/cleanup failure out of that retry. Fixed seed is not a GPU bitwise-reproducibility claim. Never resubmit a Job, rerun interpretation, duplicate terminal mutations or raise resource limits merely to hide OOM. NMRNet adds no automatic OOM/inference retry in this work; its current native-failure ownership and retained evidence remain. 2026-10-22 unresolved inventory takes priority over slot-limit advice =================================================================== Service's explicit pre-admission archive pass now raises the existing AdmissionHeld as soon as an active unresolved record is observed. Previously it returned and delegated to capacity preflight; a full store then suggested raising the record limit before explaining the actual retained recovery obligation. The shared _require_confirmed_inventory predicate preserves one owned recovery explanation for this pass and the standalone admission path. No unresolved record is archived, changed, replayed or replaced. No capacity guard or API admission is weakened. Tests first tightened the existing lost-completion service witness to ONE record slot, and the full mixed confirmed/pending witness now requires AdmissionHeld. Both reproduced the old StoreRefused remedy. Independent review then found stop arriving during the awaited unresolved-inventory read could become a new admission failure. Check the existing stop event immediately after that read and before classification; retain the per-archive stop check too. The actual filesystem barrier is now qualified with BOTH confirmed and lost-ACK TerminalPending records: clean stop, exact original bytes, no archive/API request/fresh allocation. make test/integration/provider-core/service:41tests/9.923s. Ruff0.15.15 and diff whitespace checks passed. Final independent review found no new actionable issue. Logs:/tmp/nmrnet-unresolved-capacity-{red,green,stop-red,final,style}.log. This narrows the same full-pending classification exposed by historical R37's aggregate failure, without rerunning its already measured scientific outputs. It does not retroactively turn that historical exit2 into a green aggregate. The installed/native evidence above still describes source ee97077, not this subsequent admission edit; image refresh will accompany the next coherent batch. 2026-10-22 next recovery slices: exact START, then progress separately =================================================================== Finish the runnable service's operation-owned recovery before optional package work. A lost START response currently leaves safe durable recovery state but stops the service. The same controller must retain its existing AttemptStarter, claim, StartPending body and provider key, settle the original I/O, then use AttemptStarter.resume. Never allocate a new key or repeat interpretation/science. Authority: tests/fixtures/nmr_api_v1/openapi/openapi.v1.json (under provider-core), source12a53e720fc87e1a4144c76203f8853d5afaf753, release sha256:719055db7751605c0e5325ca23bcbe66cde631376d4b2b99523c8e4db75f0d01; /x-nmr-attempt-recovery/start, START POST's x-nmr-recovery and HTTP500 response. The API explicitly permits unchanged Job/key/body replay with fresh signature and nonce. The returned current state, including terminal state, controls whether science can start. An in-progress reply alone does not prove a worker ran. Tests-first slices: 1. API-owned can_replay_start: exact current settled POST/target, reviewed availability and pinned HTTP500/lost-head permission. Refuse wrong topology, authentication, malformed success, TLS, cancellation and cleanup failure. Share evidence classification with terminal replay only where identical; operation permissions remain explicit and dispatch no requests themselves. 2. Controller-owned bounded StartRecovery: same starter.resume and pending record; retry admission includes retirement, observers and paced backoff. Received but undurable acknowledgements, storage/claim failures and unsettled cleanup never qualify. A terminal replay follows the existing no-execution retirement branch. Prove exact body/key plus fresh signatures, one science execution, terminal replay with none, deadline/cancellation holds and acknowledgement-write failure. 3. Required production configuration, protected Job-scoped retry/recovery notices (no Attempt ID before verified admission), service receiving proof and one coherent image refresh. Preserve unresolved acknowledgements; do not broaden confirmed-history admission to hide terminal START recovery obligations. Progress is a separate later decision. The API's progress PUT is observational and permits only still-current facts. Core report_condition additionally promises acknowledgement before dependent session effects. Do not swallow its failures, replay stale phases, or turn read-only ObservationRecovery into write authority. Any explicit phase-only continuation must retain delivery uncertainty, observe fresh allowed state, and recover outside the API lock. No generic mutation retry engine or new recovery framework is needed for these operation-specific policies. START permission slice qualified: can_replay_start now owns the exact POST/target permission; START and terminal share only settled API failure evidence. Existing terminal behavior is unchanged. The three-operation matrix exercises real API methods, plus late retirement/topology/cleanup evidence, foreign/subclass/stale failure and wrong method/query/trailing-slash targets. Predicates dispatch nothing. Tests first failed for the absent permission. make test/unit/provider-core/api: 62tests/0.254s; Ruff0.15.15 and diff whitespace checks passed. Two independent read-only reviews found no actionable signal. Logs: /tmp/nmrnet-start-api-{red,green,style}.log. Automatic START dispatch still awaits the controller and required production binding slices below this evidence. Controller START slice qualified -------------------------------- StartRecovery admits bounded retries through the SAME AttemptStarter.resume and StartPending after original I/O retirement and API permission. Its finite window starts when the first send failure is observed; it includes retirement, observers and capped jittered backoff. No new invocation starts after expiry; admitted I/O keeps its existing owner/bounds. StartRecoveryExpired preserves the original cause, window and pending Job in protected diagnostics, without an invented Attempt ID. Received but undurable acknowledgements and cleanup/storage/claim failures never enter this loop. Terminal replay admissions use the existing session-retirement branch and leave their retained obligation visible; no history policy was widened. Tests first exposed the absent policy. Normative proof: exact noncompact body/key across three sends, fresh signature/nonce on every send, durable acknowledgement observed by preparation, one prepare/execute/retire, claim release; succeeded/ failed/expired replay causes retirement only. An admitted late receipt may finish after the retry window. Adversarial proof: auth/conflict/malformed success/topology/ TLS/cleanup refusal, observer-induced expiry, cancelled backoff, held original retirement with late certificate/cleanup/availability evidence, and real failed or cancelled acknowledgement writes. Failed os.replace preserves original record bytes and poisons storage as intended; cancelled replacement settles its original future once, with one API send and no scientific work. No guard was weakened to make the storage-fault test reusable. make test/unit/provider-core/recovery:84tests/1.346s; make test/repository/provider-core:49tests/1.963s. Ruff0.15.15 and diff whitespace checks passed. Independent ownership/proof/simplicity/diagnostic reviews found no remaining actionable signal. Logs:/tmp/nmrnet-start-controller- {red,green,final,style,conventions}.log. Direct core callers can explicitly disable automatic recovery; required NMRNet production wiring is the next separate slice. Production START recovery binding qualified ------------------------------------------ lifecycle.start_retry_window_seconds is now required and validated by the core window owner. NativeAttemptFactory refuses a disabled policy before allocation; the exact configured policy is passed through assemble_attempt to the controller. Direct scientific/stopped-recovery witnesses select explicit None instead of acquiring a hidden retry default. Foreground api_start_retry notices name only the known Job, already redacted before output/fallback retention. Recovery notices use the actual durable acknowledgement and its Attempt reference. Existing bounded failed-output retention remains the only notice fallback. The signed local TLS service witness retains its first accepted admission, loses the reply, then returns that admission on unchanged-body replay with fresh signing. It observes two START requests, ONE local acceptance, one model exchange, one scientific allocation/prepare/execute and confirmed channel/host retirement. Recovery observes NOT_ENTERED; execution advances phase afterward. This is a stateful authored local peer, not proof of a deployed API transaction. No server idempotency implementation, external model, native scientific output or GUI is qualified by this witness. Existing native scientific evidence is unchanged. Actual receiving tests cover Job/Attempt references equal to configured model keys, successful notice output and failed-sink fallback. Expiry reaches both protected outputs with HTTP503/request correlation/mutation uncertainty and a redacted known Job, without an invented Attempt ID or private response body. The required-key table, recovery guide and package contract now match behavior; the guide's stale claim that confirmed records always consume active slots was corrected to the implemented evidence-preserving archive policy. Tests first rejected the added required setting. Focused contained qualification: config30tests/3.279s; native-factory10/0.042s; service42/10.066s; process63/34.679s; runtime14/2.106s; repo conventions49/2.093s. Ruff0.15.15 and diff whitespace passed. Independent boundary/diagnostic/proof/ simplicity reviews found no remaining actionable signal. Logs: /tmp/nmrnet-start-binding-{config-red,green,final,owners,style}.log. The first service run exposed a test comparison between the pre-execution acknowledgement and its later EXECUTION_ENTERED record; compare exact start/ admission plus the appropriate explicit phase, rather than erasing that phase. Image refresh remains batched after the next coherent local recovery changes. Next: elapsed input-selection limits without losing operational evidence ----------------------------------------------------------------------- An aggregate input-selection deadline is a per-Job capacity limit, but only its OWN asyncio.timeout context may establish that classification. A foreign API/ worker/storage TimeoutError, external cancellation, independent late operation failure or failed retirement must remain operational. Settle original chooser, source and native owners before admitting a public budget FAIL; core still gates publication and the next Job on full session retirement. No interpretation or scientific retry is implied. First close a necessary diagnostic gap independently: InputInterpreter currently snapshots endpoint/correction failures only before tool dispatch. A deadline during the first model POST can therefore lose its bounded model interruption/ effect-uncertainty evidence when converted to an AnalysisFailure. Use the existing renderer and configured-secret owner, with a final snapshot AFTER original model I/O retirement. Keep the original capability as the immutable diagnostic recipient for that interpreter lifetime; do not retarget old Job diagnostics on reuse. Permit evidence updates during selected/retiring input phases without granting scientific work. Keep the pre-tool snapshot, original exception identities, and independent cleanup/snapshot failures; add no transcript, journal or generic port. Qualify a real interrupted POST after received headers, credential/body canaries, successful selection/fallback, cleanup and rejected recipient retargeting first. Then implement the owned timer classification with its concrete failure fields and a budget-FAIL followed by later Jobs witness. No broad TimeoutError catch at the Session boundary and no new lifecycle registry. Final interpreter diagnostic prerequisite qualified -------------------------------------------------- The existing diagnostic renderer now runs before tool effects AND after original model retirement. It includes ToolConversation.last_failure, so cancellation during the first model POST retains its actual ChatFailed cause, received head, request correlation and effect uncertainty. Handled endpoint failures already in the history are not copied again. The same capability remains the diagnostic recipient for this interpreter lifetime; reuse cannot retarget private bytes. Evidence-only updates admit SELECTED, FINISHED and RETIRING as well as CHOOSING. FINISHED matters when repeated cancellation ends prepare's waiter while its original shielded retirement task continues. Tool-effect admission stays CHOOSING-only. No transcript, new port, cleanup owner or lifetime registry. Tests first reproduced missing diagnostics during a real local TLS POST after received headers. A second causal witness holds original model retirement, cancels the outer waiter twice, then releases that SAME shared task and verifies late evidence. Both keep status200/request ID/request_cancelled, one POST and zero source/scientific allocations, excluding configured keys, private headers and original instructions. Retargeting fails without changing the second recipient. Independent review caught the evidence-admission summary's established entry vocabulary: use {failure:graph}, not a new graph key. The interrupted-POST fixture now also passes through PreparationEvidenceFailed's actual operator projection. Snapshot errors remain operational and Python context preserves an independent operation/cleanup error; no generic exception stringification was added. Focused contained results: interpreter28tests/0.640s; connected service42/10.643s; repo conventions49/2.061s; Ruff0.15.15 and diff whitespace clean. Three independent read-only reviews found no remaining actionable signal after the phase and receiving-shape corrections. Logs:/tmp/nmrnet-final-interpreter-diagnostics- {red,finished-red,green,final,accepted,style}.log. This prerequisite does not yet classify aggregate elapsed preparation time as a public Job-capacity failure. The changed snapshot also passed the actual foreground/shutdown receiving lane: make test/integration/provider-core/process,63tests/48.271s; /tmp/nmrnet-final-interpreter-diagnostics-process.log. No unchanged native science or paid model witness was repeated for this diagnostic-only change. Installed recovery image checkpoint ----------------------------------- make provider/image/build completed offline at source 39f04431fe99a4bd225bcc3fdc0406c7ca6305b5. Provider image: sha256:67b30e79bedc913ffe91fb47b9eb29397dda259bad3f7b104063197fa5e21a88. Committed provider input-tree digest: sha256:cb64eb7b7a2eff12faed88f9bf7e052133773a7beb817555224d550f1b2fc32a. requirements/provider-core.lock SHA256: 79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Image-ID record SHA256: 2154ed34be5d0917a4eeb7ff639b80ed6a4f4c27cad10810f6aafd9bd15fee4b. make test/integration/provider-runtime:4tests/0.835s; logs: /tmp/nmrnet-recovery-image-{build,runtime}.log. No native outputs were rerun. Sequencing: implement the narrow owned-deadline behavior and failed-Job→later-Jobs story with existing recording ports first. Read-only native review identified an additional COMBINED proof not yet run: three actual pasted Jobs through one production service/factory/store/host, one active record, six allocations against the unchanged four-active-request bound, middle exact COMPLETE replay. Existing native single-Job stopped/reopened replay and recording three-Job/real host-client capacity tests remain independent useful evidence; do not conflate them. A later fixed successive native profile can reuse NM_TABLE/expected.json and the original SuppliedLifecycle assertions, retain every result/Attempt history/native archive, and keep scripted model scope explicit. Do not build a qualification framework or reconstruct the existing fixtures before the deadline behavior works. 2026-10-22 owned input-selection time limit and successive Jobs -------------------------------------------------------------- InputPreparation.prepare now retains its actual asyncio.timeout owner and tests that owner's expired() fact. A foreign TimeoutError is never reclassified. After its own expiry, full original chooser/source/native retirement must settle before InputSelectionTimeLimit can be returned. Independent late operation or cleanup failures remain operational. Session maps only that typed outcome to input_selection_time_limit, retaining configured seconds and finalized protected interpreter diagnostics; public guidance names the limit and operator next step. This is not a claim that a handed-off model POST had no effects or stopped at the remote model. External cancellation still propagates as the original cancellation. Ownership correction from independent review: provider_core.conversation owns independent_interruption_failure, because it already owns ConversationFailed's single history wrapper and ChatFailed. InputPreparation consumes its factual result without inspecting HTTP carrier internals. Exact original cancellation, no independent interruption/cleanup, and absent/200 received head distinguish the expected interrupted model exchange; late I/O primary or known non-200 service head remains operational. Every non-None returned fault is retained, including a nested cancellation with an operational cause. No arbitrary cause-graph search, new lifecycle registry, model retry or science retry was introduced. Source cumulative deadline/grant/cleanup faults remain operational at their existing owner. Tests first exposed nested cancellation being dropped by a second blanket filter: /tmp/nmrnet-input-selection-deadline-nested-cancel-red.log,38tests/one expected failure. The repaired integration witness retains the actual nested object, useful worker reason and secret redaction. Real local TLS witnesses cover a first model POST interrupted after headers, prior endpoint503 then interrupted fallback, and late I/O/status evidence observed during retirement. Additional cases preserve foreign timeout identity, source failure after cancellation, held cleanup and external cancellation during retirement. The established upload-retirement test now expects the owned typed limit without weakening its cleanup assertions. InputTimeLimitPeers plus SuccessiveServiceRecoveryTests.test_time_limited_first_job_fails_then_later_jobs_finish_in_one_active_slot exercise one ProviderService/store with max_records1: Job1's own model selection limit produces durable FAIL with protected request uncertainty and zero science; Jobs2/3 complete, including Job2's lost accepted receipt and exact terminal replay. Distinct Job/input/Attempt joins, three model conversations, no redispatch, original resource retirement before later START, confirmed historical bytes and reopen equality are checked. Scientific ports are recording fixtures, not native models. Focused contained final results, all pass: - make test/integration/provider-core/interpreter:38tests/2.048s; - make test/integration/provider-core/service:43tests/10.434s; - make test/integration/provider-core/process:63tests/33.872s; - make test/repository/provider-core:49tests/1.908s. Combined log:/tmp/nmrnet-input-selection-deadline-final.log. The unchanged upload lane also passed38tests/0.690s (one native opt-in skip), before moving the factual helper; log:/tmp/nmrnet-input-selection-deadline-owner-final.log. Ruff0.15.15 and diff whitespace clean. Two independent final reviews found no actionable issue after the owner and nested-cancellation corrections. docs/provider.md distinguishes this owned Job limit from operational deadlines. No paid model, external API Job, unchanged scientific matrix or sibling/upstream changes in this slice. The prior installed image checkpoint predates these changes and must not represent them. Next: phase-progress delivery resilience, before optional combined native proof ----------------------------------------------------------------------------- Preparing/running labels are observations, not scientific dispatch permission. Choose explicit phase-only continuation after reviewed delivery failure, not an automatic PUT retry. Keep report_condition's acknowledgement-before-dependent- effects contract unchanged. A fresh Attempt GET does not return phase/condition and cannot establish that any failed progress PUT was accepted. Authority: pinned OpenAPI source12a53e720fc87e1a4144c76203f8853d5afaf753, release719055db7751605c0e5325ca23bcbe66cde631376d4b2b99523c8e4db75f0d01, /paths/~1provider~1v1~1execution-attempts~1{execution_attempt_ref}~1progress/put/ x-nmr-recovery (mode latest_progress) and that operation's HTTP500 description. They warn that replay can overwrite a newer condition. No stale phase is resent. Tests-first order: API-owned exact current retired PUT/Attempt target + reviewed availability evidence; executor._progress owns opt-in continuation, original API retirement under its lock, then releases the lock before mandatory fresh allowed observation. The synchronous protected on_unconfirmed_phase_progress observer opts into this policy; explicit/default None keeps core fail-stop. Existing ObservationRecovery bounds/paces the fresh GET; no extra timer/configuration, progress generations, writer registry or mutation-retry framework. Conditions remain in _ConditionReporter, with no second competing observation waiter. Qualify preparing/running failures followed by fresh read and science exactly once; fresh terminal/cancelled state preventing effects; foreign/cleanup/late failure/cancellation refusal; unchanged condition acknowledgement, stale capability and swallowed-failure gates. Preserve original PUT uncertainty plus independent read/cleanup causes through protected receiving diagnostics. Production must emit delivery-unconfirmed, never progress-recovered/accepted based on a GET. Bind the reviewed callback through existing factory/controller owners and refresh once. Park optional three-native-Job fixture work: existing native single-Job, actual host/client capacity and recording three-Job evidence remain separate claims. Progress evidence predicate qualified before executor wiring ------------------------------------------------------------ ProviderAPI.can_defer_phase_progress checks the exact current ApiFailure, original retirement and actual PUT target for this validated Attempt. The API owns settled send evidence, not the condition payload: phase-only use remains an executor precondition, explicitly documented without introducing copied body authority. The predicate dispatches nothing and confirms no progress delivery or lifecycle permission. START/terminal operation permissions are unchanged. The existing real-method availability matrix now includes progress alongside START/COMPLETE/FAIL: reviewed availability/500/pre-head uncertainty, wrong topology, refusal/conflict, malformed received200, TLS, cancellation and failed cleanup. Exact-target tests exclude foreign Attempt, GET, query, trailing slash, unrelated route, foreign/stale failure and unretired exchange. Red run failed for the absent method; make test/unit/provider-core/api then passed63tests/0.265s. Logs:/tmp/nmrnet-progress-api-{red,green,style}.log. One independent review identified the payload-ownership wording correction above; no body shadow or generic retry API was added. Executor/production behavior is still unchanged by this predicate-only slice. Core phase-only continuation qualified before production binding ---------------------------------------------------------------- AttemptExecutor/AttemptController now accept the explicit bounded synchronous on_unconfirmed_phase_progress observer (default None keeps fail-stop). Only fixed _progress preparing/running labels use it. After original retirement and exact API evidence under the exchange lock, the callback retains delivery uncertainty; fresh allowed lifecycle observation runs outside the lock before dependent work. Original PUT remains exception context if callback/read/cleanup fails. Only that identical active API failure is cleared on successful continuation. No PUT replay, new deadline/configuration, competing observation owner or condition-policy change. New structured execution_progress/controller_progress tests first failed for the absent executor/controller parameters. They prove both phase positions, fresh cancelled/terminal state preventing effects, separate read+PUT causes, callback or retirement failure, default/refused behavior and unchanged condition ACK gating. Three independent read-only reviews found no actionable defect. Moved the new controller witness to its own focused file to avoid formatting unrelated tests. Contained results:/tmp/nmrnet-phase-progress-core-final.log: test/unit/provider-core/prepared-identity102tests/2.069s; test/unit/provider-core/recovery85/1.409s; test/unit/provider-core/api63/0.267s; test/repository/provider-core49/1.941s, all pass. Controller discovery after moving its test:85/1.359s, log /tmp/nmrnet-phase-progress-controller-final.log. Ruff0.15.15/diff whitespace clean. Core README documents the observer's protected-evidence responsibility and GET's limited meaning. Production callback wiring/receiving proof follows separately. Production phase-delivery continuation and recipients qualified ---------------------------------------------------------------- NativeAttemptFactory requires a callable unconfirmed-phase observer before any allocation and transfers it unchanged through runtime/controller. run_provider uses existing report_attempt_notice/redaction/nonblocking output and failed-sink retention. api_progress_unconfirmed contains phase, progress_delivery_confirmed false, the real acknowledged Job/Attempt and reviewed safe cause/correlation. It is emitted before the fresh read, so it claims neither acceptance nor that dependent work already continued. No new selector/configuration/deadline. The successive local TLS witness now delivers503 for Job1 preparing and Job2 running; all three distinct Jobs durably complete with one interpretation and science invocation each, one active record, exact middle terminal replay and reopen-stable original confirmed history. No failed phase PUT is resent. The actual foreground subprocess receives a signed preparing503, emits the safe notice, sends a fresh GET immediately afterward, then one model POST. It remains alive until requested SIGTERM; final exit1 preserves that handed-off model POST's interruption/effect evidence. No prediction entered. Private response/key canaries are absent; no progress_recovered/accepted event is invented. This is real local TLS/carrier plumbing with a scripted model peer, not external semantic inference. Factory tests first failed for the absent production argument (11 errors). Contained final results:/tmp/nmrnet-phase-progress-binding-green.log: native-factory11tests/0.039s; runtime14/1.985s; service44/10.961s; process64/36.636s, all pass. Ruff0.15.15/diff whitespace clean. Three independent final read-only ownership/U&A/simplicity reviews found no actionable defect. Existing native qualification callers were explicitly adapted, without rerunning unchanged scientific outputs or changing their oracles. Direct nonproduction assemble fixtures retain explicit None/fail-stop where appropriate. Provider guide records the new behavior and condition/operational failure distinctions. Installed service-resilience checkpoint --------------------------------------- Offline make provider/image/build at cd6765892810d02777ed43a29993424105f88a01 produced sha256:fe3bb302d3d36f1a6c355d996a9c7ea170b72164169defadb5eccd44ab5918a5. Committed input-tree digest: sha256:65e6f68051c0522b2dbbfe85c0f4e0eae689f28c099e7f21ddb9896ca11f7529. requirements/provider-core.lock SHA256 remains 79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac; image-ID record SHA256: 33f483cae71d63eca10d4042f42912d6b4e89799555bc56ca4f9ffc1a160dda9. make test/integration/provider-runtime passed4tests/0.725s, and final production repo conventions49/1.908s. Logs:/tmp/nmrnet-service-resilience-image-{build,runtime}.log and /tmp/nmrnet-phase-progress-binding-conventions.log. Source tests above prove behavior; this separate installed check proves image admission/package isolation. It adds no native accuracy, selected external-model, deployed API or GUI claim. U27/A11 remains open for awaited conditions: _ConditionReporter currently latches even a reviewed503. Preserve acknowledgement-before-dependent-effects while adjudicating bounded recovery of still-current facts, original I/O and observation ownership; phase-label continuation does not close this distinct requirement. Condition-report recovery: settled design before implementation --------------------------------------------------------------- AnalysisSession (provider_core/analysis.py:65-74) already requires sequential, awaited reporting and excludes detached/concurrent calls. The pinned progress PUT's latest_progress recovery permits the same still-current phase/code with fresh signing. It does not require a GET per resend, and a GET cannot inspect condition currentness. Keep _monitor the sole lifecycle-observation owner. Use separate opt-in ConditionRecovery(window_seconds, backoff_max_seconds, on_retry, on_recovered), default None fail-stop. API.can_retry_condition supplies settled exact current PUT/Attempt evidence; the reporter owns current facts. Inline recovery retains one pending awaited condition. Settle/classify under the existing API lock, release it during bounded paced waiting so the monitor can observe stop, then recheck phase activity, failure latch and retry-admission deadline under that lock before resending. Return only after matching progress receipt; no silent deferral, scientific/model retry, observation waiter, condition queue or generation history. An overlap refusal can poison the existing latch before an old condition is resent if a binding violates the sequential contract. Retry admission begins at first failed send and includes retirement, notices, lock wait and jittered backoff. Existing bounded I/O admitted before expiry keeps its owner; a timer creates no replacement task or proof of stopped work. Preserve first/current fault and independent cleanup evidence. Expiry stays operational and must join the existing suppressed-outcome rules if a binding catches it and later returns science. Protected notices identify actual Attempt/phase/condition and say recovered only after matching acknowledgement. Conditions remain code-owned public vocabulary; never derive them from exception/model/input text. Tests first: actual current/cleared-condition retry after settled transient fault; monitor read during backoff, observed server stop preventing resend; matching ACK before exactly one dependent effect; cancellation/cleanup/late fault/foreign or permanent refusal; deadline while waiting for the lock; overlap and swallowed failure poisoning. Reuse condition and executor fixtures and focused lanes. Condition API permission qualified ----------------------------------- can_retry_condition and can_defer_phase_progress share only exact current retired PUT/Attempt failure evidence. Sequential pending phase/code and matching receipt remain the caller's separate authority; no body shadow or generic mutation retry. The real-method availability matrix now includes a non-null condition as well as phase-only None, retaining its refusal/topology/malformed-success/TLS/cancellation/ cleanup cases. Missing-method red run preceded the implementation; focused make test/unit/provider-core/api passed63tests/0.344s. Ruff0.15.15/diff whitespace clean; independent API review found no issue. Logs:/tmp/nmrnet-condition-api- {red,green,style}.log. No actual condition retry or production change yet. The current top completion audit was refreshed separately from dated entries: implemented read/START/terminal/phase recovery and active-slot renewal are now distinguished from open condition recovery, native-history disk envelope and independent diagnostic lookup. No new runtime qualification was used for that edit. Core bounded condition recovery qualified; production follows -------------------------------------------------------------- ConditionRecovery opts into retrying one still-current sequential awaited report. Default None stays fail-stop. _ConditionReporter refuses overlap and poisons both callers; activity/failure guards precede dispatch and follow parsed receipt. Original PUT retirement and exact API permission stay under the exchange lock; pacing releases it so the existing monitor alone observes lifecycle stop. No condition await returns before a matching acknowledgement. No scientific retry, second reader, queue, generation counter or replacement I/O task was introduced. Controller validates and forwards this same policy before session handoff. Window starts at first send failure, includes original retirement/notices/lock wait and jittered backoff, and gates retry admission rather than cancelling owned I/O. ConditionRecoveryExpired is operational and participates in existing suppressed- outcome retention; a binding catching it cannot publish returned science. First/latest condition faults and actual parsed receipt are borrowed by existing ExecutionFailed/projection. Latest report evidence is independent of monitor API state: a real GET503/recovery/cancel sequence reproduced its loss (112tests/one failure), then passed with this bounded first/latest retention. Expiry borrows the latest fault; receipt presence survives recovered-observer failure. No transcript or per-retry journal. Core README makes exclusive progress writing a composition requirement; local claims/locks do not claim distributed writer exclusion. Tests cover setting/clearing in both phases with identical bodies/fresh signatures, held original retirement, monitor stop during pacing, overlap, cancellation, expiry behind the actual monitor lock, swallowed expiry with returned science, receipt-before-observer failure, permanent/cleanup refusal and controller handoff. Audit corrections preserved actual EXECUTION_ENTERED state in running callbacks, latest rather than first-only expiry cause, and cancellation at a causal monitor callback barrier. Removed the dead _api reporter branch and shared the existing SwallowingSession fake instead of importing another test module. Final contained results:/tmp/nmrnet-condition-core-final.log: prepared-identity112tests/2.466s; recovery86/1.397s; diagnostics8/0.002s; repository conventions49/1.980s, all pass. Ruff0.15.15/diff whitespace clean; focused logs also include /tmp/nmrnet-condition-{core-red,core-guards,latest-cause-red,core-evidence}.log. This qualifies core behavior, not production configuration/notices or installed image. Those remain the next bounded slice; unchanged native science was not run. Final independent review found the cancelled-send variant of that evidence loss: a binding catches condition cancellation, then monitor GET503/recovery clears the shared API failure before the binding returns. The entered condition exchange now retains its actual cancelled-send ApiFailure as latest, without changing or retrying cancellation. Cancellation while awaiting the lock cannot capture a GET failure. The new actual-executor witness failed before repair (113tests/one failure) and passed afterwards (113tests/2.884s). Logs: /tmp/nmrnet-condition-cancelled-send-{red,green}.log. Independent follow-up found no further issue; focused Ruff/diff checks remained clean. Production condition recovery and receiving proof -------------------------------------------------- NativeAttemptFactory now requires an exact ConditionRecovery before allocation and passes that same object through runtime.py to core. Production uses the existing configured observation_gap_seconds/backoff_max_seconds API outage envelope with a separate condition-specific permission and matching-receipt gate. The daemon is the intended sole progress writer for its Attempt; local claims do not fence independently deployed writers. Core's default remains fail-stop. Existing protected api_condition_retry/api_condition_recovered notices identify the actual Job/Attempt, phase and condition, bounded cause/correlation evidence, and false/true condition_receipt_received. Dynamic code/references pass through the existing credential redactor; failed output retains existing final-report fallback rather than stopping recovery or creating a journal. Operator docs describe the window, gate, single-writer requirement and unrecoverable exits. Tests first: absent-policy admission and exact handoff failed before wiring (12tests/two errors). Actual contained process/TLS witness injects one awaited condition before input interpretation: first signed PUT503, same body with fresh signing receives matching ACK, then exactly one real local model POST receives headers. Retry/recovered notices reach actual stderr without response-body or credential canaries. SIGTERM retains known POST uncertainty; no science occurs. This test-only injected report qualifies the production plumbing, not a claim that every current NMRNet preparation emits that particular condition. The actual executor's exhausted running-condition witness reaches BOTH protected receiving sinks with first/latest correlation IDs, expiry, condition/phase and mutation uncertainty; returned science cannot publish. Reference-equals-key tests also exercise both successful notice output and failed-sink retention for this new policy. Existing native qualification callers explicitly supply a bounded policy without rerunning their unchanged science. Focused contained results: native-factory12tests/0.041s; runtime14/2.642s; process/receiving66/39.342s; repository conventions49/2.702s, all pass. Logs:/tmp/nmrnet-condition-production-{red,factory,runtime,process,conventions,style}.log. Ruff0.15.15/diff whitespace clean. Two independent reviews found no runtime defect; one caught and corrected an obsolete blanket-stop sentence in operator docs. No paid model call, external API Job, native science or GUI proof added. Installed image refresh follows this committed source slice. Installed condition-recovery checkpoint ----------------------------------------- Source:dc25708264396178c1765557d8eb3e25bfe08369. One offline build produced: sha256:9e78e4e646b5405b86ec9d78661815a9ef516b9350441a8f6a412bc08ddf8496. Committed provider-image input tree: sha256:36a542a2d597ccad7fd23b9895de556897f5db1036736abc39afd6a2c1271c5e. requirements/provider-core.lock remains: sha256:79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Image-ID record SHA256: 822bc3f3fe2f6f1fbae391a0f411702aa1516aabdeac862a722486527473ae0d. make test/integration/provider-runtime passed4tests/0.711s for isolated installed imports/help, native signing and complete consumed dependency inventory. Logs: /tmp/nmrnet-condition-image-{build,runtime}.log. This installed checkpoint includes current-condition recovery; it does not add deployment, native scientific, external-model or GUI observations. Earlier scientific evidence remains unchanged. The four-case paid ambiguity approval remains pending after the recorded pre-execution automatic-review rejection; no external call or alternate destination was attempted here. Porting bounded native prediction recovery (2026-10-23) ------------------------------------------------------- Joint decisions: one retry of pure prediction inside the same Attempt, frozen geometry bytes/models, a new native token, complete old host/channel/consumption retirement before replacement, and no interpretation, conformer generation or API lifecycle replay. Existing process-owned bounded/redacted notices retain the first failure even on success; do not append an unreserved traceback graph to expensive scientific evidence. Cancellation and partial replacement allocation keep their existing owners. Inspected Magnet5578bc3c21a74dcdd9875a1500642c1c057f0915: notes/033_bounded_generation_recovery_20261022.txt:7-75,104-129; models/{e_01_jvae_nmrexp,e_02_ch_nmrexp}/provider/magnet_provider_bindings/ <stage>/unix_runner_backend.py::generate; magnet_provider/ single_runner_boot_owner.py::use/_detach and owner_session_supervisor.py; scripts/test-generation-oom.sh and tests/unit/oom_recovery.py:72-85. Retained /tmp/magnet-verbosity-oom.log records both actual64MiB/no-swap cgroup kernel kills and identical-request recovery. That is a synthetic lifecycle proof, not native model/GPU memory or numerical equivalence qualification. Port retirement authority, not Magnet's supervisor/restart architecture. Classification slice: NMRNet's old generic failure reply covers admission and bad tokens as well as prediction exceptions. Retrying it wholesale would violate the intended exclusions. Worker now emits execution_failed only after consuming a valid execution token and entering prediction.execute. PredictionClient admits that exact reply as PredictionExecutionFailed; malformed replies and generic failures remain non-retryable. WorkerExchangeTimedOut marks only this channel's own timer or explicit deadline checks; foreign TimeoutError keeps its identity. The existing protected receiving projection deliberately includes both types. No retry loop is enabled in this first slice. Focused maintained lane make test/unit/provider/worker passed25tests. New tests distinguish execution failure/refusal, owned/foreign timeout, private diagnostic handling; existing token/protocol/batch tests remain. Independent review found the synchronous buffered-reply deadline also needed the owned timeout type; fixed without weakening foreign-timeout exclusion. Repository conventions49/2.186s passed. A preliminary broad test/unit/provider run encountered39 unrelated image-fixture missing /input/provider-core-build.lock grants; it was not green and was replaced here by the focused maintained worker lane. No host fallback, dependency acquisition or scientific matrix rerun. Logs: /tmp/nmrnet-prediction-recovery-protocol-{red,green,focused,style,conventions}.log. Final review reproduced a dependency catching the owned timer's cancellation and raising its own TimeoutError. Expired alone would misclassify it. Classification now also requires the manager's explicit cause to be the exact cancellation escaping the exchange body; the new identity witness passed after repair. Red:/tmp/nmrnet-prediction-recovery-foreign-timeout-red.log. Bounded prediction recovery connected --------------------------------------- NMRNetSession optionally owns PredictionRecovery with an allocation callback and process-owned observer; production supplies it explicitly. Only its execute call catches admitted PredictionExecutionFailed, owned WorkerExchangeTimedOut or EOF/reset/broken pipe. Preparation/refusal/protocol/caller cancellation and ResultPlan.finish stay outside eligibility. At most two execute calls, using the same frozen request tuple and a new native prepare/token. The original ResultPlan still checks the complete returned batch/model bytes/runtime; no partial merge. Before replacement, the original retire_channel must confirm exact host removal, local close and allocation consumption/archive. Factory.allocate_prediction reuses only the existing fixed prediction profile; it cannot recreate an Attempt or interpreter. It retains partial setup and transfers the pair plus admitted runtime synchronously. Session adopts before phase/runtime rechecks. One pending handoff fact plus exact-pair identity across retire's await prevents a late replacement from being hidden by RETIRED. No new registry, lifecycle task or distributed restart framework. Both replacement/final retirement use the same helper preserving original cancellation and independent cleanup observations. PredictionRecoveryFailed explicitly retains first prediction fault, later replacement/cleanup failure and interruption cause. Production's existing bounded protected notice owner projects/redacts first-fault evidence with actual Attempt IDs, retaining failed-output evidence via its existing api_notice_failure field. Successful recovery adds no unreserved traceback graph to scientific evidence. Second failure or unconfirmed cleanup stays operational; there is no third try, automatic Job replay or increased resource limit. Tests first: the missing policy failed the installed-core session lane. New normative/adversarial cases cover exact frozen bytes, one replacement, host and channel barriers independently, second failure, exclusions, runtime drift, cancellation and late handoff. Independent review caught handoff occurring DURING old-channel retirement; the exact-pair guard and causal barrier test close that interleaving. A later red45/one error showed cleanup cancellation becoming ordinary recovery failure; the shared retirement helper restored cancellation. Configured local TLS runtime witness proves one interpretation, one conformer generation, two native prediction allocations and one START/COMPLETE publication. No real-model science is claimed by those recording ports. Factory handoff tests exercise replacement ownership without a second lifetime registry. Both operator sinks and failed-notice fallback retain useful diagnostics without credential or raw partial-reply canaries. Focused contained results: session45tests/5.651s; runtime15/2.235s; native-factory12/0.045s; process/receiving67/38.696s; repository conventions49/1.967s. Ruff0.15.15/diff clean. Sources/logs: /tmp/nmrnet-prediction-recovery-{session-red,session-green,session-final, retirement-cancel-red,runtime,factory,process,conventions,binding-style}.log. The launcher campaign test was updated to require the new structured recovery tests; its exact readonly/offline assertions were preserved. Joint improvements in Magnet, authored there by the requested peer: 66292bc Preserve worker diagnostics when generation recovers; 9374f1a Retain private IO evidence across generation recovery. Its notes/033_bounded_generation_recovery_20261022.txt records jointly reviewed portable rules: operation-owned eligibility, existing complete retirement fence, frozen inputs/new transport tokens, protected first-fault diagnostics, no unreserved post-compute evidence graph, and real-kernel versus synthetic/scientific proof. Only read/review/messages were performed by this owner in Magnet; no sibling edits. No automatic OOM diagnosis follows from EOF, exit137 or a traceback substring. The opt-in synthetic kernel-OOM/real-framing retirement proof and installed image refresh are qualified in the next entry. External model/API/GUI gates remain separate. Real kernel OOM and installed recovery checkpoint -------------------------------------------------- make test/integration/provider/prediction-recovery exited0 at committed proof source de09db7be2f29c2c6e99897ead3db95634ebfe12. It reused the installed provider image built once at8c3206e4ae015c86fc60fb836988356e79deb497: sha256:c05a43b95289ecb26ec6010ba2d23a6c2354b0b85e91a4a8ed35a7a438f464b0. Committed provider-image input tree SHA256: 1622334d1693567aea8f7e941b3dae8b84eeb3bc4c0e6e4c700431562e69425f. requirements/provider-core.lock remains: 79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Image-ID record SHA256: 410307c72cb15e6965d2f5c360d7b57c8f61acab02700facde07f4891aaa8108. make test/integration/provider-runtime passed4tests/0.914s. Logs: /tmp/nmrnet-prediction-recovery-image-{build,runtime}.log. The opt-in fixture changes only its fixed synthetic worker launch profile to 64MiB/no additional swap. Production memory/profile settings are unchanged. It uses real NativeAttemptFactory.allocate_prediction, NMRNetSession, PredictionClient and nmrnet_inference.worker.serve_connection, plus existing host service/CID admission/retirement/consumption/archive. The worker loop is an explicit frozen readonly bind because the controller image intentionally includes only predict.py from nmrnet_inference. No native models, credentials, API or interpreter are granted. The authored Attempt/input/artifacts and shift1.25 are fixture values, not scientific or API observations. First child touched/retained pages until the kernel killed it. A small parent kept its accepted stream open until waitpid and the cgroup counter witness were published, then exited137. This prevents EOF-triggered retirement racing witness publication. Actual first kernel oom_kill delta1, reaped child signal9; exact container OOMKilled=true/exit137 observed before removal. Second worker delta0, child exit0, exact container OOMKilled=false/exit0. These are independent facts; runtime recovery classifies EOF as response uncertainty, not an OOM diagnosis. The same ordered scientific bytes were prepared/executed twice with fresh worker allocations/tokens. Both exact allocations were retired and consumed/archived; the first archive receipt was required BEFORE replacement allocation. Existing retirement helpers also removed the controller; the target exited0 after cleanup. Private receipt relative to repository: .work/qualification/prediction-recovery-1VYqqnKZ/ output/summary.json SHA256: 8af884d2790921bbd932eb6b1f48eb2720ce657d4e2c7af0015ba18613bcdd97 output/result.json SHA256: bfd33831bcd8b265bc2d536468f4fe32b3ce2f7f88f94ec51c7f50f9a937ebe7 output/retry.json SHA256: 035eb9d8a812b5a69d9370f0c1a64a2529f34cb1e8bb036bc5a52beded339ed1 sources.sha256 SHA256: d0798f39a880f2d52bff5f1882c380fbdc68e0757b0fabdfbc523d1e216a7d12 scientific request SHA256: 6130e1aa9512882c3feeed9d62122170676198c34f3051a203e8f6de50074182. The receipt preserves both original worker trees/requests, exact engine posture, kernel/request observations, removal receipts, controller diagnostics and source closure. Root/output mode0700; summary0600. Captured public source files retain their Git modes under the private root, unlike private runtime/diagnostic data. Log:/tmp/nmrnet-prediction-recovery-oom.log. Final repository conventions49/2.039s passed. Independent source/receipt reviews found no remaining changed-code issue; one caught and corrected the obsolete 'proof remains next' status above. This establishes synthetic CPU kernel-OOM/session/allocation recovery. It does not qualify released-model or GPU OOM capacity, numerical equivalence on retry, whole API recovery, live selected-model/GUI delivery or the full unattended disk envelope. Separate configured runtime proof above covers one interpretation, one conformer generation and one terminal publication. Original scientific accuracy evidence remains unchanged. No new acquisition or paid calls occurred. + 2026-10-23 native history release: source-grounded proposal, not implementation ============================================================================ Investigated at6dc5c1e. No native history, receipt, Attempt record or old qualification artifact was changed or deleted. No model/API Job, native prediction or new test run occurred. This is a proposed next bounded slice, not closure of003 or qualification of unattended disk capacity. Existing cutpoints and owners ----------------------------- - tools/provider_workers.sh:217-249 owns exact engine removal, IPC cleanup and the final resource-report receipt. Its251-321 archive operation requires independently retired state plus exact consumed/result bytes, moves original owned/request trees and releases existing maps. That renews live slots only. - nmrnet_provider/allocation.py:133-211 owns consumption after setup, host retirement and channel settlement. Its archived receipt is still being read asynchronously. Physical retirement or consumed publication alone grants no permission to delete that receipt or crash-reconciliation evidence. - packages/provider-core/src/provider_core/controller.py:208-257 returns cleanly only after execution retirement, terminal publication and claim release. nmrnet_provider/session.py:424-443 confirms input/prediction owners, including replacement handoffs. A pending/failed cleanup never reaches that clean return. - nmrnet_provider/service.py:282-308 reaches the existing next-work-cycle barrier after that return. admission.py:61-84 rejects every unresolved store neighbor, then archives each exact TerminalConfirmed record. attempt_files.py:335-380 owns the archive's write/sync/unlink ordering. It does not own native files. - TerminalConfirmed (attempt_record.py:237-246) establishes matching API receipt, NOT native retirement. Both preceding clean lifetime and durable archival must therefore precede a native release request; no one flag replaces them. What remains necessary ---------------------- 1. Active requests, in-flight setup/channel work, retired-but-unconsumed leaves, partial native archives and all uncertain transfer/cleanup evidence remain untouched. Native archive errors already hold maps and preserve remaining paths (provider_workers.sh:267-318). Neither API confirmation nor age repairs a native transfer that never completed. 2. Durable Attempt records retain original START/acknowledgement, execution-entry prepared identity, exact terminal body, protected scientific evidence and matching API receipt (attempt_record.py:122-136,182-205,237-246). These stay under AttemptStore ownership. Stopped recovery (nmrnet_provider/recovery.py: 98-143) operates on those exact records, not native engine-command files. session.py:106-122,338-356 retains raw scientific output/diagnostics separately from its public rounding. Native history is not a substitute for that evidence. 3. Native history's owned/ subtree holds engine creation/posture/removal evidence and resource observations; requests/ holds allocation/retire/consumption bytes. These are valuable until the clean publication/archive cutpoint, especially after a controller crash. They are not required to replay a confirmed terminal command after that cutpoint. Input/artifact/source roots remain separate and must never be included in this deletion authority. 4. Existing receipts/history presence prevents old-token reuse before another create (provider_workers.sh:340-344). Erasing every token path would silently weaken that rule under today's random-token protocol. Compact archived receipts would preserve it, but still grow indefinitely. The bounded sequence alternative below preserves stale-request refusal without one file per token. 5. Scientific qualification capsules deliberately retain complete historical proof (tools/provider_service_qualification.sh:427-439). Existing capsules and that explicit qualification retention remain outside production pruning. Smallest proposed change ------------------------ Use one awaited handoff between the existing service and host owners, immediately AFTER the clean confirmed-inventory archival pass and BEFORE fresh selection. The service authorizes release of prior completed work from THIS fresh host lifetime; it supplies no path, shell command or new Job lifecycle state. The host rechecks its own exact retired/consumed/archived evidence and no active or partial native obligation before pruning completed leaves. Unknown names, symlinks, mismatched receipts and partial transfers refuse release and retain the remaining evidence. A copied diagnostics JSON or TerminalConfirmed flag alone never grants deletion authority. Closed-world prerequisite: provider_workers.sh:92-100 and provider.sh:606-616 refuse old/nonempty roots and require their exclusive locks. There is one serial service/controller lifetime; all earlier controllers and setup/source/replacement work must have settled, the WHOLE core inventory must be confirmed/archived, and no fresh allocation passes the awaited release. This composes existing service facts with host-owned retirement evidence. It does not generalize to simultaneous lanes, an adopted old root, detached writers or a store with unresolved neighbors. Under these premises a per-Attempt token list adds no necessary authority. The initial stricter proposal and its supervisor attribution in4f9d81f are superseded by this adjudication; do not reintroduce retired clients/tasks or another registry to satisfy that earlier wording. A crash leaves the original installation for stopped inspection, not automatic history reconstruction or deletion. Carry the handoff through the existing private request/read-only-receipt grant, with one outstanding operation and an exactly matched response identity. Keep only its current request/receipt; do not accumulate a second history ledger. The original asynchronous operation remains owned across cancellation/timeout. No fresh admission passes until its outcome is known. A stop before publication submits nothing; a stop after publication settles the original handoff. A partial filesystem failure reports the original cause and removed-versus-retained facts, holds further work and never reruns science or silently retries deletion. This proposal does not extend native files' existing power-loss guarantees or add fsync. Tests first in current focused allocation/service lanes: successful completion and durable archive precede release; lost API ACK/archive error/unresolved neighbor submit none; partial native archive and live/unconsumed worker refuse pruning; old-token reuse still refuses after old receipts are gone; cancellation settles the same handoff once; deletion/receipt failure preserves useful causes and prevents fresh allocation. Keep existing scientific reference outputs and old capsules unchanged. Adjudicated bounded native end state: one existing host generation and sequence ----------------------------------------------------------------------------- The fresh, exclusively held installation already supplies the generation. No extra generation service/file tree is required. Replace random allocation names (native_factory.py:251-258) with increasing allocation numbers represented in the existing32-lowercase-hex token shape. The factory chooses the next request number; the host owns acceptance of exactly the next number before any create or explicit never-dispatched retirement. Keep one accepted-number frontier plus existing live/held maps. A request at/below that frontier whose original map is no longer owned is stale even if its old history/receipts have been removed. Known current maps still settle their ORIGINAL operations; old numbers never trigger a create. Future gaps refuse rather than being skipped. Numeric range/overflow belongs to these owners' actual representation, with explicit drain/refusal before wrap; never reset the number inside a live installation. Token secrecy is not an authority: private mounts, closed roles and fixed host grants already own it. The clean service-wide handoff binds the expected accepted frontier. The host requires exact completed dispositions for all retained work through that frontier and no active/partial obligation. It can then release full native trees AND token receipts, retaining only its current frontier and matched release response. A stale release request cannot delete work after its declared frontier. One current request/response is enough; there is no per-Job interval ledger. A host/controller restart cannot silently reset and reuse the root: the existing nonempty-root refusal remains. Never-dispatched requests, interrupted publications and missing sequence entries need focused causal witnesses before this becomes code. This is a proposed change to the production allocation pair, not to prestarted worker grants or public API identifiers. Here frontier is inclusive: the factory's largest issued number, consumed before publication and never rolled back, must equal the host's largest accepted number. An unseen reservation therefore refuses release rather than disappearing. The host performs release inside its existing serialized request-service owner; any request leaf, current/held map, partial transfer or frontier mismatch blocks it. Confirmed Attempt retention: lifecycle obligation versus evidence policy ----------------------------------------------------------------------- Already-confirmed recovery is a no-op: provider_core/recovery.py:98-115 returns TerminalConfirmed unchanged, whereas TerminalPending delegates the exact stored terminal command. Public receiving reads the API's result, not local history. Thus no lifecycle replay obligation alone requires every confirmed byte forever. The current history-key refusal (attempt_files.py:298-301) is also a local policy, not the server's Job/Attempt admission authority. Normal discovery uses the API's has_provider_execution_attempt=false and generates a fresh key (admission.py: 114-135); forever-retained old keys do not by themselves prevent another Job run. Deleting them must not permit execution without the normal START acknowledgement and durable execution-entry gate, or change unresolved recovery in any way. There IS unique evidence: prepared identity, unrounded predictions, native/model diagnostics and original API commands/receipts remain in the complete confirmed record. A4-digit public result cannot reconstruct its full raw prediction. That justifies an explicit scientific/operator retention window, not an undocumented promise of infinite local storage. U19 (notes/013_sibling_practices_20261016.txt: 281-299) preserves evidence while a claim relies on it and debug captures until resolution/reviewed replacement; it does not require every production record forever. docs/provider.md:210-217 currently promises no automatic expiry; changing that contract must be explicit. No existing byte is authorized for removal here. Recommended healthy-run end state: one finite, operator-visible confirmed-record window managed by the EXISTING AttemptStore/archive I/O owner, plus the bounded native sequence/release above. Retain whole exact confirmed records in that window rather than inventing a summary/second ledger. A finite record count and the existing record-size cap yield a finite logical storage bound; reserve space for active obligations and the archive transition. Expire only confirmed history past that window after the clean cutpoint, with ordinary existing failure/poison/ settlement semantics. Never expire active, held or uncertain records. Published qualification capsules and explicitly selected scientific evidence are outside the production window. Past expiry, the API still owns its public result; local raw-value and historical diagnostic lookup is no longer promised. State that limit plainly. No retention count/default or migration deletion is approved by this investigation. Without a finite evidence window, full disk closure is unproven even if native history becomes bounded; bulk pruning alone is not that closure. No quota framework, offload service, extra registry or fsync campaign is proposed. Resource bounds are for healthy operation; failures still hold original evidence and require exceptional reconciliation instead of silently discarding it. Actual normal GUI submission and real-model semantic proof in003R45/R50 remain pending. Independent read-only source review confirmed the existing cutpoints, consumption receipt reader and held-transfer protection. It identified random token generation, never-dispatched sequence holes and unique private scientific evidence as required design considerations. The supervisor retracted the earlier per-Attempt-binding requirement after reviewing fresh/exclusive root and serial lifetime premises. Final independent review found no causal contradiction under those premises and required explicit treatment of never-dispatched reservations/frontier mismatch. This is design evidence only; sequence allocation, expiry and pruning remain unimplemented and unqualified. Native sequence implementation, 2026-10-23 ------------------------------------------ NativeAttemptFactory consumes an increasing positive signed-64-bit number before request construction, encoded as the existing32-lowercase-hex allocation token. The original fresh/exclusive host owner accepts exactly its next number before dispatch or never-dispatched retirement. Gaps, zero, overflow and stale numbers refuse without engine effects; neither side wraps or reuses a number. Incomplete publication consumes no host number until an exact allocation or retirement is present. Existing maps/receipt checks and uncertain setup ownership are retained. The format qualification alone carries its one host's scalar between separately scoped case factories; production has one factory per fresh host lifetime. Tests first reproduced random IDs and missing exhaustion refusal. Focused offline lanes then passed native-factory14/0.045s and allocation53/19.408s, including the existing real client/recording host protocol. Independent read-only code/caller review, pinned Ruff0.15.15, bash syntax and diff checks passed. Only disposable test roots were used; no scientific matrix, external call, store or capsule was changed. Native release and confirmed-history expiry remain the next slices; this sequence-only change does not authorize or perform their deletion. Awaited native history release, 2026-10-23 ----------------------------------------- The accepted storage contract now requires an explicit positive confirmed_history_records (example64, no unlimited/legacy fallback). The next retention slice must order by receipt.committed_at then canonical filename, not started_at/mtime. Existing oversized history refuses rather than migrating or purging it. All deletion witnesses below use disposable roots only. ProviderService now requires its native owner's release port. Only a complete, nonempty confirmed archival pass with stop still clear calls it; idle polling, unresolved inventory and interrupted archival publish none. Production supplies NativeAttemptFactory.release_history. Its one original shielded thread survives cancelled/expired observation, blocks new setup and is joined by factory.settle before process dependencies close. Successful observation forgets that task. The existing private request/read-only receipt grants carry one atomic current release/ACK pair containing the inclusive32-hex frontier. The host checks its accepted number, empty active roots/maps and ALL completed archive/receipt trees before removing any leaf. Known names and private regular-file/directory types limit deletion. Exact consumed/retired/archived markers bind the already admitted disposition; worker identity and resources are not re-admitted by a second owner. Sequence counters survive pruning within the original exclusive host lifetime. No recursive deletion, token registry, new journal, host Python or power-loss guarantee was added. The host observes find/sort's original completion status; enumeration failure preserves its native stderr cause and refuses before unlink. Partial removal latches phase, target, observed file/directory removals, bounded native filesystem cause and unattempted directory-sync status. ACK publication failure cannot become success or trigger another deletion; remaining paths stay for stopped inspection. Clean repeat polls observe only the prior stable ACK. Tests first reproduced missing release. Focused contained results: allocation57/ 20.012s; native-factory15/0.050s; service lane passed; process/receiving63/34.645s. Witnesses cover later unknown/symlink entries preserving earlier histories, active/frontier refusal, partial scan, one observed unlink then EIO, ACK rename failure, retained interruption ownership, exact wire bytes/private publication, and durable complete archive plus native retirement BEFORE release. A missing release ACK prevents new API observations and scientific work. Two independent read-only reviews, Ruff0.15.15, bash syntax and whitespace checks passed. Existing installed images, real stores/capsules and scientific references were not changed or requalified. No paid/external call or deployment occurred. Confirmed-record expiry is not implemented by this native-release slice. Confirmed evidence window and shutdown batch, 2026-10-23 ------------------------------------------------------- Required StoreLimits keyword/TOML field confirmed_history_records now names a positive finite record count; the authored configuration example is64, not an implicit default. Existing callers supply their policy explicitly. H is the confirmed window, A the active-slot limit and R the full record budget. Steady history is at most H records; the bounded archive transition permits H+A, plus one complete staging/archive copy. Production R=3,725,916 from provider_core/attempt_record.py::MAX_RECORD_BYTES gives H64/A2 peak249,636,372 bytes (~238MiB), excluding filesystem metadata and configured reserve. Existing fstatvfs headroom still covers outstanding growth/staging; it reserves no blocks and cannot constrain other writers or guarantee failure-free disk operation. AttemptFiles.open bounds history NAMES at H+A for stopped inspection, preserving original active/matching-history admission. It does not decode unrelated old payloads merely to inspect/recover an active obligation. Ordinary service preflight/fresh admission require <=H before any archive/release. Existing excess history refuses rather than migrating. AttemptFiles.trim_confirmed_history owns the whole-byte admission at the deletion boundary: active inventory must be empty; every historical file must pass original private-file/TerminalConfirmed admission BEFORE any unlink. It reads one payload at a time, explicitly discarding per-record locals after saving only (receipt.committed_at, canonical filename). Sorted keys select oldest whole records; retained bytes are never regenerated. History directory fsync follows observed unlink operations. AttemptStore's original executor/future retains cancelled or expired I/O without resubmission. The earlier per-phase stop rule is explicitly SUPERSEDED for an admitted maintenance batch. Its counterexample: stop during archival at a full H window could leave H+1, then the next ordinary startup would refuse its own valid transition. One existing-service-owned maintenance task now spans complete archive -> native-release ACK -> trim. Stop before the complete inventory gate admits none; afterward shutdown drains/settles that SAME task, including startup and between Jobs. Bounded timeout/cancellation retains it and its native/storage dependencies; no replacement cleanup, hidden cap exception, restart migration or durable marker/ledger is added. Genuine failed/crashed maintenance still holds remaining evidence for explicit inspection; old native roots are not adopted. StoreFailed retains expiry phase, exact observed removed filenames, uncertain target, unconfirmed directory sync, original cause and existing cleanup causes. provider_core.failure_projection projects only these owned facts; NMRNet's actual stderr receiving renderer preserves errno/phase/removal facts and key redaction. Failed sync or partial deletion poisons further storage use, with no automatic expiry retry. Ordinary Docker logs remain bounded as described in019. Tests first reproduced the missing retention contract. Focused witnesses include timestamp ordering different from START/filename order, tied-receipt filename ordering, byte-identical retained evidence, active-obligation refusal, bounded stopped inspection versus fresh-admission refusal, malformed later history preventing ALL expiry, unrelated malformed history preserving active recovery, one observed unlink followed by EIO, failed directory sync and original cancelled expiry settlement. The full-window service witness covers BOTH startup and between-Job stop, observes archive H+1 before ACK, returns to H, reopens and finishes a third Job with exactly three starts/model/scientific executions. The older lost-reply/retirement/headroom gates remain; its reusable fixture uses the explicit retention window when counting still-retained confirmations. Focused contained results recorded so far: store/admission36/0.575s; service46/10.148s; receiving/process64/34.282s; core diagnostics8/0.002s; required configuration lane passed. Three independent read-only owner/policy/ scientific reviews found no remaining issue after correcting the two-payload loop-local lifetime; Ruff0.15.15 and whitespace pass. Repository/provider-core's 49-test lane revealed four stale launcher-fixture/argv expectations from earlier format/upload lane changes; those need a separate narrow test-only repair. Installed controller/config capture refresh is still required before live GUI. No existing store, installation, qualification capsule or scientific reference was expired or modified. All new deletion witnesses use disposable test roots. No new model/API/GUI call, deployment or scientific matrix was run. Focused launcher-check follow-through ------------------------------------- The stale mock checkout now includes interpreter_formats.json as a required regular authored file, and aggregate/dedicated tests require its readonly mount. The Upload lane's expected argv now includes test_nmrnet_upload_preparation.py. No production launcher, grant, selection or assertion was relaxed. The same repository/provider-core49 tests passed in1.619s; pinned Ruff/diff checks pass. Operator/core docs also make the evidence-retention boundary explicit: preserve needed long-lived evidence outside store history BEFORE expiry. There is no in-window selection exemption or new export feature; only independent copies and capsules outside that window remain unaffected. Installed image refresh follows. Installed bounded-storage checkpoint ------------------------------------- One offline build from6deb6b7 produced controller image sha256:e0c953f63a1c3ad51250aff8c5e03b40876053d6684b39beefb0e67f0a357330. Provider-input Git-tree SHA256: dde514d04341990fce9cd9ca62477aeffe629464d1f01ccd514a0a6383843ef8. Image-ID record SHA256: 9d1eabfcc8b7e5f1a65268ace025fec3c9472a6fb54c56da51fc321cad4bdeb0. The unchanged full dependency lock remains79c90c01283941561cbc6f5838f700f5dd932388890ba7510e55bf5d23a11dac. Installed-runtime4/0.721s and installed API staging/composition15/3.434s passed; the latter generates and admits fresh synthetic TOML with required history64. Actual private GUI configuration must be staged afresh through its maintained lane after authorization; R48's previous image/config is not this checkpoint. The final focused allocation57/21.776s now also connects the actual Python release handoff to the same recording host AFTER all five original consumed/ archived/channel-retirement assertions. It observes exact frontier5, no remaining native histories and only the stable acknowledgement, with all original three- slot/five-create/five-remove assertions intact. An independent read-only final test review found no issue. Final store/admission36/0.510s also passed. Source and scientific/effect limits, existing evidence preservation and pending external gates are recorded together in003R52. No more science, paid calls or deployment.