PARITY: every user action available over API, CLI, MCP and WebMCP (one registry, generated adapters, fail-closed gate) #484

Open
opened 2026-09-30 06:01:11 +00:00 by kayg · 27 comments
Owner

Request (owner, 2026-09-30)

"we need to have any actions that can be performed over the UI also over MCP/WebMCP/API/CLI - basically functional parity! i don't literally mean it but i broadly mean it!"

Where we are

  • scripts/parity_matrix.py (#395) and docs/parity-matrix.md: 463 web actions are listed, and 323 of them have NO CLI, MCP or WebMCP adapter.
  • --check currently FAILS on dev ("Parity gaps changed"): merges added actions without updating the matrix. The gate is broken.

Rule ("broadly", not literally)

  • Parity applies to every action on the User's data or account: create, read, update, delete, move, share, search, sync, import and export across Calendar, Tasks, Notes, Files, Photos, Mail, Money, Contacts and Analytics; App Passwords; Connected Accounts; jobs; settings that change behaviour (not looks). These must exist in the API, CLI, MCP and WebMCP.
  • Admin actions: API and CLI always; MCP and WebMCP only behind an admin-scoped credential.
  • Exempt (UI only): pure presentation such as theme, backgrounds, layout, panel widths, animations, hover and drag gestures (their underlying action, for example "move event", is NOT exempt), plus onboarding screens. Every exemption is listed with a one-line reason in docs/parity-exceptions.json.

Approach

  1. One action registry, generated adapters: derive the CLI commands, MCP tools and WebMCP tools from ONE registry built on the OpenAPI contract (operation id, summary, parameters, scopes), with a small per-action override for names and help text. No hand-written duplicate per surface; duplicated logic is a defect. A new API route then gets its CLI, MCP and WebMCP entries automatically unless it is exempt.
  2. Safety: each tool carries the same scope check as the API (App Password scopes; the #331 and #472 cross-user matrix and the #483 admin denial cover every tool). Destructive tools need a confirm flag in the CLI and destructiveHint in MCP. Settings → Apps & Devices can turn each surface (API, CLI, MCP, WebMCP) on or off (owner's earlier ask).
  3. Gate: parity_matrix.py --check fails on any non-exempt action without all four surfaces. Fix today's failing gate first. Then CI runs it on every merge.
  4. Tests: a generated smoke test calls each tool once through each surface against a real local server (read tools with real data; write tools in a throwaway Home).
    Work in slices: fix the gate, build the registry and generator, then close the gaps area by area (Calendar/Tasks/Notes first, then Files/Photos, Mail, Money, account and admin). Report the gap count after each slice.
## Request (owner, 2026-09-30) "we need to have any actions that can be performed over the UI also over MCP/WebMCP/API/CLI - basically functional parity! i don't literally mean it but i broadly mean it!" ## Where we are - `scripts/parity_matrix.py` (#395) and `docs/parity-matrix.md`: 463 web actions are listed, and 323 of them have NO CLI, MCP or WebMCP adapter. - `--check` currently FAILS on dev ("Parity gaps changed"): merges added actions without updating the matrix. The gate is broken. ## Rule ("broadly", not literally) - **Parity applies to every action on the User's data or account:** create, read, update, delete, move, share, search, sync, import and export across Calendar, Tasks, Notes, Files, Photos, Mail, Money, Contacts and Analytics; App Passwords; Connected Accounts; jobs; settings that change behaviour (not looks). These must exist in the API, CLI, MCP and WebMCP. - **Admin actions:** API and CLI always; MCP and WebMCP only behind an admin-scoped credential. - **Exempt (UI only):** pure presentation such as theme, backgrounds, layout, panel widths, animations, hover and drag gestures (their underlying action, for example "move event", is NOT exempt), plus onboarding screens. Every exemption is listed with a one-line reason in `docs/parity-exceptions.json`. ## Approach 1. **One action registry, generated adapters:** derive the CLI commands, MCP tools and WebMCP tools from ONE registry built on the OpenAPI contract (operation id, summary, parameters, scopes), with a small per-action override for names and help text. No hand-written duplicate per surface; duplicated logic is a defect. A new API route then gets its CLI, MCP and WebMCP entries automatically unless it is exempt. 2. **Safety:** each tool carries the same scope check as the API (App Password scopes; the #331 and #472 cross-user matrix and the #483 admin denial cover every tool). Destructive tools need a confirm flag in the CLI and `destructiveHint` in MCP. Settings → Apps & Devices can turn each surface (API, CLI, MCP, WebMCP) on or off (owner's earlier ask). 3. **Gate:** `parity_matrix.py --check` fails on any non-exempt action without all four surfaces. Fix today's failing gate first. Then CI runs it on every merge. 4. **Tests:** a generated smoke test calls each tool once through each surface against a real local server (read tools with real data; write tools in a throwaway Home). Work in slices: fix the gate, build the registry and generator, then close the gaps area by area (Calendar/Tasks/Notes first, then Files/Photos, Mail, Money, account and admin). Report the gap count after each slice.
Author
Owner

Started #484 on branch job/parity-484, base 0dc772c3697ea9bd01822c26440c32206d472715.

Evidence: python3 scripts/parity_matrix.py --check exits with Parity gaps changed; review them and run --accept-current-gaps. The contract has 304 HTTP operations; none declares OpenAPI security. Existing exceptions accept missing data adapters, and CLI matching ignores the HTTP method.

I will replace accepted adapter gaps with a fail-closed check, derive adapter metadata from the contract, and reuse existing route authorization. Remaining gaps will stay visible until their adapters pass validation.

Started #484 on branch `job/parity-484`, base `0dc772c3697ea9bd01822c26440c32206d472715`. Evidence: `python3 scripts/parity_matrix.py --check` exits with `Parity gaps changed; review them and run --accept-current-gaps`. The contract has 304 HTTP operations; none declares OpenAPI security. Existing exceptions accept missing data adapters, and CLI matching ignores the HTTP method. I will replace accepted adapter gaps with a fail-closed check, derive adapter metadata from the contract, and reuse existing route authorization. Remaining gaps will stay visible until their adapters pass validation.
Author
Owner

Registry/runtime slice status (#484): 304 contract operations. The generated finite-JSON data adapters cover 195 operations in source; parity_matrix.py --check reports 105 unresolved operations. Runtime Rust gates are still building, so these counts do not certify successful calls.

Contract evidence: Notes listing, templates and Daily note queries were declared as path parameters with no path placeholders. Backlinks and linked-notes have the same defect; CLI approval's query also has it. I am correcting only their OpenAPI annotations and regenerating the client; handler behavior stays the same.

Transport evidence: notes_events, mail_download_attachment and tus creation operations do not declare their stream/bytes/header transport completely. These must remain gaps; an empty OpenAPI response is not proof of a JSON response.

Decisions: generated names use calternal_api_<operationId> to retain existing tool names; CLI exposes stable IDs under action list|run; all generated mutations require explicit CLI confirmation and browser confirmation. Account/admin MCP stays unavailable under existing App Password policy. No credential authority is broadened.

Registry/runtime slice status (#484): 304 contract operations. The generated finite-JSON data adapters cover 195 operations in source; `parity_matrix.py --check` reports 105 unresolved operations. Runtime Rust gates are still building, so these counts do not certify successful calls. Contract evidence: Notes listing, templates and Daily note queries were declared as path parameters with no path placeholders. Backlinks and linked-notes have the same defect; CLI approval's query also has it. I am correcting only their OpenAPI annotations and regenerating the client; handler behavior stays the same. Transport evidence: `notes_events`, `mail_download_attachment` and tus creation operations do not declare their stream/bytes/header transport completely. These must remain gaps; an empty OpenAPI response is not proof of a JSON response. Decisions: generated names use `calternal_api_<operationId>` to retain existing tool names; CLI exposes stable IDs under `action list|run`; all generated mutations require explicit CLI confirmation and browser confirmation. Account/admin MCP stays unavailable under existing App Password policy. No credential authority is broadened.
Author
Owner

Progress on job/parity-484, head f48a2fb55.

The registry has 304 API operations. It generates CLI, MCP and WebMCP descriptors for 252 finite JSON operations. The parity gate reports 51 remaining non-exempt adapter gaps. This is a different measure from the old count of 323 UI-only actions: the old report mixed UI actions and missing adapters. The static UI lists still need a route audit.

The generated CLI supports offline schema discovery and requires --confirm for mutations. Its clippy gate and all CLI tests passed. WebMCP registers tools lazily, uses the existing confirmation sheet, repeats surface checks after confirmation, and lists admin tools only after the API admin guard accepts the session. Web type checks and 9 WebMCP tests passed. The full web test run passed 890 tests.

MCP dispatch now uses ordinary API session middleware with the original bearer credential. A private request extension selects the MCP surface and protocol; it cannot grant scope. This keeps App Password account/admin denial, installation scopes, freshness, network audit and Home restrictions in the API path. Server verification is running.

Decisions: JSON tools use stable calternal_api_<operationId> names, with small name/help overrides. Binary streams, tus uploads and public authentication flows remain explicit gaps. OpenAPI has no security declarations, so the registry reuses the reviewed authorization groups from the existing cross-user probe without importing credentials. This is temporary until the contract declares scopes.

The requested per-action successful smoke suite through all four surfaces is still incomplete. The extended local MCP probe checks every generated mutation with a read-only credential, plus real Note reads and account/admin denial.

Progress on `job/parity-484`, head `f48a2fb55`. The registry has 304 API operations. It generates CLI, MCP and WebMCP descriptors for 252 finite JSON operations. The parity gate reports 51 remaining non-exempt adapter gaps. This is a different measure from the old count of 323 UI-only actions: the old report mixed UI actions and missing adapters. The static UI lists still need a route audit. The generated CLI supports offline schema discovery and requires `--confirm` for mutations. Its clippy gate and all CLI tests passed. WebMCP registers tools lazily, uses the existing confirmation sheet, repeats surface checks after confirmation, and lists admin tools only after the API admin guard accepts the session. Web type checks and 9 WebMCP tests passed. The full web test run passed 890 tests. MCP dispatch now uses ordinary API session middleware with the original bearer credential. A private request extension selects the MCP surface and protocol; it cannot grant scope. This keeps App Password account/admin denial, installation scopes, freshness, network audit and Home restrictions in the API path. Server verification is running. Decisions: JSON tools use stable `calternal_api_<operationId>` names, with small name/help overrides. Binary streams, tus uploads and public authentication flows remain explicit gaps. OpenAPI has no security declarations, so the registry reuses the reviewed authorization groups from the existing cross-user probe without importing credentials. This is temporary until the contract declares scopes. The requested per-action successful smoke suite through all four surfaces is still incomplete. The extended local MCP probe checks every generated mutation with a read-only credential, plus real Note reads and account/admin denial.
Author
Owner

Production SPA evidence for #484: the registry-backed confirmation sheet at 390, 820 and 1440 px, in light and dark. These screenshots use this worktree's production SPA and a real local server. The compatible prebuilt server accepted generated Note create/read and scope-gated tool registration. The complete legacy browser test reached Log creation, then failed because that older binary lacks the batch Log route. A run with the new server binary is still required. Visual review remains with Claude.

webmcp-confirm-1440-dark.png

webmcp-confirm-1440-light.png

webmcp-confirm-390-dark.png

webmcp-confirm-390-light.png

webmcp-confirm-820-dark.png

webmcp-confirm-820-light.png

Production SPA evidence for #484: the registry-backed confirmation sheet at 390, 820 and 1440 px, in light and dark. These screenshots use this worktree's production SPA and a real local server. The compatible prebuilt server accepted generated Note create/read and scope-gated tool registration. The complete legacy browser test reached Log creation, then failed because that older binary lacks the batch Log route. A run with the new server binary is still required. Visual review remains with Claude. ![webmcp-confirm-1440-dark.png](https://git.kayg.org/attachments/78e6f0e9-bd5b-4e86-a983-e133c8124bce) ![webmcp-confirm-1440-light.png](https://git.kayg.org/attachments/be11fdd6-dbbe-4fe8-b0d9-4eba16a61f22) ![webmcp-confirm-390-dark.png](https://git.kayg.org/attachments/ea29329f-8b6d-4783-944e-8314ae4536ce) ![webmcp-confirm-390-light.png](https://git.kayg.org/attachments/388187d9-96d2-4c61-b288-0bb55326fce4) ![webmcp-confirm-820-dark.png](https://git.kayg.org/attachments/eeeedf6d-2491-4cfe-ac77-d5740821f421) ![webmcp-confirm-820-light.png](https://git.kayg.org/attachments/74b5839c-7d4f-4222-8f13-a49172ec4a54)
Author
Owner

Finding on job/parity-484: the tus contract omits required protocol input.

crates/plugins/files/src/uploads.rs checks tus-resumable: 1.0.0 in tus() (line 545). Both patch() and terminate() call that check. Their OpenAPI annotations declare only the upload ID; PATCH also omits its raw byte body. A JSON adapter cannot complete those operations from the declared input schema.

The registry now leaves these operations, and their public equivalents, uncovered until the contract declares their input. A regression test prevents false coverage. The count is now 304 API actions, 250 generated MCP/WebMCP tools and 53 non-exempt adapter gaps. The count rose by two because this check removed two false coverage claims; no exemption was added.

Decision: do not invent hidden tus headers or raw transport defaults in each adapter. Keep one contract and expose this as required Files/Photos work.

Finding on `job/parity-484`: the tus contract omits required protocol input. `crates/plugins/files/src/uploads.rs` checks `tus-resumable: 1.0.0` in `tus()` (line 545). Both `patch()` and `terminate()` call that check. Their OpenAPI annotations declare only the upload ID; PATCH also omits its raw byte body. A JSON adapter cannot complete those operations from the declared input schema. The registry now leaves these operations, and their public equivalents, uncovered until the contract declares their input. A regression test prevents false coverage. The count is now 304 API actions, 250 generated MCP/WebMCP tools and 53 non-exempt adapter gaps. The count rose by two because this check removed two false coverage claims; no exemption was added. Decision: do not invent hidden tus headers or raw transport defaults in each adapter. Keep one contract and expose this as required Files/Photos work.
Author
Owner

Finding: five Note mutations require an input that their contract omitted.

match_etag() in crates/plugins/notes/src/lib.rs returns HTTP 428 without If-Match, and HTTP 412 for a stale ETag. update_body, update_properties, retitle, move_note and notes_trash called it, but their OpenAPI entries declared no header. A generated tool therefore could not complete these mutations from its schema.

The annotations now declare required If-Match, with the current Note ETag as its description. This changes contract metadata only. It does not change handlers, scope checks or conflict policy. The registry and typed client were regenerated. The MCP and production browser probes now test generated Note CRUD, and the MCP probe checks stale revision denial. The coverage count remains 250 generated MCP/WebMCP tools and 53 adapter gaps.

Decisions: adapters pass the ETag read by the caller. They never fetch a revision automatically or bypass the server's conflict check.

Finding: five Note mutations require an input that their contract omitted. `match_etag()` in `crates/plugins/notes/src/lib.rs` returns HTTP 428 without `If-Match`, and HTTP 412 for a stale ETag. `update_body`, `update_properties`, `retitle`, `move_note` and `notes_trash` called it, but their OpenAPI entries declared no header. A generated tool therefore could not complete these mutations from its schema. The annotations now declare required `If-Match`, with the current Note ETag as its description. This changes contract metadata only. It does not change handlers, scope checks or conflict policy. The registry and typed client were regenerated. The MCP and production browser probes now test generated Note CRUD, and the MCP probe checks stale revision denial. The coverage count remains 250 generated MCP/WebMCP tools and 53 adapter gaps. Decisions: adapters pass the ETag read by the caller. They never fetch a revision automatically or bypass the server's conflict check.
Author
Owner

#484 four-hour handoff — incomplete, not merge-ready

Branch: job/parity-484. Head: 74daa858313bcfd3a691120c69b9a2d8ac6bf081.
Fetched and merged origin/dev once before final gates. No push or deployment.

Built

  • An OpenAPI action registry with shared request mapping, schema generation, name/help overrides, scope labels and destructive hints.
  • Registry-driven CLI, MCP and WebMCP adapters. API middleware retains authorization, App Password scopes, Home restrictions and surface controls. CLI mutations require confirmation; WebMCP uses the existing confirmation and step-up flow.
  • A fail-closed parity gate and CI checks. Missing adapters cannot be accepted as a baseline. This repairs the gate semantics; it does not make the gate green.
  • Note query/revision-header contract corrections, declared empty-success handling, input/header protections, and generated Note CRUD/scope probes.

Current inventory: 304 API operations; 250 generated MCP/WebMCP operations; 270 generated CLI operations; 53 non-exempt actions still have adapter gaps. These API-operation counts differ from the earlier UI-action counts. A full semantic audit of UI actions is still required.

Files

Registry/gate: scripts/action_registry.py, scripts/parity_matrix.py, their unit tests, contracts/actions.json, contracts/action-overrides.json, docs/parity-exceptions.json, docs/parity-matrix.md, .forgejo/workflows/ci.yml.
Adapters: crates/calternal-api/src/actions.rs, API module exports, CLI manifest/main/remote commands, server MCP/wire/authz modules, apps/web/src/lib/webmcp/{generated.ts,generated.test.ts,tools.ts}, web layout, API-client implementation/tests.
Contract: auth CLI-login and Notes annotations, contracts/openapi.json, generated API client, Cargo.lock.
Evidence/docs: tests/adversarial/mcp_probe.py, apps/web/e2e/webmcp.mjs, docs/action-registry.md, docs/mcp.md.
Changes brought by the origin/dev merge are separate from these job changes. Review artifacts remain untracked.

Gate output (verbatim summary lines)

cargo fmt --check: no output.

cargo clippy -p calternal-api --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 34.02s

cargo test -p calternal-api:

test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s

cargo clippy -p calternal-cli --all-targets -- -D warnings:

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

cargo test -p calternal-cli:

test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.34s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.72s

cargo clippy -p calternal-server --all-targets -- -D warnings:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 22s

cargo test -p calternal-server:

test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 52.85s

Web checks after merging origin/dev:

svelte-check found 0 errors and 0 warnings
 Test Files  138 passed (138)
      Tests  893 passed (893)

API-client tests:

 11 pass
 0 fail
 32 expect() calls
Ran 11 tests across 1 file. [5.11s]

Parity gate:

Parity failed: 53 non-exempt API actions lack all four surfaces
Parity matrix: 304 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 53 actions with adapter gaps

Registry and matrix unit tests passed (7 and 4 tests). Registry freshness check passed. Production web build passed. Complete local logs are in artifacts/.

The full workspace clippy and test commands were attempted once with time limits. They did not complete; the test log ends at Blocking waiting for file lock on build directory. This is not a passing workspace gate. Separate auth and Notes crate gates remain pending. CLI gates predate the final Note contract metadata changes. The origin/dev merge did not change Rust files.

Known gaps

  • 53 missing adapters: streaming, binary/non-JSON, multipart and protocol-specific actions need transport implementations. Underspecified tus operations are deliberately uncovered.
  • The new server binary and a complete real-server adversarial round did not finish within the four-hour limit. The extended MCP/API/CLI probe is committed but unrun against the new build. Generated smoke tests do not yet call every action across all four surfaces.
  • Generated WebMCP Note create/read/update/Trash passed against a real older local backend. The complete browser suite failed on that backend's absent legacy Log batch route. This does not validate the new MCP implementation.
  • Actual server-generated OpenAPI freshness still needs verification; annotation-generated summary metadata may differ from the manually aligned contract.
  • Scope labels temporarily reuse the reviewed authorization matrix; OpenAPI security declarations and a complete UI-action/exemption audit remain work.
  • Six production screenshots (390/820/1440, light/dark) are already attached above. They predate the merged glass changes; refreshed evidence and Claude visual review remain pending.
  • API-client/WebMCP changes and probes are covered by tests, but this does not establish full functional parity or authorization coverage for every operation.

Decisions

Generate finite JSON adapters first and leave unsupported transports visible as gaps. Use calternal_api_<operation_id> tool names with small overrides. Route MCP through ordinary API authorization with a private transport marker. Require confirmation for every CLI mutation and preserve current WebMCP confirmation/step-up behavior. Do not silently fetch a new Note revision after a conflict. Preserve bounded request/response sizes. Never exempt a data action merely because its adapter is missing.

No merge is requested. Resume from these commits, complete the missing transports and fixtures, regenerate the contract from the actual server, and finish the pending gates and real-server authorization round.

# #484 four-hour handoff — incomplete, not merge-ready Branch: `job/parity-484`. Head: `74daa858313bcfd3a691120c69b9a2d8ac6bf081`. Fetched and merged `origin/dev` once before final gates. No push or deployment. ## Built - An OpenAPI action registry with shared request mapping, schema generation, name/help overrides, scope labels and destructive hints. - Registry-driven CLI, MCP and WebMCP adapters. API middleware retains authorization, App Password scopes, Home restrictions and surface controls. CLI mutations require confirmation; WebMCP uses the existing confirmation and step-up flow. - A fail-closed parity gate and CI checks. Missing adapters cannot be accepted as a baseline. This repairs the gate semantics; it does not make the gate green. - Note query/revision-header contract corrections, declared empty-success handling, input/header protections, and generated Note CRUD/scope probes. Current inventory: **304 API operations; 250 generated MCP/WebMCP operations; 270 generated CLI operations; 53 non-exempt actions still have adapter gaps.** These API-operation counts differ from the earlier UI-action counts. A full semantic audit of UI actions is still required. ## Files Registry/gate: `scripts/action_registry.py`, `scripts/parity_matrix.py`, their unit tests, `contracts/actions.json`, `contracts/action-overrides.json`, `docs/parity-exceptions.json`, `docs/parity-matrix.md`, `.forgejo/workflows/ci.yml`. Adapters: `crates/calternal-api/src/actions.rs`, API module exports, CLI manifest/main/remote commands, server MCP/wire/authz modules, `apps/web/src/lib/webmcp/{generated.ts,generated.test.ts,tools.ts}`, web layout, API-client implementation/tests. Contract: auth CLI-login and Notes annotations, `contracts/openapi.json`, generated API client, `Cargo.lock`. Evidence/docs: `tests/adversarial/mcp_probe.py`, `apps/web/e2e/webmcp.mjs`, `docs/action-registry.md`, `docs/mcp.md`. Changes brought by the origin/dev merge are separate from these job changes. Review artifacts remain untracked. ## Gate output (verbatim summary lines) `cargo fmt --check`: no output. `cargo clippy -p calternal-api --all-targets -- -D warnings`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 34.02s ``` `cargo test -p calternal-api`: ``` test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.06s ``` `cargo clippy -p calternal-cli --all-targets -- -D warnings`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 20m 54s ``` `cargo test -p calternal-cli`: ``` test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 4.34s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.72s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings`: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 22s ``` `cargo test -p calternal-server`: ``` test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 52.85s ``` Web checks after merging origin/dev: ``` svelte-check found 0 errors and 0 warnings Test Files 138 passed (138) Tests 893 passed (893) ``` API-client tests: ``` 11 pass 0 fail 32 expect() calls Ran 11 tests across 1 file. [5.11s] ``` Parity gate: ``` Parity failed: 53 non-exempt API actions lack all four surfaces Parity matrix: 304 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 53 actions with adapter gaps ``` Registry and matrix unit tests passed (7 and 4 tests). Registry freshness check passed. Production web build passed. Complete local logs are in `artifacts/`. The full workspace clippy and test commands were attempted once with time limits. They did not complete; the test log ends at `Blocking waiting for file lock on build directory`. This is not a passing workspace gate. Separate auth and Notes crate gates remain pending. CLI gates predate the final Note contract metadata changes. The origin/dev merge did not change Rust files. ## Known gaps - 53 missing adapters: streaming, binary/non-JSON, multipart and protocol-specific actions need transport implementations. Underspecified tus operations are deliberately uncovered. - The new server binary and a complete real-server adversarial round did not finish within the four-hour limit. The extended MCP/API/CLI probe is committed but unrun against the new build. Generated smoke tests do not yet call every action across all four surfaces. - Generated WebMCP Note create/read/update/Trash passed against a real older local backend. The complete browser suite failed on that backend's absent legacy Log batch route. This does not validate the new MCP implementation. - Actual server-generated OpenAPI freshness still needs verification; annotation-generated summary metadata may differ from the manually aligned contract. - Scope labels temporarily reuse the reviewed authorization matrix; OpenAPI security declarations and a complete UI-action/exemption audit remain work. - Six production screenshots (390/820/1440, light/dark) are already attached above. They predate the merged glass changes; refreshed evidence and Claude visual review remain pending. - API-client/WebMCP changes and probes are covered by tests, but this does not establish full functional parity or authorization coverage for every operation. ## Decisions Generate finite JSON adapters first and leave unsupported transports visible as gaps. Use `calternal_api_<operation_id>` tool names with small overrides. Route MCP through ordinary API authorization with a private transport marker. Require confirmation for every CLI mutation and preserve current WebMCP confirmation/step-up behavior. Do not silently fetch a new Note revision after a conflict. Preserve bounded request/response sizes. Never exempt a data action merely because its adapter is missing. No merge is requested. Resume from these commits, complete the missing transports and fixtures, regenerate the contract from the actual server, and finish the pending gates and real-server authorization round.
Author
Owner

Round 2 started on job/parity-484 at 775d2e813f565010f6935830fa0ec9e3f84c1182. Merged origin/dev before work. Round-one inventory: 53 non-exempt transport/public-flow gaps. Inspecting transport contracts and extending the shared registry and adapters. No push or deployment.

Round 2 started on `job/parity-484` at `775d2e813f565010f6935830fa0ec9e3f84c1182`. Merged origin/dev before work. Round-one inventory: 53 non-exempt transport/public-flow gaps. Inspecting transport contracts and extending the shared registry and adapters. No push or deployment.
Author
Owner

Round 2 transport inventory: the generator now describes raw text requests, base64 chunks, tus protocol headers and finite SSE polling. Public-link data tools retain the public route's grants. Sign-in ceremonies are explicit onboarding exclusions. WebSocket editor synchronization is an explicit presentation exclusion; content read/write actions remain covered. The stricter transport detector also found private/shared WebSocket routes that round one incorrectly counted as JSON.

Eight registry unit tests and four parity-gate unit tests passed. API-client transport tests: 15 pass, 0 fail, including idle SSE reader cancellation. Final Rust and real-server validation remain in progress. One unchanged Money parser test hit its 5-second timeout in the web suite; no expectation was changed.

Round 2 transport inventory: the generator now describes raw text requests, base64 chunks, tus protocol headers and finite SSE polling. Public-link data tools retain the public route's grants. Sign-in ceremonies are explicit onboarding exclusions. WebSocket editor synchronization is an explicit presentation exclusion; content read/write actions remain covered. The stricter transport detector also found private/shared WebSocket routes that round one incorrectly counted as JSON. Eight registry unit tests and four parity-gate unit tests passed. API-client transport tests: `15 pass`, `0 fail`, including idle SSE reader cancellation. Final Rust and real-server validation remain in progress. One unchanged Money parser test hit its 5-second timeout in the web suite; no expectation was changed.
Author
Owner

Round 2 checkpoint at 5cf77bea4 (Rust adapter changes are still awaiting their final crate tests).

Inventory gates:

Action registry: 306 operations, 288 generated tools
Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps

The inventory includes the two tus HEAD operations that the first inventory omitted. All three generated surfaces now support text, byte chunks, tus creation/PATCH/HEAD/termination and finite SSE polling. Public text editing has its required If-Match precondition. Sign-in ceremonies remain in the existing login flow. The three live editor WebSocket routes have explicit presentation exclusions; their content actions remain available.

Evidence so far:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 13m 07s
test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.76s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s

These lines are from CLI clippy and tests. API clippy passed; its new regression tests are queued behind the server build lock. The generated WebMCP unit suite invokes all 288 callbacks with a transport stub. This is adapter mapping evidence, not full real-server smoke coverage.

The real-server transport runner now includes tus, byte/range/ZIP downloads, five SSE streams, TOML reads, public file drops and public text editing across CLI/MCP/WebMCP, plus 57 selector-free reads per surface. The new bench/parity.sh profile measures average 64 KiB transfers and sixteen concurrent 1 MiB downloads, with latency, CPU and RSS. Both await the new server binary. Complete per-action real fixtures and live cross-User coverage remain unfinished.

Round 2 checkpoint at `5cf77bea4` (Rust adapter changes are still awaiting their final crate tests). Inventory gates: ``` Action registry: 306 operations, 288 generated tools Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps ``` The inventory includes the two tus HEAD operations that the first inventory omitted. All three generated surfaces now support text, byte chunks, tus creation/PATCH/HEAD/termination and finite SSE polling. Public text editing has its required If-Match precondition. Sign-in ceremonies remain in the existing login flow. The three live editor WebSocket routes have explicit presentation exclusions; their content actions remain available. Evidence so far: ``` Finished `dev` profile [unoptimized + debuginfo] target(s) in 13m 07s test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.76s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.20s ``` These lines are from CLI clippy and tests. API clippy passed; its new regression tests are queued behind the server build lock. The generated WebMCP unit suite invokes all 288 callbacks with a transport stub. This is adapter mapping evidence, not full real-server smoke coverage. The real-server transport runner now includes tus, byte/range/ZIP downloads, five SSE streams, TOML reads, public file drops and public text editing across CLI/MCP/WebMCP, plus 57 selector-free reads per surface. The new bench/parity.sh profile measures average 64 KiB transfers and sixteen concurrent 1 MiB downloads, with latency, CPU and RSS. Both await the new server binary. Complete per-action real fixtures and live cross-User coverage remain unfinished.
Author
Owner

Round-2 checkpoint at 5e0f5079a1d6b8e9202a89aac1250ef491c53ea2. The MCP transport dispatcher is committed. The generated registry has 306 actions and 288 tools per surface; adapter gaps: 0. The offline cross-User guard classifies all 864 generated entry points. This does not certify live authorization or complete smoke coverage.

Gate output:

round2-server-clippy-final.log
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 06s
round2-server-test.log
    Finished `test` profile [unoptimized + debuginfo] target(s) in 22m 38s
test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 23.03s
round2-auth-test.log
    Finished `test` profile [unoptimized + debuginfo] target(s) in 23m 39s
test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 97.23s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
round2-web-check-final3.log
svelte-check found 0 errors and 0 warnings
round2-web-test-final3.log
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯
 Test Files  3 failed | 135 passed (138)
      Tests  3 failed | 893 passed (896)
round2-web-timeouts-rerun.log
 Test Files  3 passed (3)
      Tests  28 passed (28)

Three web component tests timed out at 5 seconds in the full run; all three passed unchanged on their targeted rerun. Notes gates and the server binary build remain in progress. The real-server transfer runner and contract freshness check have not run yet.

Round-2 checkpoint at `5e0f5079a1d6b8e9202a89aac1250ef491c53ea2`. The MCP transport dispatcher is committed. The generated registry has 306 actions and 288 tools per surface; adapter gaps: 0. The offline cross-User guard classifies all 864 generated entry points. This does not certify live authorization or complete smoke coverage. Gate output: ``` round2-server-clippy-final.log Finished `dev` profile [unoptimized + debuginfo] target(s) in 23m 06s round2-server-test.log Finished `test` profile [unoptimized + debuginfo] target(s) in 22m 38s test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 23.03s round2-auth-test.log Finished `test` profile [unoptimized + debuginfo] target(s) in 23m 39s test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 97.23s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s round2-web-check-final3.log svelte-check found 0 errors and 0 warnings round2-web-test-final3.log ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 3 ⎯⎯⎯⎯⎯⎯⎯ Test Files 3 failed | 135 passed (138) Tests 3 failed | 893 passed (896) round2-web-timeouts-rerun.log Test Files 3 passed (3) Tests 28 passed (28) ``` Three web component tests timed out at 5 seconds in the full run; all three passed unchanged on their targeted rerun. Notes gates and the server binary build remain in progress. The real-server transfer runner and contract freshness check have not run yet.
Author
Owner

Round-2 live checkpoint at 4fc0dd832bba61dead4d872664e0f021acdc1fd5. Contract freshness now passes after real-server regeneration corrected three optional Notes query groups and revision-header documentation. Registry/parity check: 306 actions, 288 generated tools per surface, 0 adapter gaps. Offline cross-User classification: 864 entry points.

The live CLI fixture slice reached 113 distinct successful tools. Complete smoke coverage remains unfinished; provider-backed operations still need fixtures. The template fixture was missing its installed source, and the stateless MCP test request was missing its matching HTTP protocol-version header. Both test setup corrections are in progress. The readiness check now uses bounded API polling rather than a Promise-valued Playwright predicate.

Fresh production confirmation screenshots (390/820/1440, light/dark):

Svelte check:

svelte-check found 0 errors and 0 warnings

The full web run had one 5-second timeout (895 passed); that unchanged test passed on a targeted rerun with a 20-second timeout. Notes tests passed (126 unit tests and one integration test). The final metadata-aware server tests are running.

Round-2 live checkpoint at `4fc0dd832bba61dead4d872664e0f021acdc1fd5`. Contract freshness now passes after real-server regeneration corrected three optional Notes query groups and revision-header documentation. Registry/parity check: 306 actions, 288 generated tools per surface, 0 adapter gaps. Offline cross-User classification: 864 entry points. The live CLI fixture slice reached 113 distinct successful tools. Complete smoke coverage remains unfinished; provider-backed operations still need fixtures. The template fixture was missing its installed source, and the stateless MCP test request was missing its matching HTTP protocol-version header. Both test setup corrections are in progress. The readiness check now uses bounded API polling rather than a Promise-valued Playwright predicate. Fresh production confirmation screenshots (390/820/1440, light/dark): - [webmcp-confirm-1440-dark.png](https://git.kayg.org/attachments/56c5fc4e-e387-4300-bc6d-b98ed59e0a7b) - [webmcp-confirm-1440-light.png](https://git.kayg.org/attachments/2e8e6a34-318d-4ac5-a6b0-ab64b5d3080b) - [webmcp-confirm-390-dark.png](https://git.kayg.org/attachments/762a17d3-f679-4b95-b41f-73eb5b82aff7) - [webmcp-confirm-390-light.png](https://git.kayg.org/attachments/225d798a-7217-4ec9-8887-315fce4a7508) - [webmcp-confirm-820-dark.png](https://git.kayg.org/attachments/34f7e8b1-439d-4d79-89d3-f7f1532f935b) - [webmcp-confirm-820-light.png](https://git.kayg.org/attachments/ebb6672e-b1e0-4658-8496-538823b08193) Svelte check: ``` svelte-check found 0 errors and 0 warnings ``` The full web run had one 5-second timeout (895 passed); that unchanged test passed on a targeted rerun with a 20-second timeout. Notes tests passed (126 unit tests and one integration test). The final metadata-aware server tests are running.
Author
Owner

#484 round 2: adapters complete; verification partial

Head: 413eb4fad294d9eaf42c8f28fe99bb963500711b on job/parity-484. Merged origin/dev once at the start (775d2e813). No push or deploy.

Remaining adapter gaps: 0. The registry has 306 operations and 288 generated tools per surface. Real-server smoke calls 122/288 distinct tools on each of CLI, MCP and WebMCP. 166 tools per surface still need fixtures. The strict full-smoke requirement is not satisfied. This job is not ready to merge. The four-hour time box requires a handoff.

Built and files

  • Generated text, base64 file upload/download, HEAD, safe transfer headers and finite SSE transports: scripts/action_registry.py, contracts/actions.json, crates/calternal-api/src/actions.rs, crates/calternal-cli/src/remote_commands.rs, crates/calternal-server/src/mcp.rs, apps/web/src/lib/webmcp/generated.ts, and their tests.
  • Bounded browser decoding and cache bypass for generated transfers: packages/api-client/src/index.ts and index.test.ts. A finite GET cache must not read an entire stream before the transport enforces its budget.
  • MCP API dispatch uses a JoinSet task. A normal File move exposed a fatal worker stack overflow while the SDK and API router were polled on the same stack. The separate task fixed the same real fixture on MCP and the final combined run. Dropping the JoinSet aborts the child; the transport semaphore remains held through response processing. crates/calternal-server/src/serve.rs adds HTTP failure diagnostics without payloads or credentials.
  • Real-server production smoke, fixture plans and six confirmation screenshots: apps/web/e2e/webmcp.mjs, apps/web/e2e/harness.mjs, tests/parity/notes-smoke.json. Writes use a throwaway Home and the normal server APIs. Notes, templates, saved searches, Tasks, Logs, reminders, Files, Photos, Versions and public transfers have real fixtures.
  • Entry-point classification: tests/adversarial/xuser_matrix.py, test_xuser_classification.py. All 864 generated entry points are classified. This is not a completed live cross-User run.
  • Current contract regeneration and prebuilt-binary freshness option: contracts/openapi.json, packages/api-client/src/generated.ts, packages/api-client/check-generated.sh. The default CI path still builds. The supplied binary was built from this checkout.
  • Parity documentation and profile: docs/action-registry.md, docs/parity-matrix.md, docs/parity-exceptions.json, scripts/parity_matrix.py, scripts/test_action_registry.py, bench/parity.sh, crates/calternal-api/Cargo.toml, Cargo.lock.

Verification

All Rust commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0 and CARGO_BUILD_JOBS=4. Gates ran per crate. Below are output lines copied verbatim from logs; complete logs remain in artifacts/.

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

cargo clippy -p calternal-api --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 33.62s

cargo test -p calternal-api

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

cargo clippy -p calternal-cli --all-targets -- -D warnings

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

cargo test -p calternal-cli

test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.76s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.11s

cargo clippy -p calternal-server --all-targets -- -D warnings

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

cargo test -p calternal-server

test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 32.79s

cargo clippy -p calternal-auth --all-targets -- -D warnings

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 50s

cargo test -p calternal-auth

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

cargo clippy -p calternal-notes --all-targets -- -D warnings

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

cargo test -p calternal-notes

test result: ok. 126 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 199.14s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.89s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

bun run --cwd apps/web check

svelte-check found 0 errors and 0 warnings

bun run --cwd apps/web test --maxWorkers 2 --testTimeout 20000

 Test Files  138 passed (138)
      Tests  896 passed (896)

API client tests

 17 pass
 0 fail
Ran 17 tests across 1 file. [1139.00ms]

Registry generator tests

Ran 10 tests in 0.173s
OK

Parity matrix tests

Ran 4 tests in 0.005s
OK

round2-registry-check-final.log

Action registry: 306 operations, 288 generated tools

round2-parity-check-final.log

Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps

round2-crossuser-classification.log

Cross-User classification gate: 308 operations classified
Generated entry point classification: 864 tools classified

round2-smoke-final.log

Generated transfer performance: {"environment":{"label":"local","build":"debug","cpus":8,"load_average":[26.65,24.74,26.71]},"average":{"count":32,"concurrency":1,"response_bytes":65536,"p50_ms":40.06459199999881,"p95_ms":59.71684699999969,"cpu_percent":49.80589120474907,"rss_bytes":228311040,"peak_rss_bytes":228311040},"worst":{"count":16,"concurrency":16,"response_bytes":1048576,"p50_ms":1322.074499000002,"p95_ms":1679.719384,"cpu_percent":136.30044644318417,"rss_bytes":281198592,"peak_rss_bytes":281198592}}
PASS cli: 60 generated current-User reads
PASS cli: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails
PASS mcp: 60 generated current-User reads
PASS mcp: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails
PASS webmcp: 60 generated current-User reads
PASS webmcp: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails
Generated smoke coverage: {"cli":{"called":122,"missing":166},"mcp":{"called":122,"missing":166},"webmcp":{"called":122,"missing":166}}
CSP REPORTS webmcp: 0 across 1 pages

Freshness passed (exit 0): CALTERNAL_SERVER_BIN=$CARGO_TARGET_DIR/debug/calternal-server bash packages/api-client/check-generated.sh. The production web build passed. git diff --check passed. Earlier web runs hit five-second timeouts under shared-host load. Unchanged tests passed with two workers and a 20-second timeout; no existing expectations were changed.

Performance

Measured locally on the debug build. Load average: 26.65 / 24.74 / 26.71. These are not quiet-host release measurements.

Run p50 ms p95 ms CPU % peak RSS bytes
Average: 32 sequential 64 KiB transfers 40.065 59.717 49.806 228311040
Worst: 16 concurrent 1 MiB transfers 1322.074 1679.719 136.300 281198592
docs/perf/baseline.json release request storm, concurrency 24 22.8 67.3 56.49 166264832

The baseline has no matching generated-transfer profile. Before dispatch isolation, the local burst p95 was 983.151 ms; after isolation it was 1679.719 ms (+70.85%). Load and CPU differ. This does not establish a release regression. #524 records the numbers and requests a comparable release measurement under the perf VM lock.

Known gaps

  • 166 generated tools per surface still need real-server smoke fixtures. Coverage artifacts list the missing operation IDs. Do not count unit callback coverage as live smoke.
  • The live cross-User matrix and the final time-boxed adversarial round were not run. Only entry-point classification passed.
  • Claude visual review remains pending. Production screenshots cover 390, 820 and 1440 px in light and dark.
  • The MCP stack-overflow fix passed the fixture that exposed it and all server tests. Broader transport and authorization checks remain part of the unfinished live matrix.

Decisions

  • Finite SSE polls use a bounded 1–10000 ms window, default 1000 ms; only complete frames are returned. Polling keeps generated tool calls finite while preserving event cursors.
  • Raw request/response bodies have a 1 MiB budget. CLI/MCP input has a 128 KiB JSON budget; 64 KiB upload chunks fit the base64 envelope. These tools do not materialize unlimited files.
  • Eighteen actions remain excluded: onboarding/passkey login flows and three live editor CRDT WebSocket actions. Ordinary content tools remain available. Removed the obsolete appearance exemptions. Each exclusion has a user-visible reason.
  • Registry header supplements describe the existing tus, Range, SSE and guarded-edit protocol; they do not change route behavior or grant authority.
  • MCP dispatch uses a separate cancellable task to bound stack depth. Existing API session middleware still chooses the User and permissions.
  • Reused base64 0.22.1 from the lockfile, verified with cargo info, instead of adding a second version. The dependency is MIT/Apache-2.0 compatible.
  • Public helper additions are limited to harness diagnostic/PID access and the optional prebuilt freshness binary. They do not change product behavior.

Production screenshot attachments

Cleanup

cargo clean completed:

Removed 21537 files, 12.3GiB total

Removed generated web build output. Working tree is clean; screenshots and logs remain in artifacts/.

# #484 round 2: adapters complete; verification partial Head: `413eb4fad294d9eaf42c8f28fe99bb963500711b` on `job/parity-484`. Merged `origin/dev` once at the start (775d2e813). No push or deploy. Remaining adapter gaps: **0**. The registry has 306 operations and 288 generated tools per surface. Real-server smoke calls **122/288 distinct tools on each of CLI, MCP and WebMCP**. **166 tools per surface still need fixtures**. The strict full-smoke requirement is not satisfied. This job is not ready to merge. The four-hour time box requires a handoff. ## Built and files - Generated text, base64 file upload/download, HEAD, safe transfer headers and finite SSE transports: `scripts/action_registry.py`, `contracts/actions.json`, `crates/calternal-api/src/actions.rs`, `crates/calternal-cli/src/remote_commands.rs`, `crates/calternal-server/src/mcp.rs`, `apps/web/src/lib/webmcp/generated.ts`, and their tests. - Bounded browser decoding and cache bypass for generated transfers: `packages/api-client/src/index.ts` and `index.test.ts`. A finite GET cache must not read an entire stream before the transport enforces its budget. - MCP API dispatch uses a JoinSet task. A normal File move exposed a fatal worker stack overflow while the SDK and API router were polled on the same stack. The separate task fixed the same real fixture on MCP and the final combined run. Dropping the JoinSet aborts the child; the transport semaphore remains held through response processing. `crates/calternal-server/src/serve.rs` adds HTTP failure diagnostics without payloads or credentials. - Real-server production smoke, fixture plans and six confirmation screenshots: `apps/web/e2e/webmcp.mjs`, `apps/web/e2e/harness.mjs`, `tests/parity/notes-smoke.json`. Writes use a throwaway Home and the normal server APIs. Notes, templates, saved searches, Tasks, Logs, reminders, Files, Photos, Versions and public transfers have real fixtures. - Entry-point classification: `tests/adversarial/xuser_matrix.py`, `test_xuser_classification.py`. All 864 generated entry points are classified. This is not a completed live cross-User run. - Current contract regeneration and prebuilt-binary freshness option: `contracts/openapi.json`, `packages/api-client/src/generated.ts`, `packages/api-client/check-generated.sh`. The default CI path still builds. The supplied binary was built from this checkout. - Parity documentation and profile: `docs/action-registry.md`, `docs/parity-matrix.md`, `docs/parity-exceptions.json`, `scripts/parity_matrix.py`, `scripts/test_action_registry.py`, `bench/parity.sh`, `crates/calternal-api/Cargo.toml`, `Cargo.lock`. ## Verification All Rust commands used CARGO_PROFILE_DEV_DEBUG=line-tables-only, CARGO_INCREMENTAL=0 and CARGO_BUILD_JOBS=4. Gates ran per crate. Below are output lines copied verbatim from logs; complete logs remain in artifacts/. `cargo fmt --check`: no output, exit 0. `cargo clippy -p calternal-api --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 33.62s ``` `cargo test -p calternal-api` ```text test result: ok. 8 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-cli --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 28s ``` `cargo test -p calternal-cli` ```text test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.76s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.11s ``` `cargo clippy -p calternal-server --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 3m 20s ``` `cargo test -p calternal-server` ```text test result: ok. 87 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 32.79s ``` `cargo clippy -p calternal-auth --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 12m 50s ``` `cargo test -p calternal-auth` ```text test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 97.23s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `cargo clippy -p calternal-notes --all-targets -- -D warnings` ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 18m 26s ``` `cargo test -p calternal-notes` ```text test result: ok. 126 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 199.14s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.89s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` `bun run --cwd apps/web check` ```text svelte-check found 0 errors and 0 warnings ``` `bun run --cwd apps/web test --maxWorkers 2 --testTimeout 20000` ```text Test Files 138 passed (138) Tests 896 passed (896) ``` `API client tests` ```text 17 pass 0 fail Ran 17 tests across 1 file. [1139.00ms] ``` `Registry generator tests` ```text Ran 10 tests in 0.173s OK ``` `Parity matrix tests` ```text Ran 4 tests in 0.005s OK ``` `round2-registry-check-final.log` ```text Action registry: 306 operations, 288 generated tools ``` `round2-parity-check-final.log` ```text Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps ``` `round2-crossuser-classification.log` ```text Cross-User classification gate: 308 operations classified Generated entry point classification: 864 tools classified ``` `round2-smoke-final.log` ```text Generated transfer performance: {"environment":{"label":"local","build":"debug","cpus":8,"load_average":[26.65,24.74,26.71]},"average":{"count":32,"concurrency":1,"response_bytes":65536,"p50_ms":40.06459199999881,"p95_ms":59.71684699999969,"cpu_percent":49.80589120474907,"rss_bytes":228311040,"peak_rss_bytes":228311040},"worst":{"count":16,"concurrency":16,"response_bytes":1048576,"p50_ms":1322.074499000002,"p95_ms":1679.719384,"cpu_percent":136.30044644318417,"rss_bytes":281198592,"peak_rss_bytes":281198592}} PASS cli: 60 generated current-User reads PASS cli: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails PASS mcp: 60 generated current-User reads PASS mcp: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails PASS webmcp: 60 generated current-User reads PASS webmcp: tus create/offset/chunk/terminate, byte download/range/zip, five finite SSE polls, TOML read, public file drop/download/edit, Version download/restore, Photos upload/thumbnails Generated smoke coverage: {"cli":{"called":122,"missing":166},"mcp":{"called":122,"missing":166},"webmcp":{"called":122,"missing":166}} CSP REPORTS webmcp: 0 across 1 pages ``` Freshness passed (exit 0): `CALTERNAL_SERVER_BIN=$CARGO_TARGET_DIR/debug/calternal-server bash packages/api-client/check-generated.sh`. The production web build passed. `git diff --check` passed. Earlier web runs hit five-second timeouts under shared-host load. Unchanged tests passed with two workers and a 20-second timeout; no existing expectations were changed. ## Performance Measured locally on the debug build. Load average: 26.65 / 24.74 / 26.71. These are not quiet-host release measurements. | Run | p50 ms | p95 ms | CPU % | peak RSS bytes | | --- | ---: | ---: | ---: | ---: | | Average: 32 sequential 64 KiB transfers | 40.065 | 59.717 | 49.806 | 228311040 | | Worst: 16 concurrent 1 MiB transfers | 1322.074 | 1679.719 | 136.300 | 281198592 | | docs/perf/baseline.json release request storm, concurrency 24 | 22.8 | 67.3 | 56.49 | 166264832 | The baseline has no matching generated-transfer profile. Before dispatch isolation, the local burst p95 was 983.151 ms; after isolation it was 1679.719 ms (+70.85%). Load and CPU differ. This does not establish a release regression. [#524](https://git.kayg.org/kayg/calternal/issues/524) records the numbers and requests a comparable release measurement under the perf VM lock. ## Known gaps - 166 generated tools per surface still need real-server smoke fixtures. Coverage artifacts list the missing operation IDs. Do not count unit callback coverage as live smoke. - The live cross-User matrix and the final time-boxed adversarial round were not run. Only entry-point classification passed. - Claude visual review remains pending. Production screenshots cover 390, 820 and 1440 px in light and dark. - The MCP stack-overflow fix passed the fixture that exposed it and all server tests. Broader transport and authorization checks remain part of the unfinished live matrix. ## Decisions - Finite SSE polls use a bounded 1–10000 ms window, default 1000 ms; only complete frames are returned. Polling keeps generated tool calls finite while preserving event cursors. - Raw request/response bodies have a 1 MiB budget. CLI/MCP input has a 128 KiB JSON budget; 64 KiB upload chunks fit the base64 envelope. These tools do not materialize unlimited files. - Eighteen actions remain excluded: onboarding/passkey login flows and three live editor CRDT WebSocket actions. Ordinary content tools remain available. Removed the obsolete appearance exemptions. Each exclusion has a user-visible reason. - Registry header supplements describe the existing tus, Range, SSE and guarded-edit protocol; they do not change route behavior or grant authority. - MCP dispatch uses a separate cancellable task to bound stack depth. Existing API session middleware still chooses the User and permissions. - Reused base64 0.22.1 from the lockfile, verified with cargo info, instead of adding a second version. The dependency is MIT/Apache-2.0 compatible. - Public helper additions are limited to harness diagnostic/PID access and the optional prebuilt freshness binary. They do not change product behavior. ## Production screenshot attachments - [webmcp-confirm-1440-dark.png](https://git.kayg.org/attachments/56c5fc4e-e387-4300-bc6d-b98ed59e0a7b) - [webmcp-confirm-1440-light.png](https://git.kayg.org/attachments/2e8e6a34-318d-4ac5-a6b0-ab64b5d3080b) - [webmcp-confirm-390-dark.png](https://git.kayg.org/attachments/762a17d3-f679-4b95-b41f-73eb5b82aff7) - [webmcp-confirm-390-light.png](https://git.kayg.org/attachments/225d798a-7217-4ec9-8887-315fce4a7508) - [webmcp-confirm-820-dark.png](https://git.kayg.org/attachments/34f7e8b1-439d-4d79-89d3-f7f1532f935b) - [webmcp-confirm-820-light.png](https://git.kayg.org/attachments/ebb6672e-b1e0-4658-8496-538823b08193) ## Cleanup `cargo clean` completed: ```text Removed 21537 files, 12.3GiB total ``` Removed generated web build output. Working tree is clean; screenshots and logs remain in artifacts/.
Author
Owner

Resumed #484 round 3 on job/parity-484 from 413eb4fad2. Fetch and merge origin/dev in progress. Resolve generated parity conflicts from the current contract. Verify real-server fixtures and positive/negative authorization checks on local throwaway data. No push or deploy.

Resumed #484 round 3 on job/parity-484 from 413eb4fad294d9eaf42c8f28fe99bb963500711b. Fetch and merge origin/dev in progress. Resolve generated parity conflicts from the current contract. Verify real-server fixtures and positive/negative authorization checks on local throwaway data. No push or deploy.
Author
Owner

Round 3 finding: all three generated adapters reject / in every path parameter. The Tags API uses /items/{*path} for a Home-relative path and /{*tag} for a namespaced Tag (crates/calternal-tags/src/lib.rs:435,439). Thus an ordinary nested Note path cannot call get_file_assignment, and an area/verification Tag cannot call tag_page through generated tools. This is an adapter mismatch; the API owns the path validation.

The registry now marks only path/tag slots with x-calternal-allow-slash. Rust CLI/MCP and WebMCP encode their separators within the selected route. Item ID validation stays in place. New generator, Rust and WebMCP tests cover ordinary nested Home paths and namespaced Tags. Generator tests pass (15); WebMCP adapter tests pass (9). Rust checks and real-server verification are running.

Round 3 finding: all three generated adapters reject `/` in every path parameter. The Tags API uses `/items/{*path}` for a Home-relative path and `/{*tag}` for a namespaced Tag (`crates/calternal-tags/src/lib.rs:435,439`). Thus an ordinary nested Note path cannot call get_file_assignment, and an area/verification Tag cannot call tag_page through generated tools. This is an adapter mismatch; the API owns the path validation. The registry now marks only path/tag slots with x-calternal-allow-slash. Rust CLI/MCP and WebMCP encode their separators within the selected route. Item ID validation stays in place. New generator, Rust and WebMCP tests cover ordinary nested Home paths and namespaced Tags. Generator tests pass (15); WebMCP adapter tests pass (9). Rust checks and real-server verification are running.
Author
Owner

Verification progress: merged origin/dev at c4e7eac15. Current registry: 306 operations, 288 tools per surface, 0 adapter gaps. Offline classification: 864 generated entry points. Generator/fixture gate: 15 tests passed. Full web suite: 138 files, 907 tests passed. New wildcard transport tests: 9 passed. Web check: 0 errors and 0 warnings.

Added real API fixture recipes for additional Notes, Logs, Calendar reads, Tags, Mail preferences, Photos settings and Money actions. Added a 39-action standard-User admin denial plan and two-User Note read/update/Trash checks for CLI, MCP and WebMCP. These are awaiting the real-server run, not yet verified. Server/CLI cold build is still running. Broader provider-backed fixtures and the full live cross-User matrix remain incomplete.

Verification progress: merged origin/dev at c4e7eac15. Current registry: 306 operations, 288 tools per surface, 0 adapter gaps. Offline classification: 864 generated entry points. Generator/fixture gate: 15 tests passed. Full web suite: 138 files, 907 tests passed. New wildcard transport tests: 9 passed. Web check: 0 errors and 0 warnings. Added real API fixture recipes for additional Notes, Logs, Calendar reads, Tags, Mail preferences, Photos settings and Money actions. Added a 39-action standard-User admin denial plan and two-User Note read/update/Trash checks for CLI, MCP and WebMCP. These are awaiting the real-server run, not yet verified. Server/CLI cold build is still running. Broader provider-backed fixtures and the full live cross-User matrix remain incomplete.
Author
Owner

Real-server smoke finding: the Tag rename tools reach the API and return HTTP 422 when input follows the generated schema. Files and Tags both declare a Rust type named RenameInput. Files defines path/name; Tags defines old_tag/new_tag (crates/calternal-tags/src/lib.rs:228). The combined OpenAPI component RenameInput contains only path/name, so both Tag operations inherit the wrong request body. No server crash occurred.

The fix is in the OpenAPI composer, not a per-tool override. It renames only conflicting incoming component schemas and updates their local references. It repeats this step for containers whose child references changed. Identical shared DTOs keep their names. Handler behavior is unchanged. Regression tests check transitive references and both real Tag rename routes. Rust gates and regeneration are in progress.

The fixture recipes also now use a toggleable plugin (Photos), an existing Notes/ subfolder for move_note, and a real binary File for Files Tag assignment. The existing Notes move and Tag assignment handlers require those inputs. Notes store their Tags through Note content operations.

Real-server smoke finding: the Tag rename tools reach the API and return HTTP 422 when input follows the generated schema. Files and Tags both declare a Rust type named RenameInput. Files defines path/name; Tags defines old_tag/new_tag (crates/calternal-tags/src/lib.rs:228). The combined OpenAPI component RenameInput contains only path/name, so both Tag operations inherit the wrong request body. No server crash occurred. The fix is in the OpenAPI composer, not a per-tool override. It renames only conflicting incoming component schemas and updates their local references. It repeats this step for containers whose child references changed. Identical shared DTOs keep their names. Handler behavior is unchanged. Regression tests check transitive references and both real Tag rename routes. Rust gates and regeneration are in progress. The fixture recipes also now use a toggleable plugin (Photos), an existing Notes/ subfolder for move_note, and a real binary File for Files Tag assignment. The existing Notes move and Tag assignment handlers require those inputs. Notes store their Tags through Note content operations.
Author
Owner

Round 3 contract fix committed at b7a7cf3ac, generated contracts at 89b906d10. The shared OpenAPI composer now qualifies only different schemas with the same component name and rewrites typed references, including transitive containers. Tags RenameInput and TagCount were both affected. The Tag rename schema now requires old_tag/new_tag; the Files rename schema retains path/name. Two server regression tests pass, the API client has 17 passing tests, parity remains 0 gaps, and freshness passes. Standard User checks pass for all 39 admin tools through CLI/MCP and tool absence in WebMCP; the two-User Note read/update/Trash check passes on all three surfaces. Full live smoke is running; full two-User coverage is still open. Local debug benchmark results and exact counts will be included in the final report.

Round 3 contract fix committed at b7a7cf3ac, generated contracts at 89b906d10. The shared OpenAPI composer now qualifies only different schemas with the same component name and rewrites typed references, including transitive containers. Tags RenameInput and TagCount were both affected. The Tag rename schema now requires old_tag/new_tag; the Files rename schema retains path/name. Two server regression tests pass, the API client has 17 passing tests, parity remains 0 gaps, and freshness passes. Standard User checks pass for all 39 admin tools through CLI/MCP and tool absence in WebMCP; the two-User Note read/update/Trash check passes on all three surfaces. Full live smoke is running; full two-User coverage is still open. Local debug benchmark results and exact counts will be included in the final report.
Author
Owner

The real-server CLI smoke reached 151/288 distinct successful tools, then ordinary rename_tag failed with network exit code 9. The harness reported stackOverflow=true and healthy=false. This is a merge blocker. A shared server API dispatch boundary is in progress: handlers run in a cancellable task outside the enclosing HTTP middleware stack, analogous to the existing MCP API dispatch boundary. A regression test checks that cancelling one request drops its handler. The fix applies to all actions; it does not change Tag inputs or per-tool implementations. Server gates and a fresh real-server smoke are pending.

The real-server CLI smoke reached 151/288 distinct successful tools, then ordinary rename_tag failed with network exit code 9. The harness reported stackOverflow=true and healthy=false. This is a merge blocker. A shared server API dispatch boundary is in progress: handlers run in a cancellable task outside the enclosing HTTP middleware stack, analogous to the existing MCP API dispatch boundary. A regression test checks that cancelling one request drops its handler. The fix applies to all actions; it does not change Tag inputs or per-tool implementations. Server gates and a fresh real-server smoke are pending.
Author
Owner

Local native HLS probe: the existing source-generated.mp4 fixture uploads through Files and video_source_by_item returns the correct 8-byte range through CLI. The HLS readiness probe returned HTTP 202 on all 58 polls in its 60-second deadline. Local load averages were [23.21, 24.51, 28.00] on 8 CPUs. The server stayed healthy, with no panic or stack overflow; no 5xx was observed in this probe. This is pending/SLOW-only evidence, not successful playlist/segment smoke. HLS verification remains open. The probe is retained behind --hls-fixtures, while the common smoke now includes the real Video source fixture. Full three-surface smoke is running again; final counts will be posted separately.

Local native HLS probe: the existing source-generated.mp4 fixture uploads through Files and video_source_by_item returns the correct 8-byte range through CLI. The HLS readiness probe returned HTTP 202 on all 58 polls in its 60-second deadline. Local load averages were [23.21, 24.51, 28.00] on 8 CPUs. The server stayed healthy, with no panic or stack overflow; no 5xx was observed in this probe. This is pending/SLOW-only evidence, not successful playlist/segment smoke. HLS verification remains open. The probe is retained behind --hls-fixtures, while the common smoke now includes the real Video source fixture. Full three-surface smoke is running again; final counts will be posted separately.
Author
Owner

#484 round 3 verification — not ready to merge

Branch: job/parity-484
Head: e83efa1686ed15beec05605b25c53975d52c13c1
Base: 413eb4fad. Merged origin/dev once at c4e7eac15. No push, deployment, or merge into dev/main was performed.

Built

  • Shared adapter mapping preserves encoded Home paths and Tag namespaces while retaining single-segment item IDs.
  • Shared OpenAPI composition preserves different plugin schemas with the same name, including transitive references. Tags RenameInput and TagCount no longer use Files/Notes schemas.
  • Shared core/plugin API dispatch uses a request-owned task. Ordinary Tag rename previously overflowed a worker stack; the corrected live smoke passes on all three surfaces. A regression test proves cancellation drops the handler.
  • Real API fixture plans cover Notes, Logs, Calendar, Tags, Money, Analytics, Files pins and bookmarks. Video source ranges use the existing licensed MP4 fixture. Writes use a throwaway Home; CLI mutations use --confirm.
  • Live standard User checks cover every admin tool. Seven private Note routes are checked on all surfaces. The benchmark adds nested Home path lookups.

Smoke and matrices

The full target remains unmet. Counts are distinct successful operation IDs per surface. Rejected calls and inventory entries are not positive smoke.

Surface Successful Target Remaining
cli 170 288 118
mcp 170 288 118
webmcp 170 288 118

Total: 510/864 generated entry points. This adds 48 verified tools per surface to the previous 122.

  • Standard User: 39 admin routes return API 403 through CLI and MCP (78 requests). All 39 admin tools are absent in WebMCP. MCP wraps the API denial as a JSON-RPC error over HTTP 400; the test checks the API status in that error.
  • Two-User: get_note, note_backlinks, notes_list_block_reminders, update_body, retitle, move_note and notes_trash deny User B on every surface (21 requests). A content, revision and path stay unchanged.
  • Offline classification: 308 API operations and 864 generated entry points classified. This does not prove the full live matrix.
Route group Successful per surface Eligible per surface
admin 12 30
ai 2 10
analytics 1 1
appearance 2 5
apps 1 2
auth 7 33
calendar 10 24
files 32 37
jobs 2 4
mail 4 21
money 12 13
notes 41 47
notifications 5 12
photos 10 12
plugins 2 2
public 11 14
search 7 8
system 1 1
tags 7 8
video 1 4

Gates — verbatim output

cargo fmt --check exited 0 with no output. Rust commands used CARGO_BUILD_JOBS=4, CARGO_INCREMENTAL=0 and CARGO_PROFILE_DEV_DEBUG=line-tables-only.

API clippy

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 7m 41s

API tests

    Finished `test` profile [unoptimized + debuginfo] target(s) in 11.80s
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

CLI clippy

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

CLI tests

    Finished `test` profile [unoptimized + debuginfo] target(s) in 1m 12s
test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.77s
test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s

Server clippy

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

Server tests

    Finished `test` profile [unoptimized + debuginfo] target(s) in 8m 19s
test result: ok. 90 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 16.31s

Auth clippy

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

Auth tests

    Finished `test` profile [unoptimized + debuginfo] target(s) in 15m 20s
test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 96.48s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Notes clippy

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

Notes tests

    Finished `test` profile [unoptimized + debuginfo] target(s) in 13m 39s
test result: ok. 126 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 263.94s
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.82s
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

Web check

svelte-check found 0 errors and 0 warnings

Web tests

 Test Files  138 passed (138)
      Tests  908 passed (908)

API client tests

 17 pass
 0 fail
Ran 17 tests across 1 file. [4.01s]

Generator tests

Ran 15 tests in 0.656s
OK

Registry

Action registry: 306 operations, 288 generated tools

Parity

Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps

Classification

Cross-User classification gate: 308 operations classified
Generated entry point classification: 864 tools classified

Freshness

$ bunx --package openapi-typescript@7.13.0 openapi-typescript ../../contracts/openapi.json -o src/generated.ts
✨ openapi-typescript 7.13.0
🚀 ../../contracts/openapi.json → src/generated.ts [4.9s]

Live smoke

PASS WebMCP standard User: 39 admin tools unavailable
PASS standard User: 39 admin routes denied through each of CLI and MCP
PASS two-User Note checks: 7 routes denied on each of CLI, MCP, WebMCP; A content, revision and path unchanged
Generated smoke coverage: {"cli":{"called":170,"missing":118},"mcp":{"called":170,"missing":118},"webmcp":{"called":170,"missing":118}}
CSP REPORTS webmcp: 0 across 2 pages

Performance

Local debug build, 8 CPUs, load averages [43.91, 41.07, 38.01]. The release baseline uses different requests and payloads. There is no matching transfer/wildcard baseline, so these numbers do not establish a release regression. Release confirmation remains in #524.

Profile p50 ms p95 ms CPU % Peak RSS bytes
Release baseline request storm (docs/perf/baseline.json) 22.80 67.30 56.49 166264832
Local 64 KiB transfer, sequential 139.42 319.23 15.83 230608896
Local 1 MiB transfer, burst 16 2394.52 2826.45 83.90 291803136
Local Nested path lookup, sequential 11.43 42.37 41.22 291827712
Local Nested path lookup, burst 16 31.52 40.06 147.41 291852288

Known gaps

  • 118 tools per surface still need successful real fixtures. The full missing-ID inventory is in artifacts/round3-smoke-complete.json. Remaining groups include admin jobs, account ceremonies, provider-backed AI/Mail/Calendar, private/share/reminder and native HLS operations. Zero adapter gaps does not close verification gaps.
  • The full live two-User and authorization matrices across all 864 entries were not completed. Live coverage is the admin and seven-Note-route checks above.
  • The requested adversarial round was not completed. Exploit-style protocol abuse and cancellation storms were not executed under this agent's CY safemode restrictions. Live malformed/oversized validation remains unverified. Finite SSE functional smoke and one cancellation regression passed; they do not substitute for that round.
  • Native HLS remained HTTP 202 on all 58 polls within 60 seconds. Load averages were [23.21, 24.51, 28.00] on 8 CPUs. The server stayed healthy with no panic, stack overflow or observed 5xx in that probe. No playlist/segment tool is counted as verified. --hls-fixtures retains the probe.
  • Performance was measured locally, not on the release perf VM. Largest realistic Home/provider datasets remain unmeasured for this profile.

Decisions

  • Mark Home path and Tag parameter slots as slash-capable; preserve the item-ID guard.
  • Qualify only conflicting incoming schema names with the fragment title. Keep identical shared DTO names. Rewrite typed references rather than serialize the OpenAPI model.
  • Use an owned cancellable task for core/plugin API dispatch, instead of changing individual tool handlers or increasing worker stack sizes.
  • Keep fixture identities and revisions from API results, with names separated per surface. Require a real 200 rendition for native HLS content smoke; retain pending readiness as an explicit probe.

Files

  • apps/web/e2e/webmcp.mjs
  • apps/web/src/lib/webmcp/generated.test.ts
  • apps/web/src/lib/webmcp/generated.ts
  • bench/parity.sh
  • contracts/actions.json
  • contracts/openapi.json
  • crates/calternal-api/src/actions.rs
  • crates/calternal-server/src/main.rs
  • docs/action-registry.md
  • packages/api-client/src/generated.ts
  • scripts/action_registry.py
  • scripts/test_action_registry.py
  • tests/parity/admin-denial.json
  • tests/parity/notes-smoke.json

Merge conflict resolutions also touched docs/parity-exceptions.json and docs/parity-matrix.md. No screenshots or review artifacts were committed.

Production screenshots

Six fresh production-build screenshots are attached for Claude review: 390, 820 and 1440 px, light and dark. No visual quality judgment is claimed.

Cleanup

     Removed 21632 files, 12.9GiB total

Web build output and Python cache were removed. The worktree is clean. Automatic approval review rejected the combined rm -f style cleanup command; cleanup was completed with cargo clean and checked, named directory deletion instead.

# #484 round 3 verification — not ready to merge Branch: job/parity-484 Head: `e83efa1686ed15beec05605b25c53975d52c13c1` Base: 413eb4fad. Merged origin/dev once at c4e7eac15. No push, deployment, or merge into dev/main was performed. ## Built - Shared adapter mapping preserves encoded Home paths and Tag namespaces while retaining single-segment item IDs. - Shared OpenAPI composition preserves different plugin schemas with the same name, including transitive references. Tags RenameInput and TagCount no longer use Files/Notes schemas. - Shared core/plugin API dispatch uses a request-owned task. Ordinary Tag rename previously overflowed a worker stack; the corrected live smoke passes on all three surfaces. A regression test proves cancellation drops the handler. - Real API fixture plans cover Notes, Logs, Calendar, Tags, Money, Analytics, Files pins and bookmarks. Video source ranges use the existing licensed MP4 fixture. Writes use a throwaway Home; CLI mutations use --confirm. - Live standard User checks cover every admin tool. Seven private Note routes are checked on all surfaces. The benchmark adds nested Home path lookups. ## Smoke and matrices The full target remains unmet. Counts are distinct successful operation IDs per surface. Rejected calls and inventory entries are not positive smoke. | Surface | Successful | Target | Remaining | |---|---:|---:|---:| | cli | 170 | 288 | 118 | | mcp | 170 | 288 | 118 | | webmcp | 170 | 288 | 118 | Total: 510/864 generated entry points. This adds 48 verified tools per surface to the previous 122. - Standard User: 39 admin routes return API 403 through CLI and MCP (78 requests). All 39 admin tools are absent in WebMCP. MCP wraps the API denial as a JSON-RPC error over HTTP 400; the test checks the API status in that error. - Two-User: get_note, note_backlinks, notes_list_block_reminders, update_body, retitle, move_note and notes_trash deny User B on every surface (21 requests). A content, revision and path stay unchanged. - Offline classification: 308 API operations and 864 generated entry points classified. This does not prove the full live matrix. | Route group | Successful per surface | Eligible per surface | |---|---:|---:| | admin | 12 | 30 | | ai | 2 | 10 | | analytics | 1 | 1 | | appearance | 2 | 5 | | apps | 1 | 2 | | auth | 7 | 33 | | calendar | 10 | 24 | | files | 32 | 37 | | jobs | 2 | 4 | | mail | 4 | 21 | | money | 12 | 13 | | notes | 41 | 47 | | notifications | 5 | 12 | | photos | 10 | 12 | | plugins | 2 | 2 | | public | 11 | 14 | | search | 7 | 8 | | system | 1 | 1 | | tags | 7 | 8 | | video | 1 | 4 | ## Gates — verbatim output cargo fmt --check exited 0 with no output. Rust commands used CARGO_BUILD_JOBS=4, CARGO_INCREMENTAL=0 and CARGO_PROFILE_DEV_DEBUG=line-tables-only. **API clippy** ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 7m 41s ``` **API tests** ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 11.80s test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` **CLI clippy** ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 6m 52s ``` **CLI tests** ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 1m 12s test result: ok. 28 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.77s test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.18s ``` **Server clippy** ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 4m 03s ``` **Server tests** ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 8m 19s test result: ok. 90 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 16.31s ``` **Auth clippy** ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 8m 44s ``` **Auth tests** ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 15m 20s test result: ok. 63 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 96.48s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` **Notes clippy** ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 14m 57s ``` **Notes tests** ```text Finished `test` profile [unoptimized + debuginfo] target(s) in 13m 39s test result: ok. 126 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 263.94s test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.82s test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s ``` **Web check** ```text svelte-check found 0 errors and 0 warnings ``` **Web tests** ```text Test Files 138 passed (138) Tests 908 passed (908) ``` **API client tests** ```text 17 pass 0 fail Ran 17 tests across 1 file. [4.01s] ``` **Generator tests** ```text Ran 15 tests in 0.656s OK ``` **Registry** ```text Action registry: 306 operations, 288 generated tools ``` **Parity** ```text Parity matrix: 306 API actions, 113 shortcuts, 2 static commands, 131 menu actions, 30 settings groups, 0 actions with adapter gaps ``` **Classification** ```text Cross-User classification gate: 308 operations classified Generated entry point classification: 864 tools classified ``` **Freshness** ```text $ bunx --package openapi-typescript@7.13.0 openapi-typescript ../../contracts/openapi.json -o src/generated.ts ✨ openapi-typescript 7.13.0 🚀 ../../contracts/openapi.json → src/generated.ts [4.9s] ``` **Live smoke** ```text PASS WebMCP standard User: 39 admin tools unavailable PASS standard User: 39 admin routes denied through each of CLI and MCP PASS two-User Note checks: 7 routes denied on each of CLI, MCP, WebMCP; A content, revision and path unchanged Generated smoke coverage: {"cli":{"called":170,"missing":118},"mcp":{"called":170,"missing":118},"webmcp":{"called":170,"missing":118}} CSP REPORTS webmcp: 0 across 2 pages ``` ## Performance Local debug build, 8 CPUs, load averages [43.91, 41.07, 38.01]. The release baseline uses different requests and payloads. There is no matching transfer/wildcard baseline, so these numbers do not establish a release regression. Release confirmation remains in #524. | Profile | p50 ms | p95 ms | CPU % | Peak RSS bytes | |---|---:|---:|---:|---:| | Release baseline request storm (docs/perf/baseline.json) | 22.80 | 67.30 | 56.49 | 166264832 | | Local 64 KiB transfer, sequential | 139.42 | 319.23 | 15.83 | 230608896 | | Local 1 MiB transfer, burst 16 | 2394.52 | 2826.45 | 83.90 | 291803136 | | Local Nested path lookup, sequential | 11.43 | 42.37 | 41.22 | 291827712 | | Local Nested path lookup, burst 16 | 31.52 | 40.06 | 147.41 | 291852288 | ## Known gaps - 118 tools per surface still need successful real fixtures. The full missing-ID inventory is in artifacts/round3-smoke-complete.json. Remaining groups include admin jobs, account ceremonies, provider-backed AI/Mail/Calendar, private/share/reminder and native HLS operations. Zero adapter gaps does not close verification gaps. - The full live two-User and authorization matrices across all 864 entries were not completed. Live coverage is the admin and seven-Note-route checks above. - The requested adversarial round was not completed. Exploit-style protocol abuse and cancellation storms were not executed under this agent's CY safemode restrictions. Live malformed/oversized validation remains unverified. Finite SSE functional smoke and one cancellation regression passed; they do not substitute for that round. - Native HLS remained HTTP 202 on all 58 polls within 60 seconds. Load averages were [23.21, 24.51, 28.00] on 8 CPUs. The server stayed healthy with no panic, stack overflow or observed 5xx in that probe. No playlist/segment tool is counted as verified. --hls-fixtures retains the probe. - Performance was measured locally, not on the release perf VM. Largest realistic Home/provider datasets remain unmeasured for this profile. ## Decisions - Mark Home path and Tag parameter slots as slash-capable; preserve the item-ID guard. - Qualify only conflicting incoming schema names with the fragment title. Keep identical shared DTO names. Rewrite typed references rather than serialize the OpenAPI model. - Use an owned cancellable task for core/plugin API dispatch, instead of changing individual tool handlers or increasing worker stack sizes. - Keep fixture identities and revisions from API results, with names separated per surface. Require a real 200 rendition for native HLS content smoke; retain pending readiness as an explicit probe. ## Files - `apps/web/e2e/webmcp.mjs` - `apps/web/src/lib/webmcp/generated.test.ts` - `apps/web/src/lib/webmcp/generated.ts` - `bench/parity.sh` - `contracts/actions.json` - `contracts/openapi.json` - `crates/calternal-api/src/actions.rs` - `crates/calternal-server/src/main.rs` - `docs/action-registry.md` - `packages/api-client/src/generated.ts` - `scripts/action_registry.py` - `scripts/test_action_registry.py` - `tests/parity/admin-denial.json` - `tests/parity/notes-smoke.json` Merge conflict resolutions also touched docs/parity-exceptions.json and docs/parity-matrix.md. No screenshots or review artifacts were committed. ## Production screenshots Six fresh production-build screenshots are attached for Claude review: 390, 820 and 1440 px, light and dark. No visual quality judgment is claimed. - [webmcp-confirm-1440-dark.png](https://git.kayg.org/attachments/5006f5d4-5d0d-4ab8-a458-69fd9cc1bf61) - [webmcp-confirm-1440-light.png](https://git.kayg.org/attachments/99a56d45-1f34-4010-b404-984cb3fde286) - [webmcp-confirm-390-dark.png](https://git.kayg.org/attachments/7f143599-e808-440d-9e3a-22ac9575e061) - [webmcp-confirm-390-light.png](https://git.kayg.org/attachments/e42b9c35-93b2-4723-988f-f8f180e9df4c) - [webmcp-confirm-820-dark.png](https://git.kayg.org/attachments/9094cec2-4234-4157-92a6-c7080d46bad5) - [webmcp-confirm-820-light.png](https://git.kayg.org/attachments/431a16b8-b2ed-4ce6-85f8-efef017bf630) ## Cleanup ```text Removed 21632 files, 12.9GiB total ``` Web build output and Python cache were removed. The worktree is clean. Automatic approval review rejected the combined rm -f style cleanup command; cleanup was completed with cargo clean and checked, named directory deletion instead.
Author
Owner

Registry core shipped in merge round 4 (1af8ead26). Still open: real fixtures for the 118 unverified tools (parity-fixtures follow-up).

Registry core shipped in merge round 4 (1af8ead26). Still open: real fixtures for the 118 unverified tools (parity-fixtures follow-up).
Author
Owner

Research and review started on job/research-surfaces.
Base SHA: c4a61e8cf090170f35b1bed3350d9de20c83ecd5.
Scope: current protocol research, source review, User capability matrix, and grouped follow-up issues. The checkout already has registry-generated adapters. I will distinguish bound adapters from complete workflows and live verification. No runtime feature changes, push or deploy are planned.

Research and review started on `job/research-surfaces`. Base SHA: `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. Scope: current protocol research, source review, User capability matrix, and grouped follow-up issues. The checkout already has registry-generated adapters. I will distinguish bound adapters from complete workflows and live verification. No runtime feature changes, push or deploy are planned.
Author
Owner

Source review finding for #484:

  • Current checks pass: 333 API operations, 315 generated tools, zero non-exempt adapter gaps.
  • contracts/openapi.json has no global or operation security declarations and no security schemes. 63/333 operations have summaries; 3/333 have descriptions. Generated scope metadata comes from authorization test categories, not OpenAPI.
  • mcp.rs:registered_tool_router emits generated JSON in a text block; generated_tool_definitions supplies no output schema. list_tools ignores its cursor. API domain errors become JSON-RPC errors.
  • CLI already has global JSON, versioned envelopes, stable documented exit codes and a server-bound environment credential. Its missing pieces include generated input-file support, completion, area discovery and consistent write confirmation.
  • The static parity gate leaves 145 menu rows and dynamic UI actions unaudited. Historical smoke evidence covers 170/288 operations per surface, not today's 315-operation set.

First atomic commit: d94134024 (standards research and source review). Next slice adds the capability matrix and grouped follow-up issues. These are review findings; no live authorization failure or duplicate mutation was reproduced.

Decisions: distinguish route coverage from workflow parity; keep existing route gate; do not implement optional protocol features or OPEN product decisions in this research job.

Source review finding for #484: - Current checks pass: 333 API operations, 315 generated tools, zero non-exempt adapter gaps. - `contracts/openapi.json` has no global or operation security declarations and no security schemes. 63/333 operations have summaries; 3/333 have descriptions. Generated scope metadata comes from authorization test categories, not OpenAPI. - `mcp.rs:registered_tool_router` emits generated JSON in a text block; `generated_tool_definitions` supplies no output schema. `list_tools` ignores its cursor. API domain errors become JSON-RPC errors. - CLI already has global JSON, versioned envelopes, stable documented exit codes and a server-bound environment credential. Its missing pieces include generated input-file support, completion, area discovery and consistent write confirmation. - The static parity gate leaves 145 menu rows and dynamic UI actions unaudited. Historical smoke evidence covers 170/288 operations per surface, not today's 315-operation set. First atomic commit: `d94134024` (standards research and source review). Next slice adds the capability matrix and grouped follow-up issues. These are review findings; no live authorization failure or duplicate mutation was reproduced. Decisions: distinguish route coverage from workflow parity; keep existing route gate; do not implement optional protocol features or OPEN product decisions in this research job.
Author
Owner

Concrete semantic parity finding:

PATCH /api/v1/notes/{id}/properties references PropertiesPatch. The checked-in schema requires Task task_id and describes fields/tags. The Note handler in crates/plugins/notes/src/lib.rs expects title, tags and properties; the second same-named type is in tasks_api.rs. The registry inherits the wrong schema. The web client uses its own Note property type. Raw adapter dispatch can still send valid server fields, so this is partial contract/tool parity rather than an absent route.

The web client's comment about three query/path defects is stale: those parameter locations are correct in this checkout. I checked the current contract instead of copying the comment.

NoteView.svelte:makeNoteFromBlock also creates a Note and then changes the source in the browser editor. The child-block behavior setting is local to the browser Settings store. Neither is a single shared registry intent. The matrix records these as partial workflow parity and a missing behavior preference, respectively.

Matrix commit: see branch head. It covers 58 User capability groups, all 333 routes, all 145 static menu entries and all 126 shortcut entries. No live exploit or failed authorization was reproduced by this source review.

Concrete semantic parity finding: `PATCH /api/v1/notes/{id}/properties` references `PropertiesPatch`. The checked-in schema requires Task `task_id` and describes `fields`/`tags`. The Note handler in `crates/plugins/notes/src/lib.rs` expects `title`, `tags` and `properties`; the second same-named type is in `tasks_api.rs`. The registry inherits the wrong schema. The web client uses its own Note property type. Raw adapter dispatch can still send valid server fields, so this is partial contract/tool parity rather than an absent route. The web client's comment about three query/path defects is stale: those parameter locations are correct in this checkout. I checked the current contract instead of copying the comment. `NoteView.svelte:makeNoteFromBlock` also creates a Note and then changes the source in the browser editor. The child-block behavior setting is local to the browser Settings store. Neither is a single shared registry intent. The matrix records these as partial workflow parity and a missing behavior preference, respectively. Matrix commit: see branch head. It covers 58 User capability groups, all 333 routes, all 145 static menu entries and all 126 shortcut entries. No live exploit or failed authorization was reproduced by this source review.
Author
Owner

Research/review complete for #484 on job/research-surfaces.

Head SHA: 23bdcd9d7259858dc821c09cff5f5e3d09365240.
Source/base SHA: c4a61e8cf090170f35b1bed3350d9de20c83ecd5.
The requested single fetch and merge of origin/dev returned Already up to date. No push or deploy occurred.

What was built

docs/research/agent-surfaces.md: cited current standards research; action registry, MCP, WebMCP, HTTP contract and CLI source review; 58 User capability groups; all 333 contract routes; all 145 static menu entries; all 126 shortcuts; Settings/command crosswalk; prioritized recommendations. Three atomic documentation commits: d94134024, 75f68c348, 23bdcd9d7.

Only the research document is changed. No runtime feature, route, dependency, migration or UI changed.

Findings and follow-ups

Route coverage is present: 333 operations, 315 generated tools, 18 recorded exclusions and zero non-exempt adapter gaps. Complete User workflow parity is not proved.

  • #833: contract authority and concrete Note/Task PropertiesPatch schema collision.
  • #834: UI intent bindings and complete successful/denied live fixture evidence.
  • #835: write replay risk after gateway statuses, typed errors and continuation.
  • #836: MCP structured output, domain errors, discovery and remote sign-in.
  • #837: WebMCP invocation cancellation and native browser evidence.
  • #838: shared CLI discovery, input-file support and confirmation.
  • #839: Notes, Journal, Tasks and Calendar workflows.
  • #840: Files, Photos and Sharing workflows.
  • #841: Mail continuation and save-to-Home workflow.
  • #842: Money, Search, Tags, Analytics and Location discovery.
  • #843: account/admin/AI/background-work ceremonies and discovery.

Recommendation: fix the schema collision and replay risk first; require UI bindings and real fixtures; then improve shared CLI input/discovery before area wrappers and tool-wire improvements. Existing raw adapters remain the shared write path.

Gates: output verbatim

$ cargo fmt --check
Exit status: 0
$ python3 scripts/action_registry.py --check
Action registry: 333 operations, 315 generated tools
Exit status: 0
$ python3 scripts/parity_matrix.py --check
Parity matrix: 333 API actions, 126 shortcuts, 2 static commands, 145 menu actions, 35 settings groups, 0 actions with adapter gaps
Exit status: 0
$ python3 -m unittest discover -s scripts -p test_action_registry.py
...........
----------------------------------------------------------------------
Ran 11 tests in 0.935s

OK
Exit status: 0
$ python3 -m unittest discover -s scripts -p test_parity_matrix.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.001s

OK
Exit status: 0
$ python3 artifacts/research-surfaces/verify-report.py
Research evidence check: 333 routes, 58 capabilities, 145 menus, 126 shortcuts, 11 issue links; PASS
Exit status: 0
$ git diff --check
Exit status: 0

No crate or web source changed, so per-crate clippy/test and web check/test are not applicable. No new benchmark profile or production screenshots apply to a research-only document. The merge introduced no API change, so no runtime adversarial round applies. No fresh live-server pass or performance measurement is claimed. cargo clean completed (Removed 1 file, 356B total); this job produced no web build output. Working tree is clean. All linked local files in the report exist.

The job-local document check initially counted priority labels as capability IDs. Its scope was corrected to the capability matrix without changing expected counts or production tests; the corrected output is above.

Known gaps

The matrix is source evidence, not full runtime certification. Dynamic UI mappings remain review mappings rather than production registry bindings. Historical smoke evidence is 170/288 per surface; today's denominator is 315. No full current provider/browser/credential smoke run was performed. New issues are open; no issue was closed. Source review found no reproduced authorization bypass, duplicate write or data-loss incident.

UX gaps closed

No UI code changed. The report separates raw route coverage from complete workflow coverage, records the schema defect and browser-owned block behavior, and corrects stale inventory/smoke assumptions in the review.

UX gaps left

CLI ergonomics/continuation/input/confirmation; block and Make-a-Note shared intents and child-block preference; full credential ceremonies; native invocation cancellation and current complete live proof. These are assigned to the follow-up groups.

Decisions

  • Use current source counts and label historical evidence with its actual denominator.
  • Count generated access as route coverage; mark workflow/ceremony/transfer limits separately.
  • Treat block edits and child-block choice as data/behavior; keep pure gestures and pixels exempt.
  • Treat optional resources, prompts and task extensions as enhancements, not mandatory missing adapters.
  • Keep unbuilt or OPEN product decisions separate from existing UI parity. No new product architecture was implemented.
  • Limit implementation to the requested research artifact and issue groups; runtime fixes belong to the follow-up slices.
Research/review complete for #484 on `job/research-surfaces`. Head SHA: `23bdcd9d7259858dc821c09cff5f5e3d09365240`. Source/base SHA: `c4a61e8cf090170f35b1bed3350d9de20c83ecd5`. The requested single fetch and merge of `origin/dev` returned `Already up to date.` No push or deploy occurred. ## What was built `docs/research/agent-surfaces.md`: cited current standards research; action registry, MCP, WebMCP, HTTP contract and CLI source review; 58 User capability groups; all 333 contract routes; all 145 static menu entries; all 126 shortcuts; Settings/command crosswalk; prioritized recommendations. Three atomic documentation commits: `d94134024`, `75f68c348`, `23bdcd9d7`. Only the research document is changed. No runtime feature, route, dependency, migration or UI changed. ## Findings and follow-ups Route coverage is present: 333 operations, 315 generated tools, 18 recorded exclusions and zero non-exempt adapter gaps. Complete User workflow parity is not proved. - #833: contract authority and concrete Note/Task `PropertiesPatch` schema collision. - #834: UI intent bindings and complete successful/denied live fixture evidence. - #835: write replay risk after gateway statuses, typed errors and continuation. - #836: MCP structured output, domain errors, discovery and remote sign-in. - #837: WebMCP invocation cancellation and native browser evidence. - #838: shared CLI discovery, input-file support and confirmation. - #839: Notes, Journal, Tasks and Calendar workflows. - #840: Files, Photos and Sharing workflows. - #841: Mail continuation and save-to-Home workflow. - #842: Money, Search, Tags, Analytics and Location discovery. - #843: account/admin/AI/background-work ceremonies and discovery. Recommendation: fix the schema collision and replay risk first; require UI bindings and real fixtures; then improve shared CLI input/discovery before area wrappers and tool-wire improvements. Existing raw adapters remain the shared write path. ## Gates: output verbatim ```text $ cargo fmt --check Exit status: 0 $ python3 scripts/action_registry.py --check Action registry: 333 operations, 315 generated tools Exit status: 0 $ python3 scripts/parity_matrix.py --check Parity matrix: 333 API actions, 126 shortcuts, 2 static commands, 145 menu actions, 35 settings groups, 0 actions with adapter gaps Exit status: 0 $ python3 -m unittest discover -s scripts -p test_action_registry.py ........... ---------------------------------------------------------------------- Ran 11 tests in 0.935s OK Exit status: 0 $ python3 -m unittest discover -s scripts -p test_parity_matrix.py .... ---------------------------------------------------------------------- Ran 4 tests in 0.001s OK Exit status: 0 $ python3 artifacts/research-surfaces/verify-report.py Research evidence check: 333 routes, 58 capabilities, 145 menus, 126 shortcuts, 11 issue links; PASS Exit status: 0 $ git diff --check Exit status: 0 ``` No crate or web source changed, so per-crate clippy/test and web check/test are not applicable. No new benchmark profile or production screenshots apply to a research-only document. The merge introduced no API change, so no runtime adversarial round applies. No fresh live-server pass or performance measurement is claimed. `cargo clean` completed (`Removed 1 file, 356B total`); this job produced no web build output. Working tree is clean. All linked local files in the report exist. The job-local document check initially counted priority labels as capability IDs. Its scope was corrected to the capability matrix without changing expected counts or production tests; the corrected output is above. ## Known gaps The matrix is source evidence, not full runtime certification. Dynamic UI mappings remain review mappings rather than production registry bindings. Historical smoke evidence is 170/288 per surface; today's denominator is 315. No full current provider/browser/credential smoke run was performed. New issues are open; no issue was closed. Source review found no reproduced authorization bypass, duplicate write or data-loss incident. ## UX gaps closed No UI code changed. The report separates raw route coverage from complete workflow coverage, records the schema defect and browser-owned block behavior, and corrects stale inventory/smoke assumptions in the review. ## UX gaps left CLI ergonomics/continuation/input/confirmation; block and Make-a-Note shared intents and child-block preference; full credential ceremonies; native invocation cancellation and current complete live proof. These are assigned to the follow-up groups. ## Decisions - Use current source counts and label historical evidence with its actual denominator. - Count generated access as route coverage; mark workflow/ceremony/transfer limits separately. - Treat block edits and child-block choice as data/behavior; keep pure gestures and pixels exempt. - Treat optional resources, prompts and task extensions as enhancements, not mandatory missing adapters. - Keep unbuilt or OPEN product decisions separate from existing UI parity. No new product architecture was implemented. - Limit implementation to the requested research artifact and issue groups; runtime fixes belong to the follow-up slices.
Author
Owner

This issue carries forward the parity request from #395 with a newer owner scope: one action registry, generated adapters, explicit exemptions and the fail-closed gate. DESIGN §50 places the surface controls in Settings → Apps & Devices. Recommend keeping #484 as the current tracker and linking #395 as the earlier request; carry forward only requirements that still match this design.

This issue carries forward the parity request from #395 with a newer owner scope: one action registry, generated adapters, explicit exemptions and the fail-closed gate. DESIGN §50 places the surface controls in Settings → Apps & Devices. Recommend keeping #484 as the current tracker and linking #395 as the earlier request; carry forward only requirements that still match this design.
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#484
No description provided.