carlos / platform Public

activator test: wait for the worker's spawn before it reports ready

TestWorkerReadyEndsSettleWindowEarly waited only for the waking entry,
which appears before the wake mints the worker token and spawns the
child, so under load it reported ready as a child that did not exist yet
(main 9c535162's CI: presents "", WorkerToken says ""). It now waits
for the spawn, as TestWorkerTokenIsLiveDuringTheSettleWindow does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8636c91b4c5757f8f003f41ccdc0bec4871309b0 parent 9c53516
1 file changed, +4 −0
  • internal/activator/activator_test.go +4 −0

CI passed — run details

CI log
=== gate ===
.amadan/test-gate.sh
=== launchctx (1 s)
ok  	amadan.net/carlos/platform.git/launchctx	0.012s
?   	amadan.net/carlos/platform.git/launchctx/controlname	[no test files]
?   	amadan.net/carlos/platform.git/launchctx/wireid	[no test files]
=== vet (18 s)
=== gofmt (1 s)
gofmt -l .: clean
=== rest (180 s)
?   	github.com/carlosframework/platform/cmd/changelog	[no test files]
ok  	github.com/carlosframework/platform/cmd/console	3.799s
ok  	github.com/carlosframework/platform/cmd/moveprobe	11.913s
ok  	github.com/carlosframework/platform/cmd/zddprobe	0.774s
ok  	github.com/carlosframework/platform/internal/activator	61.149s
ok  	github.com/carlosframework/platform/internal/agentsock	0.022s
ok  	github.com/carlosframework/platform/internal/alerting	0.006s
ok  	github.com/carlosframework/platform/internal/analytics	0.045s
ok  	github.com/carlosframework/platform/internal/appconfig	2.911s
ok  	github.com/carlosframework/platform/internal/apperr	0.173s
ok  	github.com/carlosframework/platform/internal/applog	0.296s
ok  	github.com/carlosframework/platform/internal/assetcache	0.228s
ok  	github.com/carlosframework/platform/internal/awsinv	0.009s
ok  	github.com/carlosframework/platform/internal/boxchoice	0.009s
ok  	github.com/carlosframework/platform/internal/boxid	0.857s
?   	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.011s
ok  	github.com/carlosframework/platform/internal/caps	0.017s
ok  	github.com/carlosframework/platform/internal/certwarm	0.005s
ok  	github.com/carlosframework/platform/internal/cgroup	0.842s
ok  	github.com/carlosframework/platform/internal/changelog	0.477s
ok  	github.com/carlosframework/platform/internal/claimactivation	1.232s
ok  	github.com/carlosframework/platform/internal/clamd	0.063s
?   	github.com/carlosframework/platform/internal/cliflag	[no test files]
?   	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	7.844s
ok  	github.com/carlosframework/platform/internal/dbdoor/dbdoortest	0.015s
ok  	github.com/carlosframework/platform/internal/dbquery	0.012s
ok  	github.com/carlosframework/platform/internal/dbreads	2.238s
?   	github.com/carlosframework/platform/internal/dbreads/dbreadstest	[no test files]
ok  	github.com/carlosframework/platform/internal/dbverify	0.011s
ok  	github.com/carlosframework/platform/internal/dnsrec	0.004s
ok  	github.com/carlosframework/platform/internal/docsite	0.012s
ok  	github.com/carlosframework/platform/internal/domains	2.669s
ok  	github.com/carlosframework/platform/internal/doorkey	0.008s
ok  	github.com/carlosframework/platform/internal/economics	0.007s
ok  	github.com/carlosframework/platform/internal/edge	48.699s
?   	github.com/carlosframework/platform/internal/edgeproof	[no test files]
ok  	github.com/carlosframework/platform/internal/edgesfile	0.008s
ok  	github.com/carlosframework/platform/internal/fleetapi	0.132s
ok  	github.com/carlosframework/platform/internal/gate	1.655s
ok  	github.com/carlosframework/platform/internal/genselect	0.015s
ok  	github.com/carlosframework/platform/internal/geo	0.015s
ok  	github.com/carlosframework/platform/internal/geoip	0.031s
ok  	github.com/carlosframework/platform/internal/historyreadback	0.152s
ok  	github.com/carlosframework/platform/internal/host	151.628s
ok  	github.com/carlosframework/platform/internal/hostactors	8.168s
ok  	github.com/carlosframework/platform/internal/hostactors/awsmembership	0.006s
ok  	github.com/carlosframework/platform/internal/hostbox	6.057s
ok  	github.com/carlosframework/platform/internal/hostclaim	2.697s
ok  	github.com/carlosframework/platform/internal/hostenv	0.004s
ok  	github.com/carlosframework/platform/internal/hostevidence	0.007s
ok  	github.com/carlosframework/platform/internal/hostexec	10.867s
ok  	github.com/carlosframework/platform/internal/hostfence	0.063s
ok  	github.com/carlosframework/platform/internal/hostfiles	10.715s
ok  	github.com/carlosframework/platform/internal/hostfloor	0.022s
ok  	github.com/carlosframework/platform/internal/hostguard	1.483s
ok  	github.com/carlosframework/platform/internal/hostops	5.276s
?   	github.com/carlosframework/platform/internal/hostops/fencerelease	[no test files]
ok  	github.com/carlosframework/platform/internal/hostops/internal/fencerelease	0.005s
ok  	github.com/carlosframework/platform/internal/hostquarantine	0.003s
ok  	github.com/carlosframework/platform/internal/hostrelocate	1.642s
ok  	github.com/carlosframework/platform/internal/hostresolve	0.228s
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.302s
ok  	github.com/carlosframework/platform/internal/instanceexec	3.085s
ok  	github.com/carlosframework/platform/internal/instancefs	0.018s
ok  	github.com/carlosframework/platform/internal/instancekey	0.018s
ok  	github.com/carlosframework/platform/internal/instanceupdates	0.018s
ok  	github.com/carlosframework/platform/internal/layout	4.017s
ok  	github.com/carlosframework/platform/internal/lbhealth	0.002s
ok  	github.com/carlosframework/platform/internal/lease	10.529s
ok  	github.com/carlosframework/platform/internal/lease/leasetest	0.768s
ok  	github.com/carlosframework/platform/internal/ledger	0.023s
ok  	github.com/carlosframework/platform/internal/mail	0.513s
ok  	github.com/carlosframework/platform/internal/maintenance	0.092s
ok  	github.com/carlosframework/platform/internal/maintenanceexec	5.832s
ok  	github.com/carlosframework/platform/internal/maintenanceguard	0.080s
ok  	github.com/carlosframework/platform/internal/metrics	0.005s
ok  	github.com/carlosframework/platform/internal/moves	29.997s
ok  	github.com/carlosframework/platform/internal/moves/archive	2.293s
ok  	github.com/carlosframework/platform/internal/objstore	0.721s
ok  	github.com/carlosframework/platform/internal/ops	0.250s
ok  	github.com/carlosframework/platform/internal/park	0.587s
ok  	github.com/carlosframework/platform/internal/plans	0.008s
ok  	github.com/carlosframework/platform/internal/privatefile	0.004s
ok  	github.com/carlosframework/platform/internal/provision	44.412s
ok  	github.com/carlosframework/platform/internal/publicrelease	0.017s
?   	github.com/carlosframework/platform/internal/regionname	[no test files]
ok  	github.com/carlosframework/platform/internal/registry	8.997s
ok  	github.com/carlosframework/platform/internal/relay	7.299s
ok  	github.com/carlosframework/platform/internal/release	38.227s
ok  	github.com/carlosframework/platform/internal/rollout	5.867s
ok  	github.com/carlosframework/platform/internal/rolloutwords	0.005s
ok  	github.com/carlosframework/platform/internal/rootaws	0.011s
ok  	github.com/carlosframework/platform/internal/rootparticipation	0.066s
ok  	github.com/carlosframework/platform/internal/rootstate	0.027s
ok  	github.com/carlosframework/platform/internal/runs	0.676s
ok  	github.com/carlosframework/platform/internal/s3compat	0.011s
ok  	github.com/carlosframework/platform/internal/safefile	0.004s
ok  	github.com/carlosframework/platform/internal/schedule	4.161s
ok  	github.com/carlosframework/platform/internal/seeds	0.027s
ok  	github.com/carlosframework/platform/internal/sim/engines	7.602s
ok  	github.com/carlosframework/platform/internal/sim/hostlife	27.591s
ok  	github.com/carlosframework/platform/internal/sim/litestreamfacts	4.436s
ok  	github.com/carlosframework/platform/internal/status	0.399s
ok  	github.com/carlosframework/platform/internal/steering	0.017s
ok  	github.com/carlosframework/platform/internal/stopevidence	0.737s
ok  	github.com/carlosframework/platform/internal/svcrole	0.003s
ok  	github.com/carlosframework/platform/internal/telemetry	0.007s
ok  	github.com/carlosframework/platform/internal/termfence	0.010s
ok  	github.com/carlosframework/platform/internal/tunnelclient	0.005s
ok  	github.com/carlosframework/platform/internal/unixdial	0.006s
ok  	github.com/carlosframework/platform/internal/updatewords	0.012s
ok  	github.com/carlosframework/platform/internal/usage	0.015s
ok  	github.com/carlosframework/platform/internal/version	0.002s
ok  	github.com/carlosframework/platform/internal/vet	2.163s
=== internal_console@0 (84 s)
ok  	github.com/carlosframework/platform/internal/console	82.992s
=== internal_console@1 (50 s)
ok  	github.com/carlosframework/platform/internal/console	49.317s
=== internal_console@2 (52 s)
ok  	github.com/carlosframework/platform/internal/console	51.055s
=== internal_console@3 (54 s)
ok  	github.com/carlosframework/platform/internal/console	52.950s
=== internal_console@4 (51 s)
ok  	github.com/carlosframework/platform/internal/console	49.770s
=== internal_console@5 (48 s)
ok  	github.com/carlosframework/platform/internal/console	46.738s
=== internal_console@6 (54 s)
ok  	github.com/carlosframework/platform/internal/console	52.719s
=== internal_console@7 (54 s)
ok  	github.com/carlosframework/platform/internal/console	53.216s
=== root@0 (116 s)
ok  	github.com/carlosframework/platform	114.598s
=== root@1 (104 s)
ok  	github.com/carlosframework/platform	102.885s
=== root@2 (82 s)
ok  	github.com/carlosframework/platform	81.044s
=== 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: 50659490 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.027s
=== RUN   TestT4StorageProbeMinio
2026/10/24 23:03:36 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18E1999ACFE7AF0D, 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.01s)
PASS
ok  	github.com/carlosframework/platform/internal/host	0.023s
=== RUN   TestS3StoreMinioContract
=== RUN   TestS3StoreMinioContract/conditional_get_and_etag_listing
=== RUN   TestS3StoreMinioContract/bump_through_every_mutation_path
--- PASS: TestS3StoreMinioContract (0.03s)
    --- PASS: TestS3StoreMinioContract/conditional_get_and_etag_listing (0.01s)
    --- PASS: TestS3StoreMinioContract/bump_through_every_mutation_path (0.02s)
