Skip to content

Complete async query-job waiting and result handoff - #6

Merged
Broccolito merged 14 commits into
mainfrom
codex/async-job-contract
Oct 24, 2026
Merged

Broccolito merged 14 commits into
mainfrom
codex/async-job-contract

Conversation

@Broccolito

@Broccolito Broccolito commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Durable job storage now enforces owner-private permissions in the backend while preserving the six job tools, normal submission/wait/cancellation and completed local output. Existing safe owned stores are repaired without deleting results. New output is private before bytes are written. Storage failures retain actionable codes/guidance while synchronous startup and all six job-tool registrations remain available.

Fixes #7. The original async-job contract and original-head native-app evidence below retain their original scope.

On Windows, retained no-reparse handles verify ownership and link counts. Protected DACLs grant only TokenUser. The process default-owner exception applies only to the exact current token owner when it is SYSTEM or Builtin Administrators; arbitrary ordinary group owners are refused because their members may have implicit permission-change rights.

Before changing any existing Windows ACL, every managed directory is inspected. A mutation allow ACE for an ordinary foreign account, an unknown ACE form or an unsafe mask refuses automatic migration with private_storage_requires_quiescent_repair. The user is advised to stop writers and have the owner/administrator remove foreign write/delete/change-permission rights throughout the tree, or select a fresh private root while retaining the old data. This prevents inheritable ACL repair from touching an entry a foreign writer could insert after enumeration. Known private stores and elevated SQLite journals keep working; no routine approval dialog is added. macOS/Linux inherited ACL cleanup and descriptor-relative checks are preserved.

Latest local validation on source ab33f32701e1ea64c813d660d8638ffc3e7665f8; shipping head ded5d6eeb56c833ce15bc1c63cf474c350c48acb:

  • macOS full credential-free suite: 90 tests, 13 explicit skips, no failures. Skips comprise ten Windows controls, two Linux-only controls and the existing Neo4j-only case. Both connector suites ran serially. No real credentials, PHI or live database queries were used.
  • Wheel built twice identically: SHA-256 ef4a60c224dd18caaf4201380593dfcbca0842d2420ca58fbeed90e4884fd17e. BRXT built twice identically: 308800 bytes, SHA-256 1e0923a6616a47719ed4acc7f2684bde8304f5a14db616959b8ddd851cff3bcd. A separate build from committed source matches the BRXT; git diff --check passes.
  • New Windows controls cover an unprotected outside hardlink canary at the first directory-repair boundary, rejection before any repair callback for a nested foreign-writable directory, unknown-ACE helper rejection, and a non-administrator default-owner helper negative. Positive legacy tests use read/list inheritance; existing real junction/hardlink/foreign-owner/first-write and SQLite controls remain.
  • Final head ded5d6eeb56c833ce15bc1c63cf474c350c48acb passed ten hosted Windows controls, zero skips, including the migration/default-owner regressions, in Windows private storage. All six Linux/macOS/Windows jobs across push and PR workflows are SUCCESS on this head. The two injected-helper controls test owner/unknown-ACE refusal; the remaining controls use actual Windows filesystem/ACL operations. This is not a second-account execution claim.

Scope limits: administrators/root, arbitrary same-user processes and foreign handles opened before permission tightening are outside the confidentiality claim. SQLite open and final result rename retain pathname seams after checks; use owner-controlled local storage. Windows chunked result reading retains its existing explicit unsupported-platform response; completed local worker files remain available. Native BioRouter and live database acceptance have not been rerun on these storage heads.


Query jobs currently require immediate status polling and return a local result path that a jailed host cannot read. A successful status lookup also hides a failed operation from the host's failure tracking. This adds native waiting, capacity discovery and bounded result reading by job ID, with an explicit operation outcome independent of lookup success.

