Skip to content

fix: align runtime with documented contract (spec-drift code fixes)#245

Merged
jrosskopf merged 1 commit into
mainfrom
fix/spec-alignment-runtime
Jul 7, 2026
Merged

fix: align runtime with documented contract (spec-drift code fixes)#245
jrosskopf merged 1 commit into
mainfrom
fix/spec-alignment-runtime

Conversation

@jrosskopf

@jrosskopf jrosskopf commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Part 1 of the spec↔implementation drift remediation. Four fail-closed / contract fixes where the runtime had diverged from the documented behaviour:

  1. MCP resource reads fail closed on unresolved placeholdersremote_backend.rs now runs the same unfilled_placeholders guard the openapi path/body paths use; an unresolved {x} in a resource: URI degrades to an issue instead of being sent literally upstream.
  2. tenant_delete requires confirm == tenant_id — the destructive wipe was firing with no confirmation token, contrary to protocol.md §Admin surface + platform.md. Threaded through escurel-types (TenantDeleteRequest.confirm) and escurel-client; the escurel CLI echoes the operator-typed id as the confirmation (typing the id on the command line is the confirmation).
  3. tenant_export carries format_version + sha256 — the backup contract (protocol.md) promises an export-format version and a SHA-256 of the body so consumers can verify durability; the result previously had only {tarball_b64, bytes}.
  4. OTLP endpoint honours the naming convention — reads ESCUREL_OBSERVABILITY_OTLP_ENDPOINT (env = TOML key path, as the deploy docs instruct) with the bare ESCUREL_OTLP_ENDPOINT kept as a deprecated fallback.

The pure doc drift (protocol.md read/admin surface, storage.md, dx.md, platform.md, Dockerfile, CLAUDE.md CI status) is reconciled in a follow-up doc-sync PR; a dead-code cleanup PR follows that. Two larger feature gaps found in the audit — update_page optimistic concurrency (base_version/three-way-merge, new_version is a stub) and tenant_update suspend/quota/embedding — will be filed as issues.

Test plan

  • cargo test -p escurel-server --test remote_backend_toolsmcp_resource_read_fails_closed_on_unresolved_placeholder (verified red→green: disabling the guard sends the literal URI and the read stops degrading).
  • cargo test -p escurel-server --test mcp_admin_toolstenant_delete_requires_matching_confirm (missing/wrong confirm → -32602); tenant_export_then_import_round_trips now asserts format_version == 1 + sha256 matches the body.
  • escurel-cli / escurel-client admin e2e updated to pass confirm.
  • Full local gate green: fmt --check, clippy --workspace --all-targets -D warnings, test --workspace --all-targets, build --workspace --release.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.

…ixes)

A spec↔implementation audit surfaced places where the runtime diverged
from its documented contract. Four fail-closed / contract fixes:

- remote MCP `resource` reads now fail closed on an unresolved placeholder
  (`unfilled resource placeholders`), matching the openapi path/body guard —
  previously a literal `{x}` URI was sent upstream.
- `tenant_delete` requires `confirm` == `tenant_id` before the destructive
  wipe (protocol.md §Admin, platform.md §Tenant lifecycle); threaded through
  `escurel-types` / `escurel-client`; the `escurel` CLI echoes the operator-
  typed id as the confirmation.
- `tenant_export` now returns `format_version` + a SHA-256 of the tarball
  body so a consumer can verify durability before trusting it (protocol.md
  §backup contract).
- telemetry reads the convention-compliant `ESCUREL_OBSERVABILITY_OTLP_ENDPOINT`
  (env = TOML key path), keeping bare `ESCUREL_OTLP_ENDPOINT` as a deprecated
  fallback so existing deployments don't break.

Each behaviour is covered by a real no-mock test; the resource-guard test was
verified red→green (disabling the guard sends the literal URI and the read
stops degrading). Docs are reconciled to these fields in the follow-up
doc-sync PR.

Test plan: cargo test -p escurel-server --test remote_backend_tools
(mcp_resource_read_fails_closed_on_unresolved_placeholder) --test
mcp_admin_tools (tenant_delete_requires_matching_confirm, export sha256);
full fmt/clippy/test/build gate green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@jrosskopf jrosskopf merged commit 1b56575 into main Jul 7, 2026
1 check passed
@jrosskopf jrosskopf deleted the fix/spec-alignment-runtime branch July 7, 2026 18:14
jrosskopf added a commit that referenced this pull request Jul 7, 2026
A doc↔implementation audit (6 scoped passes + codex) found the specs had
drifted from the code across the agent surface, admin surface, storage, DX,
and platform docs. This syncs the docs to what the code actually does; where
the spec described an unbuilt feature it is now clearly marked
**Not yet implemented** rather than presented as current.

protocol.md (agent + admin wire contract):
- expand/neighbours/list_instances/resolve request args + response fields
  corrected to the real handlers; `scenario`/`full`/`as_of` documented;
  removed never-emitted fields (`snapshot_version`, resolve `error`, session
  `content`/`conflicts`/`issues`) as not-yet-implemented.
- documented `fetch_blob` (was undocumented); added `search.similarity` +
  `queries`/`page_id`; `validate` returns `{ok, issues}`.
- admin tool names fixed (`admin_audit`/`admin_quota`/`admin_delete_chat_history`);
  removed the non-existent `health` tool; tenant/attach_external arg+output
  shapes fixed; added the ~11 previously-undocumented admin tools; documented
  `tenant_delete` confirm + `tenant_export` `{format_version, sha256}` +
  markdown-only tarball (matches #245).
- `tools/list` is not role-gated (admin tools listed, dispatch-gated); added
  the plain-HTTP endpoints incl. `/openapi.json`; versioning corrected
  (crate semver, no `escurel-ws/1`); `backend_ref` is `{kind, endpoint}`.

storage.md: removed the phantom `frontmatter_index` table (filtering is a
direct `json_extract` over `pages`); `open_writer` marked not-implemented;
`url()` → `Result<Url>`; `links` PK includes `dst_anchor`; FTS ignore regex;
`put_blob` signature; `compact_db` → `compact_lanes`.

dx.md: `Role::User` → `Role::Agent` (the example didn't compile); added the
`AuthMode::ExternalMulti` variant; TestIssuer is RSA-2048.

platform.md / README.md / deploy: the multi-tenant TenantManager model, the
sizing knobs, `log_format=text`, and the `/readyz` OTel check are marked not-
implemented; OTLP env is the convention name (`ESCUREL_OBSERVABILITY_OTLP_ENDPOINT`,
bare name a deprecated alias).

Dockerfile: base bumped rust:1.88 → 1.91 (matches rust-toolchain.toml); the
bundled-DuckDB build comments rewritten to describe download mode.

CLAUDE.md: CI is live (re-enabled at v1.0.0) — flipped the three "CI is paused"
claims; the local four-command gate remains the fast inner loop.

ADR-0002: appended a note that gRPC was retired (surface is MCP-only).

Docs-only; no code changed. Depends on #245 for the `tenant_delete`/
`tenant_export`/OTLP field names it documents.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant