Commit graph

1,089 commits

Author SHA1 Message Date
iris
2a2d76d733 hive-ag3nt: scrub mcp.rs cookies (#716 batch 8)
Last #716 hotspot — scrub-only batch. All substantive prose is
already documented in docs/turn-loop.md::MCP surface (Sub-agent
tools, Manager tools, Tool whitelist, Tool envelope), so the 10
cookies in mcp.rs come out without prose extraction.

- format_agent_meta rustdoc: drop #432 attribution, add docs pointer
  for the running=false / status_text-stale rationale
- get_agent_meta hive/swarm comment: drop #710 attribution
- AgentServer + ManagerServer add-tool warnings: drop #511 attribution
  twice (kept the lockstep invariant)
- edit_schedule description: drop #474 + #478 cookies in user-facing
  tool text
- cancel_loose_end description: drop #250 cookie in user-facing text
- Manager allow-list block: drop the long #444/#235/#467/#472/#474/
  #478/#509 attribution roll, keep the lockstep invariant
- check_send_allowed (<parent> branch): drop #692, replace with the
  actual semantics ("falls back to operator for root agents")
- prompts/system.md: drop #474 cookie from edit_schedule line
- Cargo.toml [[bin]]: drop #598 pre-/post- split history, add docs
  pointer to docs/turn-loop.md::Harness binary shape

cargo check + 56 tests pass.
Closes #716 (last cookie hotspot).
2026-05-31 17:39:45 +02:00
damocles
d62a9518c0 hive-c0re: scrub attribution cookies across background-task modules (#715 batch 6) 2026-05-31 17:39:40 +02:00
damocles
50a1eb41cf hive-gateway: nginx Requires= cert oneshot (fixes #856 from #848) 2026-05-31 17:34:23 +02:00
damocles
d2f1a9d291 hive-c0re: extract agent-socket-plumbing prose (#715 batch 5) 2026-05-31 17:32:21 +02:00
iris
f8e0061f3f hive-ag3nt: scrub turn.rs cookies (#716 batch 7)
12 → 0 cookies in turn.rs (claude --print pump + stream-json +
compaction + wait_for_login). Cookie scrub only — substantive
prose (auth-failed detection, mtime-snapshot resumption,
DirSnapshot two-axis design, AuthFailed turn outcome) is already
documented in docs/turn-loop.md::The loop and the Turn outcomes
table. Rustdocs trimmed to point at the doc where useful
(AUTH_FAIL_MARKERS, wait_for_login).

- AUTH_FAIL_MARKERS doc: drop #658, #419 attribution
- write_settings inner comment: drop #555 attribution
- write_system_prompt doc: drop #519 attribution
- TurnOutcome::AuthFailed doc: drop #419 attribution
- wait_for_login doc: drop #542 attribution, point at docs
- wait_for_login inner emit_status comment: drop #563 attribution
- Test comments: drop #542 and argus #545 attribution
2026-05-31 17:29:20 +02:00
iris
55716be8fc hive-ag3nt + docs: extract web_ui prose (#716 batch 6)
docs/web-ui.md:
- New `### Listener bind` subsection — uncapped TCP retry rationale
  (replaces stale "12 tries" claim that contradicted the code) +
  pointer to gateway.md for unix-socket transition
- Expand `/api/logout` bullet with three-step teardown rationale
  (SIGINT race, selective cred-file wipe preserves --continue,
  wait_for_login resumption path)

hive-ag3nt/src/web_ui.rs:
- serve / bind_unix / bind_with_retry rustdocs trimmed to docs
  pointers (binding modes, .bound marker, retry budget all live in
  the prose now)
- AgentLink / StateSnapshot.links / agent_links rustdocs trimmed
  to single-line summaries
- post_logout / CRED_FILE_NAMES rustdocs reference docs/web-ui.md
- 13 → 0 cookies
2026-05-31 17:25:27 +02:00
atlas
604146992a nix/hive-c0re: trim duplicate identity + flag prose (#718 batch 7)
Three blocks in `nix/modules/hive-c0re.nix` duplicated content that
already exists in extracted docs since iris's #717 batch (identity
section) and earlier #718 batches landed:

- `services.hyperhive.domain` option intro — collapsed to a short
  purpose statement + pointer to
  `docs/conventions.md::Hive identity (label + domain + display names)`
  (iris's section covering the full env-var propagation chain).
- `hiveName` / `swarmName` option intros (display names) — same.
- `HYPERHIVE_HIVE_DOMAIN` / `HIVE_NAME` / `SWARM_NAME` env-var
  injection comments (three near-identical blocks) — collapsed to
  a single shared pointer block + dropped the per-var redundant
  explanation.
- `HIVE_MATRIX_GUI_ENABLED` + `HIVE_GATEWAY_ENABLED` flag comments
  — tightened to one-line purpose statements; the gateway routing
  detail already lives in `docs/gateway.md::Vhost map`.
- Dropped the trailing "Matrix GUI static serving lives entirely
  on the gateway" comment block — duplicates docs/gateway.md
  content.

`description = ''…''` blocks (operator-facing options docs)
preserved per iris #718 unchanged.

Net: ~30 lines removed from hive-c0re.nix, no docs additions
needed — extracted prose already exists from prior batches.

`nix flake check` clean.
2026-05-31 17:25:14 +02:00
damocles
0b3aa5391e hive-c0re/container_view.rs: scrub attribution cookies (#715 batch 4) 2026-05-31 17:21:53 +02:00
iris
94c110fd5f hive-ag3nt + docs: extract harness binary shape prose (#716 batch 5)
`bin/hive.rs` carries ~15 attribution cookies (#598, #676, #692,
#693, #778, #788, #682, #688) plus structural prose about the
single-binary architecture (role-from-env), the `Surface` trait
pattern (zero-sized type tags + generic dispatch), boot wiring
(label fallback, plugin install → send_to_parent failure routing),
and turn-outcome branching (ack / requeue / wait_for_login / parent
notify).

Migrated to a new `docs/turn-loop.md::Harness binary shape`
subsection covering:

- Single-binary rationale (server-side privilege boundary on the
  broker socket means no escalation risk in shipping both wire
  surfaces in the same process).
- Three subcommands (`serve` / `mcp` / `wake`).
- Surface trait + zero-sized type tags (AgentSurface,
  ManagerSurface) — picks per-role FLAVOR / FORGE_IS_MANAGER and
  exposes the broker wire ops behind trait methods so the turn
  loop is written once.
- Boot wiring (HIVE_PORT, HIVE_LABEL fallback, plugin failures
  routed via send_to_parent, web_ui + forge_notify spawn).
- Turn outcomes table (Ok/Compacted/RateLimited/AuthFailed/Failed)
  + continue-sentinel pickup.

In-code rustdocs reduced to 1-line summaries + doc pointers;
inline cookies stripped from boot wiring + plugin install +
sentinel cleanup paths.

15 → 0 cookies in bin/hive.rs; cargo check -p hive-ag3nt passes.
2026-05-31 17:18:22 +02:00
damocles
2ce8bb5b77 scheduled_prompts: address argus 🟡 on #849 — submit paths section + persistence.md anchor fix 2026-05-31 17:18:15 +02:00
damocles
50879cea5a hive-c0re + docs: extract scheduled_prompts prose (#715 batch 2) 2026-05-31 17:18:15 +02:00
damocles
c7777f3d58 hive-gateway: hoist publicScheme/Port helpers to outer let (argus 🟡 on #848) 2026-05-31 17:17:58 +02:00
damocles
314f1774d8 hive-gateway: self-signed TLS for matrix-client well-known fetch (closes #837) 2026-05-31 17:17:58 +02:00
iris
76d3267b55 hive-ag3nt + docs: extract forge_notify prose (#716 batch 4)
forge_notify.rs is the biggest remaining #716 hotspot: ~22 attribution
cookies (#110 #230 #231 #253 #256 #455 #518 #539 #544) plus a thick
module-level docstring + per-function rationale blocks for the
notification pipeline. The substantive prose lives in a new
`docs/forge.md` covering the wider forge integration story:

- Per-agent forge accounts + agent-configs mirror (was implicit
  across `hive-c0re/src/forge.rs` rustdocs).
- Notification poller: activation gates, self-notification filtering,
  body excerpt + truncation + ATX heading escape pipeline, wrapper
  formats (comment / review / new-item / state-change) with shape
  table, meta suffix shape, review-request override, reason
  drop-list rationale (drop vs allow), auto-unsubscribe on broad
  watches.

In-code rustdocs reduced to 1-line semantic summaries + doc
pointers; inline cookie comments scrubbed. Net diff is ~150 lines
removed from the .rs file. All 16 forge_notify unit tests pass.

CLAUDE.md gets a new `docs/forge.md` file-map entry + reading-path
question entry. The existing `src/forge_notify.rs` file-map blurb
keeps its `(#539 / #544)` cookie — consistent with the rest of
CLAUDE.md's lineage attributions.
2026-05-31 17:17:24 +02:00
damocles
4f9697220e hive-c0re/topology.rs: trim prose to docs pointers (#715 batch 3) 2026-05-31 17:17:07 +02:00
iris
fbc41d42a6 dashboard: build same-origin /agent/<name>/ links when gateway is up (closes #842)
When `services.hyperhive.gateway.enable` is on (default), the c0re
NixOS module now sets `HIVE_GATEWAY_ENABLED=1` on the service env.
`/api/state` exposes the flag as `gateway_enabled`; the SW4RM tab's
container-row renderer flips three link sites (primary agent-name
link, favicon fetch, `container`-kind nav-strip links) from the
legacy `http://<host>:<port>/` direct TCP shape to same-origin
`/agent/<name>/` URLs — the gateway proxies them to the per-agent
harness via `agent-ports.json` or `agent-sockets.json` (#784 / #815).
Gateway-off deploys keep the direct TCP fallback so local-dev /
operator opt-out keeps working.

`forge`-kind nav-strip links still resolve against `:3000` (separate
sub-domain transition, tracked by `forge.behindGateway`);
`external`-kind links are already absolute.

Mirrors the `HIVE_MATRIX_GUI_ENABLED` env→snapshot-flag pattern.
Docs updated: `docs/web-ui.md::Container row` + new
`docs/gateway.md::Dashboard link shape` section.
2026-05-31 17:16:53 +02:00
atlas
b50f182396 hive-gateway: note common-case dnsmasq address redundancy (argus 🟡 on #845)
forge/matrix subdomain address rules are redundant when those are
sub-domains of hyperhive.domain (dnsmasq's /<domain>/ matches
sub-domains). Keep explicit for the cross-domain case (e.g.
forge.domain = "git.example.com") + add a comment explaining
the trade-off.
2026-05-31 16:56:59 +02:00
atlas
ed3b9d853e nix/hive-network: bridge + dnsmasq resolver, opt-in (#805 v1)
Stand up the host-side bridge interface + per-agent DNS resolver
ahead of #14 (netns isolation). Mara on #805#11541: "we need it
before #14 so nothing breaks when we switch over". v1 ships the
endpoint live but containers stay on shared host netns — when #14
flips them to private netns the DNS contract is already there.

Shape:

- new `nix/modules/hive-network.nix` with `services.hyperhive.network.*`
  options (enable + bridgeName + bridgeIp + bridgePrefixLength +
  upstreamDns). Default off. Imported from `hive-c0re.nix`.
- bridge interface via `networking.bridges` (no slave NICs at v1;
  per-agent veth pairs attach once #14 lands).
- bridge IP assigned via `networking.interfaces`.
- `networking.firewall.interfaces.<bridge>.allowed{UDP,TCP}Ports =
  [ 53 ]` opens the resolver on the bridge interface only —
  other interfaces stay closed.
- dnsmasq config added to the existing `hive-gateway` container
  (mara on #805:10957: "put the resolver into the gateway container").
  Listens only on `bridgeName` + `lo`; authoritative for
  `<hive-domain>`, `forge.<hive>`, `matrix.<hive>` answering with
  the bridge IP; forwards everything else to upstream.
  `resolveLocalQueries = false` keeps the gateway container's own
  resolver untouched.

Asserts `services.hyperhive.domain != null` + `gateway.enable =
true` — both required for the resolver to be meaningful.

Docs: new `docs/network.md` covering v1 vs v2 split, container shape
rationale, default addressing, resolver behaviour, firewall posture.

`nix flake check` clean.
2026-05-31 16:56:59 +02:00
lexis
0d328d1fcd docs(CLAUDE.md): add network.md to file index + reading paths (follow-up to #845) 2026-05-31 16:56:08 +02:00
damocles
91e50d843c hive-c0re/matrix.rs: trim UIAA prose to docs pointer (#715 batch 1) 2026-05-31 16:55:55 +02:00
iris
017786564a hive-ag3nt: scrub stale #658/#419 attribution cookies (#716 batch 2) 2026-05-31 16:48:13 +02:00
iris
84f3fe5f69 hive-ag3nt + docs: extract prompt-rendering prose (#716 batch 3) 2026-05-31 16:46:00 +02:00
iris
2bb8f2a3f7 hive-ag3nt + docs: extract identity prose (#716 batch 1) 2026-05-31 16:41:24 +02:00
atlas
4821f1a36e docs/gateway.md: drop duplicate 'Per-agent UDS upstream' section
mara/damocles wrote a fuller version of the same section at line 70
(`Per-agent unix-socket upstream (#784)`) as part of #832 — covers
the 4-step rollout flow including the .bound marker filter that
landed in #832. The atlas-side section at line 207 was the pre-#832
version with the eval-time path-exists gate notes; superseded.

Net effect: one canonical section on the unix-socket upstream story
rather than two with overlapping content.
2026-05-31 16:35:26 +02:00
damocles
73e55dc44a docs(CLAUDE.md): note .bound marker filter on agent_sockets (follow-up to #832) 2026-05-31 16:31:46 +02:00
iris
c058558a2a hive-sh4re/lib.rs: scrub remaining self-ref cookies (#717 batch 9 final) 2026-05-31 16:28:46 +02:00
damocles
02d458cdf5 agent_sockets: address argus 🟡 on #832 (doc attribution + drop unused arg)
argus on PR #832:
- 🟡 spawn_poll was inserted BETWEEN write's closing doc and the
  pub fn write line; rust treated the consecutive /// as one block,
  so spawn_poll inherited write's tail and write ended up with no
  closing doc. moved spawn_poll AFTER write to fix attribution.
- 🟡 spawn_poll(coord) took Arc<Coordinator> just to drop it
  immediately. dropped the param; main.rs call site now just
  agent_sockets::spawn_poll().

no functional change. 10 tests still pass.
2026-05-31 16:28:36 +02:00
damocles
90c72d9131 docs/gateway.md: section on the #784 unix-socket upstream chain (mara on #832) 2026-05-31 16:28:36 +02:00
damocles
5e0cb5e0f5 hive-c0re + harness: filter agent-sockets.json by .bound marker (#784, atlas concern)
closes the gate atlas raised on PR #813: without per-agent opt-in
signal, agent-sockets.json listed every sub-agent, and any agent
that hadn't flipped hyperhive.web.useUnixSocket would 502 the
gateway (its harness still binds TCP, no socket at the published
path).

harness side (web_ui::bind_unix):
- after successful bind + chmod, drop a `.bound` marker in the
  per-agent dir as a stable 'this agent has a unix socket here'
  signal. best-effort: a failed marker write logs at WARN but
  doesn't abort serve (the socket still binds fine; gateway just
  keeps using TCP for one more poll).

c0re side (agent_sockets):
- new READY_MARKER const + ready_marker_for(name) helper
- build_map filters by ready_marker_for(name).exists() — only agents
  whose harness has bound the socket appear in the JSON map
- new build_map_with<F> internal extracts the predicate so tests
  pass a controlled is_ready closure (no real fs access)
- new spawn_poll() background task: re-fires agent_sockets::write
  every 10s so the JSON catches up to fresh markers without
  needing a container-start hook. write() idempotency means
  steady-state cost is one stat per agent per tick.

10 tests: 6 prior + new build_map_filters_by_ready_predicate +
ready_marker_path_is_sibling_of_socket. existing tests adjusted to
call build_map_with(_, |_| true) since the default path now hits
the fs.

once this lands + #822 lands, atlas's gateway-side step 3 can drop
its eval-time `pathExists` fallback — c0re only publishes opted-in
agents, so the gateway can trust the JSON unconditionally.
2026-05-31 16:28:36 +02:00
iris
777d26812a hive-sh4re + docs: extract AgentMeta wire-shape prose (#717 batch 8) 2026-05-31 16:25:10 +02:00
iris
29fda64866 docs/approvals.md: split sha vs tag scoping per argus on #833 2026-05-31 16:25:03 +02:00
iris
f3fefe7f7e hive-sh4re + docs: extract HelperEvent prose (#717 batch 7) 2026-05-31 16:25:03 +02:00
damocles
d59bfb899f hive-forge: drop boilerplate # Errors from pure-GET verbs (mara on #827, option A)
mara: 'those comments seem very redundant'. true — the 16 pure-GET
verbs all got the same 'transport error + stdout I/O' boilerplate,
which just restates the Result<()> contract that's trivially
derivable from the type.

dropped # Errors from: assign, branches, close, comment_show,
comments, diff, issue, labels, lint, list, milestone, pr,
pr_reviews, subscription, timeline, tree_sha, view (17 files).

kept on the 7 verbs that have a non-Forgejo failure surface worth
documenting:
- comment, comment_edit, issue_create, issue_edit — body input I/O
  via --body-file / stdin
- pr_create — body input + --push shellout to git
- attach::run_issue, attach::run_comment — explicit bail! on
  missing file

net: 23 verbs touched in the original PR → 17 trimmed back to
no-doc, 6 kept (with the 7th call being attach::run_comment in the
same file). 38 tests still pass.
2026-05-31 16:22:05 +02:00
damocles
1195bfbe11 hive-forge: add # Errors docs on every verb's pub fn run (closes #816)
systemic gap argus flagged on PR #798 (timeline verb). every `pub fn
run` in hive-forge/src/verbs/*.rs lacked a `# Errors` block —
violates Rust API guidelines + obscures the failure surface for
operators reading the source.

uniform doc per verb category:
- pure GET + print verbs: "transport error from the Forgejo REST call
  + I/O error from stdout"
- body-from-file verbs (comment/comment_edit/issue_create/issue_edit/
  pr_create): adds 'I/O error from --body-file/stdin input'
- file-upload verbs (attach-issue, attach-comment): adds 'file
  read/exist check'
- pr_create: also mentions the --push shellout

23 `pub fn run` signatures touched. no behaviour change; pure
documentation sweep. cargo test green (38 tests).
2026-05-31 16:22:05 +02:00
iris
a12c097044 hive-sh4re + docs: extract Ask/Answer routing prose (#717 batch 2) 2026-05-31 16:18:01 +02:00
atlas
3958079a8e harness-base: pin hive-dashboard-links doc ref to section anchor (argus 🟡 on #823) 2026-05-31 16:14:38 +02:00
atlas
a043c61828 docs: extract best-effort oneshot service contract + matrix-avatar (#718 batch 6)
Two new sections housing rationale that was inline in
`harness-base.nix`:

- `docs/conventions.md::Best-effort oneshot services` — shape
  contract shared by `tea-login`, `forge-avatar-sync`, and
  `matrix-avatar-sync`: always exit 0, no `set -e`, skip silently
  on missing prerequisites, wired to multi-user.target,
  re-runnable. Plus the artefact-under-agent-home + service-stays-
  root posture and the operator-visible-via-journalctl trade-off.

- `docs/persistence.md::matrix-avatar-sync` — the two-step `media
  upload` → `set avatar_url` matrix-spec dance + why
  `RemainAfterExit = false` (so the `.path` watcher's re-fire on
  token appearance actually re-executes the unit).

In-code comments trim to one-liner purpose + pointers; the script
bodies stay (they're the actual implementation) but their inline
`#` rationale comments collapse where the docs cover them.

`description = ''…''` blocks (operator-facing options docs)
preserved per iris #718.

`nix flake check` clean; `nix fmt` clean.
2026-05-31 16:14:38 +02:00
iris
fe6f96397e hive-sh4re: trim HostRequest::SetParent rustdoc (#717 batch 6) 2026-05-31 16:14:18 +02:00
iris
18d0fbfecb hive-sh4re + docs: extract Wake-injection prose (#717 batch 5) 2026-05-31 16:14:07 +02:00
atlas
e1bc9e42f1 hive-gateway: tmpfiles rule for /run/hive-agent (argus 🟡 on #829)
Defensive against the fresh-boot-before-any-agent-spawn window where
the bind-mount source wouldn't exist from c0re's per-agent
`set_nspawn_flags` mkdir chain yet. nspawn auto-creates missing
sources, so this is intent-explicit rather than functional fix.
2026-05-31 16:14:02 +02:00
atlas
3a29aee001 nix/hive-gateway: UDS upstream for /agent/<name>/ (#784 phase 2 step 3)
Switch per-agent gateway upstreams from TCP loopback to unix-domain
socket when the agent has opted in via `hyperhive.web.useUnixSocket`
(#822). Coexists with the TCP path during rollout.

Changes:

- New `agentSocketsFile` option (default
  `/var/lib/hyperhive/agent-sockets.json`) — c0re writes the map
  there via `hive_c0re::agent_sockets::write` (#809).
- `agentSocketsTable = lib.importJSON ...` (graceful empty when
  file missing).
- `agentUpstreamFor name port` picks `http://unix:<path>:/` when the
  socket has a JSON entry AND the file exists at eval time; else
  `http://127.0.0.1:<port>/`. Path-exists gate guards against
  c0re's blanket-emit shape during the canary window (agents in
  `agent-sockets.json` who haven't actually flipped have no
  bound socket on disk → fall back to TCP). Damocles will ship a
  `.bound` marker filter on the c0re side (#784 step 2d
  follow-up); once that's in, the path-exists check is redundant
  but harmless. Step 4 drops it entirely along with the TCP
  fallback.
- `containers.hive-gateway.bindMounts."/run/hive-agent"` —
  read-only, unconditional. Inert when no agents have opted in.
  Required so nginx inside the gateway container can `connect(2)`
  to the per-agent sockets damocles's #813 bind-mounts into agent
  containers at the same paths.

Docs:

- `docs/gateway.md::Per-agent UDS upstream (#784)` — full rollout
  flow, subdir-bind rationale (damocles #813), eval-time gate
  explainer, step 4 drop plan.

`nix flake check` clean; `nix fmt` clean.

Canary plan: once #822 (`useUnixSocket` option) lands + this PR
merges, manager flips atlas's agent.nix to `useUnixSocket = true`
via the config-update flow. End-to-end validation against atlas
before broader rollout.
2026-05-31 16:14:02 +02:00
iris
22b3e542c5 hive-sh4re + docs: extract LooseEnd wire-shape prose (#717 batch 4) 2026-05-31 16:13:24 +02:00
iris
a0b15ed6a4 hive-sh4re + docs: extract Approval lifecycle prose (#717 batch 3) 2026-05-31 16:12:36 +02:00
lexis
eacfa9bdb3 docs(CLAUDE.md): add agent_sockets.rs to hive-c0re file map (follow-up to #809) 2026-05-31 16:12:17 +02:00
damocles
e04b6075e5 harness-base: hyperhive.web.useUnixSocket option to flip HIVE_WEB_SOCKET (#815)
closes #815. last harness-side piece of the #784 phase 2 rollout.

new option `hyperhive.web.useUnixSocket` (default false). When true,
the harness service env gets HIVE_WEB_SOCKET set to the canonical
/run/hive-agent/${userName}/web.sock path — making web_ui::serve
bind a UnixListener (PR #800) instead of TCP. Path matches
hive_c0re::agent_sockets::socket_path_for(name) so the c0re
bind-mount (#813) and the gateway's eventual upstream config all
derive from the same canonical shape (no triangulation drift).

Default false so an agent's web UI keeps binding TCP until the
per-agent flip is explicit. Rollout shape:
1. flip one canary agent (atlas volunteered) to true via agent.nix
2. validate atlas's gateway-side step 3 against that canary
3. flip remaining agents per-agent as the gateway side soaks
4. eventually drop this option once everyone's on unix (step 4 of #784)

Sub-agent-only by design — manager UI serves at / via the c0re
dashboard upstream, never via /agent/<name>/, so the per-agent
unix path is irrelevant for it (the env var is set unconditionally
for code simplicity; the manager's bind socket would just sit
unused).
2026-05-31 16:09:31 +02:00
iris
a443108be5 hive-sh4re + docs: extract broker delivery/ack/requeue prose (#717 batch 1) 2026-05-31 15:53:00 +02:00
iris
33683f2de2 shared/terminal.css: drop stale hive-fr0nt ref; point at docs (#714) 2026-05-31 15:49:53 +02:00
lexis
68c6a5ae19 docs(CLAUDE.md): add matrix.md to file index + reading paths (follow-up to #811) 2026-05-31 15:49:42 +02:00
iris
7bb55bca43 docs/agent-hierarchy.md: scrub self-ref cookies (#719 batch 5) 2026-05-31 15:49:37 +02:00
iris
bd6b48a883 docs/persistence.md: scrub self-ref cookies (#719 batch 4) 2026-05-31 15:49:32 +02:00