diff --git a/.corviduo-canonicals.toml b/.corviduo-canonicals.toml index 8044924..c468a94 100644 --- a/.corviduo-canonicals.toml +++ b/.corviduo-canonicals.toml @@ -104,8 +104,8 @@ id = "worldtree-conversation-api-openapi-v2" canonical_source = "Worldtree" canonical_path = "docs/conversation-api-openapi.json" consumer_path = "docs/conversation-api-openapi.json" -pinned_sha256_16 = "dbdf4e24c8b06c92" -pinned_at = "2026-06-30T22:25:56+00:00" +pinned_sha256_16 = "36148179601453a0" +pinned_at = "2026-07-06T16:09:05+00:00" [[pins]] id = "worldtree-conversation-api-sse-events-v1" diff --git a/docs/SPEC-PIN.md b/docs/SPEC-PIN.md index 26b9b8e..0cc7e2a 100644 --- a/docs/SPEC-PIN.md +++ b/docs/SPEC-PIN.md @@ -7,16 +7,17 @@ documents the pin, the vendored artifacts, and the bump procedure. | Field | Value | |---|---| -| Worldtree git SHA | `5810a26b38a5ea6630892f9a39756f57c5b7b41e` | -| Worldtree HEAD message | `memory: snapshot — v1.0.0b2 shipped complete (demo + personal green); consumer loop closed` | -| Pinned on | 2026-06-30 | -| Pinned by | ratatoskr-dev (v1 coverage-audit — re-pin to the FROZEN OpenAPI 2.2.0 + SSE schema) | -| Worldtree version at pin | `v1.0.0b2` | +| Worldtree git SHA | `879cefef02bbf442c2d01ff4214299fac7c89809` | +| Worldtree HEAD message | `fix(#347): freeze the authored-history route into the OpenAPI schema (spec 2.3.0)` | +| Pinned on | 2026-07-06 | +| Pinned by | ratatoskr-dev (re-vendor OpenAPI 2.2.0→2.3.0 — #347 authored-history-write route shipped) | +| Worldtree version at pin | `v1.0.0b22` | ## Pin history | Date | SHA | Version | Notable deltas consumed | |---|---|---|---| +| 2026-07-06 | `879cefe` | v1.0.0b22 | **Re-vendor OpenAPI 2.2.0→2.3.0 — Worldtree shipped #347 authored-history-write.** One new REST path-group: `POST /sessions/{session_id}/history` (the authored-history-write primitive) + the `AuthoredTurnResponse` schema (openapi path count 40→41). #347 is **OpenAPI-only** — the prose `conversation-api-spec.md` + server `conversation_api.contract.md` are byte-unchanged since the 5810a26 pin (empty `git log` delta), so those `tolerate_drift` pins stay clean; the SSE schema is unchanged (#347 is event-silent by design). **Consumer side NOT yet built** — `POST /sessions/{id}/history` is a fresh in-scope ⬜ gap in `docs/coverage-map.md` (re-opens the v1 coverage-audit with exactly one gap; Heimdall-gated hide-existence → consumer treats 404 as feature-absent). `pin:`-only, no version bump. | | 2026-06-30 | `5810a26` | v1.0.0b2 | **Re-pin to Worldtree's FROZEN v1 surface (#326), as part of the v1 coverage-audit.** Vendored the machine-readable artifacts — `conversation-api-openapi.json` (OpenAPI **2.2.0**, 40 path-groups) + `conversation-api-sse-events.schema.json` (11 events) — now the **authoritative drift gates** (pinned in `.corviduo-canonicals.toml`, CI-checked by `canonical_drift.py`). The prose `conversation-api-spec.md` is **byte-identical** to the v0.35.16 pin (last WT markdown edit 2026-05-31), kept as the human reference (`tolerate_drift`). b2 deltas already consumed in code: 409/503 eager turn-launch statuses (#331, v0.18.3/.4) + the unified error envelope (#328). 7 endpoints documented only in the OpenAPI, not the prose, all classified in `docs/coverage-map.md`: `admin/keys/bulk`, `admin/persona/{archive,erase}`, `admin/usage`, `embed`, `judgments`, `me/usage`. No client-breaking change — `pin:`-only, no version bump. | | 2026-06-17 | `f1b59f8` | v0.35.16 | **#297 + #298/#299 — Worldtree adopts the bifrost v0.6 scope wire (emits `scope_any`/`scope_all`) + client-side per-scope-value union recall. With our v0.17.6 provider this closes cold cross-session recall end-to-end.** Catch-up bump (v0.29.0→v0.35.16). Intervening client-facing deltas reviewed, none break our consumer: #211 agent rename (`saga`→`echo`, `actor`→`mask` — slugs only); #245 `end_user_id` persistence + memory-scope resolver; #187/#188/#219 Tier-3 define/PATCH policy (additive); `bifrost` binding field + `ephemeral_does_not_accept_bifrost` 422 now documented (the #17 surface). Error codes stable; no ratatoskr code change required. | | 2026-05-25 | `da93ca7` | v0.28.0 | #204 — new SSE event `affect_update` (current/scheduled), new endpoint `GET /agents/{id}/persona_state`, auth-model doc edits | @@ -26,7 +27,7 @@ documents the pin, the vendored artifacts, and the bump procedure. **Authoritative (FROZEN, machine-readable — the drift gates):** -- `docs/conversation-api-openapi.json` — copy of `Worldtree/docs/conversation-api-openapi.json` (OpenAPI `info.version` **2.2.0**). The frozen v1 REST wire (40 path-groups). Pinned `worldtree-conversation-api-openapi-v2` in `.corviduo-canonicals.toml`; drift gated by `canonical_drift.py`. +- `docs/conversation-api-openapi.json` — copy of `Worldtree/docs/conversation-api-openapi.json` (OpenAPI `info.version` **2.3.0**). The frozen v1 REST wire (41 path-groups; 2.3.0 added `POST /sessions/{session_id}/history` per #347). Pinned `worldtree-conversation-api-openapi-v2` in `.corviduo-canonicals.toml`; drift gated by `canonical_drift.py`. - `docs/conversation-api-sse-events.schema.json` — copy of `Worldtree/docs/conversation-api-sse-events.schema.json`. The frozen SSE event schema (11 discriminated event types). Pinned `worldtree-conversation-api-sse-events-v1`. **Reference (prose; allowed to lag — `tolerate_drift`):** diff --git a/docs/conversation-api-openapi.json b/docs/conversation-api-openapi.json index 7bd3024..05bd253 100644 --- a/docs/conversation-api-openapi.json +++ b/docs/conversation-api-openapi.json @@ -1,6 +1,50 @@ { "components": { "schemas": { + "AuthoredTurnResponse": { + "description": "#347 — the authored-write ack. Provenance is audit-only and NEVER on this\npayload (INV-347-7). ``content_chars`` is the CHARACTER count (may differ from\nthe UTF-8 byte length the request is bounded against — INV-347-12).", + "properties": { + "author": { + "title": "Author", + "type": "string" + }, + "content_chars": { + "title": "Content Chars", + "type": "integer" + }, + "injected_at": { + "title": "Injected At", + "type": "string" + }, + "phase": { + "title": "Phase", + "type": "string" + }, + "seq": { + "title": "Seq", + "type": "integer" + }, + "session_id": { + "title": "Session Id", + "type": "string" + }, + "turn_id": { + "title": "Turn Id", + "type": "integer" + } + }, + "required": [ + "turn_id", + "session_id", + "author", + "phase", + "seq", + "injected_at", + "content_chars" + ], + "title": "AuthoredTurnResponse", + "type": "object" + }, "BifrostBindingRequest": { "additionalProperties": false, "description": "Bifrost binding parameters for session-create (issue #160).", @@ -390,6 +434,7 @@ "session_not_found", "session_not_bifrost_bound", "session_retired", + "generation_active", "agent_not_available", "turn_not_found", "turn_finished", @@ -905,7 +950,7 @@ "info": { "description": "Multi-turn conversation interface for Worldtree agents.", "title": "Worldtree Conversation API", - "version": "2.2.0" + "version": "2.3.0" }, "openapi": "3.1.0", "paths": { @@ -6382,6 +6427,141 @@ "summary": "Update Session" } }, + "/sessions/{session_id}/history": { + "post": { + "description": "#347 — write one model-visible turn into a session's ledger AS the bound\nagent, WITHOUT a generation and WITHOUT lived-turn side effects.\n\nHide-existence ordering (INV-347-13): the ``session.history.write`` grant is\nchecked FIRST — before session resolution, before ANY body parse/validation,\nbefore the active-generation guard. An ungranted caller receives ONLY the\nhide-404 (byte-identical to session-not-found, INV-347-1) — never a\n422/409/403 that would distinguish feature-absent from session-absent.", + "operationId": "authored_history_write_sessions__session_id__history_post", + "parameters": [ + { + "in": "path", + "name": "session_id", + "required": true, + "schema": { + "title": "Session Id", + "type": "string" + } + } + ], + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthoredTurnResponse" + } + } + }, + "description": "Successful Response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "401": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "403": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "404": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "405": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "409": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "412": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "500": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + }, + "503": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + }, + "description": "Error — unified envelope (detail.error_code is the stable identifier)." + } + }, + "security": [ + { + "HTTPBearer": [] + } + ], + "summary": "Authored History Write" + } + }, "/sessions/{session_id}/messages": { "get": { "description": "Return paginated message history for a session.", diff --git a/pyproject.toml b/pyproject.toml index 4ebda27..019087a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -60,9 +60,9 @@ Repository = "https://gitea.phasefinal.com/vh/ratatoskr" # Ratatoskr is built against Worldtree at this commit; the vendored # spec snapshot in docs/ reflects that SHA. [tool.ratatoskr.spec-pin] -worldtree-spec-rev = "5810a26b38a5ea6630892f9a39756f57c5b7b41e" -worldtree-version = "v1.0.0b2" -pinned-on = "2026-06-30" +worldtree-spec-rev = "879cefef02bbf442c2d01ff4214299fac7c89809" +worldtree-version = "v1.0.0b22" +pinned-on = "2026-07-06" # Bifrost lives on the auth-gated gitea PyPI index (not public PyPI). # uv reads the credential from UV_INDEX_GITEA_USERNAME / _PASSWORD or ~/.netrc.