carlos / platform Public

console, census and copy: the health probe asks in probe mode and requires the target's box id; plan 3 Task 6 re-pins

probeAt is handed the row's pinned target, sends X-Carlos-Probe: local,
and passes only on a 2xx whose X-Carlos-Served-By is the target's box id
and whose x-carlos-version is the sealed build. Each failure has its own
sentence: a redirect, another status, no serving box, the target's label
in place of its id, another box, no build version, another build, and a
target with no recorded id (refused before dialling).
TestConsoleProbeRequiresServedByAndVersion.

Census (rev3=PROPOSED-self-serve-moves-3): Edge.ServeHTTP re-pinned in
place and Server.probeTarget re-pinned from plan 2; the internal/edge and
internal/console envelopes re-pinned; seal f512b220. Copy: MV-O263's file
cell names internal/edge/servedby.go, which the moves scan now lists.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 9ae9fdaabd0ade96422b965aee930e5266bd01de parent 8582e1c
7 files changed, +164 −22
  • approved_moves_copy_test.go +2 −0
  • docs/superpowers/notes/census-proposal-self-serve-moves-3.md +8 −0
  • docs/superpowers/plans/2026-10-06-moves-phase1-copy.md +3 −1
  • internal/console/selfserve_health.go +31 −12
  • internal/console/selfserve_health_test.go +107 −4
  • internal/provision/plan14_root_reads_test.go +6 −2
  • internal/provision/testdata/plan14-root-reads-self-serve-moves-3.tsv +7 −3

CI failed — run details

CI log
=== gate ===
sigwho: pid 2 ppid 1 pgid 0 sid 0; child pid 3
.amadan/test-gate.sh
gate: 2026-10-24T05:33:12Z on aarch64, 32 cpus, 61392 MB available, go1.26.8 linux/arm64
gate: +0s start launchctx
gate: +0s start vet
gate: +0s start gofmt
gate: +1s start rest
gate: +18s start internal_console@0
gate: +18s start internal_console@1
gate: +18s start internal_console@2
gate: +18s start internal_console@3
gate: +18s start internal_console@4
gate: +18s start internal_console@5
gate: +18s start internal_console@6
gate: +18s start internal_console@7
gate: +18s waiting for internal_console's shards before the next split package
gate: +188s start root@0
gate: +188s start root@1
gate: +188s start root@2
gate: +188s waiting for root's shards before the next split package

amadan: step gate failed: signal: terminated