PASS
ok  	github.com/carlosframework/platform/internal/release	0.032s
Bucket created successfully `local/dbf-deploy`.
Bucket created successfully `local/dbf-data-ie`.
Bucket created successfully `local/dbf-data-uk`.
local/dbf-deploy versioning is enabled
Created policy `dbf-console` successfully.
Created policy `dbf-ukbox` successfully.
Added user `dbfconsole` successfully.
Added user `dbfukbox` successfully.
Attached Policies: [dbf-console]
To User: dbfconsole
Attached Policies: [dbf-ukbox]
To User: dbfukbox
=== RUN   TestDBForwardMinio
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000000 txid.db=0000000000000001
2026/10/24 23:03:39 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000001 maxTXID=0000000000000001 size=720
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000001
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000002
2026/10/24 23:03:39 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000002 maxTXID=0000000000000002 size=370
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000002 txid.db=0000000000000002
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000002 txid.db=0000000000000003
2026/10/24 23:03:39 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000003 maxTXID=0000000000000003 size=454
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000003 txid.db=0000000000000003
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000000 txid.db=0000000000000001
2026/10/24 23:03:39 INFO ltx file uploaded system=store db=source.db replica=file level=0 minTXID=0000000000000001 maxTXID=0000000000000001 size=720
2026/10/24 23:03:39 INFO replica sync system=store db=source.db replica=file txid.replica=0000000000000001 txid.db=0000000000000001
2026/10/24 23:03:39 console: CARLOS_SECRETS_PUBKEY is unset, so no region outside the home can be chosen automatically
2026/10/24 23:03:39 console: could not notify member@example.com of a CLI token issue: keymail: lookup member@example.com: keymail: GET /api/federation/lookup?addr=member%40example.com&from=console%40127.0.0.1%3A35451: could not determine target mailbox
    agent.go:135: dbreads: dbr_g2tohkos2e25qd4lbq7jinsgui: planned 3 files (1544 bytes) and restored to 3 in 12ms
    agent.go:135: dbreads: dbr_g2tohkos2e25qd4lbq7jinsgui: output 5 bytes in 1 confirmed chunks in 1ms
