Repository navigation
feat: deliver DAG communication and audited runtime repairs - #699
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 67ce58b7ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ARG BUN_VERSION | ||
| FROM oven/bun:${BUN_VERSION}-alpine AS base |
There was a problem hiding this comment.
Pass the Bun version into stats image builds
Both production SST services build this Dockerfile from infra/stats.ts and infra/lake.ts without supplying build arguments, so BUN_VERSION is empty and the base reference becomes the invalid oven/bun:-alpine; Docker explicitly requires an ARG used by FROM to produce a valid reference when no argument is supplied (Docker build check). Pass the packageManager-derived version through those image configurations rather than leaving the deployment builds unusable.
AGENTS.md reference: AGENTS.md:L8-L8
Useful? React with 👍 / 👎.
| pendingRecipients: (scope) => | ||
| transaction((tx) => |
There was a problem hiding this comment.
Use a read transaction for mailbox sweeps
When a DagLoop is active, pollAgentMailboxes calls this read-only query every 250 ms, but transaction is the shared helper that opens every operation with BEGIN IMMEDIATE. Each idle poll therefore reserves SQLite's single writer slot even when there are no messages; multiple open instances or processes continually contend with session, event, and DAG persistence and can trigger busy-timeout failures. Run this scan in a deferred/read transaction while retaining immediate transactions for message acceptance and settlement.
Useful? React with 👍 / 👎.
| "x86_64-linux": "sha256-rnbiNAgVgWVQuHsAxji+grqBoKAUFGdB661zGFyZmTs=", | ||
| "aarch64-linux": "sha256-jyt2IP293k+YeQuHdTWzmOPuOm2tCfGFADEKuRxP3k8=", | ||
| "aarch64-darwin": "sha256-B/ce+3L8PhPN9oSrFySCVsCPwM7Te1mc/zv5hF7mzkw=", | ||
| "x86_64-darwin": "sha256-AltVjSpNMd5PPgkfNgc7py7ANXipzn95bI0W1jLL6SE=" |
There was a problem hiding this comment.
Regenerate the native Nix dependency hashes
These replacement hashes are not accepted outputs for the updated workspace dependency graph: nix/README.md explicitly says nix/hashes.json still predates that update, and verify_build.py rejects a normal PR run whenever the native measurement differs. Consequently the new four-platform Nix workflow and ordinary opencode/desktop derivations remain failing until each platform's measured artifact is copied into this file and the normal builds pass.
AGENTS.md reference: AGENTS.md:L17-L17
Useful? React with 👍 / 👎.
| await lockBilling(tx, workspaceID, customerID) | ||
| // A delayed failure notification must not undo a successful reload. | ||
| if (await hasPayment(tx, workspaceID, invoiceID)) return | ||
| const invoice = await Billing.stripe().invoices.retrieve(invoiceID, { expand: ["payments"] }) |
There was a problem hiding this comment.
Move Stripe lookups outside the billing transaction
For manual payment failures, this Stripe invoice lookup—and the later payment-intent lookup—runs after lockBilling has acquired a FOR UPDATE lock. If Stripe is slow or unavailable during the exact failure scenario handled here, the PlanetScale transaction and workspace billing lock remain open across external network waits, blocking concurrent success, checkout, and refund webhooks and increasing the chance that they time out. Fetch and validate the remote objects before opening the transaction, then acquire the lock and repeat the local hasPayment/paid-state guards before updating billing.
Useful? React with 👍 / 👎.
| const boxes = yield* tx.all<{ id: string }>( | ||
| sql`SELECT id FROM agent_mailbox WHERE session_id = ${sessionID}`, | ||
| ) | ||
| yield* close( |
There was a problem hiding this comment.
Purge agent messages when deleting their owning session
When the parent/owning session is deleted, this path only marks its mailboxes closed; the new agent tables have no session foreign keys, so agent_message content and agent_input_snapshot rows survive indefinitely after the session, transcript, workflow, and event aggregates are removed. This violates the session.delete HTTP contract in groups/session.ts, which promises to permanently remove all associated messages and history. Preserve queued reports when only a child source session is removed, but delete the mailbox, snapshot, and message rows once the owning parent session itself is deleted.
Useful? React with 👍 / 👎.
Why
DAG workers can now ask the main conversation questions and report progress while working, and the main conversation can inspect and reply to its own nodes. Durable input revisions prevent a result computed before a reply from silently finishing the node. This delivery also repairs the completed runtime and authorization audit and keeps dependencies and local/CI toolchains aligned.
Closes #697
Closes #698
Closes #700
What changed
agenttool (observe,send,receive) with identities resolved from trusted session context. Main-to-node messages target an exact attempt. Node reports remain deliverable after their source node ends. Observation omits hidden reasoning and tool arguments/outputs.Evidence
Pre-integration evidence: the DAG feature passed its complete behavior/coverage gate and multiple Astra review rounds, with real SQLite concurrent-process/replay tests and live/recovered race barriers. The completed audit passed a fresh root typecheck (31 tasks), lint under the unchanged cap, authorization/installer regressions, and source final review. Both workstreams preserve their reproduced-failure regressions.
Isolated calls to configured Qwen, GLM, and DeepSeek providers exercised source-runtime agent-tool use and capability descriptions. The corrected GLM driver activates the prepared busy parent after durable question acceptance, allowing the node to wait for its answer; a deterministic regression verifies that order and live GLM passes in 32.13 seconds. DeepSeek covers late input and a simple task without tools. Active conversations and configuration were preserved.
Combined local verification passed the DAG behavior/coverage gate (1062 tests, 1 existing skip), the affected prepared-parent prompt phase (14 tests), HTTP exerciser (708 scenarios, no missing or skipped), generated-client idempotence, 31 typecheck tasks, and the unchanged lint cap. Before the additional worker extraction, the full workspace run recorded 8076 passing tests, 65 existing skips, 1 existing TODO, and 6 host-restricted failures (macOS file watching and MCP process-tree observation), with 4 associated watcher readiness errors. The corrected documentation peer graph reproduced all 649 baseline HTML routes. The final native Linux Test run 37085826494 executed the full workspace with 25/25 Turbo tasks successful and zero task-cache hits: 8101 tests passed, 71 skipped, 1 TODO, and 0 failed. Go tests and both generated-client drift checks passed. HTTP coverage, auth, and effect modes each passed all 236 scenarios (708 total), with no failures, skipped or missing scenarios. Both Linux and Windows E2E executed successfully; these first-round jobs had no verified-content proof hit.
A controlled pre-fix subprocess reproduced approximately 1.1 seconds of host event-loop blocking for a 100,000-character regex submission; the async regression and private compiled-worker smoke cover the deadline and responsiveness. Frozen worker and capture regressions, actual native Node execution and desktop asset/ASAR checks pass; private compiled backreference/null/deadline checks passed. Astra independently verified the frozen final commit
67ce58b7badea7d0a4dab7106c6c6699041e46ef(41 tests, 152 assertions; final helper check: 2 tests, 7 assertions). All four strict native Nix jobs passed run 37085826496: x86_64/aarch64 on Linux and Darwin, each building both normal CLI and desktop outputs. The transient ARM Linux cache-download failure was rerun without source or hash changes; the accepted attempt is recorded separately. Measured hashes match committed hashes, and the native synthetic merge has the same tree as the frozen source. Current-head required Typecheck, Unit Tests (linux), and full Linux/Windows E2E are all successful. The ready-event Test run 37085968901 and Typecheck run 37085968852 also passed on the same final head; native PR readback reports CLEAN with every reported check successful.Local full-suite failures are confined to sandbox-restricted native macOS file watching and MCP process-tree observation. They are not counted as passing or skipped by this change; native CI must supply acceptance. Docker is unavailable locally. Source-runtime calls and private builds are not acceptance of an installed
/usr/local/bin/opencodeartifact.Limits and release
The bounded audit does not claim exhaustive line or transitive-dependency coverage. Worker isolation bounds the production schema-validation path; it is not a claim that every host operation or historical #349 item is covered. Cached CDN objects, distributed orphan cleanup, and existing partial-refund policy are not represented as solved. Feishu deployments must set
FEISHU_VERIFICATION_TOKEN; no deployment credentials are changed.Merge requires current-head native evidence and final source review. Stable publication is a later operation: verify actual merge and all three Issue closures, review the resulting main tree, then dispatch the main-only stable release workflow. The next-version notes are included and validated.
Checklist
Merged main readback
PR #699 merged to
mainas10806c9ad70ff0c6a3965c7c3718062725c40c82on 2026-10-03 at 02:12:46 UTC. Issues #697, #698 and #700 are CLOSED with completion reason. The actual merge tree58e6871ce728e2ba8a58e32bf7a576450befe7a7equals the reviewed final head and native Nix test-merge tree. Astra independently reviewed actual main and found no new confirmed release blocker. SpecGit native readback reports completed with no diagnostics. Stable publication and release-asset acceptance remain separate operations.