From 64defdf467fd259416c636ffacbf6bdb083754dd Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Wed, 19 Aug 2026 15:07:15 -0400 Subject: [PATCH] docs(todo): record why the read paths stay on serde_json::Value Typing one is either less tolerant than what is there, or the same thing with a discarded parse in front of it. The second entry names the gap the new test exposed: no `sh.tangled.repo .issue` or `.issue.state` record is captured anywhere, so that one family's tolerance still rests on doc comments with no bytes behind them. Co-Authored-By: Claude Opus 5 (1M context) Change-Id: Ia7b5ec17dbb79c845f692978c433467cf0a3b193 --- TODO.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/TODO.md b/TODO.md index e6f8807..720f1a0 100644 --- a/TODO.md +++ b/TODO.md @@ -2893,6 +2893,41 @@ and borrows `pr`'s conventions rather than inventing new ones beside them. known cost for a known bug. Left recorded rather than fixed: the patch is what pins the three vendored fixes, and dropping it is the same work as landing them upstream +- [ ] **The read paths stay on `serde_json::Value`, and that is a finding + rather than a backlog item.** The generated bindings under + `vendor/tangled-lexicon/` are lexicon-*faithful*: a property the schema + marks required is a non-`Option` field, so a record missing it fails to + deserialize whole rather than arriving with that one field empty. Every + `sh.tangled.*` record atgc reads was written by somebody else, and the + shapes in the wild predate the schema: + + - a pre-rounds `sh.tangled.repo.pull` carries an inline `patch` and has + neither `rounds` nor `target`, both required, so `Pull` refuses it + outright — while `pr list`, `pr view`, `pr diff` and `pr merge` all + still work on one; + - a legacy `sh.tangled.repo.issue.comment` names its subject as a bare + at-uri where `sh.tangled.feed.comment` takes a strongRef whose CID it + has nowhere to put, so a thread older than the unification would read + as empty (`clients::tangled::comments` reads both shapes); + - `sh.tangled.repo.issue` types `repo` as a DID and the appview still + ingests records carrying an at-uri there, which `FetchedIssue:: + repo_did` answers `None` for — where `Issue` would refuse the record. + + So typing a read path is either *less* tolerant than what is there, or + exactly what is there with a discarded parse in front of it. The + generated types earn their keep on the write side, where atgc controls + the bytes and a schema-invalid record is a bug — `cmd/*/write.rs`, + `cmd/key.rs` and `fetch_own_pull` already use them, and `fetch_own_pull` + says in as many words that it is "the caller that wants the lot". + `lexicon::tangled`'s `generated_types_against_live_records` pins which + captured shapes each generated type accepts and which it refuses, so a + regeneration against a tightened schema fails there instead of in + somebody's listing +- [ ] No `sh.tangled.repo.issue` or `sh.tangled.repo.issue.state` record is + captured under `tests/fixtures/`, so the issue read path is the one + record family whose tolerance rests on doc comments with no bytes behind + them — including the at-uri-in-`repo` case above, which is asserted + nowhere. A capture off a live PDS would close it - [x] Integration environments: whole *sequences* of commands driven through the built binary against mock services on loopback ports (`tests/support/`, `tests/stack_flows.rs`, `tests/pr_flows.rs`). What -- 2.51.2