census: fix-empty-app-key ruled (census-ruling-fix-empty-app-key, platform-1e)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2 files changed,
+4
−4
internal/provision/plan9_b8_census_test.go+3 −3internal/provision/testdata/plan14-root-reads-fix-empty-app-key.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.011s
? 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 306.202s
? github.com/carlosframework/platform/cmd/changelog [no test files]
ok github.com/carlosframework/platform/cmd/console 2.765s
ok github.com/carlosframework/platform/cmd/moveprobe 93.349s
ok github.com/carlosframework/platform/cmd/zddprobe 0.722s
ok github.com/carlosframework/platform/internal/activator 249.122s
ok github.com/carlosframework/platform/internal/agentsock 0.015s
ok github.com/carlosframework/platform/internal/alerting 0.005s
ok github.com/carlosframework/platform/internal/analytics 0.022s
ok github.com/carlosframework/platform/internal/appconfig 2.505s
ok github.com/carlosframework/platform/internal/apperr 0.070s
ok github.com/carlosframework/platform/internal/applog 0.124s
ok github.com/carlosframework/platform/internal/awsinv 0.004s
ok github.com/carlosframework/platform/internal/boxchoice 0.004s
ok github.com/carlosframework/platform/internal/boxid 0.763s
? 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.008s
ok github.com/carlosframework/platform/internal/caps 0.011s
ok github.com/carlosframework/platform/internal/certwarm 0.002s
ok github.com/carlosframework/platform/internal/cgroup 0.690s
ok github.com/carlosframework/platform/internal/changelog 0.326s
ok github.com/carlosframework/platform/internal/clamd 0.054s
? github.com/carlosframework/platform/internal/cliflag [no test files]
ok github.com/carlosframework/platform/internal/console 396.683s
? 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 5.956s
ok github.com/carlosframework/platform/internal/dbdoor/dbdoortest 0.009s
ok github.com/carlosframework/platform/internal/dbverify 0.004s
ok github.com/carlosframework/platform/internal/dnsrec 0.002s
ok github.com/carlosframework/platform/internal/docsite 0.005s
ok github.com/carlosframework/platform/internal/domains 2.435s
ok github.com/carlosframework/platform/internal/doorkey 0.006s
ok github.com/carlosframework/platform/internal/economics 0.003s
ok github.com/carlosframework/platform/internal/edge 27.305s
? github.com/carlosframework/platform/internal/edgeproof [no test files]
ok github.com/carlosframework/platform/internal/edgesfile 0.007s
ok github.com/carlosframework/platform/internal/fleetapi 0.130s
ok github.com/carlosframework/platform/internal/gate 1.656s
ok github.com/carlosframework/platform/internal/genselect 0.014s
ok github.com/carlosframework/platform/internal/geo 0.016s
ok github.com/carlosframework/platform/internal/geoip 0.030s
ok github.com/carlosframework/platform/internal/host 172.473s
ok github.com/carlosframework/platform/internal/hostactors 0.454s
ok github.com/carlosframework/platform/internal/hostbox 2.796s
ok github.com/carlosframework/platform/internal/hostclaim 0.527s
ok github.com/carlosframework/platform/internal/hostevidence 0.006s
ok github.com/carlosframework/platform/internal/hostexec 6.183s
ok github.com/carlosframework/platform/internal/hostfence 0.035s
ok github.com/carlosframework/platform/internal/hostfiles 11.354s
ok github.com/carlosframework/platform/internal/hostfloor 0.012s
ok github.com/carlosframework/platform/internal/hostguard 1.011s
ok github.com/carlosframework/platform/internal/hostops 1.628s
? github.com/carlosframework/platform/internal/hostops/fencerelease [no test files]
ok github.com/carlosframework/platform/internal/hostops/internal/fencerelease 0.002s
ok github.com/carlosframework/platform/internal/hostquarantine 0.002s
ok github.com/carlosframework/platform/internal/hostrelocate 0.434s
ok github.com/carlosframework/platform/internal/hostresolve 0.141s
ok github.com/carlosframework/platform/internal/hostwrite 0.002s
ok github.com/carlosframework/platform/internal/infraview 0.002s
ok github.com/carlosframework/platform/internal/instancectl 4.189s
ok github.com/carlosframework/platform/internal/instanceexec 2.762s
ok github.com/carlosframework/platform/internal/instancefs 0.018s
ok github.com/carlosframework/platform/internal/instancekey 0.016s
ok github.com/carlosframework/platform/internal/instanceupdates 0.019s
ok github.com/carlosframework/platform/internal/layout 1.629s
ok github.com/carlosframework/platform/internal/lease 9.891s
ok github.com/carlosframework/platform/internal/lease/leasetest 0.005s
ok github.com/carlosframework/platform/internal/ledger 0.012s
ok github.com/carlosframework/platform/internal/mail 0.183s
ok github.com/carlosframework/platform/internal/maintenance 0.089s
ok github.com/carlosframework/platform/internal/maintenanceexec 5.687s
ok github.com/carlosframework/platform/internal/maintenanceguard 0.076s
ok github.com/carlosframework/platform/internal/metrics 0.004s
ok github.com/carlosframework/platform/internal/moves 21.841s
ok github.com/carlosframework/platform/internal/moves/archive 0.821s
ok github.com/carlosframework/platform/internal/objstore 0.174s
ok github.com/carlosframework/platform/internal/ops 0.171s
ok github.com/carlosframework/platform/internal/park 0.198s
ok github.com/carlosframework/platform/internal/privatefile 0.003s
ok github.com/carlosframework/platform/internal/provision 19.332s
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 5.469s
ok github.com/carlosframework/platform/internal/relay 7.255s
ok github.com/carlosframework/platform/internal/release 21.264s
ok github.com/carlosframework/platform/internal/rollout 4.575s
ok github.com/carlosframework/platform/internal/rolloutwords 0.004s
ok github.com/carlosframework/platform/internal/rootaws 0.007s
ok github.com/carlosframework/platform/internal/rootparticipation 0.008s
ok github.com/carlosframework/platform/internal/rootstate 0.025s
ok github.com/carlosframework/platform/internal/runs 0.579s
ok github.com/carlosframework/platform/internal/s3compat 0.005s
ok github.com/carlosframework/platform/internal/safefile 0.003s
ok github.com/carlosframework/platform/internal/schedule 2.833s
ok github.com/carlosframework/platform/internal/seeds 0.011s
ok github.com/carlosframework/platform/internal/sim/hostlife 13.692s
ok github.com/carlosframework/platform/internal/sim/litestreamfacts 4.362s
ok github.com/carlosframework/platform/internal/status 0.038s
ok github.com/carlosframework/platform/internal/steering 0.006s
ok github.com/carlosframework/platform/internal/stopevidence 0.190s
ok github.com/carlosframework/platform/internal/svcrole 0.002s
ok github.com/carlosframework/platform/internal/telemetry 0.004s
ok github.com/carlosframework/platform/internal/termfence 0.004s
ok github.com/carlosframework/platform/internal/tunnelclient 0.004s
ok github.com/carlosframework/platform/internal/unixdial 0.002s
ok github.com/carlosframework/platform/internal/updatewords 0.004s
ok github.com/carlosframework/platform/internal/usage 0.004s
ok github.com/carlosframework/platform/internal/version 0.002s
ok github.com/carlosframework/platform/internal/vet 1.635s
=== 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: 47120546 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/16 13:43:39 moves: T4: STORE: list: operation error S3: ListObjectsV2, https response error StatusCode: 403, RequestID: 18DF0667B9FE4029, 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.020s
minio contract: PASS
diff --git a/internal/provision/plan9_b8_census_test.go b/internal/provision/plan9_b8_census_test.go| index 3641cd3f6..9df7fd0e1 100644 |
| --- a/internal/provision/plan9_b8_census_test.go |
| +++ b/internal/provision/plan9_b8_census_test.go |
| @@ -650,7 +650,7 @@ var plan9B8CensusInventory = []censusEntry{ |
| {"schedule.go", "renderScheduleList", "key-site", "lit:instances", "af6d666083fbbc753eecc98809d3d307344cc15110362a7e93afab573749ea6e"}, |
| {"internal/activator/layout.go", "LayoutInputs.sockets", "key-site", "lit:instances", "1d11ac5ac5be6a42e676e064771141fe8f4367c78cbb7e5c5cca072f40c27c42"}, |
| {"internal/activator/paths.go", "ExecBackend.pathsFor", "key-site", "lit:instances", "cbc01865e27934cb38baab9329a0867b899149531b4706a533a6956afc7c71b3"}, |
| - // Re-digested for fix-empty-app-key (RULING OWED, platform-1e): DayKey now returns an error for an empty or invalid account, app, box or date, and UpsertDay returns it before any Get or Put. Same single Put of the app-day file; no record key. |
| + // Re-digested for fix-empty-app-key (census-ruling-fix-empty-app-key, platform-1e 2026-10-16): DayKey now returns an error for an empty or invalid account, app, box or date, and UpsertDay returns it before any Get or Put. Same single Put of the app-day file; no record key. |
| {"internal/analytics/day.go", "UpsertDay", "nonrecord", "sel:Put", "ab892656cdbce1c80f0c33441341cf9c94dd22f06716ffffbd6c025100adb1b8"}, |
| {"internal/appconfig/configack.go", "WriteConfigAck", "nonrecord", "sel:Put", "211c8417bdbd6c6721fc503db085e9df073adeba623d9daa1e226554760ef5d1"}, |
| {"internal/appconfig/generation.go", "claimRawTouchGeneration", "nonrecord", "sel:Put", "313a5de17aee1b9ed6a344f6b785637c6978b60552a2243ef208c28eb8401a02"}, |
| @@ -761,10 +761,10 @@ var plan9B8CensusInventory = []censusEntry{ |
| {"internal/host/claimretire_transport.go", "retirementAcknowledgement", "nonrecord", "sel:Put", "5c09795fbe9b952436d16bcd58e846ac27e9dbcf959fcf1cd6c432af0f3ee416"}, |
| // D1 compares the retained registration's record key to the fresh claim; no record write. |
| {"internal/host/rootexecution_authority.go", "ClaimRootHTTP.executionAuthority", "key-site", "key:RecordKey", "107989f561409fd8c11c2666d0672b8dbeb368842fe00ad6a7b84fece2150438"}, |
| - // Re-digested for fix-empty-app-key (RULING OWED, platform-1e): a chunk key the errors builder refuses (empty or invalid account or app) drops that app's records and logs once; no Put happens for it. Same single Put of the errors chunk; no record key. |
| + // Re-digested for fix-empty-app-key (census-ruling-fix-empty-app-key, platform-1e 2026-10-16): a chunk key the errors builder refuses (empty or invalid account or app) drops that app's records and logs once; no Put happens for it. Same single Put of the errors chunk; no record key. |
| {"internal/host/errship.go", "errshipFlush", "nonrecord", "sel:Put", "b340b3dede6d5cab08a13a2ee8dbef5bb6dfb4943264e9835489292c479a379d"}, |
| {"internal/host/fleetbind.go", "WriteFleetBinding", "nonrecord", "sel:Put", "44ab984c2c9b30abcc938132118f61a6922ccc0cd40ed2b6cb61c7654aa0a1c3"}, |
| - // Re-digested for fix-empty-app-key (RULING OWED, platform-1e): as errshipFlush, for the logs family. Same single Put of the log chunk; no record key. |
| + // Re-digested for fix-empty-app-key (census-ruling-fix-empty-app-key, platform-1e 2026-10-16): as errshipFlush, for the logs family. Same single Put of the log chunk; no record key. |
| {"internal/host/logship.go", "logshipFlush", "nonrecord", "sel:Put", "214a52ecc3bef193b8edcd6998cdaa75da182d552f4e605f68a5dededa4ffb68"}, |
| {"internal/host/metrics_loop.go", "putAlertState", "nonrecord", "sel:Put", "d5b6e8b34dc5a731d6bbafeac0b7d0c5c20706d6f413dff38088b3321b35a26c"}, |
| // Clears an aborting record through SetRecordMove (MoveGuardedAbortComplete) once nothing is owed under the op, then ReleaseAbort: record first, ruling M4. |
diff --git a/internal/provision/testdata/plan14-root-reads-fix-empty-app-key.tsv b/internal/provision/testdata/plan14-root-reads-fix-empty-app-key.tsv| index 7a286b5c4..566baca57 100644 |
| --- a/internal/provision/testdata/plan14-root-reads-fix-empty-app-key.tsv |
| +++ b/internal/provision/testdata/plan14-root-reads-fix-empty-app-key.tsv |
| @@ -1,4 +1,4 @@ |
| -# Plan 14 census overlay fix-empty-app-key (branch fix-empty-app-key, 2026-10-16; loaded last, after home-part2). RULING OWED: platform-1e has not ruled on this overlay. Envelope-only, at main's dispositions: no root-read unit is added, removed or changed, so no row and no frozen declaration moves, and the legacy seal stands. |
| +# Plan 14 census overlay fix-empty-app-key (branch fix-empty-app-key, 2026-10-16; loaded last, after home-part2). RULED by the Plan 14 controller 2026-10-16 as census-ruling-fix-empty-app-key. Envelope-only, at main's dispositions: no root-read unit is added, removed or changed, so no row and no frozen declaration moves, and the legacy seal stands. |
| # The fix: the apps/<sqid>/<app>/{logs,errors,analytics}/ key builders (internal/applog FamilyPrefix, FamilyBoxPrefix, FamilyHourPrefix, FamilyChunkKey and their logs, errors and analytics wrappers, and analytics DayKey) return an error, applog.ErrBadKeySegment, for an empty or invalid account or app, or an empty or slash-bearing box, hour or date. They never build a key with an empty segment. An app-less route on the dev box leo-climbing (proof.dev.carlosframework.com: kind instance, account bab, app "", an Addr upstream nobody listens on) had its refused 502s filed under (bab, "") and shipped to apps/bab//errors/, which hostops.Apps refuses to walk. |
| # Envelopes: internal/applog gains the checks (CheckApp, CheckSegment, ErrBadKeySegment) and ReadWindow returns the builder's error. internal/apperr and internal/analytics change their builder signatures, and their readers (apperr.ReadWindow, analytics.ReadRange) and analytics.UpsertDay return the error before any store call. internal/host's logshipFlush, errshipFlush, chunkPrune and usageFlush skip a refused app and log once (unshippable, unshippableSeen); usageFlush drops a refused analytics delta instead of re-queueing it. None of these reads anything new, from the box or the bucket; the only reads that change are ones a refused key no longer makes. |
| @coverage internal/analytics e7461d39edd1660289669fdb5185f5231ef52e380978ce1d5765e91878f2c907 |