2026/10/24 23:03:40 console: db read dbr_g2tohkos2e25qd4lbq7jinsgui: relayed 1 chunks (102 bytes) in 1.005s, ended done
    agent.go:135: dbreads: dbr_cfyhs4xq4isheqcoebyj5u575e: planned 1 files (720 bytes) and restored to 1 in 9ms
    agent.go:135: dbreads: dbr_cfyhs4xq4isheqcoebyj5u575e: output 5 bytes in 1 confirmed chunks in 1ms
2026/10/24 23:03:41 console: db read dbr_cfyhs4xq4isheqcoebyj5u575e: relayed 1 chunks (102 bytes) in 1.004s, ended done
    agent.go:135: dbreads: dbr_35ucbroxlmeookxhvtk5wm7i64: planned 3 files (1544 bytes) and held through 3 in 11ms
    agent.go:135: dbreads: dbr_35ucbroxlmeookxhvtk5wm7i64: output 1544 bytes in 1 confirmed chunks in 1ms
2026/10/24 23:03:42 console: db read dbr_35ucbroxlmeookxhvtk5wm7i64: relayed 1 chunks (1641 bytes) in 1.004s, ended done
=== RUN   TestDBForwardMinio/by_disconnect
=== NAME  TestDBForwardMinio
    agent.go:135: dbreads: dbr_hs4cernrzi3o2mpkfoqg4mni4i: planned 3 files (1544 bytes) and restored to 3 in 11ms
