carlos / platform Public

carlos run logs: finish logs a run's ending only once its result has landed (#325, Astra round 3)

Human

Prompt

re-up copy review?

From this commit's own message. The prompt ledger has no entries for it — which is what a squashed, rebased or amended commit looks like, and what every commit looks like in a repo without a ledger.

Summary

Astra round 3 (1 P2, accepted): a result that never landed left the run picked for a later agent's close-out, which logged a second, contradictory ending. finish now logs only after its result write lands; the close-out owns the ending otherwise. Regression test (failed result writes, then restart) mutation-checked; census re-pinned.
claude agent, operated by paul@keymail.dev 44148d2b99b6f6d66ab69ee01485acccb8c8c880 parent 3a73324
4 files changed, +59 −12
  • internal/host/runevents_linux_test.go +42 −0
  • internal/host/runexec.go +14 −9
  • internal/provision/plan9_b8_census_test.go +2 −2
  • internal/provision/testdata/plan14-root-reads-run-lifecycle-logs-325.tsv +1 −1

CI passed — run details

CI log
=== gate ===
cd launchctx && go vet ./... && go test ./... -count=1
ok  	amadan.net/carlos/platform.git/launchctx	0.013s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
go vet ./...
gofmt -l .: clean
go test ./... -count=1 -timeout 30m
ok  	github.com/carlosframework/platform	333.474s
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	3.447s
ok  	github.com/carlosframework/platform/cmd/moveprobe	94.495s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.708s
ok  	github.com/carlosframework/platform/internal/activator	249.866s
ok  	github.com/carlosframework/platform/internal/agentsock	0.073s
ok  	github.com/carlosframework/platform/internal/alerting	0.009s
ok  	github.com/carlosframework/platform/internal/analytics	0.095s
ok  	github.com/carlosframework/platform/internal/appconfig	2.742s
ok  	github.com/carlosframework/platform/internal/apperr	0.419s
ok  	github.com/carlosframework/platform/internal/applog	0.330s
ok  	github.com/carlosframework/platform/internal/awsinv	0.005s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.020s
ok  	github.com/carlosframework/platform/internal/boxid	1.002s
?   	github.com/carlosframework/platform/internal/boxid/boxidtest	[no test files]
?   	github.com/carlosframework/platform/internal/boxid/internal/signtest	[no test files]
ok  	github.com/carlosframework/platform/internal/boxvolumes	0.071s
ok  	github.com/carlosframework/platform/internal/caps	0.019s
ok  	github.com/carlosframework/platform/internal/certwarm	0.072s
ok  	github.com/carlosframework/platform/internal/cgroup	0.914s
ok  	github.com/carlosframework/platform/internal/changelog	0.503s
ok  	github.com/carlosframework/platform/internal/claimactivation	1.303s
ok  	github.com/carlosframework/platform/internal/clamd	0.069s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
ok  	github.com/carlosframework/platform/internal/console	418.627s
?   	github.com/carlosframework/platform/internal/controlname	[no test files]
?   	github.com/carlosframework/platform/internal/controlsock	[no test files]
ok  	github.com/carlosframework/platform/internal/dbdoor	6.526s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.019s
ok  	github.com/carlosframework/platform/internal/dbverify	0.071s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.071s
ok  	github.com/carlosframework/platform/internal/docsite	0.068s
ok  	github.com/carlosframework/platform/internal/domains	2.744s
ok  	github.com/carlosframework/platform/internal/doorkey	0.018s
ok  	github.com/carlosframework/platform/internal/economics	0.070s
ok  	github.com/carlosframework/platform/internal/edge	46.154s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.015s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.407s
ok  	github.com/carlosframework/platform/internal/gate	1.968s
ok  	github.com/carlosframework/platform/internal/genselect	0.051s
ok  	github.com/carlosframework/platform/internal/geo	0.051s
ok  	github.com/carlosframework/platform/internal/geoip	0.106s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.419s
ok  	github.com/carlosframework/platform/internal/host	190.192s
ok  	github.com/carlosframework/platform/internal/hostactors	7.080s
ok  	github.com/carlosframework/platform/internal/hostactors/awsmembership	0.006s
ok  	github.com/carlosframework/platform/internal/hostbox	3.854s
ok  	github.com/carlosframework/platform/internal/hostclaim	1.465s
ok  	github.com/carlosframework/platform/internal/hostenv	0.006s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.011s
ok  	github.com/carlosframework/platform/internal/hostexec	7.677s
ok  	github.com/carlosframework/platform/internal/hostfence	0.088s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.982s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.056s
ok  	github.com/carlosframework/platform/internal/hostguard	1.113s
ok  	github.com/carlosframework/platform/internal/hostops	3.172s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.008s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.035s
ok  	github.com/carlosframework/platform/internal/hostrelocate	1.174s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.358s
ok  	github.com/carlosframework/platform/internal/hostwrite	0.004s
ok  	github.com/carlosframework/platform/internal/infraview	0.003s
ok  	github.com/carlosframework/platform/internal/instancectl	5.258s
ok  	github.com/carlosframework/platform/internal/instanceexec	2.830s
ok  	github.com/carlosframework/platform/internal/instancefs	0.007s
ok  	github.com/carlosframework/platform/internal/instancekey	0.003s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.013s
ok  	github.com/carlosframework/platform/internal/layout	2.662s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.004s
ok  	github.com/carlosframework/platform/internal/lease	9.960s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.007s
ok  	github.com/carlosframework/platform/internal/ledger	0.034s
ok  	github.com/carlosframework/platform/internal/mail	0.387s
ok  	github.com/carlosframework/platform/internal/maintenance	0.094s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.760s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.269s
ok  	github.com/carlosframework/platform/internal/metrics	0.006s
ok  	github.com/carlosframework/platform/internal/moves	24.155s
ok  	github.com/carlosframework/platform/internal/moves/archive	1.413s
ok  	github.com/carlosframework/platform/internal/objstore	0.575s
ok  	github.com/carlosframework/platform/internal/ops	0.317s
ok  	github.com/carlosframework/platform/internal/park	0.389s
ok  	github.com/carlosframework/platform/internal/privatefile	0.004s
ok  	github.com/carlosframework/platform/internal/provision	40.394s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.016s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	6.199s
ok  	github.com/carlosframework/platform/internal/relay	7.276s
ok  	github.com/carlosframework/platform/internal/release	29.073s
ok  	github.com/carlosframework/platform/internal/rollout	4.889s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.007s
ok  	github.com/carlosframework/platform/internal/rootaws	0.009s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.058s
ok  	github.com/carlosframework/platform/internal/rootstate	0.027s
ok  	github.com/carlosframework/platform/internal/runs	0.496s
ok  	github.com/carlosframework/platform/internal/s3compat	0.049s
ok  	github.com/carlosframework/platform/internal/safefile	0.005s
ok  	github.com/carlosframework/platform/internal/schedule	3.181s
ok  	github.com/carlosframework/platform/internal/seeds	0.012s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	22.905s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	4.981s
ok  	github.com/carlosframework/platform/internal/status	0.122s
ok  	github.com/carlosframework/platform/internal/steering	0.013s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.581s
ok  	github.com/carlosframework/platform/internal/svcrole	0.003s
ok  	github.com/carlosframework/platform/internal/telemetry	0.005s
ok  	github.com/carlosframework/platform/internal/termfence	0.004s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.006s
ok  	github.com/carlosframework/platform/internal/unixdial	0.004s
ok  	github.com/carlosframework/platform/internal/updatewords	0.005s
ok  	github.com/carlosframework/platform/internal/usage	0.006s
ok  	github.com/carlosframework/platform/internal/version	0.006s
ok  	github.com/carlosframework/platform/internal/vet	1.755s
=== cross ===
--- shard 0 of 5 ---
cross-compiling darwin/arm64
--- shard 1 of 5 ---
cross-compiling darwin/amd64
--- shard 2 of 5 ---
cross-compiling linux/arm64
linux/arm64 carlos binary: 49414306 bytes (ceiling 52000000)
--- shard 3 of 5 ---
cross-compiling windows/amd64
--- shard 4 of 5 ---
cross-compiling windows/arm64
=== minio-contract ===
minio contract: arm64, minio RELEASE.2025-09-07T16-13-09Z, mc RELEASE.2025-08-13T08-35-41Z
  minio: downloading https://github.com/minio/minio/releases/download/RELEASE.2025-09-07T16-13-09Z/minio.linux-arm64.RELEASE.2025-09-07T16-13-09Z
  minio: downloaded, digest verified
  mc: downloading https://github.com/minio/mc/releases/download/RELEASE.2025-08-13T08-35-41Z/mc.linux-arm64.RELEASE.2025-08-13T08-35-41Z
  mc: downloaded, digest verified
  minio healthy on 127.0.0.1:20999