The six job tools preserve atomic two-job admission and explicit resubmission. Failed jobs retain sanitized error codes, original phase and retryability, including FreeTDS timeout code 20003. Waits keep the MCP event loop responsive during SQLite contention and cancellation. A wait deadline returns an explicitly stale last observed active state when available; an unreadable initial state returns a transient lookup error without inventing an operation outcome. The POSIX result reader uses managed descriptor-relative opens, rejects links/nonregular files and unexpected result sizes, and fails closed on unsupported platforms. Updated instructions and a credential-free stdio fixture exercise real FastMCP tools without a database connection.

Fixes #5. Related host consumer: BaranziniLab/biorouter#438.

Follow-up dc26741 preserves the existing six-tool interface, 30-second contention-aware native wait, managed result reader and namespaced operation IDs. Capacity snapshots now explicitly include advisory: true. CLI watch uses native waiting. A failed worker launch or broken stdin pipe returns its allocated durable ID with failed operation metadata and releases its capacity slot; cleanup failures cannot hide that outcome. Failure guidance follows the structured cause rather than blindly rewriting SQL.

Earlier async-contract follow-up validation (before owner-private storage changes): 68 credential-free tests run, one existing Neo4j-only skip, no failures; wheel build passed; canonical BRXT rebuilt twice identically (299937 bytes, SHA-256 3c9b21110f172e827dfe97705336dd29fe231ed86514d653bdc069bc0516178e); committed-source BRXT comparison and git diff --check passed. Seven new regressions cover advisory snapshots, native CLI waiting, worker-start/pipe/reaper failures and actual MCP metadata. No live database queries or production credentials were used. Native BioRouter acceptance has not been repeated on this follow-up head; the original-head app evidence below retains its original scope.

Refs BaranziniLab/biorouter#436; leave that host issue open until both connectors and host verification are complete.

Original-head validation recorded for 0fd996e:

  • Full Python suite: 61 tests run, one unrelated Neo4j test skipped; no failures.
  • Real SQLite exclusive-lock regressions cover immediate zero waits, honest deadline snapshots, cancellation, responsive MCP requests and bounded lookup threads.
  • FastMCP/worker fixtures cover operation metadata, atomic admission, safe errors and multilingual chunked results. These are synthetic checks; live CDW connectivity and database execution have not been verified.
  • uv build --wheel produced cdwagent-0.6.0-py3-none-any.whl.
  • Canonical BRXT regenerated twice with identical output: 299496 bytes, SHA-256 faeddcc454e5f12fb526334bd6592201edfbad9511dcdc5a871cb50387ccfc5c.
  • git diff --check passed.

The original PR author reported the following native validation on 0fd996e through the actual development Electron app and Rust daemon, using this repository's credential-free stdio fixture and real JobStore, worker and FastMCP tools with a deterministic synthetic provider:

  • Repeated lookups of a deliberately failed job remained successful (isError: false) while the host showed failed-operation badges and counted one distinct failed operation; observed badges survived session reload.
  • Direct and nested Code Execution workflows completed. Inspecting a failed job did not throw (caught: false), while a third submission at full two-job capacity returned capacity_exceeded with isError: true.
  • Direct and nested chunk readers reassembled the exact 69-byte CSV, including accented text, Han characters, emoji, quoted commas and an embedded newline. SHA-256: 5ef7a0f5e2475c79a84cca0500abb12a4e25fc9bba48a763600a5d5628fed649; reconstructed bytes matched the managed artifact.
  • Zero-time waits reported an active job; cancellation reached cancelled and released both capacity slots. Nested cancellation also completed without an exception.

These app checks exercise synthetic jobs, not live database connectivity, production database execution or model reasoning. GitHub CI passed on the original 0fd996e head: all four Linux/macOS check runs across push and pull-request workflows completed successfully, including Python tests, wheel build and deterministic BRXT checks.

@Broccolito
Broccolito marked this pull request as ready for review October 24, 2026 08:22
@Broccolito
Broccolito merged commit ddd8385 into main Oct 24, 2026
6 checks passed
@Broccolito
Broccolito deleted the codex/async-job-contract branch October 24, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enforce owner-private ACLs for durable query-job storage Complete async query-job waiting, error metadata and secure result handoff

1 participant