2026/10/24 23:03:42 console: db read dbr_hs4cernrzi3o2mpkfoqg4mni4i: relayed 0 chunks (0 bytes) in 19ms, ended client gone
    agent.go:135: dbreads: dbr_hs4cernrzi3o2mpkfoqg4mni4i: output 5 bytes in 1 confirmed chunks in 46ms
=== RUN   TestDBForwardMinio/by_timeout
=== NAME  TestDBForwardMinio
    agent.go:135: dbreads: dbr_zoetvy6umrq5fvo3cwpkrvwv44: planned 3 files (1544 bytes) and restored to 3 in 12ms
2026/10/24 23:04:02 console: db read dbr_zoetvy6umrq5fvo3cwpkrvwv44: relayed 0 chunks (0 bytes) in 19.46s, ended no-result
    agent.go:135: dbreads: dbr_zoetvy6umrq5fvo3cwpkrvwv44: output 5 bytes in 1 confirmed chunks in 19.437s
--- PASS: TestDBForwardMinio (22.85s)
    --- PASS: TestDBForwardMinio/by_disconnect (0.17s)
    --- PASS: TestDBForwardMinio/by_timeout (19.57s)
PASS
ok  	github.com/carlosframework/platform/internal/console	22.872s
minio contract: PASS
diff --git a/internal/activator/activator_test.go b/internal/activator/activator_test.go
index b8c04587f..c41f4df10 100644
--- a/internal/activator/activator_test.go
+++ b/internal/activator/activator_test.go
@@ -3686,6 +3686,10 @@ func TestWorkerReadyEndsSettleWindowEarly(t *testing.T) {
go func() { done <- a.WakeWorker(testWorkerRoute("bot.x.internal")) }()
waitFor(t, "the waking entry to appear", func() bool { return a.Owns("bot.x.internal") })
+ // The entry appears before the wake has minted the token and spawned the
+ // child; a child cannot report ready before it exists. Waiting only for
+ // the entry raced the spawn under load (main 9c535162's CI).
+ waitFor(t, "the child to be spawned", func() bool { return b.workerStarts() == 1 })
noteReadyAsChild(t, a, b, "bot.x.internal", "v9")
select {