Added `local` successfully.
Bucket created successfully `local/contract-bucket`.
Bucket created successfully `local/denied-bucket`.
Created policy `contract-only` successfully.
Added user `scopeduser` successfully.
Attached Policies: [contract-only]
To User: scopeduser
  buckets and scoped user ready
=== RUN   TestDeliveredContractMinio
=== RUN   TestDeliveredContractMinio/put
=== RUN   TestDeliveredContractMinio/get_round-trips_the_body
=== RUN   TestDeliveredContractMinio/list_shows_the_key
=== RUN   TestDeliveredContractMinio/head_and_list_agree_on_the_version
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict
=== RUN   TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed
=== RUN   TestDeliveredContractMinio/delete_removes_it
=== RUN   TestDeliveredContractMinio/cross-bucket_denial
--- PASS: TestDeliveredContractMinio (0.02s)
    --- PASS: TestDeliveredContractMinio/put (0.00s)
    --- PASS: TestDeliveredContractMinio/get_round-trips_the_body (0.00s)
    --- PASS: TestDeliveredContractMinio/list_shows_the_key (0.00s)
    --- PASS: TestDeliveredContractMinio/head_and_list_agree_on_the_version (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/not_by_PutObjectTagging (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_its_own_object/and_not_by_x-amz-tagging_on_upload (0.00s)
    --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route (0.01s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CreateMultipartUpload (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/not_by_CopyObject_with_a_REPLACE_tagging_directive (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/but_multipart_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_copy_itself_is_allowed (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/a_POST-policy_forged_tag_with_a_matching_version_is_still_not_a_verdict (0.00s)
        --- PASS: TestDeliveredContractMinio/the_app_cannot_tag_by_any_other_route/and_an_ordinary_tagged-with-something-else_upload_is_allowed (0.00s)
    --- PASS: TestDeliveredContractMinio/delete_removes_it (0.00s)
    --- PASS: TestDeliveredContractMinio/cross-bucket_denial (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/objstore	0.022s
=== RUN   TestT4StorageProbeMinio
2026/10/20 15:58:20 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18E0481385F680BD, HostID: 7c420053e0fbcd7f41653fdd92ffa2802c903d05303b1aa15adc2e8bb65d183f, api error SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
--- PASS: TestT4StorageProbeMinio (0.00s)
PASS
ok  	github.com/carlosframework/platform/internal/host	0.021s
minio contract: PASS
diff --git a/internal/host/runevents_linux_test.go b/internal/host/runevents_linux_test.go
index bcbda343e..16f51b560 100644
--- a/internal/host/runevents_linux_test.go
+++ b/internal/host/runevents_linux_test.go
@@ -1,14 +1,17 @@
package host
import (
+ "context"
"errors"
"reflect"
"strings"
"testing"
+ "time"
"github.com/carlosframework/platform/internal/activator"
"github.com/carlosframework/platform/internal/applog"
"github.com/carlosframework/platform/internal/instancectl"
+ "github.com/carlosframework/platform/internal/provision"
"github.com/carlosframework/platform/internal/release"
)
@@ -70,3 +73,42 @@ func TestRunNotStartedLogsOnlyItsEnd(t *testing.T) {
}
}
}
+
+// A run whose result never landed logs no ending of its own: the run stays
+// picked, and the next agent's close-out writes and logs the one ending,
+// so the log never holds two that contradict each other (Astra round 3).
+func TestRunWhoseResultNeverLandedLeavesTheEndingToTheCloseOut(t *testing.T) {
+ defer func(d time.Duration) { runFinishBound = d }(runFinishBound)
+ runFinishBound = 300 * time.Millisecond
+ dir := release.NewDirStore(t.TempDir())
+ rec, req := pickedRun(t, dir, 60)
+ req.By = "member@example.com"
+ h := &fakeHandle{polls: make(chan instancectl.CmdStatus, 1)}
+ h.polls <- instancectl.CmdStatus{State: instancectl.CmdDone, InvocationID: "inv1", Result: "exit-code", Status: "0", Code: "1"}
+ var events eventLog
+ w := execWorker(t, &failingPuts{Store: dir, part: "/result.json"}, &fakeLauncher{handle: h}, "boot-1")
+ w.events = &events
+ rt, _ := runOwnedRoute(runHost)(runHost)
+ w.execute(context.Background(), rec, req, *rt, newRunHandle())
+ if r := currentRun(t, dir); r.State != provision.RunPicked {
+ t.Fatalf("run %+v, want still picked", r)
+ }
+ // The agent restarts once storage has recovered.
+ cur, err := provision.GetRecord(context.Background(), dir, rec.Account, rec.App, rec.Host)
+ if err != nil {
+ t.Fatal(err)
+ }
+ var l execLog
+ next := testWorker(dir, runOwnedRoute(runHost), "box-1", "boot-2", &l)
+ next.events = &events
+ next.consider(context.Background(), *cur)
+ var endings []string
+ for _, e := range events.all() {
+ if !strings.Contains(e.msg, " started by ") {
+ endings = append(endings, e.msg)
+ }
+ }
+ if len(endings) != 1 || !strings.Contains(endings[0], "the box's agent restarted") {
+ t.Fatalf("endings %q, want only the close-out's", endings)
+ }
+}
diff --git a/internal/host/runexec.go b/internal/host/runexec.go
index c0a72d7f3..f3c0004cc 100644
--- a/internal/host/runexec.go
+++ b/internal/host/runexec.go
@@ -441,16 +441,21 @@ func (w *runsWorker) finish(ctx context.Context, rec provision.Record, req runs.
})
if err != nil {
log.Printf("agent: runs: %s %s: result: %v", rec.Host, req.ID, err)
- } else if err := untilLanded(fctx, func(ctx context.Context) error {
- _, err := provision.SetRecordRun(ctx, w.store, rec.Account, rec.App, rec.Host, runFinishOurs(req.ID, w.box, w.boot))
- return err
- }); err != nil && !errors.Is(err, provision.ErrRunConflict) && !errors.Is(err, os.ErrNotExist) {
- log.Printf("agent: runs: %s %s: done: %v", rec.Host, req.ID, err)
+ } else {
+ // The ending is logged only once the result has landed (amadan
+ // #325: run lines are at most once). A result that never landed
+ // leaves the run picked, and a later agent's closeInterrupted
+ // writes and logs its own ending; logging this one too would put
+ // two contradictory endings in the log. A run with no handle never
+ // had its unit started.
+ w.runEvent(rec, runEndedLine(req.ID, res, handle != nil))
+ if err := untilLanded(fctx, func(ctx context.Context) error {
+ _, err := provision.SetRecordRun(ctx, w.store, rec.Account, rec.App, rec.Host, runFinishOurs(req.ID, w.box, w.boot))
+ return err
+ }); err != nil && !errors.Is(err, provision.ErrRunConflict) && !errors.Is(err, os.ErrNotExist) {
+ log.Printf("agent: runs: %s %s: done: %v", rec.Host, req.ID, err)
+ }
}
- // What the box saw end, written or not: a result that never landed
- // is ended as lost by the sweep, but the command's own ending was
- // this. A run with no handle never had its unit started.
- w.runEvent(rec, runEndedLine(req.ID, res, handle != nil))
w.cleanUp(rec, req, handle)
}
diff --git a/internal/provision/plan9_b8_census_test.go b/internal/provision/plan9_b8_census_test.go
index 207be0618..07840ae95 100644
--- a/internal/provision/plan9_b8_census_test.go
+++ b/internal/provision/plan9_b8_census_test.go
@@ -1102,8 +1102,8 @@ var plan9B8CensusInventory = []censusEntry{
// The run sweep clears a terminal run past retention through SetRecordRun (RunClear).
{"internal/console/runsweep.go", "Server.sweepTerminalRun", "record-writer", "key:SetRecordRun", "78e3510bbf056dbf28446391b552c87060094ca803a3b1a8b7d7013163ee136b"},
// The box records a run's end through SetRecordRun (runFinishOurs).
- // Re-reviewed for run-lifecycle-logs-325 (amadan #325, proposed): emits the run's end as a member log event; record writes unchanged.
- {"internal/host/runexec.go", "runsWorker.finish", "record-writer", "key:SetRecordRun", "8353643af2281da9b08b629d387d1d91ba0c8db2b2afbedc24cbfb3042854039"},
+ // Re-reviewed for run-lifecycle-logs-325 (amadan #325, proposed): emits the run's end as a member log event once its result has landed (at most once); record writes unchanged.
+ {"internal/host/runexec.go", "runsWorker.finish", "record-writer", "key:SetRecordRun", "42f8628f74fcdfd3a0a56d302caa6f423f6c8fe8726c3561028e94ad97037041"},
// The box closes a run an agent restart interrupted through SetRecordRun (runFinishOurs).
// Re-reviewed for run-lifecycle-logs-325 (amadan #325, proposed): reads result.json before and after its create-only write and emits the run's end as a member log event only when the result is its own and its done CAS landed (at most once); record writes unchanged.
{"internal/host/runs.go", "runsWorker.closeInterrupted", "record-writer", "key:SetRecordRun", "b540e246a977470c50d3ebbbef080f9b8a824490fd3bb8bd6f98537bc882adee"},
diff --git a/internal/provision/testdata/plan14-root-reads-run-lifecycle-logs-325.tsv b/internal/provision/testdata/plan14-root-reads-run-lifecycle-logs-325.tsv
index 29d2dce11..adfc3c4b2 100644
--- a/internal/provision/testdata/plan14-root-reads-run-lifecycle-logs-325.tsv
+++ b/internal/provision/testdata/plan14-root-reads-run-lifecycle-logs-325.tsv
@@ -1,6 +1,6 @@
# Census overlay run-lifecycle-logs-325 (amadan #325: the box's carlos run worker emits run started and run ended as info-level member log events through the agent's EventSink), loaded LAST, after bootstrap-carlos-follows-316. Proposed; ruling asked of the census owner on #280.
# No root read, file read or record write is added: the events are pure string formatting plus one EventSink.Event call, so runAgent (which passes the sink to armRunsPass) and runsWorker.execute (which emits the two events) keep their class, task and read sites, and only their digests, runAgent's Route offset and the internal/host envelope move. execute is accepted-legacy, so its declaration is re-pinned and the seal moves.
-@coverage internal/host 2866a11e1992a250b09dd560c7186c4fa42ad1019c6415dc03d82ccaca9dd832
+@coverage internal/host 8dadfcbb1f519c7596269266cd8fc61a103ab376f175b40d4946d8ac5ca35eb0
@legacy 6f7ae8c101088f20464d1a727c898190b04726de1f08ee6040212be2ad840caa internal/host/runexec.go runsWorker.execute legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): runs one picked run to its result in the bucket; every root action goes through instance control;rev3=PROPOSED-325;identity=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos);basis=emits the run's start and end as member log events through the agent's EventSink; reads unchanged file:Prepare@1838,whole:Route@2539 1b075de70048003120c62153a50f6d83bd3eff6615f9ea5008ddc747846c8fbb
internal/host/runexec.go runsWorker.execute legacy accepted-legacy accepted-legacy;rev3=census-ruling-carlos-run;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): runs one picked run to its result in the bucket; every root action goes through instance control;rev3=PROPOSED-325;identity=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos);basis=emits the run's start and end as member log events through the agent's EventSink; reads unchanged file:Prepare@1838,whole:Route@2539 1b075de70048003120c62153a50f6d83bd3eff6615f9ea5008ddc747846c8fbb
internal/host/agent.go runAgent authority B,C,D,F rev3=census-ruling-seeded-instances;basis=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos): main's body with wireSeedPlacement called in the activator start's Configure step, before armMovesPass, and the startup sweep's result stored for the import rollback in Recover; read sites unchanged, offsets moved; main's B,C,D,F authority retained PROPOSED E46: captured claim selection and root journal mutation; root RPC outside service host exclusion; SQL/route data never grants root authority. Executing identity: service controller; root for inventory/retirement callbacks.;rev3=PROPOSED-325;identity=the agent (/opt/carlos/carlos agent, carlos-edge.service, user carlos);basis=passes the agent's log sink to armRunsPass; reads unchanged file:Exec@13802,file:Open@731,registry:App@10065,whole:Route@10057,whole:Route@23122 9250dbd16a071a1f01e835f0fb8419e4de59effaa6f1d178b23547957ff66d86