Commit graph

4 commits

Author SHA1 Message Date
Arena Agent
12f59109d7 revert(nigig-site): ce9e12b was wrong — the HTTP wire field is body, not text
Commits dfffe9e + 13ae501 landed nigig-lite/crates/common (package
`nigig-common`) and a vendored xitca-web into this repository, which makes the
/sync wire format readable for the first time. Reading it shows ce9e12b was
incorrect.

There are TWO MessageContent types, deliberately:
- nigig_common::MessageContent::Text { body, formatted_body, mentions } — the
  HTTP/JSON REST DTO. Its own doc-comment: "Serialises externally tagged,
  e.g. {"Text":{"body":"hi",…}}". This is what SendMessageRequest.content and
  TimelineEvent::Message.content are.
- nimanyatta_protocol::MessageContent::Text { text } — the WebSocket chat
  protocol, serialized with postcard. nigig-common's manifest says that format
  "must match nimanyatta/crates/nimanyatta-protocol (the client library)".

ce9e12b changed the E2E test's outgoing posts from {"Text":{"body":…}} to
{"Text":{"text":…}}, reasoning from the WebSocket type. The original `body`
was correct for these HTTP endpoints; my change would have made both requests
fail deserialization. Reverted, and the now-unused nimanyatta-protocol
dev-dependency is dropped from nigig-site.

What ce9e12b got right is kept: the parser had keyed on "type":"message",
but TimelineEvent carries no serde tag attribute, so it is externally tagged —
{"Message":{…,"sender":…,"content":…}} with sender and content at the variant
level. event_text still accepts that envelope (plus the legacy lowercase shape
and `text` as last-resort field names).

The fixture's cross-check test was rebuilt against nigig_common's real shape
instead of the WebSocket type. It is NOT verified by execution: nigig-site's
test target pulls in makepad-widgets, which is SIGKILLed on this host. The
parser was verified instead by extracting event_text/sync_timelines verbatim
into a standalone harness over four cases — nigig_common Message with `body`
-> Some(("alice","slab done")); Membership -> None; Redaction -> None; legacy
lowercase -> Some(("bob","old")). All pass. The harness is scratch, not
shipped.

EXECUTION_PLAN.md SITE-12 rewritten: the sibling repos are no longer missing,
the /sync DTOs are named with their file paths, both MessageContent types are
distinguished, and the narrower remaining blockers are stated — nimanyatta
still cannot be a workspace member (xitca-web/web/Cargo.toml inherits
rust-version and lints from a workspace root, and nested here it resolves to
ours, which defines neither), and a full `cargo check --features b_server` has
not completed on this host, so no build claim is made.

