From c7c39bdd1bdf437b2a45c8023c1d7c424f174564 Mon Sep 17 00:00:00 2001 From: Han Ngo Date: Wed, 7 Oct 2026 01:03:13 +0700 Subject: [PATCH] docs(share): record the direct personal move and tick its task DEC-014, TASK-11b, Batch 9 P1 and P2 rows. --- docs/specs/SPEC-008-one-host-per-tenant.md | 5 +++-- docs/verification/one-host-per-tenant.md | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/specs/SPEC-008-one-host-per-tenant.md b/docs/specs/SPEC-008-one-host-per-tenant.md index cf4cad7..c2793de 100644 --- a/docs/specs/SPEC-008-one-host-per-tenant.md +++ b/docs/specs/SPEC-008-one-host-per-tenant.md @@ -395,7 +395,7 @@ A tunnel profile with no `bucket=` (every R2-off tenant) keeps every file, outpu - [x] TASK-9b: `tests/e2e-migrate.sh` and rehearsal R2 (the one-machine leg, then the Air to the Mini on a throwaway name), with its run log. Depends on TASK-7b. AC: R2 and its cleanup assertions. - [x] TASK-10: README, how-it-works, setup (onboarding), ADR-0008, the verification record with the negative controls. Depends on TASK-9a, TASK-9b. AC: each negative control has a red and a green run; each `docs/how-it-works.md` command, flag, and state key named in this spec is found by a `tests/share.sh` grep against `bin/share`. Done except the R2 rehearsal evidence, which lands with TASK-9b; one control (`bucket=` in a plain tunnel config) is not reachable in its spec form, see the verification record, Batch 6. - [x] TASK-11a: STOP for Han, then the Dwarves migration D1 to D5. Before D3 the lead posts the R1 log and the exact D3 command and waits for Han's explicit go; no loop may run D3 on its own. Each check is recorded in the verification record. Depends on TASK-10 and a release. AC: the Dwarves items of `## After state`. D6 runs seven days later, after a second go. -- [ ] TASK-11b: STOP for Han, then the personal move P1 to P3. Before P2 the lead posts the R2 log and the exact P2 command and waits for Han's explicit go; no loop may run P2 on its own (P2 deletes `air-share` at its step 5). Depends on TASK-10 and a release; independent of TASK-11a. AC: the personal items of `## After state`. +- [x] TASK-11b: STOP for Han, then the personal move P1 to P3. Before P2 the lead posts the R2 log and the exact P2 command and waits for Han's explicit go; no loop may run P2 on its own (P2 deletes `air-share` at its step 5). Depends on TASK-10 and a release; independent of TASK-11a. AC: the personal items of `## After state`. ## Test plan @@ -530,7 +530,7 @@ Then by hand: `tests/e2e-tenant.sh` (L1 to L10, R1) and `tests/e2e-migrate.sh` ( - [x] `share --profile dfoundation ls` on the Mini lists `a68960` (`machine`) and `ba6377` (`cloud`) in one list; the `files` profile is gone. - [x] `share --profile dfoundation add ./x` publishes from the Mini's disk; `add --cloud ./x` publishes to the bucket; both at `https://s.d.foundation//...`. - [x] With the Mini's `dfoundation` service stopped, the cloud link answers and the machine link answers the 503 offline page. -- [ ] `s.han.ws` serves from the Mini; every Air snapshot link answers at its old URL; no Worker or bucket exists for `han.ws` share. +- [x] `s.han.ws` serves from the Mini; every Air snapshot link answers at its old URL; no Worker or bucket exists for `han.ws` share. - [ ] Share Bar on the Mini shows two sections, each row with its type icon, storage badge, and link-type marker, and the lock on gated rows. ## Acceptance Criteria (global) @@ -566,6 +566,7 @@ Moving a tunnel tenant's local shares into its bucket (a `--cloud` re-add covers - DEC-011: bucket rows are display data only; the origin's index, Caddyfile, and stage paths never read a record another publisher could write. - DEC-012 (lead, build batch 3): a member's `hits` keeps SPEC-007's rule of one account call and no bucket read, so it never refuses a machine row. It must not print a bare 0 for a link it cannot count: when the count is 0 and the id is not one of this install's own cloud adds (`r2-own`), it prints the count and then `this machine counts cloud links only; if is a machine link, its stats are on the tenant's origin: hits there`. This replaces the round-2 build rule that a member refuses a machine row. - DEC-013 (lead, review fix pass): the Worker passes a 502 through unchanged instead of answering the offline page. TASK-1a(e) measured that a pass-through cannot tell a dead live port (Caddy answers 502 for the closed port, and Cloudflare swaps it for its own page) from Caddy itself being down: both arrive as the same 502. The offline page said "the machine serving this link is offline" for a machine that was up with one dead dev server. Cloudflare's signals for an unreachable origin (530, 520 to 527) still map to the offline page. The cost: with cloudflared up and Caddy itself dead, a visitor sees Cloudflare's 502 page, not the offline page. `WORKER_VERSION` is 4 for it. +- DEC-014 (lead, on Han's go, 2026-10-07): P2 reached its end state by direct setup instead of `migrate`. The Air origin held no shares and an empty index, so `migrate` had nothing to carry, and its preflight refused because an ssh session on the Mini cannot write the login Keychain. The Mini ran `share setup s.han.ws --tunnel-name air-share-m --force` from a GUI session (the name `migrate` itself would pick), then the Air ran `share teardown --yes`, which left the DNS record alone (it pointed at the new tunnel) and deleted the `air-share` tunnel. A future move of a non-empty origin still needs `migrate` and a Keychain path that works over ssh. - Round 1 (seven fresh-context reviewers, 2026-10-01): eleven criticals, all folded. Warnings that do not change the design went to `docs/implementation-notes/one-host-per-tenant.md` for the builder. | Change | Why (reviewer) | diff --git a/docs/verification/one-host-per-tenant.md b/docs/verification/one-host-per-tenant.md index 312b896..285c59f 100644 --- a/docs/verification/one-host-per-tenant.md +++ b/docs/verification/one-host-per-tenant.md @@ -391,8 +391,9 @@ Han typed the go in the operator session. Snapshots: `tests/prod-snapshot.sh` be | D5 | the user-probe roster line for f.d.foundation/healthz now probes s.d.foundation/healthz (host config, backed up) | roster lines | both lines on s.d.foundation | | post | ungated local and cloud add; gated local and cloud add with group:dwarves-ops; rm all | 200 no-store; 302 to Access with per-app kid; 404 after rm | pass | | post | `stop` then `start` with one machine and one cloud link | while stopped: machine 503, cloud 200; after start: machine 200, a68960 302, healthz 200 | pass | -| P1/P2 | not run | `mini-run --host air` | ssh to the Air timed out twice (tailnet shows the Air active via relay, port 22 unreachable) | +| P1 (2026-10-07) | Air `brew upgrade share` 0.5.2 to 0.9.0; Mini `share import --probe` | probe output; Air state | `share-import 1`; the Air served s.han.ws with no shares and an empty index | +| P2 (2026-10-07) | `migrate` refused at preflight (`mini-tieubao cannot write and read back a Keychain item`), nothing changed; then DEC-014: Mini `setup s.han.ws --tunnel-name air-share-m --force`, Air `teardown --yes` | s.han.ws/healthz via DoH; Mini `share profiles`; ungated add/rm round trip; post snapshot | healthz 200 three times; `default serving s.han.ws`; add 200, 404 after rm; DNS CNAME points at `air-share-m`, the `air-share` tunnel is gone | -Finding: `setup --alias` prints "nothing was published; the Access app of ba6377 waits in access-pending" at exit after a successful fold. `access_gate` sets `held_access_id` and the fold path never clears it, so the EXIT trap prints a false notice. `access-pending` stayed empty, so nothing is at risk. Not yet fixed. +Finding (fixed in #47): `setup --alias` prints "nothing was published; the Access app of ba6377 waits in access-pending" at exit after a successful fold. `access_gate` sets `held_access_id` and the fold path never clears it, so the EXIT trap prints a false notice. `access-pending` stayed empty, so nothing is at risk. Fixed in #47, ships with the next release. -Open: P1 and P2 (the Air must be reachable), the Share Bar After-state box (GUI, not checked), and D6 (delete Worker share-f-d-foundation after seven days, a second go). The old `files` publisher token is revoked at D6. +Open: the Share Bar After-state box (GUI, not checked), and D6, due on or after 2026-10-13 (delete Worker share-f-d-foundation after seven days, a second go). The old `files` publisher token is revoked at D6.