amadan: job failed at step gate — its output is above, not at the tail of this log
diff --git a/approved_moves_copy_test.go b/approved_moves_copy_test.go
index 9e7f5f7fb..d2d708f5e 100644
--- a/approved_moves_copy_test.go
+++ b/approved_moves_copy_test.go
@@ -1227,6 +1227,8 @@ var movesScanFiles = []string{
"internal/host/movesoffline_return.go",
// Self-serve moves plan 3 Task 2: the holding page's sentences.
"internal/edge/holding.go",
+ // Self-serve moves plan 3 Task 6: the probe refusal (MV-O263).
+ "internal/edge/servedby.go",
"internal/console/claim_runtime.go",
"internal/alerting/alerting.go",
"internal/hostops/move_log_writer.go",
diff --git a/docs/superpowers/notes/census-proposal-self-serve-moves-3.md b/docs/superpowers/notes/census-proposal-self-serve-moves-3.md
index 2ef798621..72f9f65cc 100644
--- a/docs/superpowers/notes/census-proposal-self-serve-moves-3.md
+++ b/docs/superpowers/notes/census-proposal-self-serve-moves-3.md
@@ -101,3 +101,11 @@ Task 3 is tests, apart from one tiebreak in `edge/rank.go`. rank's sort now brea
## Task 5: freshness
Task 5 is mostly tests. One change is in `edge/homemap.go`. The home map's wake used to compare the snapshots' platform hold candidates, and those include expired holds. Now `Refresh` ranks the platform holds at its own time on every poll, failed polls included (`wakeOnMove`, `livePlatformHolds`). It wakes the wildcard manager when that live set changes, and `Hosts` derives from the same live set. None of these functions reads a row, and none is a census unit. No unit's fingerprint moves, and the seal stays `6ae10fd1…`. The `internal/edge` envelope is re-pinned. No root read, class or task is added, and the record-write census is unchanged.
+
+## Task 6: probe mode
+
+A request carrying `X-Carlos-Probe: local` is never forwarded. `backhaulTo` answers it 503 "not served here" before the mesh key and the in-flight cap, so no forwarding path dials it (an ordinary request, an exact name another box wins over this box's wildcard, a door call). A probe this box serves goes through `servedByWriter` (`edge/servedby.go`, new), which stamps the box id on the final response, and is kept out of the response cache in both directions. `servedby.go` and `backhaulTo` read no row and are not census units. `edge/edge.go:Edge.ServeHTTP` is re-pinned in place: its read sites are unchanged, and the offsets moved.
+
+The console's health probe asks in probe mode. It passes only when `X-Carlos-Served-By` is the pinned target's box id and `x-carlos-version` is the sealed build. `probeAt` is handed `row.Participants.Target`. `console/selfserve_health.go:Server.probeTarget`, accepted legacy since self-serve moves 2 Task 8, is re-pinned here with its read site unchanged.
+
+Both re-pins move the seal to `f512b220…`. The `internal/edge` and `internal/console` envelopes are re-pinned. No root read, class or task is added, and the record-write census is unchanged.
diff --git a/docs/superpowers/plans/2026-10-06-moves-phase1-copy.md b/docs/superpowers/plans/2026-10-06-moves-phase1-copy.md
index 0c5da8d6c..a3a3e3427 100644
--- a/docs/superpowers/plans/2026-10-06-moves-phase1-copy.md
+++ b/docs/superpowers/plans/2026-10-06-moves-phase1-copy.md
@@ -808,10 +808,12 @@ Task 8 fix round 1 (pending Paul's review): MV-O257 is the abort of a cut write
Task 2 (pending Paul's review): the holding page every edge answers a moving host and its explicit aliases with (MV-O259 to MV-O262: the server renders N, the minutes left, rounded up and at least 1; the script switches to MV-O262 locally when the estimate passes), and MV-O263, the probe refusal Task 6 answers (today's stale-hop refusal already says it).
+Task 6 answers MV-O263 from `probeRefusal` in internal/edge/servedby.go, the file its row now names. The console probe's failure sentences (internal/console/selfserve_health.go, `probeAt`) are diagnostics in the health record's detail. The gate does not count them as copy, so they have no rows.
+
| id | file | text | status |
|---|---|---|---|
| MV-O259 | internal/edge/holding.go (self-serve moves plan 3 Task 2) | <display name> is temporarily offline. Please check back in approximately <N> minutes. | pending |
| MV-O260 | internal/edge/holding.go (self-serve moves plan 3 Task 2) | This account is temporarily offline. Please check back in approximately <N> minutes. | pending |
| MV-O261 | internal/edge/holding.go (self-serve moves plan 3 Task 2) | This account is temporarily offline. Please check back in a few minutes. | pending |
| MV-O262 | internal/edge/holding.go (self-serve moves plan 3 Task 2) | This is taking longer than expected. Please keep checking back. | pending |
-| MV-O263 | internal/edge/homemap.go (self-serve moves plan 3 Task 2; the probe refusal of Task 6) | not served here | pending |
+| MV-O263 | internal/edge/servedby.go (self-serve moves plan 3 Task 2; the probe refusal of Task 6) | not served here | pending |
diff --git a/internal/console/selfserve_health.go b/internal/console/selfserve_health.go
index d36cda943..53f53c01f 100644
--- a/internal/console/selfserve_health.go
+++ b/internal/console/selfserve_health.go
@@ -7,8 +7,9 @@ package console
// <random> with Cache-Control: no-cache, no redirects followed, 30 seconds
// per attempt; it passes on a 2xx whose x-carlos-version is the build the
// seal recorded. Two consecutive passes finish the move; the window
-// running out finishes it with a warning and a page. Plan 3 adds the
-// edge's probe mode (X-Carlos-Probe, X-Carlos-Served-By).
+// running out finishes it with a warning and a page. Plan 3 Task 6 asks
+// in the edge's probe mode (X-Carlos-Probe: local), and requires the
+// answer's X-Carlos-Served-By to be the target's box id.
import (
"context"
@@ -108,8 +109,8 @@ func (s *Server) selfServeProbe(ctx context.Context, row *SelfServeMove, rec *pr
return s.probeTarget(ctx, row, mv)
}
-// probeTarget asks the target box directly whether the account answers
-// with the build the seal recorded.
+// probeTarget asks the target box directly whether the account answers,
+// served by the target itself, with the build the seal recorded.
func (s *Server) probeTarget(ctx context.Context, row *SelfServeMove, mv *provision.MoveState) (bool, string) {
snap, err := s.liveEdges(ctx)
if err != nil {
@@ -137,7 +138,7 @@ func (s *Server) probeTarget(ctx context.Context, row *SelfServeMove, mv *provis
if _, err := rand.Read(nonce[:]); err != nil {
return false, "no probe value"
}
- return probeAt(ctx, eip, row.Host, m.ReadyPathOrDefault(), hex.EncodeToString(nonce[:]), want)
+ return probeAt(ctx, eip, row.Host, m.ReadyPathOrDefault(), hex.EncodeToString(nonce[:]), want, row.Participants.Target)
}
// The probes' transports, one per target address and shared by every
@@ -173,10 +174,16 @@ func probeTransport(addr string) *http.Transport {
return t
}
-// probeAt is one probe of host's ready path on the box at eip: no
-// redirects followed, no cache, 30 seconds; it passes on a 2xx answered by
-// build want.
-func probeAt(ctx context.Context, eip, host, readyPath, value, want string) (bool, string) {
+// probeAt is one probe of host's ready path on the box at eip, in the
+// edge's probe mode: no redirects followed, no cache, 30 seconds; it
+// passes on a 2xx the target box says it served itself (X-Carlos-Served-By
+// is its box id, which an edge stamps only on a request it did not
+// forward) from build want. Each way of failing has its own sentence, so
+// the page says which.
+func probeAt(ctx context.Context, eip, host, readyPath, value, want string, target provision.Participant) (bool, string) {
+ if target.BoxID == "" {
+ return false, "the target box has no recorded id"
+ }
u := url.URL{Scheme: "https", Host: host, Path: readyPath, RawQuery: "carlos-probe=" + value}
pctx, cancel := context.WithTimeout(ctx, selfServeProbeTimeout)
defer cancel()
@@ -185,6 +192,7 @@ func probeAt(ctx context.Context, eip, host, readyPath, value, want string) (boo
return false, "the probe could not be built"
}
req.Header.Set("Cache-Control", "no-cache")
+ req.Header.Set("X-Carlos-Probe", "local")
client := &http.Client{
Timeout: selfServeProbeTimeout,
Transport: probeTransport(net.JoinHostPort(eip, selfServeProbePort)),
@@ -196,11 +204,22 @@ func probeAt(ctx context.Context, eip, host, readyPath, value, want string) (boo
}
_, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 64<<10))
resp.Body.Close()
- switch got := resp.Header.Get("x-carlos-version"); {
+ by, build := resp.Header.Get("X-Carlos-Served-By"), resp.Header.Get("x-carlos-version")
+ switch {
+ case resp.StatusCode >= 300 && resp.StatusCode <= 399:
+ return false, fmt.Sprintf("the probe was redirected with %d", resp.StatusCode)
case resp.StatusCode < 200 || resp.StatusCode > 299:
return false, fmt.Sprintf("the probe was answered %d", resp.StatusCode)
- case got != want:
- return false, fmt.Sprintf("the probe was answered by build %q, not %q", got, want)
+ case by == "":
+ return false, "the probe's answer names no serving box"
+ case by == target.Label && by != target.BoxID:
+ return false, fmt.Sprintf("the probe's answer names the target by its label %q, not its box id %q", by, target.BoxID)
+ case by != target.BoxID:
+ return false, fmt.Sprintf("the probe was served by box %q, not the target %q", by, target.BoxID)
+ case build == "":
+ return false, "the probe's answer carries no build version"
+ case build != want:
+ return false, fmt.Sprintf("the probe was answered by build %q, not %q", build, want)
}
return true, ""
}
diff --git a/internal/console/selfserve_health_test.go b/internal/console/selfserve_health_test.go
index 4144b340f..67f6687fe 100644
--- a/internal/console/selfserve_health_test.go
+++ b/internal/console/selfserve_health_test.go
@@ -9,8 +9,110 @@ import (
"strings"
"sync"
"testing"
+
+ "github.com/carlosframework/platform/internal/provision"
)
+// ukTarget is the move's target box as the row pins it.
+var ukTarget = provision.Participant{BoxID: "i-0uk", Label: "uk-box"}
+
+// probeServer is a TLS server answering example.com with handler, the
+// probe's seams aimed at it for the test.
+func probeServer(t *testing.T, handler http.HandlerFunc) string {
+ t.Helper()
+ srv := httptest.NewTLSServer(handler)
+ t.Cleanup(srv.Close)
+ host, port, _ := net.SplitHostPort(srv.Listener.Addr().String())
+ roots := x509.NewCertPool()
+ roots.AddCert(srv.Certificate())
+ oldPort, oldRoots := selfServeProbePort, selfServeProbeRoots
+ selfServeProbePort, selfServeProbeRoots = port, roots
+ t.Cleanup(func() { selfServeProbePort, selfServeProbeRoots = oldPort, oldRoots })
+ return host
+}
+
+// TestConsoleProbeRequiresServedByAndVersion: the probe asks in probe mode
+// and passes only when the answer names the target box by its id and the
+// sealed build; every other answer fails with its own sentence.
+func TestConsoleProbeRequiresServedByAndVersion(t *testing.T) {
+ answers := map[string]func(http.Header) int{
+ "/pass": func(h http.Header) int {
+ h.Set("X-Carlos-Served-By", "i-0uk")
+ h.Set("x-carlos-version", "v42")
+ return 200
+ },
+ "/no-box": func(h http.Header) int { h.Set("x-carlos-version", "v42"); return 200 },
+ "/other-box": func(h http.Header) int {
+ h.Set("X-Carlos-Served-By", "i-0ie")
+ h.Set("x-carlos-version", "v42")
+ return 200
+ },
+ "/label": func(h http.Header) int {
+ h.Set("X-Carlos-Served-By", "uk-box")
+ h.Set("x-carlos-version", "v42")
+ return 200
+ },
+ "/no-version": func(h http.Header) int { h.Set("X-Carlos-Served-By", "i-0uk"); return 200 },
+ "/old": func(h http.Header) int {
+ h.Set("X-Carlos-Served-By", "i-0uk")
+ h.Set("x-carlos-version", "v41")
+ return 200
+ },
+ "/redirect": func(h http.Header) int {
+ h.Set("X-Carlos-Served-By", "i-0uk")
+ h.Set("x-carlos-version", "v42")
+ h.Set("Location", "/pass")
+ return http.StatusFound
+ },
+ "/refused": func(h http.Header) int { return http.StatusServiceUnavailable },
+ }
+ var mu sync.Mutex
+ probes := map[string]string{}
+ host := probeServer(t, func(w http.ResponseWriter, r *http.Request) {
+ mu.Lock()
+ probes[r.URL.Path] = r.Header.Get("X-Carlos-Probe")
+ mu.Unlock()
+ w.WriteHeader(answers[r.URL.Path](w.Header()))
+ })
+ ctx := context.Background()
+ if ok, detail := probeAt(ctx, host, "example.com", "/pass", "v1", "v42", ukTarget); !ok {
+ t.Fatalf("the target's own answer failed: %q", detail)
+ }
+ want := map[string]string{
+ "/no-box": `the probe's answer names no serving box`,
+ "/other-box": `the probe was served by box "i-0ie", not the target "i-0uk"`,
+ "/label": `the probe's answer names the target by its label "uk-box", not its box id "i-0uk"`,
+ "/no-version": `the probe's answer carries no build version`,
+ "/old": `the probe was answered by build "v41", not "v42"`,
+ "/redirect": `the probe was redirected with 302`,
+ "/refused": `the probe was answered 503`,
+ }
+ seen := map[string]string{}
+ for path, sentence := range want {
+ ok, detail := probeAt(ctx, host, "example.com", path, "v1", "v42", ukTarget)
+ if ok || detail != sentence {
+ t.Errorf("%s: %v %q, want a failure with %q", path, ok, detail, sentence)
+ }
+ if other, dup := seen[detail]; dup {
+ t.Errorf("%s and %s fail with one sentence %q", path, other, detail)
+ }
+ seen[detail] = path
+ }
+ if ok, detail := probeAt(ctx, host, "example.com", "/no-id", "v1", "v42", provision.Participant{Label: "uk-box"}); ok || detail != "the target box has no recorded id" {
+ t.Errorf("a target with no box id: %v %q", ok, detail)
+ }
+ mu.Lock()
+ defer mu.Unlock()
+ for path, v := range probes {
+ if v != "local" {
+ t.Errorf("%s was asked with X-Carlos-Probe %q, want local", path, v)
+ }
+ }
+ if len(probes) != len(want)+1 {
+ t.Errorf("%d paths asked, want %d (a redirect followed?)", len(probes), len(want)+1)
+ }
+}
+
// TestProbeAtAsksTheTargetBoxDirectly: the health probe dials the target
// box's address with the instance's host as SNI and Host, asks the ready
// path with a probe value and Cache-Control: no-cache, follows no
@@ -23,6 +125,7 @@ func TestProbeAtAsksTheTargetBoxDirectly(t *testing.T) {
mu.Lock()
seen = append(seen, r.Clone(context.Background()))
mu.Unlock()
+ w.Header().Set("X-Carlos-Served-By", "i-0uk")
switch r.URL.Path {
case "/ready":
w.Header().Set("x-carlos-version", "v42")
@@ -53,7 +156,7 @@ func TestProbeAtAsksTheTargetBoxDirectly(t *testing.T) {
path string
ok bool
}{{"/ready", true}, {"/old", false}, {"/redirect", false}, {"/down", false}} {
- if ok, detail := probeAt(ctx, host, "example.com", c.path, "v1", "v42"); ok != c.ok {
+ if ok, detail := probeAt(ctx, host, "example.com", c.path, "v1", "v42", ukTarget); ok != c.ok {
t.Errorf("%s: %v %q, want %v", c.path, ok, detail, c.ok)
}
}
@@ -63,14 +166,14 @@ func TestProbeAtAsksTheTargetBoxDirectly(t *testing.T) {
t.Fatalf("%d requests (a redirect followed?)", len(seen))
}
for _, r := range seen {
- if r.Host != "example.com" || r.TLS == nil || r.TLS.ServerName != "example.com" || r.URL.Query().Get("carlos-probe") != "v1" || r.Header.Get("Cache-Control") != "no-cache" {
- t.Errorf("request %s host %q sni %v query %q cache %q", r.URL.Path, r.Host, r.TLS, r.URL.RawQuery, r.Header.Get("Cache-Control"))
+ if r.Host != "example.com" || r.TLS == nil || r.TLS.ServerName != "example.com" || r.URL.Query().Get("carlos-probe") != "v1" || r.Header.Get("Cache-Control") != "no-cache" || r.Header.Get("X-Carlos-Probe") != "local" {
+ t.Errorf("request %s host %q sni %v query %q cache %q probe %q", r.URL.Path, r.Host, r.TLS, r.URL.RawQuery, r.Header.Get("Cache-Control"), r.Header.Get("X-Carlos-Probe"))
}
}
if probeTransport(net.JoinHostPort(host, port)) != probeTransport(net.JoinHostPort(host, port)) {
t.Error("two transports for one address")
}
- if ok, detail := probeAt(ctx, "127.0.0.2", "example.com", "/ready", "v1", "v42"); ok || !strings.Contains(detail, "answer") {
+ if ok, detail := probeAt(ctx, "127.0.0.2", "example.com", "/ready", "v1", "v42", ukTarget); ok || !strings.Contains(detail, "answer") {
t.Errorf("an address that does not answer: %v %q", ok, detail)
}
}
diff --git a/internal/provision/plan14_root_reads_test.go b/internal/provision/plan14_root_reads_test.go
index d67e33ded..4c6ae4a1a 100644
--- a/internal/provision/plan14_root_reads_test.go
+++ b/internal/provision/plan14_root_reads_test.go
@@ -1394,8 +1394,12 @@ func TestPlan14RootReadCensus(t *testing.T) {
// Edge.currentHosts and freezes two new edge units (localReady and
// localHolds), which moves it once more. Its fix round 1 re-pins
// Edge.ServeHTTP and Edge.importGateAdmit in place (the import gate
- // judges the decision's table), which moves it again.
- seal = "6ae10fd10fe66f496baf5b82bdcbbf911340425f8550ab9619f2997dacbec74b"
+ // judges the decision's table), which moves it again. Task 6 (probe
+ // mode) re-pins Edge.ServeHTTP in place (a probe is answered under
+ // servedByWriter and kept out of the response cache) and
+ // Server.probeTarget (the console's probe asks in probe mode and
+ // requires the target's box id), which moves it once more.
+ seal = "f512b220eb06d63bd3c066d37acc731a7473276fe64707a60a1e36659f11cee1"
errs := append(compareRootReads(got, inv), checkRootReadLegacy(inv, seal)...)
errs = append(errs, checkRootReadDeclarations(got, inv)...)
if len(errs) > 0 {
diff --git a/internal/provision/testdata/plan14-root-reads-self-serve-moves-3.tsv b/internal/provision/testdata/plan14-root-reads-self-serve-moves-3.tsv
index c0fa64381..2b1a3a60d 100644
--- a/internal/provision/testdata/plan14-root-reads-self-serve-moves-3.tsv
+++ b/internal/provision/testdata/plan14-root-reads-self-serve-moves-3.tsv
@@ -5,6 +5,7 @@
# Task 2 fix round 1, rev3=PROPOSED-self-serve-moves-3: the import gate judges the front row in the request decision's table (importGateAdmit takes local.table). Edge.ServeHTTP is re-pinned in place and Edge.importGateAdmit (accepted legacy since census-ruling-seeded-instances) takes a new frozen fingerprint, which moves the seal; the internal/edge envelope is re-pinned. No root read, class or task is added.
# Task 3 (the ranking's witnesses), rev3=PROPOSED-self-serve-moves-3: rank's sort breaks a tie within one file by target, so one file's two holds of different targets for one alias are ranked the same in every collection order (rank.go reads no row and is no census unit). Only the internal/edge envelope is re-pinned; no unit moves, so the seal is unchanged. No root read, class or task is added.
# Task 5 (freshness), rev3=PROPOSED-self-serve-moves-3: the home map's wake compares the platform holds live at each poll's time (wakeOnMove, livePlatformHolds in homemap.go), so a remote platform hold's expiry and its revival by a fresh fetch wake the wildcard manager; Hosts derives from the same live set. homeMap.Refresh, refreshHosts and Hosts read no row and are no census units. Only the internal/edge envelope is re-pinned; no unit moves, so the seal is unchanged. No root read, class or task is added.
+# Task 6 (probe mode), rev3=PROPOSED-self-serve-moves-3: a probe (X-Carlos-Probe: local) is refused in backhaulTo before the key and the cap (503 "not served here", no dial), and a probe served locally is answered under servedByWriter (servedby.go, new; reads no row) and kept out of the response cache. Edge.ServeHTTP is re-pinned in place (read sites unchanged, offsets moved). The console's health probe asks in probe mode and requires X-Carlos-Served-By to be the pinned target's box id: Server.probeTarget, accepted legacy since self-serve moves 2 Task 8, is re-pinned here (read site unchanged). Both re-pins move the seal; the internal/edge and internal/console envelopes are re-pinned. No root read, class or task is added.
@legacy 652c416a0cd27a153fa259d76ab20538480e2c3afd98cbec6af083902b17f5ff internal/domains/aliases.go ReconcileAliases legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos), from its fast-converge and instances loops: self-serve moves 1's body (rev3=J1, the catch-all's labels counted through domains.InstanceLabelCountsJudged), which now writes each alias row's provenance: an exact claim on the row's own name upserts it explicit (every pass, so a legacy row is upgraded on the first), and the synthetic "*.<host>" catch-all row not explicit; registry read sites unchanged, offsets moved; a report the edges file lists holding aliases by, not a decision registry:Account@15605,registry:Account@15618,registry:Alias@15220,registry:Alias@15260,registry:Alias@15330,registry:App@12165,registry:App@12365,registry:App@12521,registry:App@12722,registry:App@15631,registry:App@15640,registry:App@2026,registry:App@2222,registry:App@6036,registry:App@6235,registry:Host@15590,registry:Host@15879,registry:Host@15932,registry:Host@16004,registry:Host@16516,registry:Host@16608,registry:Host@16667,registry:Host@16748,registry:Host@406,registry:Prefix@16524,registry:Prefix@16622,registry:Prefix@16675,registry:Prefix@16756,registry:Status@8899,whole:Route@12134,whole:Route@12209,whole:Route@12356,whole:Route@12418,whole:Route@12561,whole:Route@12717,whole:Route@13613,whole:Route@1369,whole:Route@14825,whole:Route@14833,whole:Route@2066,whole:Route@2217,whole:Route@2273,whole:Route@359,whole:Route@388,whole:Route@399,whole:Route@417,whole:Route@5382,whole:Route@6080,whole:Route@6226,whole:Route@8229,whole:Route@8681,whole:Route@8843,whole:RouteAlias@14841,whole:RouteAlias@15195,whole:RoutePath@10426,whole:RoutePath@16409,whole:RoutePath@16451,whole:RoutePath@16565,whole:RoutePath@16595,whole:WildcardDomain@12933,whole:WildcardDomain@15520,whole:WildcardDomain@15569,whole:WildcardDomain@15732,whole:WildcardDomain@15838,whole:WildcardDomain@15867 edef8a1bf06cab5666a52ec19840c54f02913ddc67a32da7f6197db1606556a4
internal/domains/aliases.go ReconcileAliases legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos), from its fast-converge and instances loops: self-serve moves 1's body (rev3=J1, the catch-all's labels counted through domains.InstanceLabelCountsJudged), which now writes each alias row's provenance: an exact claim on the row's own name upserts it explicit (every pass, so a legacy row is upgraded on the first), and the synthetic "*.<host>" catch-all row not explicit; registry read sites unchanged, offsets moved; a report the edges file lists holding aliases by, not a decision registry:Account@15605,registry:Account@15618,registry:Alias@15220,registry:Alias@15260,registry:Alias@15330,registry:App@12165,registry:App@12365,registry:App@12521,registry:App@12722,registry:App@15631,registry:App@15640,registry:App@2026,registry:App@2222,registry:App@6036,registry:App@6235,registry:Host@15590,registry:Host@15879,registry:Host@15932,registry:Host@16004,registry:Host@16516,registry:Host@16608,registry:Host@16667,registry:Host@16748,registry:Host@406,registry:Prefix@16524,registry:Prefix@16622,registry:Prefix@16675,registry:Prefix@16756,registry:Status@8899,whole:Route@12134,whole:Route@12209,whole:Route@12356,whole:Route@12418,whole:Route@12561,whole:Route@12717,whole:Route@13613,whole:Route@1369,whole:Route@14825,whole:Route@14833,whole:Route@2066,whole:Route@2217,whole:Route@2273,whole:Route@359,whole:Route@388,whole:Route@399,whole:Route@417,whole:Route@5382,whole:Route@6080,whole:Route@6226,whole:Route@8229,whole:Route@8681,whole:Route@8843,whole:RouteAlias@14841,whole:RouteAlias@15195,whole:RoutePath@10426,whole:RoutePath@16409,whole:RoutePath@16451,whole:RoutePath@16565,whole:RoutePath@16595,whole:WildcardDomain@12933,whole:WildcardDomain@15520,whole:WildcardDomain@15569,whole:WildcardDomain@15732,whole:WildcardDomain@15838,whole:WildcardDomain@15867 edef8a1bf06cab5666a52ec19840c54f02913ddc67a32da7f6197db1606556a4
@legacy 887eab39c9584891268b9afedcd81c995849a97545258b3eacc506b5c0165b23 internal/domains/aliases.go deriveInstanceAliases legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): self-serve moves 1's body, whose already-the-row-we-want skip now also compares the existing row's provenance (registry:Explicit, one new site): a derived name left explicit by a detached exact claim on the same target and owner is rewritten not explicit, and both keep-as-it-is paths (a listing failure, an unjudged label) hand the kept row to keepDerived; the other registry read sites unchanged, offsets moved; no new route registry:Account@2163,registry:Account@3516,registry:Account@4587,registry:Alias@2225,registry:Alias@2293,registry:Alias@2337,registry:Alias@557,registry:App@1686,registry:App@2189,registry:App@3542,registry:App@4613,registry:Explicit@4632,registry:Host@1843,registry:Host@4566,registry:Host@4576,registry:Host@4787,registry:Provisioned@1636,registry:Replica@1672,registry:Slug@1775,whole:Route@1620,whole:Route@1726,whole:Route@3058,whole:RouteAlias@2143,whole:RouteAlias@2377,whole:RouteAlias@3498,whole:RouteAlias@3867,whole:RouteAlias@4548,whole:RouteAlias@509,whole:RouteAlias@539,whole:RouteAlias@552,whole:RouteAlias@568 42d5a40cccb38c31f306b49c00fde7482e4ee0b3cbf6a6a2dfbaac06592ef883
@@ -24,12 +25,12 @@ internal/registry/registry.go Registry.UpsertAlias legacy accepted-legacy accept
@legacy 1409145169f03f11766765601208065ab115929f8f773b23512c9465d6f6f8e3 internal/registry/registry.go Registry.migrate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=the registry's SQLite side, as carlos: in the agent (/opt/carlos/carlos agent, carlos-edge.service) and in the registry child (carlos __registry-child, which a root pass forks as the service user), on every registry open; a box CLI verb that opens the registry directly runs it as whoever runs the verb: self-serve moves 1's body with route_aliases.explicit (INTEGER NOT NULL DEFAULT 0) in the create statement and one idempotent ALTER for a table created before it (the duplicate-column rule); self-serve moves 3 Task 1 file:Exec@3622,file:Exec@3946,file:Exec@4638,file:Exec@51,file:Exec@5111,file:Exec@5971,file:Exec@6250,file:Exec@7113,file:Exec@7289,registry:sql@3622,registry:sql@3946,registry:sql@4638,registry:sql@51,registry:sql@5111,registry:sql@5971,registry:sql@6250,registry:sql@7113,registry:sql@7289 76673b36d4f61499f9649f3c0cf195ae582b6d21bea50d26dce147d59fb9c990
internal/registry/registry.go Registry.migrate legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=the registry's SQLite side, as carlos: in the agent (/opt/carlos/carlos agent, carlos-edge.service) and in the registry child (carlos __registry-child, which a root pass forks as the service user), on every registry open; a box CLI verb that opens the registry directly runs it as whoever runs the verb: self-serve moves 1's body with route_aliases.explicit (INTEGER NOT NULL DEFAULT 0) in the create statement and one idempotent ALTER for a table created before it (the duplicate-column rule); self-serve moves 3 Task 1 file:Exec@3622,file:Exec@3946,file:Exec@4638,file:Exec@51,file:Exec@5111,file:Exec@5971,file:Exec@6250,file:Exec@7113,file:Exec@7289,registry:sql@3622,registry:sql@3946,registry:sql@4638,registry:sql@51,registry:sql@5111,registry:sql@5971,registry:sql@6250,registry:sql@7113,registry:sql@7289 76673b36d4f61499f9649f3c0cf195ae582b6d21bea50d26dce147d59fb9c990
@legacy f41bc7d6d0f544ba64ab40732c62e4d11c9515dc75032e79888478236843b08a internal/edge/edge.go Edge.Reload legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body, which also hands the rows and alias rows it listed, with the table it built from them, to the local hold rebuild (holdInputs, rebuildHolds) before the reload hook runs; read sites unchanged, offsets moved; serving only registry:Account@18079,registry:Alias@16388,registry:Alias@16475,registry:Alias@16571,registry:FleetBox@5526,registry:Health@7689,registry:Health@7807,registry:Hibernate@12450,registry:Hibernate@14360,registry:Hibernate@6049,registry:Host@12498,registry:Host@14422,registry:Host@14730,registry:Host@14757,registry:Host@15525,registry:Host@15791,registry:Host@16514,registry:Host@6098,registry:Host@8290,registry:Host@8385,registry:Host@8665,registry:Host@8691,registry:Host@8743,registry:Kind@10975,registry:Kind@10997,registry:Kind@12426,registry:Kind@14336,registry:Kind@6025,registry:Kind@8831,registry:Kind@8891,registry:Name@18069,registry:Prefix@15766,registry:Region@2252,registry:Socket@14738,registry:Socket@5633,registry:Socket@6162,registry:Status@1835,registry:Target@15778,registry:Tunnel@4574,registry:Tunnel@4630,registry:Version@10956,registry:Version@11058,whole:Fleet@18019,whole:Fleet@18048,whole:Route@130,whole:Route@14790,whole:Route@14797,whole:Route@19692,whole:Route@19700,whole:Route@4692,whole:Route@5590,whole:Route@6218,whole:Route@648,whole:Route@8808,whole:Route@8881,whole:Route@8941,whole:RouteAlias@16359,whole:RouteAlias@19708,whole:RouteAlias@19717,whole:RoutePath@15503 e4e7b4dbdef60f59e2d9b3f4ad1d087d2044791764681bd827b60466ce8f7943
-@legacy c4da9b7096cb608a8a47bba1985da005162f38f5d8bf5ac0102acda4c468d79e internal/edge/edge.go Edge.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (import gate after the door's scope, a gated row left out of the response cache), with the request's one decision (resolve: this box's table, its local holds and the home map's candidates, ranked) in place of the table lookup and the exact-home probe; the prefix target, the login re-resolution and the door's check read the decision's own table (selectUpstream), and a holding decision answers the holding page; read sites unchanged, offsets moved; serving only; Task 2 fix round 1: the import gate is handed the decision's table (local.table) and judges the front row there registry:Gate@14333,registry:Gate@14393,registry:Gate@14451,registry:Host@14436,registry:ImportGate@17508,registry:Kind@12572,registry:Kind@17479,whole:Route@10577,whole:Route@10789,whole:Route@12575,whole:Route@13133,whole:Route@13228,whole:Route@13304,whole:Route@14336,whole:Route@14396,whole:Route@14439,whole:Route@14454,whole:Route@15267,whole:Route@17482,whole:Route@17511,whole:Route@18657 4ca7adfcab187bf1f37144d90e5396be6efdaa3429393471c5184e77760764b7
+@legacy 98f46a601cdff8733486f9966bbc6132b8ef6992577faa4457086ed2a2e3ed06 internal/edge/edge.go Edge.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (import gate after the door's scope, a gated row left out of the response cache), with the request's one decision (resolve: this box's table, its local holds and the home map's candidates, ranked) in place of the table lookup and the exact-home probe; the prefix target, the login re-resolution and the door's check read the decision's own table (selectUpstream), and a holding decision answers the holding page; read sites unchanged, offsets moved; serving only; Task 2 fix round 1: the import gate is handed the decision's table (local.table) and judges the front row there; Task 6: a probe (X-Carlos-Probe: local) is answered under servedByWriter, stamped with this box id on its final response, and is kept out of the response cache in both directions; the forwarding paths refuse it in backhaulTo, which reads no row registry:Gate@14812,registry:Gate@14872,registry:Gate@14930,registry:Host@14915,registry:ImportGate@18243,registry:Kind@13051,registry:Kind@18214,whole:Route@11056,whole:Route@11268,whole:Route@13054,whole:Route@13612,whole:Route@13707,whole:Route@13783,whole:Route@14815,whole:Route@14875,whole:Route@14918,whole:Route@14933,whole:Route@15746,whole:Route@18217,whole:Route@18246,whole:Route@19392 6fabacbfd2dc23d2ac258d1338e47926b4cb9c0948db5bcc1d814e2edcbb0047
@legacy 59d746cbafad658130c4c6be6d6597f0a57cd2bcb2a493e3f2f9c8a456ceb524 internal/edge/edge.go Edge.currentHosts legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body, which also lists this box's real holds of platform rows (holdSnapshot.platformNames, which reads no row) so a held row's wildcard parent stays loaded; read sites unchanged; serving only (the wildcard parent set) registry:Platform@123,registry:Provisioned@144,whole:Route@126,whole:Route@147 88419f01a8c80da7e11def22cd5512365c097ec17ee5afa895c1863d6c858ff1
@legacy 9cd24dc39fec3c4b8f569729b7a2a8fdd30a008e1064295afdf9e62937fde31c internal/edge/edge.go localReady legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, a table entry as a ranking candidate: reads the route the entry carries (its owner through release.RouteAccount, app, lifetime pair, class marks and, for an alias, its primary's host); serving only registry:App@258,registry:Host@498,registry:Incarnation@287,registry:Platform@357,registry:Provisioned@378,registry:ServingSeq@321,whole:Route@245,whole:Route@261,whole:Route@290,whole:Route@324,whole:Route@360,whole:Route@381,whole:Route@501 cabee4199c52c17849c70e7e6d7089d1e404c113008de3611083029bc4dd678d
@legacy c5d51734282888f6f4e90af026b8e369ce86f97e03e3867b1632ce70823bf1e9 internal/edge/holding.go localHolds legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, the local holds: reads the rows and alias rows the latest Reload listed (a row's status, hold op, host, owner, pair and class marks; an alias row's name, primary, provenance and DNS status through edgesfile.AliasPublishable) against the offline view's moves; serving only (the holding page and its certificate), writes nothing registry:Alias@1108,registry:Alias@1235,registry:Alias@1256,registry:Alias@1284,registry:App@532,registry:Explicit@1051,registry:HoldOp@286,registry:HoldOp@392,registry:Host@1030,registry:Host@1409,registry:Host@359,registry:Host@446,registry:Host@716,registry:Host@741,registry:Host@768,registry:Host@902,registry:Incarnation@574,registry:Incarnation@926,registry:Platform@464,registry:Provisioned@478,registry:ServingSeq@601,registry:ServingSeq@953,registry:Status@273,whole:Route@242,whole:Route@523,whole:RouteAlias@1003,whole:RouteAlias@1150 416a3342657d3672fea1fd5b31292148ee6b3b3a9601f5f48b8f436187944424
internal/edge/edge.go Edge.Reload legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body, which also hands the rows and alias rows it listed, with the table it built from them, to the local hold rebuild (holdInputs, rebuildHolds) before the reload hook runs; read sites unchanged, offsets moved; serving only registry:Account@18079,registry:Alias@16388,registry:Alias@16475,registry:Alias@16571,registry:FleetBox@5526,registry:Health@7689,registry:Health@7807,registry:Hibernate@12450,registry:Hibernate@14360,registry:Hibernate@6049,registry:Host@12498,registry:Host@14422,registry:Host@14730,registry:Host@14757,registry:Host@15525,registry:Host@15791,registry:Host@16514,registry:Host@6098,registry:Host@8290,registry:Host@8385,registry:Host@8665,registry:Host@8691,registry:Host@8743,registry:Kind@10975,registry:Kind@10997,registry:Kind@12426,registry:Kind@14336,registry:Kind@6025,registry:Kind@8831,registry:Kind@8891,registry:Name@18069,registry:Prefix@15766,registry:Region@2252,registry:Socket@14738,registry:Socket@5633,registry:Socket@6162,registry:Status@1835,registry:Target@15778,registry:Tunnel@4574,registry:Tunnel@4630,registry:Version@10956,registry:Version@11058,whole:Fleet@18019,whole:Fleet@18048,whole:Route@130,whole:Route@14790,whole:Route@14797,whole:Route@19692,whole:Route@19700,whole:Route@4692,whole:Route@5590,whole:Route@6218,whole:Route@648,whole:Route@8808,whole:Route@8881,whole:Route@8941,whole:RouteAlias@16359,whole:RouteAlias@19708,whole:RouteAlias@19717,whole:RoutePath@15503 e4e7b4dbdef60f59e2d9b3f4ad1d087d2044791764681bd827b60466ce8f7943
-internal/edge/edge.go Edge.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (import gate after the door's scope, a gated row left out of the response cache), with the request's one decision (resolve: this box's table, its local holds and the home map's candidates, ranked) in place of the table lookup and the exact-home probe; the prefix target, the login re-resolution and the door's check read the decision's own table (selectUpstream), and a holding decision answers the holding page; read sites unchanged, offsets moved; serving only; Task 2 fix round 1: the import gate is handed the decision's table (local.table) and judges the front row there registry:Gate@14333,registry:Gate@14393,registry:Gate@14451,registry:Host@14436,registry:ImportGate@17508,registry:Kind@12572,registry:Kind@17479,whole:Route@10577,whole:Route@10789,whole:Route@12575,whole:Route@13133,whole:Route@13228,whole:Route@13304,whole:Route@14336,whole:Route@14396,whole:Route@14439,whole:Route@14454,whole:Route@15267,whole:Route@17482,whole:Route@17511,whole:Route@18657 4ca7adfcab187bf1f37144d90e5396be6efdaa3429393471c5184e77760764b7
+internal/edge/edge.go Edge.ServeHTTP legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body (import gate after the door's scope, a gated row left out of the response cache), with the request's one decision (resolve: this box's table, its local holds and the home map's candidates, ranked) in place of the table lookup and the exact-home probe; the prefix target, the login re-resolution and the door's check read the decision's own table (selectUpstream), and a holding decision answers the holding page; read sites unchanged, offsets moved; serving only; Task 2 fix round 1: the import gate is handed the decision's table (local.table) and judges the front row there; Task 6: a probe (X-Carlos-Probe: local) is answered under servedByWriter, stamped with this box id on its final response, and is kept out of the response cache in both directions; the forwarding paths refuse it in backhaulTo, which reads no row registry:Gate@14812,registry:Gate@14872,registry:Gate@14930,registry:Host@14915,registry:ImportGate@18243,registry:Kind@13051,registry:Kind@18214,whole:Route@11056,whole:Route@11268,whole:Route@13054,whole:Route@13612,whole:Route@13707,whole:Route@13783,whole:Route@14815,whole:Route@14875,whole:Route@14918,whole:Route@14933,whole:Route@15746,whole:Route@18217,whole:Route@18246,whole:Route@19392 6fabacbfd2dc23d2ac258d1338e47926b4cb9c0948db5bcc1d814e2edcbb0047
@legacy 41ea8d89ccf9116ee6f6208c8edfa17bd6e79c8c2a7bd97c89c447af5dcc11a6 internal/edge/importgate.go Edge.importGateAdmit legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): the import gate (a gated row admits only a GET carrying the verify token; anything else is a 503), with host's own front row looked up in the table the request's decision was resolved in (self-serve moves plan 3 Task 2 fix round 1) rather than the live table; read sites unchanged, offsets moved; serving only registry:Host@364,registry:Host@378,registry:ImportGate@295,registry:ImportGate@318,registry:ImportGate@438,whole:Route@224,whole:Route@271,whole:Route@282 1207a7a3d9fa8c99debb563b456cfa4e472fd4c3ceba83157fb4189a12c53f70
internal/edge/importgate.go Edge.importGateAdmit legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): the import gate (a gated row admits only a GET carrying the verify token; anything else is a 503), with host's own front row looked up in the table the request's decision was resolved in (self-serve moves plan 3 Task 2 fix round 1) rather than the live table; read sites unchanged, offsets moved; serving only registry:Host@364,registry:Host@378,registry:ImportGate@295,registry:ImportGate@318,registry:ImportGate@438,whole:Route@224,whole:Route@271,whole:Route@282 1207a7a3d9fa8c99debb563b456cfa4e472fd4c3ceba83157fb4189a12c53f70
internal/edge/edge.go Edge.currentHosts legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=root-route; the edge inside the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body, which also lists this box's real holds of platform rows (holdSnapshot.platformNames, which reads no row) so a held row's wildcard parent stays loaded; read sites unchanged; serving only (the wildcard parent set) registry:Platform@123,registry:Provisioned@144,whole:Route@126,whole:Route@147 88419f01a8c80da7e11def22cd5512365c097ec17ee5afa895c1863d6c858ff1
@@ -39,9 +40,12 @@ internal/host/agent.go runAgent authority B,C,D,F rev3=PROPOSED-self-serve-moves
internal/host/movespass.go armMovesPass authority B,C rev3=PROPOSED-self-serve-moves-3;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): arms the moves worker with the box's judge (moveCfg.Judge, copied into its offline view), sets moveCfg.BoxID (the label), InstanceID and InstanceIDOf before armOffline (self-serve moves 2); self-serve moves 3 Task 2: also subscribes the ready edge to the view it arms (subscribeArmedHolds), which reads nothing; read sites unchanged, offsets moved; B,C authority retained file:Read@3311,registry:Provisioned@1807,whole:Route@1794 174924bd226e38e4476aa5458a807577c913de03328c9c52f1c3c52b18d2a8e9
internal/host/edgesfile.go edgesFileWriteClaims authority F,J1 rev3=PROPOSED-self-serve-moves-3;basis=root-route;kept=F;scope=protected-decision-only; the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): self-serve moves 1's body, whose served alias loop now decides by edgesfile.AliasPublishable over the served rows (the same rule, named once) and which, with the lifetimes switch on and a holding source, publishes the held rows as offline_moves holding entries (holdingEntries), separate from hosts, so no reader counts a held row as served; a report the edge answers holding pages from, not a decision; no record, /data, release or claim read added; F,J1 authority retained registry:Account@11974,registry:Alias@5776,registry:Alias@5811,registry:Alias@6234,registry:Alias@6391,registry:Alias@6461,registry:Alias@6644,registry:Alias@7311,registry:Alias@9666,registry:App@11986,registry:DNSStatus@5909,registry:DNSStatus@6400,registry:Host@11404,registry:Host@3208,registry:Host@5865,registry:Host@6859,registry:Host@7295,registry:Host@7468,registry:Host@9713,registry:Host@9760,registry:Host@9810,registry:Host@9845,registry:Host@9894,registry:Incarnation@3168,registry:Platform@2947,registry:Provisioned@2961,registry:Replica@2985,registry:ServingSeq@3183,registry:Status@914,whole:Route@12277,whole:Route@3462,whole:Route@360,whole:Route@388,whole:Route@3984,whole:RouteAlias@12292,whole:RouteAlias@5761,whole:RouteAlias@6622,whole:RouteAlias@9619,whole:RoutePath@12285,whole:RoutePath@3999,whole:WildcardDomain@9799 bf1537b7f8c48978f8810257ebe099157d3a2264e43fa5cfc2c33fcd50b4c6a6
internal/host/edgesfile.go holdingEntries authority F,J1 rev3=PROPOSED-self-serve-moves-3;basis=root-route;kept=F;scope=protected-decision-only; the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): new, the writer's holding entries: reads the registry rows edgesFileWriteClaims listed (Status, HoldOp, Host, Platform, Provisioned and the lifetime pair), their path prefixes (the owner projection, servedOwners) and their explicit alias rows through edgesfile.AliasPublishable, and the offline view's move for each held host; a held row whose hold op is the move id the view knows publishes one entry; a report, not a decision; no file, record, release or claim read registry:Alias@744,registry:Alias@799,registry:Explicit@663,registry:HoldOp@307,registry:HoldOp@404,registry:Host@1242,registry:Host@1279,registry:Host@375,registry:Host@438,registry:Host@467,registry:Host@646,registry:Host@766,registry:Host@790,registry:Host@886,registry:Host@931,registry:Host@992,registry:Incarnation@1070,registry:Platform@1010,registry:Provisioned@1024,registry:ServingSeq@1097,registry:Status@294,whole:Route@263,whole:Route@544,whole:Route@858,whole:RouteAlias@617,whole:RouteAlias@724,whole:RoutePath@558 da790578cea389cb43b649dea6b374236bed972f94d382ac85837de512625b2c
+@legacy 036a9e50bedc73cafc55558231b5cd0fd99eaa36367b613b1777b0da47b2b210 internal/console/selfserve_health.go Server.probeTarget legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=console.service user carlos-console, J4 root-input: the health probe value is 8 bytes of crypto/rand; the probe itself is an HTTPS request to the target box, no file; self-serve moves 2 fix round 1: the request moved to probeAt over one transport per target address; self-serve moves 3 Task 6: probeAt is handed the row's pinned target (row.Participants.Target), asks in the edge's probe mode (X-Carlos-Probe: local) and passes only when X-Carlos-Served-By is the target's box id and x-carlos-version the sealed build; read sites unchanged file:Read@854 d02f40af170fc131abd5c60a49d6e55929f6122abce1a8631f9ffc24c15750fa
+internal/console/selfserve_health.go Server.probeTarget legacy accepted-legacy accepted-legacy;rev3=PROPOSED-self-serve-moves-3;basis=console.service user carlos-console, J4 root-input: the health probe value is 8 bytes of crypto/rand; the probe itself is an HTTPS request to the target box, no file; self-serve moves 2 fix round 1: the request moved to probeAt over one transport per target address; self-serve moves 3 Task 6: probeAt is handed the row's pinned target (row.Participants.Target), asks in the edge's probe mode (X-Carlos-Probe: local) and passes only when X-Carlos-Served-By is the target's box id and x-carlos-version the sealed build; read sites unchanged file:Read@854 d02f40af170fc131abd5c60a49d6e55929f6122abce1a8631f9ffc24c15750fa
@fields A,Account,Accounts,AddedAt,Addr,Addrs,Alias,Aliases,Alive,AllowAbsent,App,Archives,Args,At,Attempts,B,Backing,Bucket,BuildState,Callback,CallbackError,CallbackFailed,Canary,Caps,CertExpiresAt,Changed,Channel,CheckedAt,ClaimIncarnation,ClaimOwner,ClaimOwnership,ClaimRowID,ClaimStamp,Class,Contents,CreatedAt,DBPath,DNSCheckedAt,DNSStatus,Deadline,Demand,Digest,DoneBefore,Due,DueAt,Env,EnvBefore,Environment,Error,ErrorKind,ExcludeHosts,ExpectGood,ExpectOp,ExpectPair,Expected,Explicit,F,Failed,FenceGen,Fleet,FleetBox,FleetBoxes,Fleets,From,FromDB,FromOp,FromSock,Gate,GoodDemand,GoodDigest,GoodVersion,Hash,Health,Held,Hibernate,HoldOp,Host,Hosts,ID,Id,IdValue,Idle,IdleSeconds,ImportGate,Incarnation,Journal,Keep,Kind,Label,LastAt,LastError,LastMs,LastStatus,Limit,MaxRun,MaxRunSeconds,Method,Ms,Name,Next,NextAt,NextDue,NextGood,NextValue,Now,Number,Number64,Observed,ObservedValue,Old,On,Op,Original,Owner,Ownership,P,Pair,Path,Paths,Platform,Pool,Prefix,Prev,PrevVersion,Provisioned,RecordKey,Region,Registration,Replica,Replicas,Replication,Retirement,Route,Routes,Row,Rows,Seed,SeedID,SeedSource,ServingSeq,ServingVersion,Slug,Socket,Spec,Sqid,State,Status,StatusNamed,Steering,StringMap,T,TValue,Tags,Target,Targets,Text,Timer,Timers,Times,To,ToDB,ToOp,ToSock,TokenHash,Tunnel,Unit,UpdateSettings,Ver,Version,W,WakeIncarnation,Wildcards,closed,conn,connect,ctx,d,dec,done,enc,full,input,mu,output,path,remote,sql,wait
+@coverage internal/console bc88b0e12e2a48b9a22951b01cf4e10f65e475079bce2a6cf076942ac1808ef6
@coverage internal/domains 0cf7748c97e4caa7d0daa73e251fdd2f2f03e425321599bf046292b0a86ebde8
-@coverage internal/edge 0a96f00fe83465a098058e7a18c9a4172c98e4bbdfec5634f1aa42347e1c2d77
+@coverage internal/edge a8b614f83ca44acbb2ab18c5bd922713b69055288eeb7fadec36ae626bbc4010
@coverage internal/edgesfile ee82e43c7d6363297f63abcde9c3e828a53d377573649f0d26a9853056aad4be
@coverage internal/host 27d077c9f63838516ad29fb69ea48ebbf85a7c17ade258a3b8ce2d57eb3cc21d
@coverage internal/registry ae19eaec5c4dde2c400fcb2fc6afd23c6b129e77306d6916fe55b2091b0fb5ed