Verified: cargo test -p nimanyatta-protocol = 14; cargo test -p nigig-site-core
= 228 / 1 ignored; clippy -D warnings clean; cargo fmt --check clean;
cargo metadata exit 0.
2026-09-26 17:39:20 +00:00
Arena Agent
ce9e12b4b9 fix(nigig-site): send and parse the message shape the server actually uses
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
nigig-site / Owned paths and honest test contracts (push) Has been cancelled
nigig-site / Cargo check-all-targets (push) Has been cancelled
nigig-site / Cargo clippy-site-owned (push) Has been cancelled
nigig-site / Cargo contained-media-export-fixtures (push) Has been cancelled
nigig-site / Cargo containment-storage-crypto (push) Has been cancelled
nigig-site / Cargo core-clippy (push) Has been cancelled
nigig-site / Cargo core-contracts (push) Has been cancelled
nigig-site / Cargo integration-non-live (push) Has been cancelled
nigig-site / Cargo production-dependency-containment (push) Has been cancelled
nigig-site / Cargo site02-crypto (push) Has been cancelled
nigig-site / Cargo site02-repository (push) Has been cancelled
nigig-site / Cargo site02-store (push) Has been cancelled
nigig-site / Cargo unit (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (macos-latest) (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (ubuntu-latest) (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (windows-latest) (push) Has been cancelled
nigig-site / SITE-02 desktop runtime and normal shutdown (push) Has been cancelled
nigig-site / SITE-02 migration, recovery, and fault corpus (push) Has been cancelled
nigig-site / Media limits (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Real server interoperability (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Security and supply-chain baseline (push) Has been cancelled
nigig-site / Release capability gate (push) Has been cancelled
Follow-up to ac40ac9, which fixed only the parse side and overstated the
consequence. Three corrections and two further defects.

CORRECTION to my own previous claim: ac40ac9's message and the SITE-12 plan
row both said that with only `content.Text.body` supported, `live_round_trip`
"would still pass". That is false. sync_e2e.rs asserts
`timelines.iter().any(|(_, lines)| lines.iter().any(|l| l.contains(&marker)))`,
so the run would have FAILED with "app parser must extract the marker" — a
misleading diagnosis, but a failure, not a silent green. The fixture bug was
real; the consequence I described was not.

Defect 1 — the test also SENT the wrong shape. Both message posts in
live_round_trip sent {"Text":{"body":...,"formatted_body":null,"mentions":[]}}.
nimanyatta/src/routes/rooms.rs binds `req.content` to a `MessageContent`,
whose Text variant has a single field named `text`, so those requests would
fail at deserialization before anything reached the timeline. Both now send
{"Text":{"text":...}}.

Defect 2 — the parser keyed on the wrong envelope. `event_text` required
`event["type"] == "message"`, but the server constructs
`TimelineEvent::Message { event_id, room_id, sender, content, timestamp,
edited, reply_to }` (verified at the construction site in routes/rooms.rs),
and `sender`/`content` live at the variant level, not under a `type` tag.

What is still unknown, and is NOT guessed here: TimelineEvent's serde tagging.
It is defined in `nigig_common`, which is absent from this repository, so
neither externally- nor internally-tagged can be confirmed. Rather than pick
one, event_text now accepts both envelopes plus the legacy lowercase shape,
and `body` is kept as a last-resort field name. Membership and Redaction
events are still skipped.

Verification, stated precisely:
- The fixture's own test target cannot be compiled here: nigig-site's test
  target pulls in makepad-widgets, which is SIGKILLed on this 2 vCPU / 1.9 GiB
  host. The shipped cross-check test remains unverified until CI runs it.
- event_text and sync_timelines were instead extracted verbatim from the
  fixture into a standalone harness and exercised over five cases: externally
  tagged -> Some(("alice","slab done")); internally tagged ->
  Some(("bob","poured")); legacy lowercase with `body` ->
  Some(("carol","old")); Membership -> None; Redaction -> None. All pass.
  That harness is scratch, not part of the tree.

Unchanged and still passing: cargo test -p nimanyatta-protocol = 14;
cargo test -p nigig-site-core = 228 / 1 ignored; clippy -D warnings clean;
cargo fmt --check clean; cargo metadata exit 0; 6/6 workflow python gates.
2026-09-26 16:12:03 +00:00
Arena Agent
ac40ac923f fix(nigig-site): read the timeline field the protocol crate actually emits
Some checks failed
nigig-site / Cargo contained-media-export-fixtures (push) Has been cancelled
nigig-site / Cargo containment-storage-crypto (push) Has been cancelled
nigig-site / Cargo core-clippy (push) Has been cancelled
nigig-site / Cargo core-contracts (push) Has been cancelled
nigig-site / Cargo integration-non-live (push) Has been cancelled
nigig-site / Cargo production-dependency-containment (push) Has been cancelled
nigig-site / Cargo site02-crypto (push) Has been cancelled
nigig-site / Cargo site02-repository (push) Has been cancelled
nigig-site / Cargo site02-store (push) Has been cancelled
nigig-site / Cargo unit (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (macos-latest) (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (ubuntu-latest) (push) Has been cancelled
nigig-site / SITE-02 native provider/filesystem (windows-latest) (push) Has been cancelled
nigig-site / SITE-02 desktop runtime and normal shutdown (push) Has been cancelled
nigig-site / SITE-02 migration, recovery, and fault corpus (push) Has been cancelled
nigig-site / Media limits (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Real server interoperability (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Security and supply-chain baseline (push) Has been cancelled
nigig-site / Release capability gate (push) Has been cancelled
repo hygiene / hygiene (push) Has been cancelled
sms / gates (push) Has been cancelled
sms / robius-sms (push) Has been cancelled
sms / android (push) Has been cancelled
sms / nigig-sms (push) Has been cancelled
sms / supply-chain (push) Has been cancelled
spreadsheet / engine-coverage (push) Has been cancelled
spreadsheet / ui-controller-coverage (push) Has been cancelled
traffic / gates (push) Has been cancelled
traffic / nigig-traffic (push) Has been cancelled
traffic / supply-chain (push) Has been cancelled
Pinning nimanyatta-protocol's JSON shape exposed a live bug in the E2E
fixture, and answering "is nigig_common in this repo?" narrowed the SITE-12
gap.

The bug: MessageContent::Text serializes as {"Text":{"text":"..."}}.
tests/support/nimanyatta_fixture.rs::event_text only looked for
content.Text.body — a field that type never emits, and which
serde_json::from_str::<MessageContent> actively rejects. Against a real
server every message would have been skipped, sync_timelines would return an
empty vec, and live_round_trip would still have passed. A silently vacuous
interop test is exactly the failure mode SITE-00 exists to prevent.

- event_text now tries `text` first and keeps `body` as a fallback.
- New test in nimanyatta-protocol pins the serialized shape and asserts the
  fixture's old guess does not decode.
- New cross-check test in the fixture builds its payload from the real
  MessageContent type, so parser and protocol cannot diverge silently again.

What was verified and what was not:
- The protocol-crate tests run: 14 passed.
- The fixture cross-check test COULD NOT be compiled or run here. nigig-site's
  test target pulls in makepad-widgets, which is SIGKILLed on this 2 vCPU /
  1.9 GiB host. The parser change was instead verified by extracting
  event_text/sync_timelines verbatim from the fixture into a standalone
  harness: {"Text":{"text":"slab done"}} -> Some(("alice","slab done")),
  the legacy {"Text":{"body":...}} shape still falls back, and a
  non-message event returns None. That harness is not part of the shipped
  tree; the shipped cross-check test is unverified until CI runs it.

Also recorded in EXECUTION_PLAN.md SITE-12: nigig_common is confirmed absent
from this repository (no package by that name; RoomEvent/RoomInfo/
JoinedRoomSync/SyncFilter/PaginationDirection defined nowhere here; nigig-core
is an email/IMAP crate), and it re-exports nimanyatta-protocol via a
`protocol` module — the server writes
nigig_common::protocol::{ClientToServerMsg, ServerToClientMsg}. So of the 75
items the server imports from nigig_common, 9 are the crate already pinned
here; the remaining 66 are the HTTP DTO layer, ~11 of which /sync needs.

Verified: cargo test -p nimanyatta-protocol = 14 passed; cargo test -p
nigig-site-core = 228 passed / 1 ignored; clippy -D warnings clean;
cargo fmt --check clean; cargo metadata exit 0; all 6 workflow python gates.
2026-09-26 12:37:08 +00:00
Arena Agent
5d2d890f70 feat(nigig-site): enforce SITE-01 fail-closed containment
Some checks failed
nigig-site / Migration and recovery (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Media limits (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Real server interoperability (explicitly skipped until enabled) (push) Has been cancelled
nigig-site / Security and supply-chain baseline (push) Has been cancelled
nigig-site / Release capability gate (push) Has been cancelled
repo hygiene / hygiene (push) Has been cancelled
doc-engine / engine (push) Has been cancelled
doc-engine / coverage (push) Has been cancelled
doc-engine / consumer (push) Has been cancelled
email / gates (push) Has been cancelled
email / email-domain (push) Has been cancelled
email / nigig-email (push) Has been cancelled
email / supply-chain (push) Has been cancelled
nigig-build (CAD) / supply-chain (push) Has been cancelled
nigig-build (CAD) / cad-module (push) Has been cancelled
nigig-build (CAD) / full-crate-check (push) Has been cancelled
nigig-build (CAD) / cad-engine-coverage (push) Has been cancelled
nigig-build (CAD) / doc-workspace-coverage (push) Has been cancelled
nigig-build (CAD) / cad-widget-coverage (push) Has been cancelled
nigig-map / test (push) Has been cancelled
sms / gates (push) Has been cancelled
sms / robius-sms (push) Has been cancelled
sms / android (push) Has been cancelled
sms / nigig-sms (push) Has been cancelled
sms / supply-chain (push) Has been cancelled
spreadsheet / engine-coverage (push) Has been cancelled
spreadsheet / ui-controller-coverage (push) Has been cancelled
traffic / gates (push) Has been cancelled
traffic / nigig-traffic (push) Has been cancelled
traffic / supply-chain (push) Has been cancelled
Contain production capabilities, remove the production sync surface, and keep legacy media/export/transport implementations test-only.

Require authenticated existing-key storage with preservation-first recovery and sticky write disablement, backed by deterministic fault and concurrency tests plus dependency and workflow contracts.
2026-09-12 15:46:30 +00:00