Root, CI, docs and packaging describe the project to a stranger (#6225)
Android / Build, or is the channel already serving this? (push) Successful in 3s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Build now, or wait for Android? (push) Successful in 2s
Desktop (Tauri) / Build, or is the channel already serving this? (push) Successful in 2s
CI & Build / Web typecheck and unit tests (push) Successful in 12s
CI & Build / Python tests (push) Successful in 23s
Android / Core and FFI clippy and tests (push) Successful in 51s
CI & Build / integration (push) Successful in 1m49s
CI & Build / Build & push image (push) Skipped
Desktop (Tauri) / Web tests, clippy, Rust tests and rustfmt (push) Successful in 2m20s
Desktop (Tauri) / Windows installer (cross-compiled) (push) Successful in 3m6s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m46s
Desktop (Tauri) / Update manifest (push) Successful in 3s
Android / Kotlin + Rust (APK) (push) Successful in 8m31s
Android / Build the server image (push) Successful in 1s

#6225 "Comment standard sweep: root, config, CI workflows, docs and
packaging", milestone 546 "Bring the repo to the comment standard (rule 32)
and compose defaults (rule 198)".

- README restructured in newcomer order: what it is, quick start,
  configuration, setup pitfalls, updating and backups, features,
  troubleshooting, development, licence. Its quick-start compose carries
  no restart policy.
- Dockerfile and .env.example trimmed to one or two lines per setting.
- Workflows, packaging scripts and docs lose issue, run, note, rule and
  milestone references and their history narration. Comments that still
  described path filters and "step 6" as future work now state what the
  workflows do.
- ci-requirements.md rewritten against the current workflows. It said the
  build gated on typecheck and lint only, the integration lane did not
  gate, a v* tag published :latest, and ci-tauri lacked bsdtar and zstd;
  none of those is true now (the last checked against run 9630's log).
- Echo strings in guard-forward.sh and version.sh drop their note
  citations; every string a test asserts on is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 20:44:02 -04:00
co-authored by Claude Opus 5.5
parent 01b53118b9
commit f16224b07c
18 changed files with 666 additions and 843 deletions
+2 -4
View File
@@ -22,9 +22,7 @@ copy.
**The channel is a property of the image you run.** A `:dev` image bakes in the
dev-channel APK, `:latest` the stable one — so pointing a phone at a stable
server gets it a stable client, with no second place holding that decision. (Until
M314 step 3 the fetch was hard-wired to the dev release on every branch, so a
stable server served a dev client.)
server gets it a stable client, with no second place holding that decision.
An image therefore carries the *newest* client on its channel rather than one
pinned to a version. That is deliberate: the two negotiate a sync protocol version
@@ -106,5 +104,5 @@ shipped with, which is the whole reason precedence runs in that direction.
Every release build is signed with the same key, so a phone can install a newer one
straight over the old one and keep its notes. That was not true before August 2026
— builds until then were signed with a throwaway key per CI run, and each install
required uninstalling the last (Scribe #2803). If you are carrying a build from
required uninstalling the last. If you are carrying a build from
before that, expect to uninstall once more and sync anything you care about first.
+9 -9
View File
@@ -52,22 +52,22 @@ syncs everything else.
### The policy
- **Any wire change** → bump `SYNC_PROTOCOL_VERSION`.
- v2 (M13): `kind` and `title` left the wire; **floor raised**, because a v1
- v2: `kind` and `title` left the wire; **floor raised**, because a v1
client kept pushing both and read back notes carrying neither — and `title` was
the note's NAME, so an old client showed nameless notes.
- v3: attachments/tombstones/revisions.
- v4 (M315): `color` left the note; **floor NOT raised**. Both directions degrade
- v4: `color` left the note; **floor NOT raised**. Both directions degrade
in silence and neither loses anything visible — an old client reading a v4 note
falls back to the colour it derives locally, and one pushing `color` has the key
ignored. The test is not "did a field leave" but "does either side end up
showing something wrong".
- v5 (#5168): attachments became a sync entity — an upload route keyed by the
- v5: attachments became a sync entity — an upload route keyed by the
client's id, and `attachment`/`preview` deletes in push. Additive, so it is
the `attachment_sync` feature and the floor stays.
- v6 (#5175): shared notes — see "Shared notes" below. Opt-in per request
- v6: shared notes — see "Shared notes" below. Opt-in per request
(`changes?shares=1`), so it is the `shares` feature and the floor stays: a v5
client never asks and gets exactly its own notes.
- v7 (#5176): a recipient's own pin, archive and position on a shared note —
- v7: a recipient's own pin, archive and position on a shared note —
see "Shared notes". Additive, so it is the `shared_state` feature and the
floor stays: a v6 client pushes only text, and reads its own state as if the
note were simply unpinned.
@@ -143,7 +143,6 @@ as `?since=`. `since=0` (or absent) is a **full initial sync**.
rename/recolor/delete propagates independently of notes.
- **Derived, NOT synced:** `#tags` are parsed from the note body. Clients recompute
them locally; the server recomputes them on push. They never travel over the wire.
(`[[wiki-links]]` were derived the same way until they were removed — note 2897.)
- **Attachment blobs** sync by id over the existing upload/download routes (see
Attachments below); only their metadata rides the delta feed.
@@ -222,7 +221,7 @@ labels are personal, and a recipient files nothing under the owner's tags.
Granting or changing a share moves the note to a new revision (without touching
`updated_at`, so last-write-wins is unaffected), which is how it passes a
recipient's cursor. Joining a group a note is shared with does the same for the
new member (#5177). Ending a share — or the owner purging the note, the person
new member. Ending a share — or the owner purging the note, the person
leaving the group, or the admin deleting it — adds the note to the `revoked` list of
each person who can no longer see it:
@@ -261,9 +260,10 @@ Body: `{ "changes": [ ... ] }` (max 1000 per batch). Each change:
state (not a partial patch) — the server overwrites all scalar fields and sets
manual label memberships from `label_ids` (tag-sourced labels are re-derived
from the body). `#tags` are recomputed server-side. A checklist is `- [ ] ` lines
inside `body` (M304), so there is no separate `items` array.
inside `body`, so there is no separate `items` array.
- **Fields a change may still carry, and the server reads past.** `title` and
`kind` (removed in v2), `items` (M304) and `color` (v4, M315). The server reads
`kind` (removed in v2), `items` (from before checklists moved into `body`) and
`color` (removed in v4). The server reads
its payload key by key and never validates the shape, which is exactly what lets
an older client keep pushing a field this one has stopped storing — see the
version policy above for why none of those needed a floor raise on their own.