Say what the docs describe, in the order they describe it

A tidy across docs/, and every change is either something that had drifted
from the code or something a reader would trip over. Nothing here is a rewrite:
the audit documents keep their audit-time text, because that is what the scope
was decided against, and corrections are marked in place the way each file
already marks them.

The one that matters is crypto.md. Section 4.3's resourceType table stopped at
13 while CryptoSpec.AadResourceType has carried ConnectionLogEntry = 14,
ActivityLogEntry = 15 and ObjectStore = 16 since the logs and the buckets
shipped — and items have been sealed under all three. That file is normative, so
a table three item kinds behind the code is the sort of gap somebody
reimplementing this would build against. Nothing on the wire or on disk changes;
the list now says what the code has been doing, and it notes the thing that
makes it worth reading carefully — 14, 15 and 16 are the first members that are
not a fixed offset from their SyncEntityType counterparts, because 12 and 13
closed a hole and pushed the two enums apart.

manual-checks.md had Phase 3 in an order nobody could follow: 3.2b, then 3.2a,
then 3.4a, then 3.3. The letters are not the problem — they exist so a check can
keep its number for life, which is what lets HostGridTests cite 7.6 and
platform-flags.md cite 3.6-3.8 — so the sections are reordered and the numbers
are untouched, and the intro now says the convention out loud rather than
leaving the next person to infer it from two orphaned letters. Phases 8 and 9
got the horizontal rule every other phase has. The Phase 3 preamble still said
"a sidebar that now draws headings", which has been two different interfaces for
a while: the desktop's grid of cards and the phone's flat list.

7.6 cited MovingAHostToAGroup_FilesItAndLeavesItSelected, which was renamed in
the commit before this one. Every other Type.Member citation across all six
files was checked against src/ and tests/ the same way; those two were the only
ones pointing at nothing.

design-import-gaps.md's v3 section described the grid of cards without saying it
holds one level, and its Groups row still said the sidebar emits one heading per
group — true of the phone and not of the desktop. The team-groups row said a
host a teammate filed "shows under UNGROUPED", which is now only half the story
and the interesting half is why: the chip resolves through groupsById, which is
every readable vault, while the level resolves through Groups, which is the
active vault alone — so the card sits at the outermost level with its group's
name still on it. Verified against both call sites rather than reasoned about.

android-port.md's destination inventory is the desktop as it stood when the
audit was taken and is deliberately left that way, with a note at its head
saying so and two inline corrections where a reader would otherwise be misled:
the rail lost FILES and S3 to fixed tabs, and the hosts sidebar became a grid —
which is exactly why the headings this head draws are the phone's alone now.

adding-hosts-on-the-phone.md is a plan marked built, so its two open questions
are answered in place: GroupId did get into the merge test's with block, and the
server test that asserts a plaintext ParentId is refused survived under a name
that says what it means. Its "found on the way" note is marked still open,
because it is: LocalCacheProtector.For has no arm for ConnectionLogEntry,
ActivityLogEntry or ObjectStore, so ConflictStore.Record still throws for all
three. That outlived the phases that shipped them, which is the drift a note
like that exists to prevent.

No code changed, so the suite is untouched at 1522 passing.
This commit is contained in:
2026-08-04 10:15:02 +02:00
parent 2a56ae3efb
commit 27bb1deb5d
5 changed files with 83 additions and 33 deletions
+8 -2
View File
@@ -299,7 +299,7 @@ because-string used as prose.
`Sync.Tests/HostCipherTests.cs`. There is no shared group factory and with five new fields there should be.
- Three guard tests fail by design and that is what they are for:
`HostSecretMergeTests.EveryScalarField_IsRoutedThroughAMerge` (note `GroupId` is missing from its `with`
block today — an existing gap worth closing while there),
block today — an existing gap worth closing while there) *(closed: `GroupId` is in that block now)*,
`ValueSemanticsTests.TryValidate_RejectsWhatCannotBeStored`, and the two "groups are flat" remarks.
- `ItemKindsTests.ThePullFilterNamesEveryTypeThisBuildSynchronises` is an ordered list — add Tag in registry
order. `AadResourceTypeTests` needs `PinnedPairs`, a `SealSample` arm and a `NewTag()` builder.
@@ -307,7 +307,9 @@ because-string used as prose.
with a reason containing "flat". Putting the parent **inside the payload** does not break it mechanically,
but its stated reason becomes wrong. It should survive with a rewritten comment — the parent lives in the
payload, the plaintext column stays refused, and ADR 0004 is why. Decide that deliberately rather than
letting it drift.
letting it drift. *(Decided that way, and the name says it now:
`SyncEndpointTests.AHostGroupCarryingAPlaintextParent_IsRejected`. The column is still refused and the
reason is the trust model rather than flatness.)*
- `Push_AnUnsupportedEntityType_IsInvalidNotAFailedBatch` picks the first type with no kind registered, very
likely Tag today. It self-heals to `HostTag` via `Assert.SkipWhen`.
- `App.Layout.Tests` measures pixels and bends rather than breaks. Extend the seeders — nesting and a tag row
@@ -323,6 +325,10 @@ because-string used as prose.
`ConflictStore.Record` throws `ArgumentOutOfRangeException` on a conflict for any of those three. Pre-existing,
unrelated to any of this, and `Tag` is already in that switch. Worth a separate fix.
> **Still open.** All three are on `SyncEntityType` and on `CryptoSpec.AadResourceType`, and all three are
> still absent from `LocalCacheProtector.For` — so this outlived the phases that shipped the logs and the
> buckets, which is exactly the drift a note like this is meant to prevent.
## Prose that becomes false
Not a tidy-up — these are the places the codebase currently tells a user or a maintainer that this feature is