SECURITY: agent container tokens can start new AI turns and read other turns' prompts #980

Open
opened 2026-10-03 06:46:57 +00:00 by kayg · 14 comments
Owner

Found (AI plan review, 2026-10-03), needs a probe to confirm

data_user() in crates/plugins/ai/src/routes.rs:1264 checks only that the caller has the data scope. An Agent turn's own container token is a data session (issue_agent_session, crates/calternal-auth/src/store.rs:1874). So an agent running inside its container appears able to:

  1. POST /api/v1/ai/turns: start more turns, each with a new write token (bounded only by MAX_ACTIVE_TURNS_PER_USER = 9), so a turn can spawn turns;
  2. GET /api/v1/ai/turns and turn output/events: read the User's other prompts and agent output, which the agent was never handed;
  3. other /ai/* routes behind data_user (lines 368, 411, 912, 949, 986, 1040, 1086): check each one.
    Ask tokens are read-only (calternal-auth/src/api.rs:379), so they cannot start turns, but they may still read turn history; check.

Fix

  • Mark agent and ask sessions with a session kind the plugin context can see (do not infer it from scopes). Reject agent/ask sessions on every /api/v1/ai/* route except the ones a running turn needs for itself (its own events/output if any), and scope those to its own turn ID.
  • Classify each /ai/* route in the isolation/authority matrix (#472/#331, action registry authority #833).

Tests

  • Adversarial probe in tests/adversarial/: with a real agent session token, call each /ai/* route and expect 403 (or own-turn-only).
  • Regression test in the AI plugin for each route.

Blocks a merge class: authorization hole. Model: Sol medium (auth).

## Found (AI plan review, 2026-10-03), needs a probe to confirm `data_user()` in `crates/plugins/ai/src/routes.rs:1264` checks only that the caller has the `data` scope. An Agent turn's own container token is a `data` session (`issue_agent_session`, `crates/calternal-auth/src/store.rs:1874`). So an agent running inside its container appears able to: 1. `POST /api/v1/ai/turns`: start more turns, each with a new write token (bounded only by MAX_ACTIVE_TURNS_PER_USER = 9), so a turn can spawn turns; 2. `GET /api/v1/ai/turns` and turn output/events: read the User's other prompts and agent output, which the agent was never handed; 3. other `/ai/*` routes behind `data_user` (lines 368, 411, 912, 949, 986, 1040, 1086): check each one. Ask tokens are read-only (`calternal-auth/src/api.rs:379`), so they cannot start turns, but they may still read turn history; check. ## Fix - Mark agent and ask sessions with a session kind the plugin context can see (do not infer it from scopes). Reject agent/ask sessions on every `/api/v1/ai/*` route except the ones a running turn needs for itself (its own events/output if any), and scope those to its own turn ID. - Classify each `/ai/*` route in the isolation/authority matrix (#472/#331, action registry authority #833). ## Tests - Adversarial probe in `tests/adversarial/`: with a real agent session token, call each `/ai/*` route and expect 403 (or own-turn-only). - Regression test in the AI plugin for each route. Blocks a merge class: authorization hole. Model: Sol medium (auth).
Author
Owner

Resuming #980 on branch job/agentscope-980. Base/checkpoint SHA: a598f1d79f. Reviewing the stored session actor, propagation into plugin context, AI route denial, migration compatibility, and focused regression coverage. No dependency additions are planned. Full adversarial matrices are reserved for the merge round under the current verification policy.

Resuming #980 on branch job/agentscope-980. Base/checkpoint SHA: a598f1d79fee00cde2e85f5ea065c4447aacdf6e. Reviewing the stored session actor, propagation into plugin context, AI route denial, migration compatibility, and focused regression coverage. No dependency additions are planned. Full adversarial matrices are reserved for the merge round under the current verification policy.
Author
Owner

Source finding: before the checkpoint, data_user() in the AI routes checked only data and the User ID. issue_agent_session() issued DATA, so the actor boundary was absent. This is a source-confirmed gap; I did not execute the pre-fix bypass.

Checkpoint review: the container runtime sends output through the server-owned runtime channel and makes no /api/v1/ai/* call. Decision: keep all ten AI operations User-only, including own-turn events. No own-turn exception is needed. Auth records Agent/Ask at issuance; migration 0012 classifies legacy Ask rows once. Request-time classification never derives from scopes.

Merged origin/dev once before gates (76a26fa36); origin/dev still ends auth migrations at 0011. Added one named rejection regression per AI operation, retained malformed-body denial, added Ask with broad scopes, and added auth scope-independence coverage. Added the route authority table in docs/ai-runtime.md. Restricted the inherited local probe fixture writer to disposable target/tmp harness data. No dependency additions.

Source finding: before the checkpoint, `data_user()` in the AI routes checked only `data` and the User ID. `issue_agent_session()` issued DATA, so the actor boundary was absent. This is a source-confirmed gap; I did not execute the pre-fix bypass. Checkpoint review: the container runtime sends output through the server-owned runtime channel and makes no `/api/v1/ai/*` call. Decision: keep all ten AI operations User-only, including own-turn events. No own-turn exception is needed. Auth records Agent/Ask at issuance; migration 0012 classifies legacy Ask rows once. Request-time classification never derives from scopes. Merged origin/dev once before gates (76a26fa36); origin/dev still ends auth migrations at 0011. Added one named rejection regression per AI operation, retained malformed-body denial, added Ask with broad scopes, and added auth scope-independence coverage. Added the route authority table in docs/ai-runtime.md. Restricted the inherited local probe fixture writer to disposable target/tmp harness data. No dependency additions.
Author
Owner

Checkpoint finding: production build_live_app() registered auth migrations 1–11, then used SqliteAuthStore::from_pools(), which does not run the SQLx migrator. Migration 0012 was absent. New Ask sessions write installation_type=ask, but the production table permitted only human/agent.

A disposable in-memory SQLite compatibility check applied the actual production include_str list. Before the fix it returned:

FAIL: production migration list cannot store an Ask actor: CHECK constraint failed: installation_type IN ('human','agent')

After registering 0012:

PASS: production migration list stores an Ask actor

The existing list is now a shared private auth_migrations() helper used by startup and server_auth_migrations_support_container_actors. The regression checks real Agent/Ask issuance on that schema without SQLx's separate auth migrator. Independent read-only review confirmed the registration fix and no additional actor-boundary blocker. Rust gates are compiling with four build jobs. Also corrected the Files Agent test fixture's actor from User to Agent, without changing any expected behavior.

Checkpoint finding: production `build_live_app()` registered auth migrations 1–11, then used `SqliteAuthStore::from_pools()`, which does not run the SQLx migrator. Migration 0012 was absent. New Ask sessions write installation_type=ask, but the production table permitted only human/agent. A disposable in-memory SQLite compatibility check applied the actual production include_str list. Before the fix it returned: ``` FAIL: production migration list cannot store an Ask actor: CHECK constraint failed: installation_type IN ('human','agent') ``` After registering 0012: ``` PASS: production migration list stores an Ask actor ``` The existing list is now a shared private `auth_migrations()` helper used by startup and `server_auth_migrations_support_container_actors`. The regression checks real Agent/Ask issuance on that schema without SQLx's separate auth migrator. Independent read-only review confirmed the registration fix and no additional actor-boundary blocker. Rust gates are compiling with four build jobs. Also corrected the Files Agent test fixture's actor from User to Agent, without changing any expected behavior.
Author
Owner

Auth gate finding: Clippy passed. The first auth test run returned:

test result: FAILED. 67 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.83s

The only failure was store::tests::all_auth_migrations_run_in_order_on_an_empty_database: actual successful migrations were [1..12], but the checkpoint left the expected sequence at [1..11]. The new actor issuance, scope-independence and legacy Ask conversion regressions all passed.

Expectation change for review: extend the explicit expected migration sequence from 1..11 to 1..12, because #980 adds migration 0012 to store the Ask actor independently of scopes. No existing migration is removed or reordered. No HTTP status or authorization expectation is changed. Re-running the affected auth gates after this fix, then continuing the remaining per-crate gates. The preliminary AI-only build was deliberately interrupted after a prolonged compiler filesystem-I/O stall; it produced no test result and is not counted as verification.

Auth gate finding: Clippy passed. The first auth test run returned: ``` test result: FAILED. 67 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 30.83s ``` The only failure was `store::tests::all_auth_migrations_run_in_order_on_an_empty_database`: actual successful migrations were [1..12], but the checkpoint left the expected sequence at [1..11]. The new actor issuance, scope-independence and legacy Ask conversion regressions all passed. Expectation change for review: extend the explicit expected migration sequence from 1..11 to 1..12, because #980 adds migration 0012 to store the Ask actor independently of scopes. No existing migration is removed or reordered. No HTTP status or authorization expectation is changed. Re-running the affected auth gates after this fix, then continuing the remaining per-crate gates. The preliminary AI-only build was deliberately interrupted after a prolonged compiler filesystem-I/O stall; it produced no test result and is not counted as verification.
Author
Owner

Verification finding: cargo test -p calternal-search -- --test-threads=4 returned exit 101. Its library suite passed (36 passed, 1 ignored), Ask evaluation and citations passed, but the indexer suite returned:

test result: FAILED. 18 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 48.56s

Failures: a_file_trashed_during_its_add_never_appears_in_search, search_drops_a_hit_whose_file_is_gone_and_queues_its_removal, watcher_indexes_create_modify_rename_and_delete. Each failed the existing wait_for_hit helper (250 polls separated by 20 ms). Search changes in this job only fill the new context actor field. No assertions or timeouts were changed; host load is a possible cause, not established. This remains a verification gap.

The initial focused server migration build returned E0432 for calternal_plugin::SessionActor, despite its unconditional public declaration and a single local dependency confirmed by source and cargo tree. The independent reviewer found no dependency mismatch. A targeted dependency clean and cache-disabled retry is running; stale shared cache metadata is suspected, not established.

Verification finding: `cargo test -p calternal-search -- --test-threads=4` returned exit 101. Its library suite passed (36 passed, 1 ignored), Ask evaluation and citations passed, but the indexer suite returned: ```text test result: FAILED. 18 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 48.56s ``` Failures: `a_file_trashed_during_its_add_never_appears_in_search`, `search_drops_a_hit_whose_file_is_gone_and_queues_its_removal`, `watcher_indexes_create_modify_rename_and_delete`. Each failed the existing `wait_for_hit` helper (250 polls separated by 20 ms). Search changes in this job only fill the new context actor field. No assertions or timeouts were changed; host load is a possible cause, not established. This remains a verification gap. The initial focused server migration build returned E0432 for `calternal_plugin::SessionActor`, despite its unconditional public declaration and a single local dependency confirmed by source and cargo tree. The independent reviewer found no dependency mismatch. A targeted dependency clean and cache-disabled retry is running; stale shared cache metadata is suspected, not established.
Author
Owner

Atomic commits: a70c13d90 registers auth migration 0012 on production startup and adds a focused schema regression; 226742acb corrects the Files container fixture actor. Format passes and the actual production migration list passed the SQLite compatibility check recorded above. The focused Rust server test is still compiling, and the remaining per-crate gates are pending. These commits preserve reviewable source progress; they do not claim completed verification.

Atomic commits: `a70c13d90` registers auth migration 0012 on production startup and adds a focused schema regression; `226742acb` corrects the Files container fixture actor. Format passes and the actual production migration list passed the SQLite compatibility check recorded above. The focused Rust server test is still compiling, and the remaining per-crate gates are pending. These commits preserve reviewable source progress; they do not claim completed verification.
Author
Owner

Implementation report for #980. Verification is incomplete. Head: 226742acb93cbd3effd60a584b36d8232a74508e. Branch: job/agentscope-980. No push or deployment.

Built:

  • Finished checkpoint actor isolation: stored User/Agent/Ask identity reaches plugin request context independently of scopes; unclassified contexts fail closed. All ten AI operations reject Agent and Ask, before parsing ordinary request bodies; handler helpers also check the actor.
  • Added ten named route rejection regressions plus malformed-body coverage, broad-scope Ask coverage, and auth scope-independence coverage. The server regression uses real issued container sessions.
  • Fixed the omitted production registration of auth migration 0012. Startup and the focused schema test share the same migration list, and the test checks real Agent/Ask issuance without SQLx's separate migrator.
  • Corrected the Files Agent fixture, documented the route authority matrix and actor invariants, and restricted the inherited probe fixture writer to disposable harness data.

Files (docs/DESIGN.md came from the authorized origin/dev merge):

  • crates/calternal-auth/migrations/0012_ask_session_type.sql
  • crates/calternal-auth/src/lib.rs
  • crates/calternal-auth/src/store.rs
  • crates/calternal-collab/tests/hostile_clients.rs
  • crates/calternal-collab/tests/journal_race.rs
  • crates/calternal-collab/tests/restart_epoch.rs
  • crates/calternal-collab/tests/shared_notes.rs
  • crates/calternal-collab/tests/two_clients.rs
  • crates/calternal-plugin/src/lib.rs
  • crates/calternal-search/src/saved.rs
  • crates/calternal-server/src/main.rs
  • crates/calternal-server/src/wire.rs
  • crates/plugins/ai/src/lib.rs
  • crates/plugins/ai/src/routes.rs
  • crates/plugins/calendar/src/routes.rs
  • crates/plugins/files/src/lib.rs
  • crates/plugins/notes/src/bookmarks.rs
  • crates/plugins/notes/src/lib.rs
  • docs/DESIGN.md
  • docs/ai-runtime.md
  • tests/adversarial/ai_container_tokens.py
  • tests/adversarial/run.sh

Decisions:

  • Preserve existing Web/Installation transport kinds. Add SessionActor::User/Agent/Ask for the actor distinction; User includes browser and human Installation sessions.
  • No own-turn exception: the container runtime makes no AI-route call and sends output through the server-owned exec channel. All AI routes stay User-only.
  • Keep migration 0012, checked free on origin/dev before final gates. It reclassifies legacy Ask rows once; runtime classification reads only the stored actor.
  • Expectation change for review: the migration sequence now explicitly expects 1..12 instead of 1..11 because this job adds the Ask actor schema. Earlier versions stay in order; no HTTP status or authorization assertion was changed.

Verification (verbatim result lines; full command output is retained under artifacts/):
cargo fmt --check: exit 0; no output.

cargo clippy -p calternal-auth --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 36s

cargo test -p calternal-auth -- --test-threads=4 (exit 0):

test result: ok. 68 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 38.63s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 38s

cargo test -p calternal-plugin -- --test-threads=4 (exit 0):

test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 25.26s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-ai --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 25m 59s

cargo test -p calternal-plugin-ai -- --test-threads=4 (exit 0):

test result: ok. 23 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.17s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-collab --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 55s

cargo test -p calternal-collab -- --test-threads=4 (exit 0):

test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.35s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.68s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.97s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 76.63s
test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 12.71s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.28s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.78s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.51s
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.29s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 149.95s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 21.42s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-search --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 20s

cargo test -p calternal-search -- --test-threads=4 (exit 101):

test result: ok. 36 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 37.79s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.43s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s
test result: FAILED. 18 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 48.56s

cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings: no result; see pending checks.

cargo test -p calternal-plugin-calendar -- --test-threads=4: not run.

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings: not run.

cargo test -p calternal-plugin-files -- --test-threads=4: not run.

cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings: not run.

cargo test -p calternal-plugin-notes -- --test-threads=4: not run.

cargo clippy -p calternal-server --all-targets -- -D warnings: not run.

cargo test -p calternal-server -- --test-threads=4: not run.

Resolved gate finding: the first auth test run returned 67 passed; 1 failed because the checkpoint left the migration expectation at 0011. After the documented schema expectation update, all 68 passed. The preliminary AI-only build was interrupted during a long compiler I/O stall and produced no test result; it is not counted as verification.

Known gaps:

  • The pre-fix API bypass was not executed. The finding was confirmed by tracing source authority from issuance through the old data_user helper.
  • The real-server adversarial probe and full matrices remain for the merge round under the 2026-10-02 verification policy. No UI files changed; no web gates or screenshots are required. No performance measurement ran: this is an authorization issue.

For the merge round:

  • bash tests/adversarial/run.sh: run the inherited container-token probe with the combined build; every AI route must refuse Agent/Ask, retain the fixture turn state and hide the fixture prompt. Known oversized bodies may return 413. The User must still read the fixture.

Cleanup: cargo clean completed (exit 0), and inherited apps/web/build output was removed. Working tree is clean.

     Removed 19423 files, 12.3GiB total

Remaining verification:

  • Calendar, Files, Notes and Server per-crate clippy/test gates have no completed results. Re-run their commands listed above against this head.
  • cargo test -p calternal-server server_auth_migrations_support_container_actors -- --test-threads=4: confirm the production migration list permits explicit Agent and Ask issuance.
  • cargo test -p calternal-server live_apps_run_in_separate_processes -- --test-threads=4: confirm the live-app GET/POST regression rejects actual issued Agent/Ask sessions.
  • cargo test -p calternal-search --test indexer -- --test-threads=4: investigate the three wait_for_hit failures without changing expectations. Each exhausted 250 polls separated by 20 ms; host load is possible, not established.

Build finding:
The first focused server build failed with an unresolved calternal_plugin::SessionActor import. The type is public and unconditional, and cargo tree has one local dependency. The read-only reviewer found no source/dependency mismatch. After a targeted dependency clean with RUSTC_WRAPPER=, the subsequent compilation output did not show that import failure, but the rebuild was stopped at the time cap without a test result. Stale shared cache metadata is suspected, not established.

Independent review: no remaining actionable source concern. The reviewer checked migration field/constraint/index preservation, production registration, scope-independent runtime classification, all ten route guards and fixture actors. Doc comments were re-read before reporting.

UX gaps closed / left: not applicable; no UI changes.

Time cap: the focused server rebuild and queued Calendar clippy command were deliberately stopped (exit 143). No test result was produced for the focused server retry. Calendar/Files/Notes/Server gates remain incomplete. The initial focused server build returned 101; its unresolved-import output is retained in artifacts/server-migration-focused.log.

Base synchronization: fetched and merged origin/dev once before final gates (76a26fa36), as requested. No push, deployment or issue closure.

Implementation report for #980. Verification is incomplete. Head: `226742acb93cbd3effd60a584b36d8232a74508e`. Branch: `job/agentscope-980`. No push or deployment. Built: - Finished checkpoint actor isolation: stored User/Agent/Ask identity reaches plugin request context independently of scopes; unclassified contexts fail closed. All ten AI operations reject Agent and Ask, before parsing ordinary request bodies; handler helpers also check the actor. - Added ten named route rejection regressions plus malformed-body coverage, broad-scope Ask coverage, and auth scope-independence coverage. The server regression uses real issued container sessions. - Fixed the omitted production registration of auth migration 0012. Startup and the focused schema test share the same migration list, and the test checks real Agent/Ask issuance without SQLx's separate migrator. - Corrected the Files Agent fixture, documented the route authority matrix and actor invariants, and restricted the inherited probe fixture writer to disposable harness data. Files (docs/DESIGN.md came from the authorized origin/dev merge): - `crates/calternal-auth/migrations/0012_ask_session_type.sql` - `crates/calternal-auth/src/lib.rs` - `crates/calternal-auth/src/store.rs` - `crates/calternal-collab/tests/hostile_clients.rs` - `crates/calternal-collab/tests/journal_race.rs` - `crates/calternal-collab/tests/restart_epoch.rs` - `crates/calternal-collab/tests/shared_notes.rs` - `crates/calternal-collab/tests/two_clients.rs` - `crates/calternal-plugin/src/lib.rs` - `crates/calternal-search/src/saved.rs` - `crates/calternal-server/src/main.rs` - `crates/calternal-server/src/wire.rs` - `crates/plugins/ai/src/lib.rs` - `crates/plugins/ai/src/routes.rs` - `crates/plugins/calendar/src/routes.rs` - `crates/plugins/files/src/lib.rs` - `crates/plugins/notes/src/bookmarks.rs` - `crates/plugins/notes/src/lib.rs` - `docs/DESIGN.md` - `docs/ai-runtime.md` - `tests/adversarial/ai_container_tokens.py` - `tests/adversarial/run.sh` Decisions: - Preserve existing Web/Installation transport kinds. Add SessionActor::User/Agent/Ask for the actor distinction; User includes browser and human Installation sessions. - No own-turn exception: the container runtime makes no AI-route call and sends output through the server-owned exec channel. All AI routes stay User-only. - Keep migration 0012, checked free on origin/dev before final gates. It reclassifies legacy Ask rows once; runtime classification reads only the stored actor. - Expectation change for review: the migration sequence now explicitly expects 1..12 instead of 1..11 because this job adds the Ask actor schema. Earlier versions stay in order; no HTTP status or authorization assertion was changed. Verification (verbatim result lines; full command output is retained under artifacts/): `cargo fmt --check`: exit 0; no output. `cargo clippy -p calternal-auth --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 36s ``` `cargo test -p calternal-auth -- --test-threads=4` (exit 0): ```text test result: ok. 68 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 38.63s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 38s ``` `cargo test -p calternal-plugin -- --test-threads=4` (exit 0): ```text test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 25.26s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-ai --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 25m 59s ``` `cargo test -p calternal-plugin-ai -- --test-threads=4` (exit 0): ```text test result: ok. 23 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.17s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-collab --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 55s ``` `cargo test -p calternal-collab -- --test-threads=4` (exit 0): ```text test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.35s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.68s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.97s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 76.63s test result: ok. 11 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 12.71s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.28s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.78s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.51s test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.29s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 149.95s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 21.42s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-search --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 20s ``` `cargo test -p calternal-search -- --test-threads=4` (exit 101): ```text test result: ok. 36 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 37.79s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.43s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.16s test result: FAILED. 18 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 48.56s ``` `cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings`: no result; see pending checks. `cargo test -p calternal-plugin-calendar -- --test-threads=4`: not run. `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings`: not run. `cargo test -p calternal-plugin-files -- --test-threads=4`: not run. `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings`: not run. `cargo test -p calternal-plugin-notes -- --test-threads=4`: not run. `cargo clippy -p calternal-server --all-targets -- -D warnings`: not run. `cargo test -p calternal-server -- --test-threads=4`: not run. Resolved gate finding: the first auth test run returned `67 passed; 1 failed` because the checkpoint left the migration expectation at 0011. After the documented schema expectation update, all 68 passed. The preliminary AI-only build was interrupted during a long compiler I/O stall and produced no test result; it is not counted as verification. Known gaps: - The pre-fix API bypass was not executed. The finding was confirmed by tracing source authority from issuance through the old data_user helper. - The real-server adversarial probe and full matrices remain for the merge round under the 2026-10-02 verification policy. No UI files changed; no web gates or screenshots are required. No performance measurement ran: this is an authorization issue. For the merge round: - `bash tests/adversarial/run.sh`: run the inherited container-token probe with the combined build; every AI route must refuse Agent/Ask, retain the fixture turn state and hide the fixture prompt. Known oversized bodies may return 413. The User must still read the fixture. Cleanup: `cargo clean` completed (exit 0), and inherited `apps/web/build` output was removed. Working tree is clean. ```text Removed 19423 files, 12.3GiB total ``` Remaining verification: - Calendar, Files, Notes and Server per-crate clippy/test gates have no completed results. Re-run their commands listed above against this head. - `cargo test -p calternal-server server_auth_migrations_support_container_actors -- --test-threads=4`: confirm the production migration list permits explicit Agent and Ask issuance. - `cargo test -p calternal-server live_apps_run_in_separate_processes -- --test-threads=4`: confirm the live-app GET/POST regression rejects actual issued Agent/Ask sessions. - `cargo test -p calternal-search --test indexer -- --test-threads=4`: investigate the three `wait_for_hit` failures without changing expectations. Each exhausted 250 polls separated by 20 ms; host load is possible, not established. Build finding: The first focused server build failed with an unresolved `calternal_plugin::SessionActor` import. The type is public and unconditional, and cargo tree has one local dependency. The read-only reviewer found no source/dependency mismatch. After a targeted dependency clean with `RUSTC_WRAPPER=`, the subsequent compilation output did not show that import failure, but the rebuild was stopped at the time cap without a test result. Stale shared cache metadata is suspected, not established. Independent review: no remaining actionable source concern. The reviewer checked migration field/constraint/index preservation, production registration, scope-independent runtime classification, all ten route guards and fixture actors. Doc comments were re-read before reporting. UX gaps closed / left: not applicable; no UI changes. Time cap: the focused server rebuild and queued Calendar clippy command were deliberately stopped (exit 143). No test result was produced for the focused server retry. Calendar/Files/Notes/Server gates remain incomplete. The initial focused server build returned 101; its unresolved-import output is retained in artifacts/server-migration-focused.log. Base synchronization: fetched and merged `origin/dev` once before final gates (`76a26fa36`), as requested. No push, deployment or issue closure.
Author
Owner

Resumed finish verification on job/agentscope-980, starting head 226742acb93cbd3effd60a584b36d8232a74508e. Fetched and merged origin/dev once before gates; only docs/DESIGN.md changed. Remaining checks: Calendar, Files, Notes and Server clippy/tests, one server build, focused live-app regression and the existing AI_CONTAINER_ONLY local disposable-server denial probe. No UI changes; #980 requests no screenshots. Known prior Search failures will be investigated against #965 without changing expectations. Build jobs limited to 3. No push or deployment.

Resumed finish verification on `job/agentscope-980`, starting head `226742acb93cbd3effd60a584b36d8232a74508e`. Fetched and merged origin/dev once before gates; only docs/DESIGN.md changed. Remaining checks: Calendar, Files, Notes and Server clippy/tests, one server build, focused live-app regression and the existing AI_CONTAINER_ONLY local disposable-server denial probe. No UI changes; #980 requests no screenshots. Known prior Search failures will be investigated against #965 without changing expectations. Build jobs limited to 3. No push or deployment.
Author
Owner

Finish verification checkpoint. Head 5827f3a25d4fdf1d787b1dba28483fe1616ef911; origin/dev base f06679b11cde29cc0b7120fdab5f721389caf695. Server Clippy completed with exit 0. The earlier unresolved SessionActor import did not recur after the clean rebuild. This does not establish its earlier cause. Auth migration 0012 is still free on origin/dev. Server test compilation is in progress; Notes, Files, Calendar and local denial probe remain pending.

cargo clippy -p calternal-server --all-targets -- -D warnings (verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s
Finish verification checkpoint. Head `5827f3a25d4fdf1d787b1dba28483fe1616ef911`; origin/dev base `f06679b11cde29cc0b7120fdab5f721389caf695`. Server Clippy completed with exit 0. The earlier unresolved SessionActor import did not recur after the clean rebuild. This does not establish its earlier cause. Auth migration 0012 is still free on origin/dev. Server test compilation is in progress; Notes, Files, Calendar and local denial probe remain pending. `cargo clippy -p calternal-server --all-targets -- -D warnings` (verbatim): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s ```
Author
Owner

Verification progress: documentation commit 8af045c73 records the focused #980 commands in docs/ai-runtime.md. Server Clippy passed (recorded above), format passed, production web build passed, and media runtime preparation passed. Server tests are still compiling; no test result exists yet. The server rustc process has a thread in folio_ disk-page wait and read_bytes advanced from 301527040 to 469536768 between observations. This is evidence of I/O progress, not a source error. The single bounded run continues with CARGO_BUILD_JOBS=3. Notes, Files, Calendar, Search diagnostic and local AI denial probe remain pending. No push or deployment.

Verification progress: documentation commit `8af045c73` records the focused #980 commands in docs/ai-runtime.md. Server Clippy passed (recorded above), format passed, production web build passed, and media runtime preparation passed. Server tests are still compiling; no test result exists yet. The server rustc process has a thread in `folio_` disk-page wait and read_bytes advanced from 301527040 to 469536768 between observations. This is evidence of I/O progress, not a source error. The single bounded run continues with CARGO_BUILD_JOBS=3. Notes, Files, Calendar, Search diagnostic and local AI denial probe remain pending. No push or deployment.
Author
Owner

Server gate result at source head 8af045c73: migration regression passed. The full Server suite returned exit 101:

test result: FAILED. 107 passed; 1 failed; 3 ignored; 0 measured; 0 filtered out; finished in 53.61s

The single failure was wire::tests::live_apps_run_in_separate_processes, whose full_app_setup_session_config_and_backup child reached the unchanged User archive-job poll at wire.rs:7768 and returned Elapsed(()). Its five-second timeout block is identical on origin/dev (there at wire.rs:7670–7679). This occurs after the #980 Agent/Ask assertions.

Focused diagnostic, using the built test binary with unchanged source and expectations:
/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_server-85d5c4e45db298f9 wire::tests::full_app_setup_session_config_and_backup --exact --ignored --test-threads=1

test wire::tests::full_app_setup_session_config_and_backup ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 110 filtered out; finished in 10.70s

Thus the real-issued-session regression passes. The initial suite failure remains in the report; it is not relabeled as a passing full suite. Shared-host scheduling or background Index work (#965) could delay the archive job, but the cause is not established by this diagnostic. No timeout or assertion was changed. Remaining per-crate gates continue.

Server gate result at source head `8af045c73`: migration regression passed. The full Server suite returned exit 101: ```text test result: FAILED. 107 passed; 1 failed; 3 ignored; 0 measured; 0 filtered out; finished in 53.61s ``` The single failure was `wire::tests::live_apps_run_in_separate_processes`, whose `full_app_setup_session_config_and_backup` child reached the unchanged User archive-job poll at wire.rs:7768 and returned `Elapsed(())`. Its five-second timeout block is identical on origin/dev (there at wire.rs:7670–7679). This occurs after the #980 Agent/Ask assertions. Focused diagnostic, using the built test binary with unchanged source and expectations: `/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_server-85d5c4e45db298f9 wire::tests::full_app_setup_session_config_and_backup --exact --ignored --test-threads=1` ```text test wire::tests::full_app_setup_session_config_and_backup ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 110 filtered out; finished in 10.70s ``` Thus the real-issued-session regression passes. The initial suite failure remains in the report; it is not relabeled as a passing full suite. Shared-host scheduling or background Index work (#965) could delay the archive job, but the cause is not established by this diagnostic. No timeout or assertion was changed. Remaining per-crate gates continue.
Author
Owner

Notes verification: Clippy passed. The full four-thread test run returned exit 101:

test result: FAILED. 166 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 223.59s

The single failure is exactly #954: tests::daily_and_composer_preserve_unrelated_bytes, lib.rs:9420, left: 404, right: 200. The focused unchanged binary diagnostic passed:

test tests::daily_and_composer_preserve_unrelated_bytes ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 166 filtered out; finished in 1.91s

Command: /mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_plugin_notes-43dde880eb034836 tests::daily_and_composer_preserve_unrelated_bytes --exact --test-threads=1.
This branch only adds SessionActor::User fields in Notes test fixtures; it does not change production Notes code, this assertion, or its timeout. Report the full-run failure under #954 rather than claiming a clean full suite. Files gates are in progress. Current head 9799241a8 includes only verification documentation changes since the last source head.

Notes verification: Clippy passed. The full four-thread test run returned exit 101: ```text test result: FAILED. 166 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 223.59s ``` The single failure is exactly #954: `tests::daily_and_composer_preserve_unrelated_bytes`, lib.rs:9420, `left: 404`, `right: 200`. The focused unchanged binary diagnostic passed: ```text test tests::daily_and_composer_preserve_unrelated_bytes ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 166 filtered out; finished in 1.91s ``` Command: `/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_plugin_notes-43dde880eb034836 tests::daily_and_composer_preserve_unrelated_bytes --exact --test-threads=1`. This branch only adds `SessionActor::User` fields in Notes test fixtures; it does not change production Notes code, this assertion, or its timeout. Report the full-run failure under #954 rather than claiming a clean full suite. Files gates are in progress. Current head `9799241a8` includes only verification documentation changes since the last source head.
Author
Owner

Verification checkpoint at 9799241a8: all four remaining Clippy gates passed. Files tests passed, including the atomic-write/reconcile storm (#942 did not reproduce). Calendar test build is in progress. Search diagnostic, one server build and local denial probe remain pending. No Rust source changed during this finish-verification job.

cargo clippy -p calternal-server --all-targets -- -D warnings (exit 0, verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s

cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings (exit 0, verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 48s

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings (exit 0, verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 44s

cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings (exit 0, verbatim):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 55s

cargo test -p calternal-plugin-files -- --test-threads=4 (exit 0, verbatim):

test tests::internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm ... ok
test result: ok. 146 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 176.83s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Verification checkpoint at `9799241a8`: all four remaining Clippy gates passed. Files tests passed, including the atomic-write/reconcile storm (#942 did not reproduce). Calendar test build is in progress. Search diagnostic, one server build and local denial probe remain pending. No Rust source changed during this finish-verification job. `cargo clippy -p calternal-server --all-targets -- -D warnings` (exit 0, verbatim): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s ``` `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings` (exit 0, verbatim): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 48s ``` `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` (exit 0, verbatim): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 44s ``` `cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings` (exit 0, verbatim): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 55s ``` `cargo test -p calternal-plugin-files -- --test-threads=4` (exit 0, verbatim): ```text test tests::internal_temp_paths_never_enter_index_during_atomic_write_reconcile_storm ... ok test result: ok. 146 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 176.83s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ```
Author
Owner

Finish verification report for #980. Branch: job/agentscope-980. Head: 9799241a8908b760ba8bbad26938014cdce163f2. Merged origin/dev once before gates (base f06679b11cde29cc0b7120fdab5f721389caf695). No push, deployment or issue closure.

Built and verified:

  • Finished the pending Server, Notes, Files and Calendar Clippy/test runs, with three build jobs and four test threads. All Clippy gates passed. Files and Calendar tests passed.
  • The production auth migration regression passed. The focused live-app regression passed with real issued Agent and Ask sessions. Search indexer tests passed, including all three cases that failed in the previous session.
  • Built the server once and ran the existing focused local container-token denial probe against this build. Results follow below.
  • Added reproducible verification commands to docs/ai-runtime.md in atomic commits 8af045c73 and 9799241a8. These commands reuse the built server and keep build output and temporary files under the job limits.

The security implementation was already committed when this finish-verification job started. It stores the session actor independently of scopes, carries it to PluginRequestContext and rejects Agent/Ask on all ten AI operations. It registers auth migration 0012 in the production startup list and tests real issuance. Migration 0012 was still free on origin/dev at the pre-gate check.

Files in the complete #980 patch:

  • crates/calternal-auth/migrations/0012_ask_session_type.sql
  • crates/calternal-auth/src/lib.rs
  • crates/calternal-auth/src/store.rs
  • crates/calternal-collab/tests/hostile_clients.rs
  • crates/calternal-collab/tests/journal_race.rs
  • crates/calternal-collab/tests/restart_epoch.rs
  • crates/calternal-collab/tests/shared_notes.rs
  • crates/calternal-collab/tests/two_clients.rs
  • crates/calternal-plugin/src/lib.rs
  • crates/calternal-search/src/saved.rs
  • crates/calternal-server/src/main.rs
  • crates/calternal-server/src/wire.rs
  • crates/plugins/ai/src/lib.rs
  • crates/plugins/ai/src/routes.rs
  • crates/plugins/calendar/src/routes.rs
  • crates/plugins/files/src/lib.rs
  • crates/plugins/notes/src/bookmarks.rs
  • crates/plugins/notes/src/lib.rs
  • docs/ai-runtime.md
  • tests/adversarial/ai_container_tokens.py
  • tests/adversarial/run.sh

Decisions:

  • Preserve Web/Installation transport kinds. Store User/Agent/Ask as a separate actor; User includes browser and human Installation sessions.
  • No own-turn AI-route exception: the runtime does not need an AI route. Output reaches the server through its exec channel.
  • Keep migration 0012; it classifies legacy read-only Agent rows once. Runtime classification reads the stored actor.
  • No new design decision was needed during finish verification. No dependencies or test expectations changed in this session. The earlier auth migration expectation change from 1..11 to 1..12 remains documented in the implementation report.

Gate output (verbatim result lines; complete output is retained under artifacts/):

cargo fmt --check: exit 0; no output.

cargo clippy -p calternal-server --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s

cargo test -p calternal-server -- --test-threads=4 (exit 101):

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 110 filtered out; finished in 18.02s
test result: FAILED. 107 passed; 1 failed; 3 ignored; 0 measured; 0 filtered out; finished in 53.61s

cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 48s

cargo test -p calternal-plugin-notes -- --test-threads=4 (exit 101):

test result: FAILED. 166 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 223.59s

cargo clippy -p calternal-plugin-files --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 44s

cargo test -p calternal-plugin-files -- --test-threads=4 (exit 0):

test result: ok. 146 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 176.83s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 55s

cargo test -p calternal-plugin-calendar -- --test-threads=4 (exit 0):

test result: ok. 83 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.72s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.34s
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_server-85d5c4e45db298f9 wire::tests::full_app_setup_session_config_and_backup --exact --ignored --test-threads=1 (exit 0):

test wire::tests::full_app_setup_session_config_and_backup ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 110 filtered out; finished in 10.70s

/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_plugin_notes-43dde880eb034836 tests::daily_and_composer_preserve_unrelated_bytes --exact --test-threads=1 (exit 0):

test tests::daily_and_composer_preserve_unrelated_bytes ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 166 filtered out; finished in 1.91s

cargo test -p calternal-search --test indexer -- --test-threads=4 (exit 0):

    Finished `test` profile [unoptimized + debuginfo] target(s) in 6m 36s
test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.31s

cargo build -p calternal-server (exit 0):

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 19s

AI_CONTAINER_ONLY=1 ADVERSARIAL_SKIP_WEB_BUILD=1 ADVERSARIAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" bash tests/adversarial/run.sh:

AI container-token probe passed: 28 refused calls

Earlier auth, Plugin, AI and Collab Clippy/test gates passed in the implementation report. Search Clippy passed there too; its failing indexer cases now pass. They were not run again because no Rust source changed in this session and origin/dev changed only design documentation.

Known gaps and failure evidence:

  • Notes full suite: the single failure matches #954 exactly. daily_and_composer_preserve_unrelated_bytes returned 404 instead of 200 at lib.rs:9420. The unchanged focused test passed in 1.91 seconds. This patch only fills actor fields in Notes test contexts; it does not change production Notes code or this test's assertion. The full suite is not reported as passing.
  • Server full suite: the live-app child reached the unchanged five-second User archive-job poll at wire.rs:7768 and returned Elapsed(()), after the new Agent/Ask assertions. The same timeout block exists on origin/dev. The focused child passed unchanged in 10.70 seconds. Scheduling or background Index work (#965) could delay the job; its cause is not established. The original failed full gate remains reported above.
  • #942 did not reproduce: the Files atomic-write/reconcile storm passed. The prior three Search indexer failures did not reproduce either: all 21 passed. This does not prove a cause for the previous failures or resolve #965.
  • No pre-fix bypass was executed. No UI files changed; #980 requires no screenshots. The production web build and media/document runtime checks passed to prepare the local server. No performance measurement ran: this is an authorization issue, not a performance issue.

UX gaps closed / left: not applicable; no UI change.

For the merge round:

  • cargo test -p calternal-server -- --test-threads=4: the complete live-app group must pass, including the User archive-job completion poll.
  • cargo test -p calternal-plugin-notes -- --test-threads=4: check the combined Notes fixture isolation fix for #954 without weakening the Journal read expectation.
  • bash tests/adversarial/run.sh: run the full matrices once on the combined build; Agent/Ask must remain outside the AI API and cross-User behavior must remain correct.

Cleanup:

     Removed 20294 files, 12.6GiB total

Removed apps/web/build. Doc comments in the patch and the updated AI runtime instructions were re-read. Working tree is clean.

READY FOR MERGE: yes

Finish verification report for #980. Branch: `job/agentscope-980`. Head: `9799241a8908b760ba8bbad26938014cdce163f2`. Merged origin/dev once before gates (base `f06679b11cde29cc0b7120fdab5f721389caf695`). No push, deployment or issue closure. Built and verified: - Finished the pending Server, Notes, Files and Calendar Clippy/test runs, with three build jobs and four test threads. All Clippy gates passed. Files and Calendar tests passed. - The production auth migration regression passed. The focused live-app regression passed with real issued Agent and Ask sessions. Search indexer tests passed, including all three cases that failed in the previous session. - Built the server once and ran the existing focused local container-token denial probe against this build. Results follow below. - Added reproducible verification commands to docs/ai-runtime.md in atomic commits `8af045c73` and `9799241a8`. These commands reuse the built server and keep build output and temporary files under the job limits. The security implementation was already committed when this finish-verification job started. It stores the session actor independently of scopes, carries it to PluginRequestContext and rejects Agent/Ask on all ten AI operations. It registers auth migration 0012 in the production startup list and tests real issuance. Migration 0012 was still free on origin/dev at the pre-gate check. Files in the complete #980 patch: - `crates/calternal-auth/migrations/0012_ask_session_type.sql` - `crates/calternal-auth/src/lib.rs` - `crates/calternal-auth/src/store.rs` - `crates/calternal-collab/tests/hostile_clients.rs` - `crates/calternal-collab/tests/journal_race.rs` - `crates/calternal-collab/tests/restart_epoch.rs` - `crates/calternal-collab/tests/shared_notes.rs` - `crates/calternal-collab/tests/two_clients.rs` - `crates/calternal-plugin/src/lib.rs` - `crates/calternal-search/src/saved.rs` - `crates/calternal-server/src/main.rs` - `crates/calternal-server/src/wire.rs` - `crates/plugins/ai/src/lib.rs` - `crates/plugins/ai/src/routes.rs` - `crates/plugins/calendar/src/routes.rs` - `crates/plugins/files/src/lib.rs` - `crates/plugins/notes/src/bookmarks.rs` - `crates/plugins/notes/src/lib.rs` - `docs/ai-runtime.md` - `tests/adversarial/ai_container_tokens.py` - `tests/adversarial/run.sh` Decisions: - Preserve Web/Installation transport kinds. Store User/Agent/Ask as a separate actor; User includes browser and human Installation sessions. - No own-turn AI-route exception: the runtime does not need an AI route. Output reaches the server through its exec channel. - Keep migration 0012; it classifies legacy read-only Agent rows once. Runtime classification reads the stored actor. - No new design decision was needed during finish verification. No dependencies or test expectations changed in this session. The earlier auth migration expectation change from 1..11 to 1..12 remains documented in the implementation report. Gate output (verbatim result lines; complete output is retained under artifacts/): `cargo fmt --check`: exit 0; no output. `cargo clippy -p calternal-server --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 25s ``` `cargo test -p calternal-server -- --test-threads=4` (exit 101): ```text test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 110 filtered out; finished in 18.02s test result: FAILED. 107 passed; 1 failed; 3 ignored; 0 measured; 0 filtered out; finished in 53.61s ``` `cargo clippy -p calternal-plugin-notes --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 48s ``` `cargo test -p calternal-plugin-notes -- --test-threads=4` (exit 101): ```text test result: FAILED. 166 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 223.59s ``` `cargo clippy -p calternal-plugin-files --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 44s ``` `cargo test -p calternal-plugin-files -- --test-threads=4` (exit 0): ```text test result: ok. 146 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 176.83s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-plugin-calendar --all-targets -- -D warnings` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 55s ``` `cargo test -p calternal-plugin-calendar -- --test-threads=4` (exit 0): ```text test result: ok. 83 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 6.72s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.34s test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.10s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_server-85d5c4e45db298f9 wire::tests::full_app_setup_session_config_and_backup --exact --ignored --test-threads=1` (exit 0): ```text test wire::tests::full_app_setup_session_config_and_backup ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 110 filtered out; finished in 10.70s ``` `/mnt/hdd/targets/jobs/agentscope-980/debug/deps/calternal_plugin_notes-43dde880eb034836 tests::daily_and_composer_preserve_unrelated_bytes --exact --test-threads=1` (exit 0): ```text test tests::daily_and_composer_preserve_unrelated_bytes ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 166 filtered out; finished in 1.91s ``` `cargo test -p calternal-search --test indexer -- --test-threads=4` (exit 0): ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 6m 36s test result: ok. 21 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 17.31s ``` `cargo build -p calternal-server` (exit 0): ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 10m 19s ``` `AI_CONTAINER_ONLY=1 ADVERSARIAL_SKIP_WEB_BUILD=1 ADVERSARIAL_SERVER_BIN="$CARGO_TARGET_DIR/debug/calternal-server" bash tests/adversarial/run.sh`: ```text AI container-token probe passed: 28 refused calls ``` Earlier auth, Plugin, AI and Collab Clippy/test gates passed in the implementation report. Search Clippy passed there too; its failing indexer cases now pass. They were not run again because no Rust source changed in this session and origin/dev changed only design documentation. Known gaps and failure evidence: - Notes full suite: the single failure matches #954 exactly. `daily_and_composer_preserve_unrelated_bytes` returned 404 instead of 200 at lib.rs:9420. The unchanged focused test passed in 1.91 seconds. This patch only fills actor fields in Notes test contexts; it does not change production Notes code or this test's assertion. The full suite is not reported as passing. - Server full suite: the live-app child reached the unchanged five-second User archive-job poll at wire.rs:7768 and returned `Elapsed(())`, after the new Agent/Ask assertions. The same timeout block exists on origin/dev. The focused child passed unchanged in 10.70 seconds. Scheduling or background Index work (#965) could delay the job; its cause is not established. The original failed full gate remains reported above. - #942 did not reproduce: the Files atomic-write/reconcile storm passed. The prior three Search indexer failures did not reproduce either: all 21 passed. This does not prove a cause for the previous failures or resolve #965. - No pre-fix bypass was executed. No UI files changed; #980 requires no screenshots. The production web build and media/document runtime checks passed to prepare the local server. No performance measurement ran: this is an authorization issue, not a performance issue. UX gaps closed / left: not applicable; no UI change. For the merge round: - `cargo test -p calternal-server -- --test-threads=4`: the complete live-app group must pass, including the User archive-job completion poll. - `cargo test -p calternal-plugin-notes -- --test-threads=4`: check the combined Notes fixture isolation fix for #954 without weakening the Journal read expectation. - `bash tests/adversarial/run.sh`: run the full matrices once on the combined build; Agent/Ask must remain outside the AI API and cross-User behavior must remain correct. Cleanup: ```text Removed 20294 files, 12.6GiB total ``` Removed apps/web/build. Doc comments in the patch and the updated AI runtime instructions were re-read. Working tree is clean. READY FOR MERGE: yes
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#980
No description provided.