Repository navigation
fix(interview): admit a fleet node's window only on the request sent to it - #1792
Merged
Merged
Conversation
Contributor
|
Claude Code Review — skipped: draft PR |
eldad-caura-ai
marked this pull request as ready for review
October 3, 2026 13:30
Contributor
Claude Code Review ✅ No issues found. Reviewed by |
eldad-caura-ai
force-pushed
the
fix/interview-fleet-window
branch
2 times, most recently
from
October 3, 2026 18:39
74fbcab to
0a2fae7
Compare
Member
Author
|
@erni-a plear rpprove |
erni-a
previously approved these changes
Oct 3, 2026
eldad-caura-ai
force-pushed
the
fix/interview-fleet-window
branch
from
October 3, 2026 18:51
0a2fae7 to
b1ce35b
Compare
Member
Author
Contributor
Claude Code Review ✅ No issues found. Reviewed by |
…to it An agent or install credential could submit an interview window for any fleet node of its tenant by naming the node and any command_id, which advanced that node's watermark and wrote its job doc (M-86, fleet-node half; #1788 bound adapter streams). A fleet node's window from an agent or install credential must now cite an interview_request the scheduler queued for that node and the node's heartbeat delivered. Storage claims the request in one conditional UPDATE, so each request admits one window, and the node's own result report still closes the command. Tenant credentials keep tenant-wide authority. The plugin already cites the delivered command's id, so its flow is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: eldad-caura <eldad@caura.ai>
eldad-caura-ai
force-pushed
the
fix/interview-fleet-window
branch
from
October 3, 2026 19:03
b1ce35b to
b56ccd7
Compare
Member
Author
|
@erni-a pl;ara rprpove |
erni-a
approved these changes
Oct 3, 2026
Merged
eldad-caura-ai
added a commit
that referenced
this pull request
Oct 3, 2026
…1794) ## Problem Migration 001 creates seventeen columns as `json`, but their models declare `JSONB` (the CAURA-595 drift). Every database built by the migration chain, CI's included, has `json`. Code written from the models fails only there: - `jsonb_typeof(fleet_commands.result)` raised `UndefinedFunctionError` in caura PR #1792's CI; - `backfill_embeddings` hit the same error on the `?` operator; - the metadata merge raised `CannotCoerceError` on `COALESCE(metadata, '{}'::jsonb)` until it gained a `::jsonb` cast. Nothing after migration 001 converts these columns. The existing model-vs-schema test (`test_models_match_the_migrated_schema.py`) checks tables and indexes only, so it never noticed. | Table | Columns | |---|---| | `memories` | `metadata` | | `documents` | `data` | | `audit_log` | `detail` | | `entities` | `attributes` | | `agents` | `search_profile` | | `analysis_reports` | `summary`, `hygiene`, `health`, `usage_data`, `issues`, `crystallization` | | `fleet_nodes` | `agents_json`, `tools_json`, `channels_json`, `metadata` | | `fleet_commands` | `payload`, `result` | The other eleven JSON columns, all added after 001, are `jsonb` in both the models and the migrations. They are unchanged. ## Change - **Models.** The seventeen columns now declare `postgresql.JSON`, which matches what the migration chain builds and what CI tests. `postgresql.JSON` keeps `.astext`; `.as_float()` and `.as_boolean()` come from the generic JSON type. Those three are the only JSON operators the ORM uses on these columns. - **Regression test.** A new storage test compares every JSON-family model column with `information_schema.columns` in the migrated schema. It fails on any `json`/`jsonb` disagreement, so the next drift fails CI. - **Comments.** Comments that said the model declared `JSONB` now describe the real situation. That includes the claim filter caura PR #1792 added, which compares `fleet_commands.result` as text so it works on both types. ## Not in this PR (approved choice) There is no migration. Converting these columns to `jsonb` would rewrite `memories`, `documents`, `audit_log` and `entities` under an exclusive lock, and `jsonb` also normalises stored JSON. A database that `create_all` built and that was stamped before the chain was authoritative may still hold `jsonb`. So statements on these columns must keep working on both types, which is why the existing `::jsonb` casts stay. ## Verification - Tests first: the test-only push ([run 37146396849](https://github.com/caura-ai/caura/actions/runs/37146396849/job/111271126592)) failed only the new test, with 674 passing. It listed exactly the seventeen columns above as `model jsonb, schema json`, matching the inventory taken from the files. The model change is now amended into the same single commit. - No repository scripts, dependency installs, tests or builds were run on Eldad's Mac under its safety hold. The inventory came from parsing the model and migration files. CI runs the suites. One signed-off commit. Do not merge or enable auto-merge; Eldad merges after review. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: eldad-caura <eldad@caura.ai> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
eldad-caura-ai
pushed a commit
that referenced
this pull request
Oct 3, 2026
🤖 I have created a release *beep* *boop* --- <details><summary>backend: 3.21.2</summary> ## [3.21.2](backend-v3.21.1...backend-v3.21.2) (2026-10-03) ### Bug Fixes * **graph:** hide graph data mined from soft-deleted memories from every reader ([#1796](#1796)) ([97315d0](97315d0)) * **interview:** admit a fleet node's window only on the request sent to it ([#1792](#1792)) ([4c56b8e](4c56b8e)) * **models:** declare the JSON columns migration 001 creates as json ([#1794](#1794)) ([e0a0a9b](e0a0a9b)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Signed-off-by: release-please[bot] <release-please[bot]@users.noreply.github.com> Co-authored-by: caura-deploy-bot[bot] <265395343+caura-deploy-bot[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Audit finding
Finishes M-86. caura PR #1788 bound adapter streams (
cc:/cursor:node ids) to the agent that advances them. Fleet-node windows were still open: an agent or install credential could submit a window for any fleet node of its tenant by naming the node and anycommand_id. That advanced the node's watermark, which only moves forward, and wrote its job doc.Change
node_id) from an agent or install credential must cite theinterview_requestthe scheduler queued for that node, and the node's heartbeat must have delivered it (acked). Anything else gets 403INTERVIEW_REQUEST_REQUIREDbefore the watermark or job doc is touched. This is the same "agent or install credential" test fix(interview): accept adapter streams and bind them to their agent #1788 applies to adapter streams.interview_request,acked, noresultyet. The claim writes a marker intoresult, so a second window citing the same id is refused. A used id stops being secret, because the job doc and watermark record it. The node's own result report still overwrites the marker and closes the command.plugin/src/heartbeat.ts), and the scheduler only looks atpendingcommands, so neither changes. A failed submit is retried by the scheduler as a fresh command, as before.Why this relies on caura PR #1789
The request id is the credential here. Since #1789, an agent or install credential can only list or receive commands for nodes bound to it, so it cannot read another node's pending
interview_requestbefore that node uses it.Verification
main, with 8644 passing. In each one the unfixed route answeredacceptedand moved the node's watermark. The tenant guard and the updated attribution test passed. That step stopped the job before the storage suite ran. The fix is now amended into the same single commit.One signed-off commit. Do not merge or enable auto-merge; Eldad merges after review.
🤖 Generated with Claude Code