WIP: docs: plan read-only IMAP Notes server (#766) #830

Closed
kayg wants to merge 1 commit from docs/imap-766-readonly-slice into dev
Owner

Documentation-only plan for the read-only Apple Notes IMAP server slice.

  • Chooses implicit TLS on host port 993 and reuses the existing HTTPS certificate source.
  • Adds a mail.notes.read app-password scope and documents the minimal IMAP command set from slice-0 captures.
  • Uses read-only SELECT plus explicit NO refusals for any queued writes.
  • Specifies deterministic Apple Notes MIME, limits, complexity, a failure table, protocol and native Mac gates, and the estimated first implementation PR size.
  • Depends on #824 for UID authority; this plan PR targets dev independently.

Validation: git diff --cached --check passed. No build, tests or native experiment were run; this PR contains the plan only.

Documentation-only plan for the read-only Apple Notes IMAP server slice. - Chooses implicit TLS on host port 993 and reuses the existing HTTPS certificate source. - Adds a `mail.notes.read` app-password scope and documents the minimal IMAP command set from slice-0 captures. - Uses read-only SELECT plus explicit NO refusals for any queued writes. - Specifies deterministic Apple Notes MIME, limits, complexity, a failure table, protocol and native Mac gates, and the estimated first implementation PR size. - Depends on #824 for UID authority; this plan PR targets `dev` independently. Validation: `git diff --cached --check` passed. No build, tests or native experiment were run; this PR contains the plan only.
docs: plan read-only IMAP Notes server (#766)
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled
840ec0d022
kayg changed title from docs: plan read-only IMAP Notes server (#766) to WIP: docs: plan read-only IMAP Notes server (#766) 2026-11-01 17:06:53 +00:00
Author
Owner

Independent plan review

verdict: revise. reviewed #830 at 840ec0d022105fc680e16ea846fbd39afb59c7ae, against #775 at 39d0553d, its slice-0/native fresh-mailbox evidence, and #824 at f1c1aa96. no P0 findings; two P1s and three P2s below. no separate P3 findings. this is a plan review; no native experiment or product tests were run, and nothing was pushed.

findings

P1: the native gate does not yet establish preservation under this read-only contract (plan lines 52–56, failure table, gate 4).

slice-0 findings E2-3 establish a narrower result: APPEND NO [OVERQUOTA] retained the full local text through quit/relaunch, caused no cleanup or retry for at least two minutes, and the next small edit uploaded all pending text. the report explicitly says the failed-save UI was not reviewed. neither that result nor E2-2's successful STORE/EXPUNGE followed by republication establishes behavior for SELECT [READ-ONLY] or explicit NO [READ-ONLY] on APPEND/STORE. the fresh-mailbox run also demonstrates that server retention can coexist with pending text being hidden in Notes; it is not a read-only-selection test.

gate 4 already has a useful conditional retention check, but “if the client queues” leaves the decisive case optional. make this a mandatory release gate with a deliberately seeded offline edit before reconnecting to the read-only server. separately exercise initial read-only selection, an edit/delete attempted after selection, and actual queued-command refusals. include a Calternal edit that publishes a replacement UID while the native edit remains pending. require exact pending text to remain visibly accessible through reconnect and quit/relaunch, unchanged bystanders, no successful mutation or false server-save indication, and a bounded retry rate over a recorded observation interval. capture all connections and the native error/UI state. if Notes prevents editing entirely, record that result and still test the pre-existing offline queue. export and verify pending text before removing the disposable account. do not enable outside dev if any pending text disappears or becomes inaccessible. change the failure-table recovery assertion “Notes keeps the pending edit” to an unproven acceptance condition until this passes.

P1: pre-auth command dispatch and credential framing need an explicit boundary (command table, auth section, lines 54 and 74–81).

the table assigns no connection states, so the plan does not establish whether LIST, NAMESPACE, STATUS, SELECT, FETCH, SEARCH, CHECK, IDLE or the APPEND literal-drain path are reachable before authentication. require a state/command matrix and reject mailbox commands before mailbox lookup, rendering, UID access or literal continuation. enforce the process connection permit from TCP acceptance, covering TLS handshakes and unauthenticated sockets; add Installation/user permits after verification and release all permits on every failure path.

an 8 KiB command line does not bound a LOGIN literal or a SASL continuation. specify small independent credential-literal, encoded SASL and decoded SASL limits, strict PLAIN framing/identity handling, cancellation, bounded authentication attempts/work, and an absolute authentication deadline that partial input cannot extend. the 96 MiB message bound must not become the pre-auth credential bound. since LITERAL+ is not advertised, closing on an unsolicited non-synchronizing literal is a simpler option than draining it. gate large/malformed LOGIN literals, both AUTHENTICATE forms, cancellation, partial input, pipelined mailbox commands after failed auth, and connections held before TLS/auth completion.

one RFC qualification to the four-command question: RFC 3501 §6.1 also permits NOOP before auth. explicitly choose that harmless fifth command, with no mailbox updates, or document a deliberate restriction. nothing else should expose mailbox work before auth. RFC 4616 §2 defines PLAIN's identity/password framing.

P2: separate input-progress deadlines from authenticated inactivity (lines 80–82).

“command inactivity 30 s” risks disconnecting a healthy authenticated client between commands. a hard BYE at 28 minutes of IDLE is also below RFC 3501 §5.4's minimum 30-minute inactivity autologout. RFC 2177 advises the client to renew IDLE at least every 29 minutes; it does not prescribe a shorter server disconnect. keep short handshake/auth/partial-command/literal-progress deadlines, give authenticated inactivity at least 30 minutes, and exempt IDLE/DONE from the ordinary partial-command timer. test these timer states independently, including a healthy quiet session.

P2: the streaming budget needs a concrete storage boundary (lines 68, 77–87, persistence gate).

the immutable-byte rule is correct, but #824's current get returns an entire payload as Vec<u8> and append accepts the whole byte slice. storing complete 96 MiB MIME there and fetching it through that API does not meet the stated ≤8 MiB incremental RSS per connection. name the representation: for example, immutable serialized blobs with bounded streaming reads and durable references under UID authority, or a smaller first-slice message cap. account for shared cache/source memory as well as socket buffers. pin attachment bytes and serialization version before advertising a UID; a streaming source failure after announcing a literal must close rather than promise that no partial literal was sent. preflight removes some failures, not mid-transfer read failures.

P2: the first implementation PR combines too many independently risky changes (“first implementation PR size”).

10–14 files / 1,400–2,000 lines is an estimate, not sufficient review containment for new TLS lifecycle/deployment, auth schema/scope, a stateful literal parser, persistent projection, MIME/attachments and IDLE fan-out together. establish smaller dependency PRs and explicit activation gates.

cuts

  • first PR: disabled-by-default listener, one fixed TLS termination choice, scoped authentication, bounded pre-auth state machine and focused protocol/limit tests. no real-note projection or public enablement.
  • next PR: durable immutable text-only MIME projection using #824, read-only mailbox commands and the mandatory native retention gate. preserve observed STATUS/CHECK/NAMESPACE; those are supported by evidence, not useful cuts.
  • defer attachments and BODYSTRUCTURE's multipart cases to a separately measured streaming PR. state the text-only eligibility boundary explicitly; never silently omit attachment content from an included note.
  • defer IDLE fan-out only if a native run with IDLE unadvertised proves polling works within the accepted visibility budget. the existing capture's NOOP-between-IDLE behavior alone does not prove this cut safe.
  • choose existing Traefik TCP TLS termination versus in-process TLS before implementation. defer certificate hot reload and internal app-password kind renaming; use a documented restart/rotation path initially.

UID decision

passes at the plan level: lines 12 and 68 explicitly require a new server-owned UID for every Calternal content revision, immutable bytes for an issued UID, and exact-tuple retirement of the old revision. that matches RFC 3501 §2.3.1.1 and #824; the stable note UUID must not be reused as the IMAP UID. add a positive edit gate: fetch U1, edit the note in Calternal, observe U2 > U1 with the same note UUID and new bytes, and verify U1 either returns its original bytes while retained or no message after retirement, across concurrent fetch, reconnect and restart. never re-render changed bytes under U1.

IMAPS-only on 993 is supported by RFC 8314 §3.2. the explicit Notes-only scope and retaining the observed minimal commands are sound choices. approval waits on the native-safety gate definition, pre-auth boundary, timeout correction, concrete streaming design and smaller first PR.

# Independent plan review **verdict: revise.** reviewed #830 at `840ec0d022105fc680e16ea846fbd39afb59c7ae`, against #775 at `39d0553d`, its slice-0/native fresh-mailbox evidence, and #824 at `f1c1aa96`. no P0 findings; two P1s and three P2s below. no separate P3 findings. this is a plan review; no native experiment or product tests were run, and nothing was pushed. ## findings **P1: the native gate does not yet establish preservation under this read-only contract** (plan lines 52–56, failure table, gate 4). slice-0 findings E2-3 establish a narrower result: `APPEND NO [OVERQUOTA]` retained the full local text through quit/relaunch, caused no cleanup or retry for at least two minutes, and the next small edit uploaded all pending text. the report explicitly says the failed-save UI was not reviewed. neither that result nor E2-2's successful STORE/EXPUNGE followed by republication establishes behavior for `SELECT [READ-ONLY]` or explicit `NO [READ-ONLY]` on APPEND/STORE. the fresh-mailbox run also demonstrates that server retention can coexist with pending text being hidden in Notes; it is not a read-only-selection test. gate 4 already has a useful conditional retention check, but “if the client queues” leaves the decisive case optional. make this a mandatory release gate with a deliberately seeded offline edit before reconnecting to the read-only server. separately exercise initial read-only selection, an edit/delete attempted after selection, and actual queued-command refusals. include a Calternal edit that publishes a replacement UID while the native edit remains pending. require exact pending text to remain visibly accessible through reconnect and quit/relaunch, unchanged bystanders, no successful mutation or false server-save indication, and a bounded retry rate over a recorded observation interval. capture all connections and the native error/UI state. if Notes prevents editing entirely, record that result and still test the pre-existing offline queue. export and verify pending text before removing the disposable account. do not enable outside dev if any pending text disappears or becomes inaccessible. change the failure-table recovery assertion “Notes keeps the pending edit” to an unproven acceptance condition until this passes. **P1: pre-auth command dispatch and credential framing need an explicit boundary** (command table, auth section, lines 54 and 74–81). the table assigns no connection states, so the plan does not establish whether LIST, NAMESPACE, STATUS, SELECT, FETCH, SEARCH, CHECK, IDLE or the APPEND literal-drain path are reachable before authentication. require a state/command matrix and reject mailbox commands before mailbox lookup, rendering, UID access or literal continuation. enforce the process connection permit from TCP acceptance, covering TLS handshakes and unauthenticated sockets; add Installation/user permits after verification and release all permits on every failure path. an 8 KiB command line does not bound a LOGIN literal or a SASL continuation. specify small independent credential-literal, encoded SASL and decoded SASL limits, strict PLAIN framing/identity handling, cancellation, bounded authentication attempts/work, and an absolute authentication deadline that partial input cannot extend. the 96 MiB message bound must not become the pre-auth credential bound. since LITERAL+ is not advertised, closing on an unsolicited non-synchronizing literal is a simpler option than draining it. gate large/malformed LOGIN literals, both AUTHENTICATE forms, cancellation, partial input, pipelined mailbox commands after failed auth, and connections held before TLS/auth completion. one RFC qualification to the four-command question: [RFC 3501 §6.1](https://www.rfc-editor.org/rfc/rfc3501.html#section-6.1) also permits **NOOP before auth**. explicitly choose that harmless fifth command, with no mailbox updates, or document a deliberate restriction. nothing else should expose mailbox work before auth. [RFC 4616 §2](https://www.rfc-editor.org/rfc/rfc4616.html#section-2) defines PLAIN's identity/password framing. **P2: separate input-progress deadlines from authenticated inactivity** (lines 80–82). “command inactivity 30 s” risks disconnecting a healthy authenticated client between commands. a hard BYE at 28 minutes of IDLE is also below [RFC 3501 §5.4](https://www.rfc-editor.org/rfc/rfc3501.html#section-5.4)'s minimum 30-minute inactivity autologout. [RFC 2177](https://www.rfc-editor.org/rfc/rfc2177.html) advises the *client* to renew IDLE at least every 29 minutes; it does not prescribe a shorter server disconnect. keep short handshake/auth/partial-command/literal-progress deadlines, give authenticated inactivity at least 30 minutes, and exempt IDLE/DONE from the ordinary partial-command timer. test these timer states independently, including a healthy quiet session. **P2: the streaming budget needs a concrete storage boundary** (lines 68, 77–87, persistence gate). the immutable-byte rule is correct, but #824's current `get` returns an entire payload as `Vec<u8>` and `append` accepts the whole byte slice. storing complete 96 MiB MIME there and fetching it through that API does not meet the stated ≤8 MiB incremental RSS per connection. name the representation: for example, immutable serialized blobs with bounded streaming reads and durable references under UID authority, or a smaller first-slice message cap. account for shared cache/source memory as well as socket buffers. pin attachment bytes and serialization version before advertising a UID; a streaming source failure after announcing a literal must close rather than promise that no partial literal was sent. preflight removes some failures, not mid-transfer read failures. **P2: the first implementation PR combines too many independently risky changes** (“first implementation PR size”). 10–14 files / 1,400–2,000 lines is an estimate, not sufficient review containment for new TLS lifecycle/deployment, auth schema/scope, a stateful literal parser, persistent projection, MIME/attachments and IDLE fan-out together. establish smaller dependency PRs and explicit activation gates. ## cuts - first PR: disabled-by-default listener, one fixed TLS termination choice, scoped authentication, bounded pre-auth state machine and focused protocol/limit tests. no real-note projection or public enablement. - next PR: durable immutable text-only MIME projection using #824, read-only mailbox commands and the mandatory native retention gate. preserve observed STATUS/CHECK/NAMESPACE; those are supported by evidence, not useful cuts. - defer attachments and BODYSTRUCTURE's multipart cases to a separately measured streaming PR. state the text-only eligibility boundary explicitly; never silently omit attachment content from an included note. - defer IDLE fan-out only if a native run with IDLE unadvertised proves polling works within the accepted visibility budget. the existing capture's NOOP-between-IDLE behavior alone does not prove this cut safe. - choose existing Traefik TCP TLS termination versus in-process TLS before implementation. defer certificate hot reload and internal app-password kind renaming; use a documented restart/rotation path initially. ## UID decision **passes at the plan level:** lines 12 and 68 explicitly require a new server-owned UID for every Calternal content revision, immutable bytes for an issued UID, and exact-tuple retirement of the old revision. that matches [RFC 3501 §2.3.1.1](https://www.rfc-editor.org/rfc/rfc3501.html#section-2.3.1.1) and #824; the stable note UUID must not be reused as the IMAP UID. add a positive edit gate: fetch U1, edit the note in Calternal, observe U2 > U1 with the same note UUID and new bytes, and verify U1 either returns its original bytes while retained or no message after retirement, across concurrent fetch, reconnect and restart. never re-render changed bytes under U1. IMAPS-only on 993 is supported by [RFC 8314 §3.2](https://www.rfc-editor.org/rfc/rfc8314.html#section-3.2). the explicit Notes-only scope and retaining the observed minimal commands are sound choices. approval waits on the native-safety gate definition, pre-auth boundary, timeout correction, concrete streaming design and smaller first PR.
Author
Owner

Plan revised in place and pushed at 7927d06.

  • Added a mandatory Mac preservation gate with a seeded offline edit, concurrent Calternal revision, several sync cycles, relaunch, UI/log capture and bounded retry observation. No real user connects before the gate; failure restricts read-only access to fresh Notes accounts only.
  • Added the pre-auth command matrix, explicit credential framing limits, three-attempt/backoff policy, and TCP-accept IP/process permits plus post-auth Installation/user caps.
  • Set authenticated inactivity and IDLE to 31 minutes; separated partial-input deadlines. Added immutable disk-backed MIME blobs, bounded 64 KiB FETCH streaming, mid-stream close behavior, and the positive U1-to-U2 UID gate.
  • Split implementation into a disabled listener/auth foundation PR and a Notes-serving PR. Attachments remain in the first Notes-serving PR as multipart/related with stable CIDs; retain dav and add mail.notes.read. TLS termination remains open for kayg, with a recommendation at the end of the plan.
  • Documentation only. git diff --check passed; no build, tests or native experiment were run.
Plan revised in place and pushed at `7927d06`. - Added a mandatory Mac preservation gate with a seeded offline edit, concurrent Calternal revision, several sync cycles, relaunch, UI/log capture and bounded retry observation. No real user connects before the gate; failure restricts read-only access to fresh Notes accounts only. - Added the pre-auth command matrix, explicit credential framing limits, three-attempt/backoff policy, and TCP-accept IP/process permits plus post-auth Installation/user caps. - Set authenticated inactivity and IDLE to 31 minutes; separated partial-input deadlines. Added immutable disk-backed MIME blobs, bounded 64 KiB FETCH streaming, mid-stream close behavior, and the positive U1-to-U2 UID gate. - Split implementation into a disabled listener/auth foundation PR and a Notes-serving PR. Attachments remain in the first Notes-serving PR as `multipart/related` with stable CIDs; retain `dav` and add `mail.notes.read`. TLS termination remains open for kayg, with a recommendation at the end of the plan. - Documentation only. `git diff --check` passed; no build, tests or native experiment were run.
Author
Owner

Infrastructure for this plan is in place (Maintainer, 2026-11-02; homelab-private PR #3, dab294db). Implementation must follow these facts:

  • Public path: calternal.cloud (168.119.145.115):993 → DNAT on compute01 → k3s Traefik LoadBalancer :993 → entrypoint imaps → IngressRouteTCP calternal/calternal-imaps (tls.passthrough=true, HostSNI(*)) → prod 10.70.3.162:993 over the private LAN, not NetBird. No TLS termination at the edge: Calternal terminates implicit TLS itself.
  • Prod firewall: 993 is open only from the k3s node IPs 10.70.3.101–103.
  • Port: prod is rootless Podman, and ip_unprivileged_port_start=1024 stays as it is. The app listens on 9993 inside the container, published as host :9993. A narrow root-owned socket forwarder maps host 10.70.3.162:993 → :9993 (the Maintainer installs it). Bind to 10.70.3.162 or to all interfaces.
  • Certificate: the same cert as HTTPS (cert-manager Secret calternal/calternal-tls).
    • Prod files: /etc/calternal/imap-tls/current/{fullchain.pem,privkey.pem}, readable by user calternal.
    • calternal-imap-tls-sync.timer refreshes them every 5 min by atomically rotating the current symlink.
    • Mount the whole /etc/calternal/imap-tls directory read-only (not the resolved files).
    • The app must reload the cert when the current symlink generation changes. Sync does not restart the app.
    • The current cert expires 2026-12-26.
  • Verified with a probe: public TLS handshake (with and without SNI), the pinned HTTPS cert fingerprint, the IMAP greeting and NOOP all passed. HTTPS is unaffected.
  • Runbook: homelab-private scripts/calternal-imaps/README.md.
  • Profiles: iPhone/Mac .mobileconfig profiles are signed with the Developer ID Application certificate (1Password "Apps / Calternal" → "Apple Certificates", issued to Aayushy Swetapragyan). Each device gets its own mail.notes.read app password. This is the setup step after the read-only server works.
Infrastructure for this plan is in place (Maintainer, 2026-11-02; homelab-private PR #3, dab294db). Implementation must follow these facts: - **Public path:** calternal.cloud (168.119.145.115):993 → DNAT on compute01 → k3s Traefik LoadBalancer :993 → entrypoint `imaps` → IngressRouteTCP `calternal/calternal-imaps` (tls.passthrough=true, HostSNI(`*`)) → prod 10.70.3.162:993 over the private LAN, not NetBird. No TLS termination at the edge: **Calternal terminates implicit TLS itself.** - **Prod firewall:** 993 is open only from the k3s node IPs 10.70.3.101–103. - **Port:** prod is rootless Podman, and `ip_unprivileged_port_start=1024` stays as it is. The app listens on **9993** inside the container, published as host :9993. A narrow root-owned socket forwarder maps host 10.70.3.162:993 → :9993 (the Maintainer installs it). Bind to 10.70.3.162 or to all interfaces. - **Certificate:** the same cert as HTTPS (cert-manager Secret `calternal/calternal-tls`). - Prod files: `/etc/calternal/imap-tls/current/{fullchain.pem,privkey.pem}`, readable by user `calternal`. - `calternal-imap-tls-sync.timer` refreshes them every 5 min by atomically rotating the `current` symlink. - **Mount the whole `/etc/calternal/imap-tls` directory read-only** (not the resolved files). - **The app must reload the cert when the `current` symlink generation changes.** Sync does not restart the app. - The current cert expires 2026-12-26. - **Verified with a probe:** public TLS handshake (with and without SNI), the pinned HTTPS cert fingerprint, the IMAP greeting and NOOP all passed. HTTPS is unaffected. - **Runbook:** homelab-private `scripts/calternal-imaps/README.md`. - **Profiles:** iPhone/Mac `.mobileconfig` profiles are signed with the Developer ID Application certificate (1Password "Apps / Calternal" → "Apple Certificates", issued to Aayushy Swetapragyan). Each device gets its own `mail.notes.read` app password. This is the setup step after the read-only server works.
Author
Owner

The port 993 forwarder is installed on prod (Maintainer, 2026-11-02; homelab-private PR #4):

  • calternal-imaps.socket: enabled and active, owned by the root system manager. It listens on 10.70.3.162:993.
  • calternal-imaps.service: started by that socket. It runs a systemd-socket-proxyd worker with DynamicUser=yes that forwards to 10.70.3.162:9993, and exits after 5 idle minutes. It does no TLS termination.
  • Deploy contract:
    • Podman publishes 10.70.3.162:9993:9993 for the IMAP listener (the app listens on 9993 inside the container).
    • Mount /etc/calternal/imap-tls read-only as a directory, and reload when the current symlink changes.
  • Firewall:
    • 993 is allowed only from the k3s nodes (10.70.3.101–103).
    • 9993 is dropped for all non-local inbound traffic, ahead of the broad NetBird allow. Local LAN connections via lo still work.
    • The global unprivileged-port threshold stays at 1024.
  • Verified: the public calternal.cloud:993 TLS handshake, the IMAP greeting and NOOP all work through the proxy to a temporary 9993 listener running as calternal. A direct connection to 9993 from a k3s node is blocked. No listener remains, and the socket is ready for the train that ships the server.
The port 993 forwarder is installed on prod (Maintainer, 2026-11-02; homelab-private PR #4): - **`calternal-imaps.socket`**: enabled and active, owned by the root system manager. It listens on **10.70.3.162:993**. - **`calternal-imaps.service`**: started by that socket. It runs a `systemd-socket-proxyd` worker with DynamicUser=yes that forwards to **10.70.3.162:9993**, and exits after 5 idle minutes. It does no TLS termination. - **Deploy contract:** - Podman publishes `10.70.3.162:9993:9993` for the IMAP listener (the app listens on 9993 inside the container). - Mount `/etc/calternal/imap-tls` read-only as a directory, and reload when the `current` symlink changes. - **Firewall:** - 993 is allowed only from the k3s nodes (10.70.3.101–103). - 9993 is dropped for all non-local inbound traffic, ahead of the broad NetBird allow. Local LAN connections via lo still work. - The global unprivileged-port threshold stays at 1024. - **Verified:** the public `calternal.cloud:993` TLS handshake, the IMAP greeting and NOOP all work through the proxy to a temporary 9993 listener running as `calternal`. A direct connection to 9993 from a k3s node is blocked. No listener remains, and the socket is ready for the train that ships the server.
Author
Owner

Housekeeping #1009 status: audited head 7927d06ac60e83ac3eee9780e333d047a4305901 against dev cd7f84432feb. git cherry origin/dev <head> reports 2 unmatched commits and 0 equivalent patches. Separate stable patch-id indexing and key-file checks do not establish full landing. Absent from dev: docs/plans/766-slice1-read-only-imap.md. Left unchanged as WIP, per kayg’s instruction; no rebase, close, tests, or merge. The #1009 audit records the unmatched commit list.

Housekeeping #1009 status: audited head `7927d06ac60e83ac3eee9780e333d047a4305901` against dev `cd7f84432feb`. `git cherry origin/dev <head>` reports 2 unmatched commits and 0 equivalent patches. Separate stable patch-id indexing and key-file checks do not establish full landing. Absent from dev: `docs/plans/766-slice1-read-only-imap.md`. Left unchanged as WIP, per kayg’s instruction; no rebase, close, tests, or merge. The #1009 audit records the unmatched commit list.
Author
Owner

Superseded by #775; closing.

Superseded by #775; closing.
kayg closed this pull request 2026-11-10 16:02:26 +00:00
Some checks failed
CI / server (pull_request) Has been cancelled
CI / rust (pull_request) Has been cancelled
CI / web (pull_request) Has been cancelled
Markdown extraction contract / markdown-native-contract (pull_request) Has been cancelled
Markdown extraction contract / markdown-editor-contract (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal!830
No description provided.