-
carlos logsnow shows each run. It shows when eachcarlos runstarted, who asked for it and how it ended. The command's output is not kept there. run-lifecycle-logs-325 carlos logs carlos run -
An app can ask for one uploaded object to be scanned. Where scanning is enabled for the deployment and an operator has granted the store, the app requests a scan with an app-scoped
servicecredential and polls for the result, or receives a signed callback. See Receiving scan results. scan-demand-revival - The console's account switcher has a search box. It helps when you belong to many accounts. console-switcher-filter
For operators
-
Roll the boxes first, then the console. Coming from v0.28.4, read the v0.28.5 operator notes first. Coming from v0.28.5, upgrade the console with
carlos system claims install-console --upgradeas the v0.28.6 notes describe. carlos system claims -
An offline move can copy most of its data before the instance goes offline. Run
carlos move offline stage --host <host> --to <region>while the instance keeps serving. It copies the instance's replica to the target region, and running it again copies only what is new.startthen takes the instance offline as before, and the seal copies only what changed since the last stage. Untilstart,abortremoves the staged copy and the instance is never offline. While a move is staged, the instance refusescarlos runand deletion, and no other instance can move offline. moves-offline-precopy carlos move carlos run -
Every box in both regions must run this release before
stageworks. Each box now publishesoffline-stage-1, andstagerefuses while any box in either region lacks it. moves-offline-precopy - Moves and replica copies now run eight object copies at once. Before, they copied one object at a time, so a large replica took minutes to copy while the instance was offline. moves-offline-precopy
-
On-demand scanning needs
CARLOS_SCAN_WEBHOOK_KEYonly for callbacks. Polling works without it. To rotate it, keep the old key inCARLOS_SCAN_WEBHOOK_KEY_PREVIOUSand runcarlos system antivirus rotate-webhook-key. Apps whose delivered secret changes restart. scan-demand-revival carlos system -
Every dormant switch stays off. Leave
CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPS,CARLOS_REQUIRE_POINTER_DIGESTandCARLOS_PLAN_CATALOGunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. KeepCARLOS_SWAPas it is: a box armed for zero-downtime deploys stays armed. carlos channels digests
Changes
7-
moves-offline-precopymoves-offline-precopy: carlos move offline stage (pre-copy while serving) and parallel mirror copies
Paul Campbell with claude carlos move 771ca01b
-
design-plans-and-capsspec: plans, caps and packs for the first paid launch (draft)
Paul Campbell with claude #280 carlos accounts plan turning plans on the catalog assigning a plan sponsored accounts f550afa2
-
test-suite-speedroot tests: the carlos binary is built once per test run, not once per test
-
test-suite-debtPrompts:
-
run-lifecycle-logs-325carlos run: a run's start and end reach carlos logs (#325)
Paul Campbell with claude #325 carlos run f54aa2fc
-
scan-demand-revivalMerge reviewed on-demand object scanning revival
Paul Campbell with claude carlos store scan deployment wide object scanning asking for a scan the states callbacks take a path 3d444a1b
-
console-switcher-filterconsole: searchable, scrolling account switcher
- Nothing changes for people deploying apps with the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.28.4, read the v0.28.5 operator notes first. They all still apply, including the one update by hand for a box whose guard is armed on v0.28.4.
-
A guard-armed box's protected console can now be replaced. Once the box's router is on this release, run
carlos system claims install-console --upgrade --from <sha256>as root, where the sha256 is the console that is running now. It refuses unless that build is what the box holds, then installs the new console and keeps the old one asconsole.prev. No hand recovery is needed. A box upgraded this way can't be armed again withcarlos system guard-armuntilinstall-consolehas been run without--upgrade, becauseguard-armexpects both copies to be the same build. install-console-upgrade carlos system claims carlos system -
A nested instance's
config.envis written as soon as its directory appears. Before, a move could leave the instance without it for up to an hour. moves-offline-fixes -
Each offline move step now sees a current box report. While a move is running, the source boxes and the sealing box report again every 15 seconds. A move takes under a minute of downtime when its steps run back to back. A step that meets a stale report now says the report is not current and to try again. Before,
flipcould answer that a process was still running. moves-offline-fixes -
A source box's scheduler leaves a moved instance alone. After
open, it no longer writes a stray token file into the instance it gave up. moves-offline-fixes -
Every dormant switch stays off. Leave
CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. KeepCARLOS_SWAPas it is: a box armed for zero-downtime deploys stays armed. carlos channels digests
Changes
2-
moves-offline-fixesmoves-offline-fixes: harness Run 9 defects. Config sync writes a nested row's config.env as soon as its instance directory appears, keeping it pending until delivered (6); each offline door step sees a current report: source boxes and the sealer refresh reports every 15 s while a move is active without renewing the tombstone, and a stale report answers MV-O178 (7); a source box's scheduler leaves a held or moved host alone, excluding it before the batch limit (8). Astra reviewed (two rounds); census-ruling-moves-offline-fixes (platform-1c); MV-O178 approved by Paul.
Paul Campbell with claude e0986eab
-
install-console-upgradeinstall-console --upgrade --from <sha256>: replace a guard-armed box's protected console
Paul Campbell with claude carlos system claims 21850356
- Nothing changes for people deploying apps with the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.28.3, read the v0.28.4 operator notes first. They all still apply.
-
carlos move offlinemoves one instance to another region, with planned downtime. It is for operators, works only while host claims and Phase 1 moves are off, and takes one step per command:start,seal,flip,open, thenfinish. The instance is offline fromstartuntilopen. Untilopen,abortputs it back where it was with nothing lost. moves-offline carlos move -
Roll every box in both regions before you start an offline move.
sealwaits until every box in the instance's current region has stopped it and said so, and a box on an earlier release never says so. moves-offline -
A box whose guard is armed on v0.28.4 needs one update by hand. Its updater reads a candidate's progress messages as part of the answer, so
carlos system updaterefuses every candidate on that box. Stopcarlos-system-update.path, put the v0.28.5 binary in a root-only file after checking it againstSHA256SUMS.txt, run it as root assystem applywith the box'shost.env, check the box, then startcarlos-system-update.pathagain. Do one box at a time. From then on the box updates as usual. armed-box-updates carlos system - The guarded updater reads only what a candidate writes to standard output. Progress and warnings no longer break its checks, so this is the last update a guard-armed box needs by hand. armed-box-updates
-
carlos system guard-armmakes its directories readable whatever your umask is. Before, a root shell with a strict umask left them unreadable to the box's updater. claim-guard-umask carlos system - Routes with their own unit now restart on boxes whose agent doesn't run as root. The agent now hands those restarts to root. Before, the restart was refused, the agent read that as a broken build and rolled back. adopt-unit-root-pass-315
-
carlos system statuswarns when a new box would boot an older build. It comparesbootstrap/carloswith stable's build and says which file to copy over it. bootstrap-carlos-follows-316 carlos system -
Every dormant switch stays off. Leave
CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. KeepCARLOS_SWAPas it is: a box armed for zero-downtime deploys stays armed. carlos channels digests
Changes
6-
armed-box-updatesarmed-box-updates: guard-armed boxes can take a release by the ruled re-arm. Cherry-picks 8376a468 (rootaws: an inherited disabled sentinel is not an override) and 8a313548 (hostfloor: a guarded run returns stdout only) from claim-empty-cohort-done, Astra-reviewed there; census-ruling-claim-rootaws-sentinel, confirmed for main by platform-1c. For v0.28.5.
Paul Campbell with claude 54ae7fb9
-
moves-offlinemoves-offline: operator-run offline region move (claims-off, planned downtime): holds and fences every source box, seals the source with a create-only tombstone after a final checkpoint, lands every dependency on the target proven against an immutable seal.json, opens, then retires the source by rename. Reviewed task by task and by Fable and Astra; census-ruling-moves-offline; copy approved by Paul 2026-10-20. Dormant until an operator runs carlos move offline.
Paul Campbell with claude carlos move 7af88155
-
changelog-v0.28.4changelog-v0.28.4: release step 10 for v0.28.1 to v0.28.4
Paul Campbell with claude 57569bff
-
bootstrap-carlos-follows-316system status: say when bootstrap/carlos is not stable's build (#316)
-
adopt-unit-root-pass-315adopt: an agent that is not root hands named-unit routes to root's pass (#315)
-
claim-guard-umaskclaim-guard-umask: guard-arm makes its guard, system and lock directories 0755 whatever the caller's umask (#317)
- Console invites now arrive. Before this release, an invite to anyone but yourself never reached them. The console now delivers the link to the invitee's Keymail inbox, or by email where console email is on. If neither works, it shows you the link to pass on yourself. design-console-invite-delivery
- An account can have 20 invites waiting at most, and send 20 an hour. An invite emailed to an address that isn't a Keymail address can't be accepted yet. design-console-invite-delivery
- Nothing changes in the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.28.2, read the v0.28.3 operator notes first. They all still apply.
-
Console email can switch itself on. A console with
CARLOS_MAIL_REGIONset and a sending address (CARLOS_CONSOLE_MAIL_FROM, or one made fromCARLOS_MAIL_PLATFORM_SUFFIX) creates an SES identity and DNS records for that address's domain the first time it starts. It sends nothing until SES has verified the domain. design-console-invite-delivery -
Sending also needs a grant that is off by default. The region-host module's
console_mail_fromandconsole_mail_regionadd anses:SendEmailgrant to the host role. Leave them unset until that grant's security review is done. Without it, invites fall back to Keymail or the link. design-console-invite-delivery -
With
CARLOS_HOST_CLAIMon, the console sends no email. Invites then go by Keymail, or the owner passes the link on. design-console-invite-delivery -
carlos system install-channel --policynow also takes--identity. The two go together. The published release identity stands in for the channel's release tag, which the channel only carries once a floor is published. claim-untagged-pointer carlos system -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. carlos channels digests
Changes
2-
claim-untagged-pointerclaim-untagged-pointer: install-channel --policy takes --identity (the published release identity) so an untagged channel pointer works; the activation witness has no hand-made input on the trial's path
Paul Campbell with claude boxes a region s group launches f3bf1214
-
design-console-invite-deliveryspec: console invite delivery by Keymail federation, then email
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.28.1, read the v0.28.2 operator notes first. They all still apply.
-
carlos system install-channel --policyprepares a box that is already running for host claims. It puts the box's current release in both its copies, so the guard can be armed before a floor is published. That replaces the box's rollback copy, and the command says so. Nothing runs it on its own, and host claims stay off. claim-prev-rehearsal carlos system -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. carlos channels digests
Changes
1-
claim-prev-rehearsalclaim-prev-rehearsal: install-channel --policy arms an updater-installed box; the activation witness starts from a box the platform made and rehearses steps 6 and 7
Paul Campbell with claude boxes a region s group launches 50f5b268
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.28.0, read the v0.28.1 operator notes first. They all still apply.
-
Three new
carlos system claimscommands prepare a box for host claims.rungains two phases,sign-policyandpublish-identity, which make the filescarlos system guard-armneeds, andinstall-consoleputs a protected copy of the console where the guard expects it. Nothing runs them on its own, and host claims stay off. claim-step6-artifacts carlos system claims carlos system -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. carlos channels digests
Changes
1-
claim-step6-artifactsclaim-step6-artifacts: claims run sign-policy and publish-identity, --out byte-exact files, claims install-console (dev cohort-1 trial step 6)
Paul Campbell with claude carlos system claims 7c1beb2d
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.27.x, read the v0.28.0 operator notes first. They all still apply.
-
A box can publish its identity record by hand.
systemd-run --wait --pipe -p EnvironmentFile=/etc/carlos/host.env -p User=carlos /opt/carlos/carlos system box publish-recordwrites the box's AWS-signed identity record to the deployment bucket once. It never replaces or deletes a record, and it refuses to run as root or on a fleet box. Nothing runs it on its own. box-publish-record -
A box that has not reported for a day drops out of status.
carlos status --live, the console's box list and the promote list leave out a box whose report has not been written for 24 hours. Before, it stayed in the list as stale. Fleet boxes are listed as before. region-ha-2b-build carlos status -
Each box gets an idle join unit.
carlos-system-join.pathis installed and enabled at the roll. Nothing touches the file it watches until region HA is turned on, so it never starts its service. region-ha-2b-build -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, don't putCARLOS_BOX_REFERENCE=groupin any host.env, and don't runcarlos channels digests on. carlos channels digests
Changes
3-
box-publish-recordbox-publish-record
Paul Campbell with claude a box s identity record 3b69c2bd
-
region-ha-2b-buildregion HA 2b: the joining and enrolment plan and its copy record
Paul Campbell with claude #275 boxes a region s group launches b1118925
-
changelog-v0.28.0changelog-v0.28.0: release step 10 for v0.28.0, plus the darwin/windows vet fix for claimunit_inputs_test.go
Paul Campbell with claude 04819f9b
-
carlos runruns one of your app's commands against one instance.carlos run --app shop --instance www.example.com -- <command>runs it as that instance, with its environment and database, and prints the output as it arrives.--fileuploads files with the run, up to 64 MB in total.--timeoutsets how long it may take, 30 minutes by default and up to 6 hours.--follow <id>reattaches to a run already started. It needs an instance on the nested layout. carlos-run carlos run -
New instances can start from a copy of another instance's database.
carlos instances create --from <host>copies the source's replica, so the source keeps serving.carlos instances importbrings an instance the platform never ran onto it, from a snapshot of its database. Both refuse until your operator turns them on. seeded-instances carlos instances - The download is smaller again. The linux/arm64 binary is about 46 MB, down from about 78 MB. fix-binary-size-275
- Nothing else changes for people using the CLI.
For operators
- Roll the boxes first, then every console. A run is refused until the console that records it is on this release. carlos-run
- Coming from v0.26.x, read the v0.27.0 to v0.27.3 operator notes first. They all still apply.
-
Instance control restarts with this update.
carlos system updatedoes that on its own. A box updated any other way needssystemctl restart carlos-instance-controlafterwards. carlos system - Give the console room for run uploads. The console holds a run's uploaded files, up to 64 MB per run, in its temporary directory until the box takes them. carlos-run
-
Seeded instances stay off until you publish the seeds floor.
carlos instances create --fromandcarlos instances importrefuse untilcarlos system seeds-floor publishnames a release every box runs. Publishing it is one way: from then on no box recovers to an older build. Leave it unpublished until you have decided to turn seeding on. seeded-instances carlos instances carlos system -
The host claim is still off. This release carries the claim's protected host state and the
carlos system claimsactivation commands, but nothing uses them whileCARLOS_HOST_CLAIMis unset. Errors from a route that has no app are now filed so the claim's checks can read the bucket. feat/claim-root-trusted-state-p3 feat/claim-files-backfill carlos system claims -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. carlos channels digests
Changes
15-
feat/claim-root-trusted-state-p3WIP claim Plan 14 foundations (not for merge): descriptor-backed root state, root-owned D3 health history, release lock, floor reconstruction and migration preflight helpers, constructor census, root-read census with the legacy freeze
Paul Campbell with claude, codex carlos proof history carlos system claims 26065378
-
region-ha-2a-buildregion HA spec 2 (two-box regions), rev 1 draft, and its Astra brief
Paul Campbell with claude #299 box and group roles 6834659c
-
fix-empty-app-keyfix-empty-app-key
Paul Campbell with claude e8e961dd
-
runbook-home2-sharunbook-home2-sha
Paul Campbell with claude e963691d
-
moves-home-part2-planmoves-home-part2-plan
Paul Campbell with claude a89e35ca
-
feat/claim-files-backfillPrompts:
-
moves-overcap-cutmoves-overcap-cut
Paul Campbell with claude 70e57449
-
docs-rehearsal-dev-uk-secrets-keydocs-rehearsal-dev-uk-secrets-key
Paul Campbell with claude a5003aba
-
docs-rehearsal-dev-uk-bootstrapdocs-rehearsal-dev-uk-bootstrap
Paul Campbell with claude 9f17062a
-
hostfiles-cap-live-entrieshostfiles: the path cap applies to live entries only (LiveEntriesWithinCap), so a manifest written before the cap that holds a tombstone or skipped entry past it stays readable, and a moves recovery that selects it is not stranded (#236, moves' review of a8cebad)
-
seeded-instancescopy gate: the seeded-instances deck, pinned (Plan 1 Task 1)
Paul Campbell with claude #292 carlos instances the seeds floor legacy route assignments f97898f1
-
carlos-runspecs: carlos run (#259) and instances seeded from a database (#260, #261)
Paul Campbell with claude #259 #260 #261 #280 #294 carlos run what an instance is started with carlos instance exec carlos instance exit 37ab10c5
-
zdd-owed-itemsactivator: write a cold wake's build-state record at its exec (#272)
-
fix-binary-size-275binary-size-275: store SDK method values, not clients, in interfaces; add a size ceiling
Paul Campbell with claude 132cf996
-
changelog-v0.27.3Prompts:
Paul Campbell with claude 2683f16a
- Restarting the edge no longer leaves an instance unreachable for 15 minutes. If the edge stopped while an instance was waking, the instance could stay locked until its lease expired, and every request to it was refused for up to 15 minutes. The stopping edge now cancels the wake, makes sure it has stopped, and lets the lease go. If it cannot confirm the stop, it keeps the lease, as before. fix-shutdown-lease-292
- New accounts never get a reserved address. An account's address is part of every app's hostname. Account creation now skips any address that spells a name the platform uses itself, such as dev, edge or www. Existing accounts keep theirs. reserved-sqids-285
- Nothing else changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.26.x, read the v0.27.0, v0.27.1 and v0.27.2 operator notes first. They all still apply.
-
Instance control restarts with this update. This release changes
carlos-instance-control, so it has to restart on each box.carlos system updatedoes that on its own. A box updated any other way needssystemctl restart carlos-instance-controlafterwards. fix-shutdown-lease-292 carlos system - Roll the console as well as the boxes. Only a console on this release skips reserved account addresses when it creates an account. reserved-sqids-285
-
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. WithCARLOS_HOST_CLAIMset, instance control now refuses to start until a later release. carlos channels digests
Changes
5-
fix-shutdown-lease-292activator: Shutdown aborts a waking entry and gives its lease back with swaps off (#292)
-
reserved-sqids-285reserved-sqids-285
Paul Campbell with claude fc70bc75
-
changelog-v0.27changelog-v0.27.x: v0.27.0, v0.27.1 and v0.27.2 (README release step 10)
Paul Campbell with claude 8b5c7561
-
rehearsal-p0-two-boxrehearsal-p0-two-box
Paul Campbell with claude a3bfa662
-
readme-roll-orderreadme-roll-order
Paul Campbell with claude 4e577fde
- Two builds at once keeps each build's socket name. Where a deployment turns on two builds at once, each build's socket now has the same file name it has with the switch off, in a directory of its own. An app that works out its own address from its socket's name now starts the same way either way. Before, such an app saw a different name for the new build and refused to start. Nothing changes where the switch is off, which is every deployment by default. zdd-gen-socket-names
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.26.x, read the v0.27.0 and v0.27.1 operator notes first. They all still apply.
- A long host name keeps stop-then-start updates. With two builds at once on, a host on a flat box whose name is longer than 59 bytes is updated the old way: stopped, then started on the new build. Its socket path would otherwise be too long. zdd-gen-socket-names
-
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. WithCARLOS_HOST_CLAIMset, instance control now refuses to start until a later release. carlos channels digests
Changes
3-
zdd-gen-socket-nameszdd rev 19 amendment: generation sockets keep the flag-off file name
-
startup-largebox-test-281startup-largebox-test-281
Paul Campbell with claude d2f58fd3
-
fix-cross-test-compilehost: rootinventory_test.go is linux-only
Paul Campbell with claude 21d91fd6
- A box with many instances no longer fails its update while it starts. On a box with over a hundred instances, v0.27.0's update could take longer than the 20 seconds it allows, because the edge waited for the agent to check every instance first. The box then rolled back after about 45 seconds of failed requests. The edge now starts serving straight away. Requests for an instance wait up to 30 seconds for that check to finish, then get the usual answer that the instance is waking. hotfix-startup-sweep-281
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.26.x, read the v0.27.0 operator notes first. They all still apply.
-
After each box updates, check that it finished starting. The update's 20-second check now passes once the edge serves, before the agent has checked every instance. So also check the box's journal for
agent: hibernation activator armed, and that one request to a sleeping instance succeeds. -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. WithCARLOS_HOST_CLAIMset, instance control now refuses to start until a later release. carlos channels digests
Changes
1-
hotfix-startup-sweep-281hotfix #281: the edge no longer waits on the startup sweep and recovery
- Root keeps its own record of each box's releases. A box's root process now keeps the builds it has seen run healthy, and the build each service ran before its current one, in directories only root can write. Before, it read them from places the platform's own service could write. Restarts, rollbacks and recovering from a bad build work exactly as they did. feat/claim-root-trusted-state
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
- Coming from v0.25.x, read the v0.26.0 operator notes and the v0.26.1 notes first. They all still apply.
-
Before rolling, check two things on each box.
/,/varand/var/libmust be owned by root and not writable by group or others, and/var/lib/carlos-claimsmust not exist. If either check fails, root can't update a service that has its own unit, such as the console, on that box, and logsrepoint failed: permission deniedon every pass. -
Health history starts empty. Root no longer reads the health history the service kept before this release. Don't add a
requireorproveentry for a service to/etc/carlos/proof-policy.jsonuntil both its current build and the one before it have been seen healthy since the roll. Otherwise rolling back to the earlier build waits for a proof. -
One earlier build per service is kept.
/opt/carlos/previous/<host>points at the build each service ran before its current one, and the box keeps that build when it prunes old versions. Disk use can grow by up to one build per service. -
carlos __cgexeccan appear inps. Each new instance process now starts through a short-lived helper that places it in its cgroup before it runs. For a few millisecondspscan showcarlos __cgexecas a child of the agent. Monitoring, or apkillthat matches "carlos" in a command line, can catch it. zdd-flag-readiness-3 -
After the roll, check placement on each box.
journalctl -u carlos-edge --since '<roll time>' | grep 'placement before exec failed'should print nothing. A line there means a process was moved into its cgroup after it started instead. That affects resource accounting, not serving. zdd-flag-readiness-3 -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. WithCARLOS_HOST_CLAIMset, instance control now refuses to start until a later release. carlos channels digests
Changes
7-
changelog-v0.26.1changelog: v0.26.1 (release step 10)
Paul Campbell with claude f4cf27dd
-
zdd-flag-readiness-3plan: zdd flag readiness round 3 (draft)
-
feat/claim-root-trusted-stateclaim Plan 14 Part 1 (#280): root-trusted state foundations, families B, C and D
-
hotfix-instance-key-gatehotfix-instance-key-gate
Paul Campbell with claude 34a4328f
-
zdd-flag-readiness-2plan: zero-downtime flag readiness, round 2 (draft for Astra's review)
Paul Campbell with claude ba52d5ef
-
changelog-nested-bulletschangelog-nested-bullets
Paul Campbell with claude 67698c9c
-
changelog-v0.26.0changelog-v0.26.0
Paul Campbell with claude 729e8508
- A box with many instances no longer fails the update. v0.26.0 gave every instance on a box its key before the edge started, with one bucket read per instance. On a box with over a hundred instances that took longer than the 20 seconds the update allows, so the box rolled back after about half a minute of failed requests. The keys are now written in the background once the edge is serving, and the update no longer waits for them.
- Nothing changes for people using the CLI.
For operators
- Roll the boxes first, then the console.
-
Coming from v0.25.x, read the v0.26.0 operator notes first. They all still apply, and that includes any box that rolled back from v0.26.0. Restart
carlos-instance-control.serviceon each box after it updates, run the instance key checks before any box rolls, and check what root's AWS settings rely on (#267). -
Wait for the instance key line.
agent: instance keys:now comes afterhibernation activator armed, up to about a minute after the agent starts. Wait for it before you check for0 failed. It also counts rows skipped because a move or a layout change held the host. Those get their key at their next start. -
Every dormant switch stays off. Leave
CARLOS_SWAP,CARLOS_MOVES_PHASE1,CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINS,CARLOS_HOST_CLAIM_RETIRED_LOCATIONS,CARLOS_CONSOLE_ID,CARLOS_REGION_HA,CONSOLE_APP_REGIONS,CARLOS_TEMPORARY_APPSandCARLOS_REQUIRE_POINTER_DIGESTunset, and don't runcarlos channels digests on. The v0.26.0 notes say where each one is set. carlos channels digests
Changes
2-
Two builds at once, off until your deployment turns it on. Where it is on, a new build starts beside the old one and takes over once it passes its health check, so no request waits. For a few seconds both builds share the instance's database and its scheduled work, and the new build's migrations run while the old one still serves. So add a column, table or index in one release and drop the old one in a later release. Keep the names of scheduled work (
carlos schedule) the same across the two builds. A release that can't follow these rules ships with--swap holdoncarlos deployorcarlos ship, which stops each instance before its new build starts.carlos apps set <app> --swap holdmakes that the app's rule, and--swap-concurrencysets how many instances swap at once on one box. Every deployment ships with this off. zdd-1-generations zdd-2-containment zdd-3-swap zdd-4-release-side zdd-5-scheduler zdd-6-surfaces zdd-flag-readiness carlos schedule carlos deploy carlos ship carlos apps -
carlos deployfollows the rollout box by box. Where a box reports its rollout, deploy counts an awake instance once the new build has passed its health check and taken over, and an asleep one once its box has installed the build. If the build fails on a box, that box stops rolling it out, and deploy names the failure and exits with an error. Boxes report only where two builds at once is on. Everywhere else deploy watches the app's URL, as before. If the console can't list the app's instances, deploy keeps asking until its deadline and then says the list could not be read. zdd-6-surfaces zdd-flag-readiness carlos deploy -
carlos instances listshows two builds. INSTALLED is the build on the instance's box, and SERVING is the one answering its requests. They differ while a build rolls out, while an asleep instance waits for its next request, and after a build has failed on that box. REASON says which. A dash under SERVING means the box doesn't report it, which is every box until two builds at once is on.carlos instances retry <host>clears the failure hold on one instance, so the build that failed there is tried again as a canary. zdd-4-release-side zdd-6-surfaces carlos instances -
Choose how each instance takes new builds.
carlos instances set <host> --updates manualstops an instance taking new builds on its own.--channel,--major(stable only) and--pin <build>set the rest, and an empty value goes back to the app's default.carlos instances update <host>asks the box to install the newest build it considers ready, even with manual updates.--fast-trackskips the safety delay, and only account owners can use it. On the app,carlos apps set --instance-control updates,pinnames the settings an instance may change for itself once instances can act for themselves.--default-updates,--default-majorand--default-channelset the app's defaults. The console accepts manual updates, a major hold or a pin only once every box can keep the builds they name, and says how many boxes it is waiting for. settings-3-console-settings settings-4-root-applies settings-5-surfaces carlos instances set carlos instances update carlos apps -
Read a database as it was.
carlos db pull --at <time>andcarlos db query --at <time>read an instance's database as it was at an earlier time, given in RFC 3339 form such as2026-10-07T14:00:00Z. The copy is never newer than that time, and the command says which transaction it stopped at. Ask for a time before the oldest history and it names the oldest time you can use. Instances that sleep now keep seven days of history, as awake ones do. That week fills in over the seven days after your deployment rolls this release. db-pull-at hibernate-retention carlos db -
Channel digests.
carlos channels digestsshows whether channel pointers carry the sha256 of each build's manifest, and lists the channels that don't yet. Once a deployment turns digests on, boxes refuse pointers without them. So update the CLI on every machine and CI job that promotes, rolls back or fast-tracks before then.carlos channels resign <channel>re-signs a channel nobody has promoted to since digests went on. It shows every digest and signs only when you type yes. settings-1-pointer-digests carlos channels digests carlos channels resign -
carlos releases authorize <app> <version>, for operators. It shows a build's manifest and file digests and, when you type yes, signs a promotion record for exactly those bytes. Every promotion now writes one. This is for a build promoted before records existed, so an instance can be pinned to it or recovered onto it. settings-2-promotion-records carlos releases -
What an instance is started with. Every instance and seed now gets
CARLOS_HOST, its hostname exactly ascarlos instances listshows it. Read it, never the socket's file name. On an isolated box, an instance starts in its own data directory, the one its database is in, so a relative path such as./data/blobslands beside its database. Files and directories named after the host, such as<host>/or<host>-blobs, now move with an instance when its box isolates it, and come back on a revert. fix-roll-incident-256 carlos instances -
carlos move, off until your deployment turns moves on. It moves one instance to another region. The instance keeps serving while its data is copied, then goes offline for the cut. If the new region can't start it, the move takes it back on its own. Against a console without moves,carlos movesends nothing. moves-phase1 moves-phase1-2 moves-phase1-3 moves-phase1-3b moves-phase1-3c moves-phase1-4 moves-phase1-5 moves-phase1-5b moves-phase1-5c moves-phase1-5d moves-phase1-5e moves-phase1-5f moves-phase1-6 moves-phase1-7 moves-cut-guard carlos move -
Smaller fixes. A build of about 100 MB no longer runs the box's staging out of memory, so its promote no longer waits for the hourly pass.
carlos sidecars lsshows the build each sidecar's box last started, and "unknown" for one that hasn't started anywhere.carlos instances set-channelfinds a host typed with capitals, and for a box route with no instance record it says how to move the route on its box. stage-stream-artifact zdd-6-surfaces setenv-box-route-error carlos sidecars carlos instances
For operators
- If your boxes haven't run v0.25.1, read its operator notes and v0.25.0's first. They all apply to this release.
-
Roll the boxes first, then the console. Roll the boxes with
carlos system update. carlos system -
After each box updates, restart
carlos-instance-control.serviceon it. The update runs the code the box already has, which installs this release without restarting that service. This release's agent refuses to wake isolated instances while the service runs an older build, and the reason incarlos logsends withrestart carlos-instance-control.service.carlos system statusstill readscurrent, so it won't tell you. From this release on,carlos system updaterestarts the service itself. fix-roll-incident-256 carlos logs carlos system -
Before any box rolls, run the instance key checks. This release writes a
CARLOS_INSTANCE_KEYinto each instance's<host>.envthe first time it starts, and starts a replica only with its home's key. instance-key-provision instance-key-build- On every box,
find <data> -maxdepth 1 -name '*.env' -type lmust print nothing. A<host>.envthat is a symlink now fails that instance's start. Stop the instance, replace the link with the real file, and treat the token in it as leaked. - On every box with a replica (
sqlite3 <data>/registry.db "select host from routes where replica=1"), compare each replica's key with its home's. A key is the lastCARLOS_INSTANCE_KEYline of<host>.env, or of<host>.config.envwhen<host>.envhas none, in the data directory for a flat instance or the instance's own directory for an isolated one. Where the two match, add<replica-host>=<sha256 of the key>to/etc/carlos/replica-home-keyson the replica's box before it rolls. Write the whole list to a temporary file in/etc/carlos, make it root:carlos 0640, and rename it into place. Where they differ, the replica is refused after the roll. Tell its owner first. - A replica with no key keeps starting where it has a control socket, but its legacy sidecar and any worker row of its own stop at the roll. List them on each box with a replica, and tell their owners.
- Check the agent can read the list:
sudo -u <agent user> test -r /etc/carlos/replica-home-keys && echo okmust printok. - After the roll,
journalctl -u carlos-edge --since '<roll time>' | grep 'agent: instance keys:'must show0 failed.
- On every box,
-
Root ignores AWS profile, endpoint and trust-store settings. A box's root processes now ignore
AWS_PROFILE,AWS_DEFAULT_PROFILE,AWS_CA_BUNDLE, theAWS_ENDPOINT_URLvariables,SSL_CERT_FILE,SSL_CERT_DIRand shared AWS config files, and log an alert when one is set. Before rolling, check that no box's host.env depends on them. On a box outside AWS,/etc/carlos/credentialsmust hold only static keys under[default]. The agent rewrites it as root:carlos 0640 on every start. fix/267-credentials fix/267-adopt-writes docs/267-remote-host -
Every dormant switch stays off. Leave each of these unset, and run none of the commands named, until its own rollout is approved.
carlos system carlos system journal migrate carlos channels digests
CARLOS_SWAPon every box. Two builds at once still has open items, and only the exact wordoverlaparms it.CARLOS_MOVES_PHASE1on the console and every box. Don't publish a moves protocol floor (control/moves-protocol.json) either.CARLOS_HOST_CLAIM,CARLOS_HOST_CLAIM_ORIGINSandCARLOS_HOST_CLAIM_RETIRED_LOCATIONSon the console and every box, andCARLOS_CONSOLE_IDon the console. Don't runcarlos system guard-armorcarlos system journal-migrate.CARLOS_REGION_HAon every box.CONSOLE_APP_REGIONSandCARLOS_TEMPORARY_APPSon the console.CARLOS_REQUIRE_POINTER_DIGESTon every box. Don't runcarlos channels digests onyet.
-
Host claims: every roster reader first. Binaries older than this release reject a signed roster that names a home region. So before anyone publishes the home designation, every reader of
control/host-actors.jsonmust run this release: every console, every box's agent and root services, the update and rollback tools, and any offline or recovery binary. The designation is write-once, and this roll doesn't publish it. feat/hostclaim-home-region fix/home-region-followups -
Digests: writers before readers. Once a box has verified a channel pointer with digests, it refuses pointers for that channel without them. So first upgrade every writer: every console, and every CLI or deploy script that promotes, rolls back or fast-tracks. Then run
carlos channels digests on, and watchcarlos channels digestsuntil it lists nothing. Only then setCARLOS_REQUIRE_POINTER_DIGEST=onin every box's host.env.carlos channels digests offstops writers adding digests while one is fixed, but doesn't clear boxes that have already seen them. settings-1-pointer-digests carlos channels digests -
Instance update settings wait for every box. The console refuses manual updates, a major hold or a pin until every box reports it can keep the builds they name. Before rolling any box back below this release, run
carlos releases retention --offfor each app that has a retention policy, because an older box prunes builds a pin or a held instance still needs. After such a rollback the console shows settings not enforced for instances on the older boxes. settings-4-root-applies settings-5-surfaces carlos releases -
Remove the staging memory drop-ins after the roll. Staging now streams a build to disk instead of reading it into memory. A deployment that raised the memory of
carlos-stage.serviceorcarlos-adopt.servicewith a drop-in can remove it from every box, and from its box bootstrap, once every box runs this release. stage-stream-artifact -
The
deployment-bucketsmodule now guards fence writes. Its new statement refuses every write undercontrol/box-fences/from a role not listed inbox_fence_writer_role_arns. Nothing writes there while host claims are off, so applying it now is safe. feat/hostclaim-activation -
Files left behind by earlier moves. An instance its box isolated before this release may have left files named after its host in the shared data directory.
carlos status --layoutand the agent log now name them on every pass. Move them into the instance's directory by hand. fix-roll-incident-256 carlos status
Changes
68-
moves-copy-approve-p5fmoves-copy-approve-p5f
Paul Campbell with claude 09c5a4a5
-
region-ha-1b-next-buildplan: region HA 1b-next, relocation released by stop evidence or a termination fence, reconcile row cases, create's once-only executor choice, and fences consumed in claim CASes
-
moves-plan15-proofmoves-plan15-proof
Paul Campbell with claude 68b6ab5e
-
region-ha-two-box-buildRegion HA two-box model: plan rev 11 and its Astra reviews (from region-ha-hostlife-two-box 8f95c4e0)
Paul Campbell with claude 93ceb6cd
-
settings-5-surfacessettings-5 task 1: draft plan 5's update settings copy for review
Paul Campbell with claude carlos apps carlos instances set carlos instances update d850865b
-
feat/claim-admitted-provenancefeat/claim-admitted-provenance
Paul Campbell with codex 01edf901
-
moves-phase1-5fmoves-phase1-5f
Paul Campbell with claude d6122533
-
moves-restoring-source-protectionmoves: restoring keeps the source region authoritative until a clean return or the commit (J2/F4, L18 finding 1)
Paul Campbell with claude 650e6152
-
settings-4-root-appliessettings-4 task 1: the build state, its registry copy, and root's consumed file
Paul Campbell with claude 8916558d
-
feat/claim-loss-pagesfeat/claim-loss-pages
Paul Campbell with claude, codex 39986908
-
zdd-flag-readinesszdd-readiness: implementation plan for the flag-readiness round (#272)
-
fix/home-region-followupsfix/home-region-followups
Paul Campbell with claude, codex 2ad5412c
-
feat/hostclaim-home-regionfeat/hostclaim-home-region
Paul Campbell with codex a0806e4c
-
moves-held-lockmoves-held-lock
Paul Campbell with claude dde859f3
-
moves-home-parksmoves-home-parks
Paul Campbell with claude 359e8ac2
-
moves-phase1-7moves-phase1-7
Paul Campbell with claude 0715faca
-
feat/hostclaim-moves-integrationfeat/hostclaim-moves-integration
Paul Campbell with codex 1b5802fb
-
moves-cut-guardmoves-cut-guard
Paul Campbell with claude b04ff852
-
moves-copy-approve-58moves-copy-approve-58
Paul Campbell with claude bd9d6321
-
moves-phase1-6moves-phase1-6
Paul Campbell with claude carlos move bc25674a
-
instance-key-buildInstance key provision (region HA L21): the platform mints CARLOS_INSTANCE_KEY create-only and durably into <host>.env on every launch path once configuration is delivered, gates every replica launch on its home's verified key, adds the writer-bound adoption verb (unmounted until O6/O7) and a legacy-box startup backfill, and carries the key byte for byte through re-render and moves. Rastrillo's carlos.InstanceKey consumes it. Effectively dormant until apps adopt the helper; rollout has pre-roll checks.
-
zdd-6-surfaceszdd-6 task 2: rolloutwords, the one home for rollout phrases
Paul Campbell with claude #1 #2 #3 #4 #5 #6 #7 #8 #9 carlos apps carlos deploy two builds at once carlos instances carlos sidecars 5da1cc9b
-
settings-3-console-settingssettings-3 task 1: release.UpdateSettings
Paul Campbell with claude 30866251
-
moves-phase1-5emoves-phase1-5e
Paul Campbell with claude 5157c1e7
-
moves-phase1-5cmoves-phase1-5c
Paul Campbell with claude e79d71b5
43 more
-
moves-phase1-5dmoves-phase1-5d
Paul Campbell with claude d562d7f2
-
instance-key-provisionInstance key provision (region HA L21) implementation plan
Paul Campbell with claude 0901e835
-
fix-restore-wal-leftovershostbox: ColdRestore removes the temp database's -wal and -shm
Paul Campbell with claude 0d338c14
-
settings-2-promotion-recordssettings-2 task 1: internal/updatewords, the draft strings for the settings plans
Paul Campbell with claude carlos releases 70f8119f
-
feat/hostclaim-moves-recoveryfeat/hostclaim-moves-recovery
Paul Campbell with codex 44c1b6d7
-
docs/267-remote-hostdocs, lease: remote-host runbook for root:carlos 0640 credentials and the fresh-inode repair; the off-cloud session-token error (#267, copy approved by Paul 2026-10-10)
-
zdd-5-schedulerzdd-5 task 1: pin the plan 1-4 surface; CARLOS_SWAP flag
Paul Campbell with claude d905a676
-
fix/268-lease-marginlease: TestBlockedRenewalDeadlinePrecedesTakeover runs at a 3s TTL so its termination margin outlasts CI scheduling (#268)
-
fix-moves-floor-gatemoves floor gate: compare the floor file in Go, not with cmp
-
feat/hostclaim-region-hafeat/hostclaim-region-ha
Paul Campbell with claude, codex 93ef4b50
-
moves-phase1-5bmoves-phase1-5b
Paul Campbell with claude ca591df7
-
fix/267-credentialsfix/267-credentials
Paul Campbell with codex 75618480
-
moves-phase1-3cmoves-phase1-3c
Paul Campbell with claude a34623bd
-
fix/267-adopt-writesfix/267-adopt-writes
Paul Campbell with claude, codex 2d3ff963
-
fix/registry-chown-nofollowfix/registry-chown-nofollow
Paul Campbell with claude, codex 29dab2d8
-
stage-stream-artifactrelease: stream the artifact to disk while staging (#269)
-
zdd-3-swapzdd plan 3 task 1: swap types, the SwapBackend seam, flat staged spawn without health, each artifact's tier, canonical link at the switch
-
moves-phase1-5moves-phase1-5
Paul Campbell with claude da76647b
-
feat/hostclaim-activationclaim Plan 9: activation readiness (amadan #250), Paul's six rulings, ResolveMoveStart, moves C1 integration
Paul Campbell with claude, codex #250 cancel an unpublished activation carlos system journal migrate abcc732d
-
moves-copy-approve-2moves copy: Paul approved the 16 rows from Plans 3 and 4 (2026-10-09), no edits
Paul Campbell with claude 17d5960b
-
moves-copy-driftmoves copy: bring 24 approved rows to their code, 21 stay pending
Paul Campbell with claude 94263187
-
fix-fdholders-alias-teststopevidence test: wait until fd 3 holds the database by identity before scanning (flaky on arm64 CI)
Paul Campbell with claude 316a0768
-
moves-copy-approve-1moves copy: Paul approved the 205 reviewed rows (2026-10-09); 160 applied rows marked approved
Paul Campbell with claude 33425265
-
moves-phase1-4moves-phase1-4
Paul Campbell with claude 412ca787
-
settings-1-pointer-digestssettings-1 task 2: manifest digests and GetManifestRaw
Paul Campbell with claude #1 #2 #3 #4 #5 #6 #7 #8 carlos channels resign carlos channels digests 8d33cef1
-
hibernate-retentionhibernate-retention: sleeping instances keep 7 days of snapshots, like awake ones (#263)
-
zdd-2-containmentzdd-2-containment
Paul Campbell with claude 218b7454
-
zdd-4-release-sidezdd-4 task 1: Manifest.Swap, the release's own demand (additive)
Paul Campbell with claude db8c3f06
-
zdd-1-generationszdd-1-generations
Paul Campbell with claude 8e066e29
-
db-pull-atdb-pull-at: carlos db pull/query --at reads a database as of a past time (#262)
-
setenv-box-route-errorinstances set-environment/set-channel: say what a 404 really was (#264)
-
moves-phase1-3bmoves-phase1-3b
Paul Campbell with claude 4a51a6da
-
moves-phase1-3moves-phase1-3
Paul Campbell with claude 81d0cc60
-
fix-roll-incident-256Roll incident #256: system apply restarts instance-control; app entries move with the host; CARLOS_HOST; WorkingDirectory for instances
Paul Campbell with claude #256 what an instance is started with the platform s own binary instance layout carlos instance control 56ebee16
-
moves-phase1-2moves-phase1-2
Paul Campbell with claude 4f26f15c
-
feat/hostclaim-consolefeat/hostclaim-console
Paul Campbell with claude, codex 76f728a9
-
feat/hostclaim-box-assemblyhost, hostbox, registry, activator, provision, instancectl, cgroup, schedule, hostguard, console: claim Plan 6b, production assembly of the box wiring
Paul Campbell with claude, codex a4cd3003
-
fix/fdholders-lstatstopevidence: an fd entry that exists but cannot be followed is unreadable, not closed
Paul Campbell with claude 9cf9f18f
-
fix/fdholders-inodestopevidence: FDHolders matches the open file's device and inode, not only its path
Paul Campbell with claude 8e9ac1b8
-
fix/moves-copy-gate-scopemoves copy gate: inventory only moves code, and skip the diff checks where git cannot name the merge base
Paul Campbell with claude e5adf329
-
fix/c7-moves-intenthostclaim: the pre-flip conversion reads the move's own intent (C7 contract with moves)
Paul Campbell with claude cfdb4e12
-
moves-phase1moves-phase1
Paul Campbell with claude 17362eaf
-
changelog-v0.25.0changelog: v0.25.0 (release step 10)
Paul Campbell with claude 76b1400f
-
Isolated instances now happen. v0.25.0 moved instances into their own box only on a box whose isolation probe passed, and no box could pass. Part of the probe checked the box's addresses using a kind of socket the probe's own unit is not allowed to open. The control service now makes that check itself, reading the addresses from
/proc. Boxes whose other checks pass are now ready, and their instances move as v0.25.0 described. -
Isolated instances stop cleanly. Inside its own box, an app ran as the first process, where the kernel ignores any signal the app has no handler for. A Go app with no SIGTERM handler could not be stopped: each stop waited 20 seconds, killed it, and left the unit failed. A small init now runs first. It passes stop signals on to the app, cleans up exited processes, and exits with the app's status. An app that dies by a signal now shows as
exit 128+nin its instance event line, so a crash on SIGSEGV readsinstance exited: exit 139. It used to readsignal. -
Temporary static sites, off until a deployment turns them on.
carlos deploy --temporary ./distcreates an app namedtmp-plus six letters and digits, ortmp-<name>with--app <name>. It lives 7 days, or what--ttlsays (1h to 30d). When its time is up it moves to the Trash, and it is purged 3 days later instead of 30.carlos apps ttlmoves the expiry andcarlos apps keepmakes it permanent. A temporary app is served only at its own platform address, so--hostand--kind binaryare refused, and an account holds at most 20. carlos deploy carlos apps -
Names starting with
tmp-are reserved for temporary sites.carlos apps create,carlos add --app, renames andconsole grantrefuse them, whether or not temporary sites are on. carlos apps carlos add -
carlos apps listshows every app in the account, the Trash included, and when each expires or is purged. carlos apps -
carlos shipchecks the program. For a Go binary, ship records its main package in the manifest. It refuses a release whose main package differs from the app's latest release. When the change is meant, ship with--program-change.carlos deployhas no such flag, so usecarlos ship --program-changeand then promote. Boxes check the bytes too, so a release shipped by an older client is refused at adoption and is not pointed live. A build the route has run before is always accepted, so going back across an intended change works. carlos ship carlos deploy -
A console that will not start is rolled back. After a box adopts a new build for a route with a named unit, such as the console, it waits for the unit to stay up and accept connections. If it doesn't, the box rolls back, refuses that promotion and alerts. A plain re-promote stays refused.
carlos promote --retry <version> <channel>tries again.carlos status --liveshows refused hosts. carlos promote carlos status -
GeoIP for apps. On a deployment that has published a GeoIP database, every request to an app carries the visitor's rough location in
X-Carlos-Geo-Country,X-Carlos-Geo-Subdivision,X-Carlos-Geo-Lat,X-Carlos-Geo-LonandX-Carlos-Geo-Source. Any of them can be missing; treat that as unknown. The edge removes any of these a visitor sends. Analytics count page views by country and credit the database.carlos geo <address> --app <a>gives the same answer for any address, and apps can callGET /api/cli/apps/<account>/<app>/geo?ip=<address>, at most 60 a minute. An app that shows visitors anything worked out from these headers must credit the databaseX-Carlos-Geo-Sourcenames. carlos geo
For operators
- If your boxes have not run v0.25.0, read its operator notes first. All of them apply to this release.
-
Instances move to the nested layout on their own, and this time they will. v0.25.0's note applies again. With no layout intent recorded, every box whose isolation probe passes starts moving its instances on the first change it sees after this release lands. Awake instances get an hour, then are stopped and moved. This includes boxes that already run v0.25.0 and recorded nothing. To keep control, record
carlos system layout revertbefore you roll, thencarlos system layout migrate --box <label>one box at a time, or putCARLOS_LAYOUT_DEFAULT=flatin a box's host.env to leave that box alone. carlos system -
Before rolling, check one box:
systemctl start carlos-instance-probe.servicethen read/run/carlos-control/probe.out. It must sayready: true. The control service no longer opens a resolver that is one of the box's own addresses. It reports that as a failingresolver-localline, and if it cannot read the box's addresses it opens no resolver at all. Landlock must be in the booted kernel'slsm=list, and/etc/resolv.conf(or resolved's upstream list) must name a resolver that isn't on loopback. -
Roll the boxes before the console. The rollback, wrong-program and
tmp-checks run on the box, and so does removing forged GeoIP headers. -
Fix each console box's binding before you rely on the rollback. The rollback check runs only when the console unit's
ExecStartnames the live link of the route stamped with that unit. Where it doesn't,adoptlogsbinding: … restart not checkedand restarts the unit as before, unchecked. On each console box, readsystemctl show -p ExecStart console.service, stamp that host withcarlos route --host <host> --unit console.service, and clear the stamp from any other host with--unit "". Until the binding is right, keep the finalsystemctl restartin your console roll. carlos route -
The rollback check is on everywhere. After adopting a build for a route with a named unit, the box waits up to 30 seconds (
CARLOS_UNIT_SETTLE, at least 5s) for the unit to stay up on the new build and accept connections. If it does not, the box rolls back, writes a refusal and alerts through SNS orCARLOS_ALERT_WEBHOOK. If your console takes longer than that to start listening, raiseCARLOS_UNIT_SETTLEon its box before you fix the binding. WithCONSOLE_GEOIP_DBset, the console now checks that file in a separate process before it listens. -
The wrong-program check is on everywhere. A box refuses a staged binary whose Go main package differs from the live build's and from every program that route has run before, unless its manifest records
--program-change. The refused build is not pointed live and nothing restarts. Each route starts its history from its live binary on its first pass. The console's ship door makes the same check once the console runs this release. Thecarlosbinary is never a console artifact; build the console from./cmd/console. -
Dev proofs are off. They are off unless a box has
/etc/carlos/proof-policy.json(root, mode 0644). On a proving console box, runcarlos proof keygenas root, then write a policy file with aproveblock: the apps, the prover's name, how long a build must run (after, such as 15m) andkey_file. That box then mints a proof for each build that runs healthily for that long. On a requiring box, arequireentry names the app, the prover and its public key. A new build of that app is then adopted only with a proof for those exact bytes, or if the box has already run that build healthily. Carry a proof withcarlos proof getagainst the proving deployment andcarlos proof putagainst the requiring one.carlos status --liveshows a host that is waiting. A policy file that does not parse holds every named-unit route on its current build and says so in the journal. To switch the requirement off, delete therequireentry (or the file) as root and runcarlos adopt --stage-only. The box then logs once an hour that it is off. Write policy files on the box over SSM, not through tofuuser_data. carlos proof carlos status carlos adopt -
Temporary sites are off until you set
CARLOS_TEMPORARY_APPS=1on the console. The console adds four columns to itsappstable when it starts. The change is additive. Its expiry pass runs every 5 minutes either way, and with no temporary apps it does nothing. Before you turn them on, roll every box, then check that no box's registry and neither the console'sappsnor itsownerstable has atmp-name. An expiry drops a temporary app's routes, so rename or remove anytmp-name you find first. -
Platform GeoIP sends nothing until you publish a database. From this release every edge removes forged
X-Carlos-Geo-headers and watches the bucket for a database.carlos system geoip publish <file.mmdb>sends one, and every edge picks it up within 12 minutes. Publish only aftercarlos system geoip statussaysready, because a box on an older release passes a visitor's forged headers straight through. A retired box that still hascontrol/edges/<label>.jsonkeeps it from sayingready; delete that record.carlos system geoip offremoves the database. On the console box, check that the console can read/data/carlos/geoip/current: withCONSOLE_GEOIP_DBunset, the console's region guess now uses that copy. carlos system -
The GeoIP feed is off until you set
CONSOLE_GEOIP_FEED.dbip-city-liteis free, needs nothing else, and requires the credit the platform already shows. For MaxMind, also setCONSOLE_GEOIP_MAXMIND_ACCOUNTandCONSOLE_GEOIP_MAXMIND_KEY. The console checks once a day. A GeoLite2 database is dropped 30 days after it was built. Before you publish GeoLite2, apply thedeployment-bucketsmodule version that expires old copies undercontrol/geoip/after a day. It is the module's first lifecycle configuration, and a bucket holds one, so check whether yours already has one before you apply. -
A new
geoipbox alert sits besidedisk,mem,cpuandlag. It fires after 30 minutes when the loaded database is over 45 days old, a GeoLite2 database is 21 days old, the database has expired, a box has not loaded the published database for over an hour, or the feed has failed 7 checks in a row. With no database and no feed it never fires. -
Host claims stay dormant. Leave
CARLOS_HOST_CLAIMunset, on the console and on every box. On a box, any value that is not blank stops the agent from starting. On the console, it starts claim recovery and backfill that have nothing to work from yet. LeaveCARLOS_CONSOLE_IDunset on the console too. Do not runcarlos system guard-arm. It replaces how the update, edge and console units start, and once armed it is enforced whateverCARLOS_HOST_CLAIMsays. With all three left alone, nothing in this release writes or reads host claims. carlos system
Changes
9-
platform-changelogchangelog: carlosframework.com/platform/changelog, generated from git, release notes and Amadan
Paul Campbell with claude 289043db
-
feat/hostclaim-consolefeat/hostclaim-console
Paul Campbell with claude, codex 3407d114
-
feat/hostclaim-floorfeat/hostclaim-floor
Paul Campbell with claude, codex #250 host lifecycle guard cbc0922e
-
geoip-followupsGeoIP follow-up (#241): DirStore.Put CAS gate by Stat and streamed hash, so an oversized object at the key is never read into memory (Astra R2-1); restore the thirteen code-review reports lost with the build worktree; Astra round 14 merge-ready.
-
geoip-for-appsPlatform GeoIP for apps (#241): bucket-mirrored database with hot swap on every edge; X-Carlos-Geo-* headers set by the ingress edge and carried across hops and tunnels; analytics countries with attribution; carlos system geoip publish/status/off; auto-update feed (DB-IP Lite default, GeoLite2 or paid MaxMind GeoIP2); geoip box alert; console follower, GET /api/cli/apps/{a}/{app}/geo and carlos geo; untrusted .mmdb verified only in a killable, memory-capped child. Spec rev 13 (Astra-accepted), 13 Astra code-review rounds.
Paul Campbell with claude #241 #249 carlos analytics headers your app receives carlos geo platform geoip 6bdaba34
-
fix-instance-initNested instances: a minimal init as PID 1 forwards stop signals and reaps, so apps stop cleanly (#126)
Paul Campbell with claude #126 carlos instance exec 40b6f50c
-
design-console-release-defencesConsole release defences: D1 settle and rollback, D2 wrong-program refusal, D3 opt-in dev proofs (after the 2026-10-06 console outage)
Paul Campbell with claude #252 carlos proof 9e628024
-
fix-probe-resolver-portsProbe: resolver checks no longer need netlink; the control service reads local addresses from /proc (#126)
-
design-temporary-sitesTemporary static sites: self-expiring tmp- apps, trashed at expiry, purged 3 days later
Paul Campbell with claude carlos apps carlos deploy 1da67e63
-
Each instance runs in its own box. Instances the platform starts on demand used to share one user and one data directory on a box, so one app could read another app's files. From this release, a box whose isolation checks pass moves every such instance into its own directory and its own mount and process namespace, where it sees its own files and nothing else. A sleeping instance moves at once; an awake one gets an hour to go to sleep, then is stopped briefly and moved. New instances on that box start out isolated.
carlos status --layoutshows where each box is. tenant-iso-default-nested tenant-iso-layout carlos status -
carlos system layoutlets an operator choose instead:migrate --box <label>moves one box at a time, andrevertmoves everything back.statusprints what is recorded. tenant-iso-plan5 carlos system - Instances get CPU and IO limits beside their memory cap, see only their own app's build, and can't reach loopback or private addresses on the box except its DNS resolver. New starts are refused while the disk is nearly full. tenant-iso-hardening
-
Custom domains can require proof. On a deployment that sets
CONSOLE_DOMAIN_PROOF=true,carlos domains attachreserves the name and prints a TXT record, and the name isn't served untilcarlos domains verifyfinds it. Names under another account's platform domain are refused everywhere. tenant-iso-domains carlos domains - Only a platform operator can add an upstream address to an instance. Upstreams an instance already has keep working, and can be kept, reordered or removed. tenant-iso-routes
-
Cookies stay within their account. On a platform hostname, a cookie whose
Domainreaches beyond the app's own account is made host-only by the edge. tenant-iso-cookies -
Instance catch-all domains.
carlos domains attach --app <a> '*.<parent>'gives every instance of the app a public name,<slug>.<parent>, with no per-instance claim or DNS. instance-catchall carlos domains -
carlos email testsends HTML too. The test message is now multipart, with a plain-text and an HTML part, so it shows that HTML mail gets through. Apps can send any MIME message over their credential. multipart-email-support carlos email -
Smaller fixes. Re-attaching a static site's own hostname to flip
--wildcardor--catchallno longer turns its route into an alias of itself. A box no longer places a certificate order every hour for a platform domain whose DNS zone its provider doesn't hold. first-route-wildcard wildcard-zone-check
For operators
-
Instances move to the nested layout on their own. This is the first release on which isolated instances run. With no layout intent recorded, every box whose isolation probe passes starts moving its instances on the first change it sees after this release lands. Awake instances get an hour, then are stopped and moved. A move refused for a reason a tenant could have caused (a planted hard link, a symlinked directory) keeps that instance stopped until an operator clears it;
carlos status --layoutnames it. To keep control, recordcarlos system layout revertbefore you roll, thencarlos system layout migrate --box <label>one box at a time, or putCARLOS_LAYOUT_DEFAULT=flatin a box's host.env to leave that box alone. tenant-iso-default-nested carlos status carlos system -
Before rolling, check one box:
systemctl start carlos-instance-probe.servicethen read/run/carlos-control/probe.out. It must sayready: true. Landlock must be in the booted kernel'slsm=list, and/etc/resolv.conf(or resolved's upstream list) must name a resolver that isn't on loopback. A box that fails any of these stays flat and says why. tenant-iso-layout tenant-iso-hardening -
Roll the boxes before the console. The console now trusts a loopback
X-Forwarded-Foronly when the edge has signed it, and switches to requiring the signature after it first sees one. Domain proof needs boxes that understand pending claims. tenant-iso-routes -
Rolling back to a release before v0.25.0 is refused while any box has nested instances. Run
carlos system layout revert, wait untilcarlos status --layoutshows every instanceflat, then roll back. tenant-iso-plan5 carlos system carlos status -
Settings worth turning on for a deployment that hosts other people's apps:
CONSOLE_DOMAIN_PROOF=trueandCONSOLE_RESERVE_PLATFORM_DOMAINS=trueon the console, after the boxes have rolled.CONSOLE_SECRETS_ENVELOPE_V2=truemakes new secrets bound to their account and app; set it only once every box runs this release. tenant-iso-domains
Changes
17-
tenant-iso-default-nestedIsolated exec: nested is the default layout on a ready box; CARLOS_LAYOUT_DEFAULT=flat opts out (#126)
Paul Campbell with claude #126 instance layout 2b2cc879
-
region-ha-contractsRegion HA contracts for the claim (L13) and moves sessions, dormant
Paul Campbell with claude 337b1062
-
tenant-iso-cookiesEdge: tenant cookies can't reach beyond their own account; never cache a trailer Set-Cookie (#217)
Paul Campbell with claude #217 carlos domains 383fae08
-
tenant-iso-plan5Isolated exec, plan 5: the console door and carlos system layout; nested minting; downgrade guards with LayoutFloor v0.25.0 (#126)
Paul Campbell with claude #126 #132 the platform s own binary instance layout f5ef8e36
-
fix/hostbox-boxid-enrollhostbox: verify box identity with boxid.Verifier.Enroll (main build fix)
Paul Campbell with claude 84c80eba
-
feat/hostclaim-boxhostwrite: the inert selection interface for host-specific writers (claim Plan 6 Task 2)
Paul Campbell with claude, codex d649d8d4
-
design-region-ha-rev5Region HA spec 1 rev 5.4 and plan 1b: claim readers and evidence, dormant
-
tenant-iso-routesRoutes: only operators add instance upstreams; the console trusts loopback X-Forwarded-For only with the edge's host-bound proof (#214 items 4-5, #50)
Paul Campbell with claude #50 #170 #214 carlos instances 1c43c2ce
-
tenant-iso-domainsDomains: opt-in proof of control; account namespaces are their own; fleet boxes see only their own claim bodies (#215)
Paul Campbell with claude #209 #215 carlos domains 9bed97b5
-
tenant-iso-hardeningNested instances: CPU/IO limits, a disk floor, own-build-only /opt/carlos, no loopback or private egress, private IPC and Landlock-scoped abstract sockets (#214 items 1-3, #178)
-
tenant-iso-layoutIsolated exec, plan 4: the nested layout and carlos layout migrate/revert (#126)
Paul Campbell with claude #126 carlos status the platform s own binary 01f890ce
-
multipart-email-supportemail test: send multipart/alternative, plain and HTML
James Adam with claude carlos email 7143c7e0
-
fix/hostclaim-r717hostclaim: a created incarnation's first admission declares nothing (moves 7.17 note 2)
Paul Campbell with claude 67547f5a
-
instance-catchallMerge instance-catchall: *.<parent> serves each instance at <label>.<parent> (#233)
James Adam with claude #233 one name per instance parent 1d1a6f13
-
first-route-wildcardMerge first-route-wildcard: a first-route claim stays first-route on a route-less re-attach (#238)
-
wildcard-zone-checkMerge wildcard-zone-check: check the DNS-01 zone before placing a wildcard order (#237)
-
fix/hostclaim-r16park, hostclaim: scopes stay in their own namespace; the legacy session-0 loss identity (joint round 16)
Paul Campbell with claude, codex c7e595be
-
CI can deploy through the console.
carlos services create --role deploy --app <a> --rungs canary,edge <name>mints a credential that can ship, and promote or roll back only the rungs you name:canary,edgeandbeta, neverstable. In CI, setCARLOS_SERVICE_TOKENandCARLOS_CONSOLEand runcarlos deployas usual. The first deploy of a new app still needs a person, because a deploy credential cannot create the app or set up its first host. It cannot hotfix, delete the app, or change retention or domains.carlos services listgains a RUNGS column. The CLI refuses to run with bothCARLOS_SERVICE_TOKENandCARLOS_DEPLOYMENT_BUCKETorCARLOS_DEPLOYMENT_DIRset. design-deploy-credential carlos services carlos deploy - A failed rollback says so. When the console cannot sign a rollback, it now answers "Nothing was rolled back." Before, it said "Nothing was promoted." fix-deploy-rollback-copy
-
carlos dbno longer panics. Ifcarlos db pullorquerycould not create its temporary file, the restore crashed. It now reports the error. feat/hostclaim-door carlos db
For operators
- The boxes come back onto the release train. The flagship boxes have been running a hotfix build of v0.23.0 (f3f6cf73). It carried four fixes. Three are in v0.24.0, and their operator notes are there: a box runs its adopt work on its own loop, lists the bucket by app, and reads in parallel. The fourth is new in this release. When a box cannot stage a release itself, it asks a root pass to do it. That request used to be sent at most once a minute, and one made inside the minute was dropped, so a second release soon after the first waited for the next change to be noticed. On the flagship that was 98 extra seconds. The request is now limited to once every 15 seconds, and one made inside that window is sent at its end instead of dropped. Rolling this release moves those boxes off the hotfix with nothing lost. fix-stage-request-deferred
-
If your boxes are coming from v0.23.0 or a hotfix of it, read v0.24.0's operator notes first. Its changes now apply to the boxes: the keyless config guard, the box with no deployment store, and alerts to SNS. The check that matters most is this one. Every box that runs placed instances must hold the right
CARLOS_SECRETS_KEYbefore you roll. A box without it, or with a key that does not open an instance's sealed config, will not wake that instance. -
Leave
CARLOS_HOST_CLAIMunset on the console. Any value that is not blank turns it on, including0andfalse. The console reads it once, when it starts. Nothing writes host claims yet, so with it on,carlos db pullandcarlos db queryfail for every host. feat/hostclaim-door carlos db -
Do not set
CARLOS_REGION_HAon a box yet. It is the switch for multi-box regions, which this release does not finish. Left unset, a box publishes noregion-ha-1capability and no headroom, and nothing changes. design-region-ha -
Deploy credentials need the console's signing key. The console signs each deploy promote with a grant limited to the credential's rungs, so the console must hold its release key, as it already does for promotes. It adds a
rungscolumn to itscli_tokenstable when it starts. The change is additive. design-deploy-credential -
Region HA foundations ship dormant. Every box's edges file gains
box_id, which is the box's label. Box bootstrap also creates/run/carlos/hostguardand/data/hostguard, mode 2770, owned bycarlos:carlos, when tmpfiles next runs. Nothing uses them yet. The host claim, generation selection and park libraries have no callers, so the boxes behave as before. design-region-ha feat/hostclaim-library feat/hostclaim-genselect feat/hostclaim-boxguard feat/hostclaim-park -
Read the plan before applying the infrastructure modules.
region-hostgains a termination queue, an EventBridge rule and a box-role policy to read the queue, and its root volume is now deleted when the instance terminates.deployment-bucketsgains a bucket policy that makescontrol/boxes/*create-only and undeletable. A bucket holds one policy, so check whether yours already has one before you apply. Nothing in this release needs them, so applying can wait. The own-bucket S3 version grants are split into separately named statements, with the same permissions. design-region-ha feat/hostclaim-door - The scanner host fix is in this release too. It is the freshclam change from v0.24.1. fix/scanner-freshclam-apparmor
- Either roll order works. Nothing in this release needs the console and the boxes to roll in a particular order.
Changes
10-
feat/hostclaim-parkpark: the claim's park engine (claim Plan 4)
Paul Campbell with claude, codex 7f403a77
-
feat/hostclaim-doorconsole, dbdoor: the claim-bracketed pull door (claim Plan 7)
Paul Campbell with claude, codex e1121997
-
feat/hostclaim-boxguardhostguard, stopevidence, cgroup: the box-local host guard and stop evidence (claim Plan 3)
Paul Campbell with claude, codex b37f73e1
-
feat/hostclaim-genselectgenselect: the shared read-only generation selector (claim Plan 7b, F)
Paul Campbell with claude, codex 4d13aec3
-
feat/hostclaim-libraryhostclaim: the host lifecycle claim library (Plan 1, E)
Paul Campbell with claude, codex 99084d7a
-
fix-deploy-rollback-copyconsole: a failed deploy rollback says nothing was rolled back (#229)
-
fix/scanner-freshclam-apparmorscanner-host: run the first freshclam with its packaged config (AppArmor denies any other)
Paul Campbell with claude 592b667a
-
fix-stage-request-deferredhost: a throttled stage request is deferred, not dropped; a blocked stage stays in the fast sweep
-
design-deploy-credentialdeploy-credential: a rung-scoped deploy credential so CI promotes through the console (#229)
Paul Campbell with claude #229 carlos services d1dab9a9
-
design-region-haRegion HA plan 1a: the foundations for running instances on any box in a region
- Nothing new for the CLI. The carlos binary is the same code as v0.24.0. This release only fixes a deployment module.
For operators
-
The scanner host boots. In v0.24.0, a new
scanner-hostbox failed its first boot withSCANNER-HOST FAILED: first freshclam failed 3 times. Debian's AppArmor profile only lets freshclam read its own config under/etc/clamav, and the boot script gave it a copy elsewhere. It now uses the packaged config. A box from v0.24.0 never opened its port, so nothing was ever scanned through it. Pinscanner-hostto v0.24.1 and replace the box withtofu apply -replace=module.<name>.aws_instance.scanner.
Changes
1-
scanner-host: run the first freshclam with its packaged config (AppArmor denies any other)
Paul Campbell with claude f4478b15
-
Canaries have a one-label address, and can be created again. A canary's host is now
<name>-<app>.<your account>.<apps domain>, so canarynew-queueof appjamisnew-queue-jam.bab.oncarlos.com. The old address put a dot between the name and the app. The console refused that, socarlos canarycould not create a canary for an app that runs a process. The name and the app together can be at most 63 characters. You need this release's CLI. fix/canary-one-label carlos canary - Deploys reach running instances sooner on busy boxes. A box notices a promote sooner, and it restarts an awake instance onto the new release on its own two-second check instead of waiting for the rest of its work. On the flagship, noticing a promote had taken 16 to 43 seconds, and the restart then waited about 48 seconds more. fix-converge-own-loop fix-reconcile-listing fix-reconcile-parallel-reads
- An instance never starts without its secrets. A box that cannot open an instance's sealed secrets no longer wakes it or takes it on. A box that can takes it instead. If none can, it does not start. Before, it could start with none of its config or secrets. fix/keyless-box-refuses
-
One address, one app.
carlos instances createandcarlos canaryare refused when another app in your account already holds the host, including an app in the Trash, or when the host is a domain attached to another app. Before, both creates succeeded and one of them served nothing. fix/canary-one-label carlos instances carlos canary - Nothing new to type. The CLI has no new commands or flags in this release.
For operators
-
Check every box's secrets key before rolling the boxes. A box now takes an exec instance only if it can open that instance's sealed config. Without
CARLOS_SECRETS_KEY, or with a key that does not open the config, it does not wake the instance or mint its record. It logsagent: config guard: refusing <host>and lists the host undermetrics.config_refusalsin its private snapshot,status/boxes/<box>.json. A box that cannot read the deployment store to check refuses too, and asks again after 30 seconds. Instances with no sealed config are not affected. fix/keyless-box-refuses -
A box with no deployment store refuses exec instances. With
CARLOS_HIBERNATE_BUCKETset and neitherCARLOS_DEPLOYMENT_BUCKETnorCARLOS_DEPLOYMENT_DIR, a box cannot tell whether an instance's config is sealed, so it refuses. On a deployment with no sealed config at all, setCARLOS_NO_SEALED_CONFIG=1. Never set it on a box that serves tenants. The box then logs that the check is bypassed and says so in its snapshot. With a deployment store configured, the setting is ignored. fix/keyless-box-refuses - Roll the console to this release before pointing it at a scanner host. An older console records an archive that clamd could only partly scan as infected. This release records it as not scanned, and a scan time-out as failed, so the next sweep tries it again. A real signature match is still infected. worktree-scanner-host
-
Object-storage scanning has its own box. The new
infra/modules/scanner-hostmodule runs clamd on one box per deployment, reachable only from the console's security group. Set its outputs on the console:clamd_addrasCARLOS_CLAMD_ADDRandstream_max_bytesasCARLOS_CLAMD_MAX_BYTES. The console also needsCARLOS_SCAN_TAG_KEY, and refuses to boot with an address and no key. Setstore_scanning = trueon the console box'sregion-hostso its role can read and tag store objects. It is off by default, and a deployment that leaves it off plans no change. Wiring the engine does not switch scanning on.carlos system antivirus enabledoes. A replaced scanner box gets a new private IP, so updateCARLOS_CLAMD_ADDRafter any-replace. Pin modules to v0.24.0: v0.23.0 does not containscanner-host. worktree-scanner-host carlos system - The app regions rollback floor is v0.23.0. v0.23.0 is the first release that understands app regions. Once any app holds a region other than the home, do not roll the console below v0.23.0. docs-regions-floor-v0.23.0
-
Boxes can send alerts to SNS. Set
CARLOS_ALERT_SNS_TOPIC_ARNto the box's own region's alerts topic, and anyone subscribed gets each fire and clear by email. The box's instance role needssns:Publishon that topic. The modules in this repo do not grant it. A box with neither this norCARLOS_ALERT_WEBHOOKlogsNO SINK CONFIGUREDwhen it starts.carlos status --livegains a last column:alerts=sns,alerts=webhook,alerts=webhook+sns,alerts=not-delivered, oralerts=sns-unavailablewhen a topic is set but the box could not build its SNS client. A dash means the box runs an older release. feat/alerts-sns carlos status -
Boxes list the bucket by app. To find instance records, a box now lists each account's apps and each app's
instances/prefix, eight requests at a time, instead of every object underapps/. If one app's listing fails, the box logs aprovision: listingline, converges everything it did see, and removes no route on that pass. The agent also logs anagent: fast converge:line when a step of its fast loop takes longer than five seconds. fix-reconcile-listing fix-reconcile-parallel-reads - Either roll order works. Nothing in this release needs the console and the boxes to roll in a particular order.
Changes
8-
fix-reconcile-parallel-readsprovision: read records eight at a time in the reconcile and record passes
Paul Campbell with claude eef3e121
-
fix-reconcile-listingprovision: find instance and sidecar records by walking app directories, not by listing all of apps/
-
fix-converge-own-loophost: the converge leg runs on its own loop; slow fast-loop legs are logged
-
docs-regions-floor-v0.23.0README: v0.23.0 is the app-regions rollback floor
Paul Campbell with claude e58a0d82
-
worktree-scanner-hostspec: scanner host, getting object-storage scanning running on Carloku and Tito
Paul Campbell with claude #235 carlos store scan 562f3dfc
-
fix/canary-one-labelconsole: the instance create door refuses a host another app holds
Paul Campbell with claude #207 #232 carlos canary carlos instances 04cd2d78
-
fix/keyless-box-refusesappconfig: CanProvideConfig, can this box provide an instance's config (#213)
-
feat/alerts-snsDeliver platform alerts to an SNS topic, and say when a box has no sink
Paul Campbell with claude #192 carlos status 6956db67
-
A deploy reaches a running instance in seconds. When a box adopts a new release, an instance that is awake restarts onto it within a few seconds. Before, it kept serving the old build for about two minutes, longer than
carlos deploywaits, so a deploy could report a timeout and a restart seemed to be needed. Instances on one box restart one at a time, two seconds apart. fix-adopted-exec-restart carlos deploy - Static sites show a deploy on the next page load. Browsers now check with the edge before reusing a page or file from a static site, and get a quick "not modified" answer while nothing has changed. Before, a browser could keep showing the old page for hours or days after a deploy. static-cache-control
-
Read a copy of an instance's database.
carlos db pull --app <a> --out <file>saves a copy of a sleeping instance's database on your machine, andcarlos db query --app <a> --sql "…"runs one query against a fresh copy. Both say how recent the copy is. The copy is read-only and never touches the live database. Name an instance with--instancewhen the app has more than one. feat/carlos-db-read carlos db -
Region flags.
carlos apps create,carlos deployandcarlos canarytake--region. A console that is not assigning app regions yet says so and starts the app in its home region.carlos deploy --regionon an existing app stops before shipping if the region differs from the app's own. The linecarlos instances createprints now names the place the instance runs. design-nearest-region carlos apps carlos deploy carlos canary carlos instances - Invite links ask before you join. Opening an invite link shows who invited you and a Join button. Nothing happens until you press it. tenant-iso-leftovers
-
Sending domains you did not set up. If a domain already has a sending identity that your account did not create,
carlos email domains addasks you to prove you control it: publish a TXT record at_carlos-mail.<domain>with the valuecarlos-mail-account=<account>, then add the domain again. A domain another account holds now reads "sending domain unavailable". A claim that is not verified within 7 days can be taken by another account. tenant-iso-mail carlos email -
Stores no longer share a bucket by accident. App and environment names are joined with "-", so app
shopwith environmenteuand appshop-euused to map to the same bucket. The second one is now refused with a 409, and nothing is created. tenant-iso-objstore -
Platform domains. An operator can attach one of the deployment's own domains to an app with
carlos domains attach --platform. Members cannot attach, change or detach those names. platform-domain-claims-209 carlos domains
For operators
- Roll the boxes, then the console. With the new switches left off, either order is safe. The two switches below need every box on v0.23.0 first.
-
Leave
CONSOLE_SECRETS_ENVELOPE_V2off until every box runs v0.23.0. When it is on, the console seals new secrets so they open only for their own account and app. A box on an older release cannot open them, and the app's whole config stops updating on that box. Rolling a box back below v0.23.0 after turning it on does the same. A value that is not true or false stops the console from starting. tenant-iso-binding -
v0.23.0 is the first release that understands app regions. That makes it the rollback floor the README describes: once any app holds a region other than the home, do not roll the console below v0.23.0.
CONSOLE_APP_REGIONSis off by default. Turn it on only by the README's steps. Boxes now publishserves_shared_pool,accepts_inboundand, where they hold the secrets key,secrets_key_fpin their edges file. design-nearest-region - Boxes restart awake instances when they adopt a release. The agent checks every two seconds and restarts at most one instance per check. Workers still converge on the old 90-second timer. A restart drains the old process as before: new requests wait for the new one. fix-adopted-exec-restart
-
Static responses change their headers. They now carry
Cache-Control: no-cacheand a weakETagworked out from each file's bytes and type, and noLast-Modified. The first request for a file after a deploy reads it once to work out the tag. The edge's own cache still does not store static responses. static-cache-control -
Pin infrastructure modules to v0.23.0. The box role gains permission to list, read and delete object versions in its own data bucket. Nothing uses it yet, so applying it can wait. Check also that nothing in your policies denies
s3:DeleteObjecton the deployment bucket: purges, store teardown and mail claim release delete objects, and fail without it. feat/hostclaim-storage -
Run
carlos accounts migratewith a v0.23.0 CLI. Pointers are now signed for their account, and migrating re-signs them, which needs the rootCARLOS_RELEASE_KEY. An older CLI copies them unchanged, and the moved app stops adopting releases. tenant-iso-binding carlos accounts - Existing data is left in place. Purging an app now also deletes its tokens, door keys and ledgers, but apps purged before this release keep theirs. Removing a sending domain that was added before this release leaves its SES identity in SES. Moving an app revokes its door keys, so moved apps need new ones. tenant-iso-leftovers tenant-iso-mail
Changes
14-
feat/hostclaim-storagelease: versioned storage primitives for the host lifecycle claim (Plan 2)
Paul Campbell with claude, codex 3ca43d33
-
static-cache-controledge: static responses revalidate, on a version ETag
-
fix-adopted-exec-restarthost, activator: the agent finishes an adoption the root pass performed
-
fix/console-capturelogconsole tests: untangle #208 and nearest-region on main
-
tenant-iso-mailMail: members can't adopt another party's SES identity; unverified sending-domain claims lapse (#216)
Paul Campbell with claude #216 carlos email be3338d4
-
tenant-iso-leftoversPurge and membership leftovers: credentials, door keys and ledgers end with their app; invite accept by POST (#219)
-
tenant-iso-bindingBind release pointers and secret envelopes to their account; close relay deny-list gaps (#220)
-
tenant-iso-objstoreobjstore: bucket and IAM user names can't collide across stores (#218, #191)
-
platform-domain-claims-209domains: the operator's door for platform hostnames (#209)
-
design-nearest-regiondocs: nearest-region default design spec
Paul Campbell with claude #169 carlos apps carlos deploy carlos canary carlos instances carlos services 3f4a9bfd
-
fix-console-registry-208console: protect shared registry lifetime (#208)
-
fix/199-create-refuses-leftoversconsole: create refuses a host that still holds a deleted instance's replica (#199 stopgap)
-
system-operators-176console: system operators can roll signed platform releases (#176)
Paul Campbell with claude #176 #201 the platform s own binary a7a2aaa2
-
feat/carlos-db-readcarlos db pull and query: read an instance's database from its replica (spec 2026-09-02, unit 1)
- Database size on the app Overview. A new tile shows how much disk your app's databases use, including copies that are asleep. feature/instance-db-stats-card
-
Busy and large instances can finish a move. An instance that is awake and writing, or that keeps large database files, can now finish moving to another region. Before, such a move could wait in
preparingand never become ready. The cut still copies everything that is left, exactly, before the instance serves from its new region. move-ready-delta-threshold - Nothing new to type. The CLI has no new commands or flags in this release.
For operators
- v0.22.1 was tagged but never published. v0.22.2 supersedes it, so roll v0.22.2 and pin modules to v0.22.2.
-
A move becomes ready when little is left to copy. By default, a preparing round now promotes when it copied 16 MiB or less. To change that bar, set
CARLOS_MOVE_READY_DELTA_BYTESin/etc/carlos/host.env; the agent reads it when it starts.0restores the old rule that a round must copy nothing. A value that is not a whole number of bytes is ignored with a log line, and the default stays. The ready log line now shows the bytes copied, the number of changes and the bar. move-ready-delta-threshold -
Copy receipts in the source box's data bucket. A box moving an instance away keeps receipts at
move-receipts/<host>.jsonin its own data bucket, so large objects that have not changed are not copied again. The cut and an abort delete them. A deployment whose data-bucket policy denies DeleteObject keeps stale receipts, which are harmless. The box policy in this repo already allows the prefix. move-ready-delta-threshold - The cut is still exact. It copies everything that is left before it flips the record. If an object changes during that final copy, the cut waits for the next pass instead of landing an incomplete copy. move-ready-delta-threshold
- The Database tile is console only. It reads the database sizes boxes have reported since v0.21.0, so it needs no box roll and no env or IAM change. A slow read shows a dash and never holds up the page. feature/instance-db-stats-card
Changes
2-
move-ready-delta-thresholdlease: MirrorPrefix reports the bytes a round copied
-
feature/instance-db-stats-cardconsole: a Database tile on the app Overview (size on disk, including sleeping copies)
Paul Campbell with claude · Tony Wood with claude #197 abe897e0
Changes
1-
feature/instance-db-stats-cardconsole: a Database tile on the app Overview (size on disk, including sleeping copies)
Paul Campbell with claude · Tony Wood with claude #197 abe897e0
-
Availability, apart from errors.
carlos availabilitylists the requests an app's instances could not answer, every 502, 503 and 504 the edge saw, grouped by cause instead of by page. One outage is one row, however many pages it hit.--fp <id>expands a cause to each request and the path it asked for. The same view is the new Availability tab beside Errors. availability-tab carlos availability -
Errors is shorter.
carlos errorsand the Errors tab keep the app's own 500s and the error lines in its logs. Edge 502s, 503s and 504s, failed wakes and exits have moved to Availability. availability-tab carlos errors -
Replica instances.
carlos instances create --role replica --region <r>makes a second instance of an app, holding a one-way copy of the live instance's data, in a region near its buyers. The live instance names the regions it allows replicas in with--replicas ie,ukwhen it is created. Until a batch of orders drains home, a replica holds order data in its own region, so the regions are always a decision on the live instance, never a default. edge-replica-placements carlos instances -
Door keys.
carlos instances door-key create,listandrevokemanage keys for the edge-local door. That is one socket on a box that a process running beside an app's instances can dial to reach any of them, whether it is asleep, moved to another box or awake. A key is shown once, when it is created. The door is off until the box's operator turns it on. instance-moves-p7 carlos instances -
Faster log reads. Log chunks are now fetched 16 at a time instead of one by one, which speeds up
carlos logs, Errors and Availability. parallel-chunk-read carlos logs - A restored app keeps its pipeline. When the console registers an app whose files are already in the bucket, it keeps that app's release pipeline instead of resetting it to the default. fix/preserve-adopted-app-pipeline
For operators
- Roll the console first, then the boxes, close together. The boxes record why the edge had no answer and the console shows it. A console on its own groups stored 502s under "cause not recorded", and new ones too until the boxes roll. Boxes on their own, under an old console, list each cause as its own row on Errors. Rolling the console back is safe: nothing in the bucket is rewritten. availability-tab
-
A new CLI against an old console.
carlos availabilityfails withnot found: check --account and --app, and that your token's address is a member. Until the console rolls, that message means the console predates the command, not that the app or your membership is missing. An old console silently ignorescarlos instances create --role replicaand creates an ordinary instance in that region instead. availability-tab edge-replica-placements carlos availability carlos instances -
No replicas until every box has rolled. Only this release keeps replicas out of DNS latency routing. Each box adds two columns to its registry when it starts (
routes.replicasandroutes.replica). There is nothing to migrate, and a box rolled back ignores them. edge-replica-placements - Long polls show up in Availability. A visitor who gives up after waiting five seconds or more, before the instance has sent response headers, is filed as an outage. On a sleeping route the five seconds include the wake. An endpoint that holds its headers longer by design, like a long poll, shows a standing row, and that row is expected. A visitor who leaves sooner is no longer filed at all, so expect fewer one-off 502s on static files. availability-tab
- Tunnelled failures are filed once. On a route a box reaches over a tunnel or a fleet, the front box files only its own hop failures, and the box serving the app files the rest. availability-tab
- Instance moves. A box cutting a move now fences the instance so a scheduled wake cannot start it again mid-move. A move past ready can no longer be aborted, and a replica cannot be moved: delete it and create one in the new region. A later release's boxes rely on this console's abort rule, which is one more reason to roll the console first. instance-moves-p0
-
The edge-local door is off by default. It stays off until a box sets
CARLOS_EDGE_DOOR=/run/carlos/edge-local.sockand its agent restarts. The calling process's user must also be enrolled withcarlos bootstrap --socket-consumer <user>. The console re-signs door keys every 12 hours, and a key whose record has not been re-signed for 72 hours stops working, so a console down that long closes every door. instance-moves-p7 carlos bootstrap -
Each instance gets its own
/dev/shm. Instance units no longer see the host's/dev/shm, so an instance cannot reach another's shared memory. They also no longer setRestrictSUIDSGID=, which brokeopenat2on systemd 257 and kept the isolated exec probe from reporting ready.carlos system updateinstalls the new units, and a running instance picks them up when it next restarts. isolated-exec-probe-fixes carlos system
Changes
13-
fix-worker-store-boundsBound worker assignment storage versions and reject enabled no-op writes
-
docs-carloku-infra-splitAGENTS.md: the flagship root lives in carloku-infrastructure, pinned to release tags
Paul Campbell with claude e8406ce6
-
instance-moves-p7instance moves P7 (#175): the edge-local door, dormant until CARLOS_EDGE_DOOR
Paul Campbell with claude #175 storage of its own for every instance 88abfae2
-
isolated-exec-probe-fixesisolated exec: the probe goes ready, and each instance gets its own /dev/shm (#126)
-
instance-moves-p0instance moves P0 (#175): fence the cut against tick wakes, refuse abort past ready, refuse moving a replica
-
fix/preserve-adopted-app-pipelinePreserve existing release pipelines when restoring app registration
Paul Campbell with codex 4d5eab8a
-
amadan-agent-skill.claude: install amadan's agent skill; ignore local Claude settings
Bill Horsman with claude 8c54ec7a
-
release-notes-v0.22.0README: operator note for v0.22.0 (Availability, replica placements)
Bill Horsman with claude 2158949f
-
refs-designspec: request references — one ID a customer can read out, and we can find
Bill Horsman with claude 1786da9c
-
agents-amadan-source-of-truthAGENTS.md: amadan is the source of truth; squash before landing
Bill Horsman with claude f50e3425
-
availability-tabAvailability: edge 502/503/504 grouped by cause, on their own tab
Bill Horsman with claude carlos errors carlos availability 38639c1e
-
parallel-chunk-readapplog: fetch chunks 16 at a time, assemble in serial order
Bill Horsman with claude 249bbe5e
-
edge-replica-placementsprovision, edge: replica placements — the routing half of edge checkout (#162)
Paul Campbell with claude #162 carlos instances b5b0a53a
-
A new address is never a dead end. An edge that hasn't heard of a host under the deployment's own domains yet answers 503 with
Retry-Afterand a page that tries again on its own for 90 seconds, instead of "unknown host". Edges also learn which box serves a new host within about 30 seconds, down from as much as six minutes. edge-unknown-host-174 - The release recipe is in the README. "Releasing the platform" now walks through tagging, building, signing, publishing, Homebrew and apt. docs-release-recipe
Before you roll
-
On an edge started with
-fallback, a mistyped or retired subdomain under a platform domain now reaches the fallback URL only after the 90-second retry page, and only in a browser. curl, crawlers and monitors see the 503.
Changes
2-
docs-release-recipedocs-release-recipe
Paul Campbell with claude 8138d942
-
edge-unknown-host-174edge-unknown-host-174
Paul Campbell with claude 055ed3b6
-
Named deploy destinations.
carlos config destinationskeeps the places an app deploys to in.carlos/config, andcarlos deploy -d <name>picks one. config-destinations-cli carlos-deploy-targets carlos config carlos deploy -
Sidecars.
carlos sidecarsruns a process beside each enrolled member of an app, such as a document converter. it takes enable, create, ls, wake, rm and logs. sidecar-members sidecar-engine-capability carlos sidecars -
Email you can follow.
carlos email eventsshows what happened to each message an app sent (delivered, bounced, complained about or delayed) for 30 days.carlos email events pushposts those events to the app itself, signed.carlos email domains rmstops an app sending from a domain and frees the domain for another account once no app uses it. mail-events-log mail-events-push carlos email -
A store per environment.
carlos store create --environment <e>gives one named environment its own bucket and credential, delivered into that environment's config. an app can now have each instance get its own environment and store. per-instance-store 412-storage-isolation-config carlos store -
Purge every host of an account at once.
Carlos-Purge-Hostnow takes a list of up to 32 hosts, each checked against the same app and account. a host the box doesn't serve is skipped. The control socket'sPOST /purgetakes{"path":"*"}to clear the whole host. edge-purge-hosts-173 - Faster edge start on distant boxes. certificates now load in parallel at boot, so a box far from its bucket no longer fails its update check. fix-edge-boot-refresh
Before you roll a console to this release
-
The control-plane role needs
ses:CreateTenantResourceAssociationandses:DeleteTenantResourceAssociation. email sender records have moved toemail/senders/app.json, and a console rolled back after the first write loses any pause or rotation made since. -
Every config pass now lists each app's
instances-config/prefix. an IAM policy that narrowss3:ListBucketby prefix will freeze that app's config until the listing succeeds, so check a hand-edited policy first. look forinstance config unresolvedin the box log.
Changes
23-
edge-purge-hosts-173edge-purge-hosts-173
Paul Campbell with claude 0d2fdd44
-
email-domains-rmemail: release a sending-domain claim without deleting the app
James Adam with claude carlos email 413256dd
-
412-storage-isolation-configApp policy: every instance gets its own environment and store (#412)
James Adam with claude storage of its own for every instance carlos services 1c4ee673
-
per-instance-storePer-environment object storage: a store an instance can own
James Adam with claude #140 #159 #172 a store for one environment 1447716c
-
worktree-instance-configappconfig: the instance config layer's key, host rule and etag-returning reader (plan 4, task 1)
Paul Campbell with claude eb9ba0fe
-
worktree-tenant-email-sendersDesign: tenant email senders (#147, #148)
-
sidecar-engine-capabilitycaps: doc-engine capability for document-conversion sidecars (Gotenberg, OCR)
-
fix-edge-boot-refreshedge: fetch the cert mirror's boot refresh concurrently
Paul Campbell with claude 1b48ed5e
-
fix/timer-rearm-completionPreserve timer replacements across in-flight delivery completion
Paul Campbell with claude, codex · James Adam with claude #120 carlos instances carlos routes carlos store carlos relay 203f67a9
-
config-destinations-clicli: carlos config destinations — manage deploy destinations
James Adam with claude #157 carlos auth carlos config deploying one checkout to several places 1643418d
-
fix-system-apply-dirshost: create the relay's state dir on every apply, and arm what the target build asks for
-
reserve-platform-domains-opt-indomains: reserving platform domains is opt-in (CONSOLE_RESERVE_PLATFORM_DOMAINS)
James Adam with claude #156 carlos domains e6773f53
-
carlos-deploy-targetscli: named deploy destinations in .carlos/config
James Adam with claude deploying one checkout to several places 1bcc593c
-
fix/tito-platform-domainsAllow trusted accounts to attach short platform app aliases
Paul Campbell 5abc9ecf
-
docs/infrastructure-approvalRequire scoped approval for production infrastructure experiments
Paul Campbell db79997d
-
sidecar-membersspec: sidecar members — a serving class that nothing can dial
Paul Campbell with claude carlos sidecars 671d3d11
-
worktree-eleven-migrationspec: refresh the Eleven→Carloku design against a week of main
Paul Campbell with claude b7fa9a69
-
instances-trashed-apexAn app's platform apex is its own, whichever arrives first (discussion 153)
Bill Horsman with claude #153 carlos apps carlos instances 520fcc04
-
mail-events-pushemail events push: tell the app itself, signed, at a path on its own host
Bill Horsman with claude #153 carlos email a430d4d6
-
mail-events-logemail events: keep what happened to each message, and `carlos email events` to read it
Bill Horsman with claude #151 #152 carlos email b9b4238d
-
minio-contract-github-sourceci: fetch the pinned MinIO and mc from GitHub — dl.min.io serves nothing now
-
worktree-isolated-exec-specAdd isolated-exec design spec and codex review brief (#126)
Paul Campbell with claude #17 #126 carlos instance control carlos instance exec carlos instance exit carlos instance probe c1d40eeb
-
feat-maintenance-worker-identitySpecify scoped maintenance worker enrollment and publication
-
Self-serve object storage.
carlos store createis the whole path once an account is approved; accounts apply and operators decide through the console. worktree-store-self-serve carlos store - Console instance pages. Instance status, activity and live logs are wired up in the console.
-
Edge reads
s-maxage, so an origin can address the edge cache and the browser cache separately. edge-s-maxage - Maintenance worker. Pinned maintenance subprocesses are supervised; a launch context codec is shared with standalone consumers. feat-maintenance-worker feat-launchctx-module
Changes
4-
feat-launchctx-moduleShare maintenance launch decoding with standalone consumers
-
feat-maintenance-workerValidate private maintenance launch contexts and checkpoint bindings
-
edge-s-maxageedge: read s-maxage, so an origin can tell the two caches apart
Bill Horsman with claude 006e7825
-
worktree-store-self-servespec: self-serve object storage via account apply/approve (#381)
Paul Campbell with claude carlos store 2e26c5f2
Changes
50-
console-ux-12-final-wiringConnect console instance status, activity and live logs
Paul Campbell 16593de5
-
console-ux-11-status-checkstatus: distinguish numeric leaks from timestamp text
Paul Campbell f773b13f
-
console-ux-01-statusconsole: derive deployment status from observed instances
Paul Campbell 64972fd9
-
console-ux-08-cliAdd optional descriptions to CLI mutations
Paul Campbell describing changes 08f27891
-
console-ux-10-actionsAdd app and instance restart controls
Paul Campbell 0bc32c46
-
console-ux-05-deploymentsMake deployments show channel targets and release history
Paul Campbell d73bd1b3
-
console-ux-02-settingsconsole: split app settings into independently saved sections
Paul Campbell f33f3404
-
console-ux-07-activityRecord structured activity descriptions
Paul Campbell with codex cff5c82b
-
console-ux-04-diagnosticsconsole: summarize account mismatches and scope account review
Paul Campbell f4207d3b
-
console-ux-06-logsconsole: filter and follow logs by instance
Paul Campbell 92361249
-
console-ux-03-instancesconsole: add instance details and channel grouping
Paul Campbell 9251082a
-
design-checker-launchSpecify checker-only closed-checkpoint launch context
Paul Campbell d492f628
-
fix-maintenance-admission-orderingBound maintenance admission and isolate scheduled token ordering
Paul Campbell 12e9c809
-
sweep-staged-versionsSweep the staged versions nothing on the box still names (#111)
-
hosting-capability-wireregions: each box answers for its own hosting, and three doors stop sharing one bar
-
design-runtime-signing-r2Specify verified runtime contract execution and writer edge cases
Paul Campbell 2ace60d2
-
design-always-awake-r2Revise always-awake lifecycle ownership and recovery contract
Paul Campbell d2cbfba6
-
design-maintenance-protocol-r2Revise maintenance protocol after independent review
Paul Campbell 4f0e078e
-
design-maintenance-launch-r3Specify private descriptor context for maintenance consumers
Paul Campbell 9969a8fe
-
feat-maintenance-writer-integrationAdd durable host maintenance guards and app lifecycle claims
Paul Campbell 11a30399
-
feat-maintenance-payloadBound encrypted maintenance input without rewriting signed JSON
Paul Campbell 9bf83ba6
-
feat-release-conditional-deleteAdd optional revision-conditional store deletion
Paul Campbell 8746297d
-
feat-maintenance-envelopeAdd recipient-bound private maintenance envelopes
Paul Campbell d43d971b
-
fix-relay-meter-waitWait for relay accounting after packet delivery
Paul Campbell b39d1efa
-
design-maintenance-execDraft exec instance maintenance boundary and review prerequisites
Paul Campbell 05c877f9
25 more
-
relay-syncexec-test-fixappconfig: the multi-upstream SyncExec test passes the ack parameter
Paul Campbell with claude dcf0cad3
-
relay-stun-turn-implplan: stage 4a relay implementation plan
Paul Campbell with claude carlos relay 4316089d
-
worktree-password-gatespec: password gate — a shared password in front of an instance
Paul Campbell with claude carlos instances carlos gate df7d1d25
-
analytics-step2plan: analytics step 2, counting at the edge
Paul Campbell with claude carlos analytics 40c6ab73
-
appconfig: deliver to multi-upstream exec routes (#391)
Paul Campbell 8e16153d
-
Sync GitHub mirror to amadan main 1a99060
Paul Campbell with claude #113 carlos errors a8f0d04f
-
Sync GitHub mirror to amadan main d1cfc65
Paul Campbell with claude carlos store scan carlos system the platform s own binary deployment wide object scanning 1a44a30d
-
Sync GitHub mirror to amadan main d2216ee
Paul Campbell with claude #6 #17 #19 carlos store scan carlos system f42bf583
-
Sync GitHub mirror to amadan main d1cfc65
Paul Campbell with claude #6 #7 #8 #9 #10 #11 #13 #16 #17 #110 carlos apps carlos deploy carlos restart restarting less than the whole app carlos env 52b398ab
-
console: the architecture page is one picture per region, stacked (#390)
Paul Campbell with claude d72ac7f8
-
purge-path-routed-hostsLet a path-routed app purge its own cache
Paul Campbell with claude eb721282
-
console: the architecture page reads as two estates, not one (#387)
Paul Campbell with claude 505addb6
-
path-based-routingPath-based routing: one hostname, many upstreams
Paul Campbell with claude 6a594976
-
instances: let a route name its own config bundle, so a canary can accept a POST (#385)
Paul Campbell with claude carlos canary carlos env carlos instances f7ac3aaf
-
canary: fill the reserved verb with the sugar over what already works (#384)
Paul Campbell with claude carlos canary everything else 537c4a1e
-
host: mark a served catch-all as an alias, so it stops refusing itself (#382)
Paul Campbell with claude ceecb3a9
-
static sites: name the shape mismatch instead of denying the promote (#380)
Paul Campbell with claude carlos promote f975b47c
-
AGENTS.md: pushing main to amadan is the last step of landing a change (#377)
Paul Campbell with claude 97eb53fb
-
docs: the instance service role provisions instances, it does not just read them (#373)
Paul Campbell with claude #4 carlos services 7f7f9417
-
instances: a first instance follows the app's pipeline entry, not stable (#372)
-
Scheduled ticks must not hold an instance awake (#371)
Paul Campbell with claude f10d8e1d
-
carlos-skills-cmdcli: carlos skills — list and fetch the published agent skills
Paul Campbell with claude carlos skills 32e8662d
-
cert-sweepdomains: the Settings page's state, the claim-fold cache, and the cert sweep (#299 §3f, #173, #243)
Paul Campbell with claude 5ef69c6b
-
cert-warm-outcomeswarm outcomes: the platform can say a certificate FAILED (#299 §3e)
Paul Campbell with claude c5e33287
-
trash-route-removalA trashed app's routes are retired on every box, and static platform hosts are steered by default
Paul Campbell with claude carlos steering c3f021d3
Release notes
Region residence: instances know where they live, and can move
This release is about placement. Three pieces land together (platform #329, #331, #346):
- Armed-placement validation on instance create (#329). Creating an instance names a region, and the console now refuses a code that is not armed on the deployment instead of provisioning into nowhere. Each box's
edgesfile publishes its own placement code, and every exec child inherits it asCARLOS_REGION, so an app can tell where it is running without asking anyone. - Two-phase, data-following instance moves (#331).
POST .../instances/{host}/moverequests a move to another armed region; the host prepares in rounds, mirroring the instance's replica prefix into the destination's staging bucket until the copy is current;POST .../move/cutthen cuts over, with a re-checkpoint at the cut so nothing written in the gap is lost.DELETE .../moveaborts cleanly at either phase. Staging wins over a stale local copy, a failed fallback is a hard fail rather than a silent downgrade, and a serial nudge on every box-side write means the cut chain converges in seconds rather than five-minute hops. - The armed-regions endpoint (#346).
GET /api/cli/apps/{account}/{app}/regionsreturns the deployment's regions with theirarmedstate, the home region's name, and the default, so pickers in the console, the CLI, and consumer apps draw from one list.
Also in this release
served_byon instances (#337): an instance row now carries where it is observed to be served (the edges that actually join it), beside where it was placed.- Control and edges files carry placement + data-bucket coordinates, so a box and its peers can locate each other's replica prefixes without a console round trip.
sibling_staging_arnson theregion-remote-hostand region-host Terraform modules: the push-onlymoves/*grant that lets a host stage into a sibling region's bucket and nothing else.carlos-app@units can no longer reach IMDS (#351/#352); ahost_roledrop-in re-opens it for the apps that need instance credentials.
The operator CLI verbs are unchanged from v0.16.0; the new surface is on the console API and in the host, edge, and activator halves of the same binary.
Changes
6-
regions-endpointinstances API: armed-regions endpoint + flat move views + the home region's name (#346)
Paul Campbell with claude e6c3bf9a
-
move-serial-nudgemoves: serial nudges — cut chain in seconds (#331 rehearsal measurement)
Paul Campbell with claude 223fc566
-
mirror-skips-the-leasemirror: skip the lease's lock.json (#331 rehearsal catch)
Paul Campbell with claude ae64ea53
-
instance-movesInstance moves: two-phase, data-following residence moves (#331)
Paul Campbell with claude fa5ba8e4
-
idms-gatecarlos-app@ units can no longer reach IMDS; host_role drop-ins re-open it
Paul Campbell with claude 08d4a489
-
region-at-the-doorregion at the door: armed-placement validation on instance create + CARLOS_REGION to exec children (#329)
Paul Campbell with claude d56ac003
Release notes
carlos features — app feature flags on the deployment object
The headline: carlos features set and carlos features list (platform #347, PR #350). An app's own feature flags — switches the app defines, the platform stores, serves and audits, but never interprets:
carlos features set --app titogo sandbox=on
carlos features list --app titogo
key= with nothing after the equals clears a key. The app reads the map off the deployment block its instance token already fetches (beside managed_domains), so a change lands on the app's next poll — no restart, no env edit, no root-owned file on an edge box. Setting is an admin-role write; the app's own credential can read its flags but never set them.
Also in this release
- Custom domains grew a lifecycle (#299, #325, #328):
carlos domains listrows now carry one derivedstate(checking,pending-dns,misdirected,issuing-cert,live,unknown) with areason, structuredrecords[]telling you exactly which DNS records to create, and achecked_atfreshness stamp; the answer's self-describingdeploymentblock says what the deployment manages. A per-host read (GET .../domains/{host}under the hood) makes single-hostname refreshes cheap. carlos deployis stricter about what it claims: it refuses a git-derived version from a dirty tree, and watches the app's own build report rather than an edge header.carlos apps creategained-control-planeand-build-probe.
Changes
19-
feature-flagsApp feature flags on the deployment object — `carlos features` (#347)
Paul Campbell with claude carlos features 9a056e54
-
reliability-followupsReliability follow-ups: #344 account tie-break + config-delete guard, spawn-seam tier pin, OOM polish
Paul Campbell cf772129
-
cp-instance-doorsGuard the provision-record lifecycle: creating, mutating or removing a record for a control-plane app transfers or destroys reconciler authority over its route. Removal refused outright; creation and mutation refuse a service principal only. Found mid-rollout — the console cannot become instance-backed until this exists.
Paul Campbell with claude d27e2f01
-
reliabilitymemwatch: publish to the box's placement region
Paul Campbell 0ac8c98a
-
reliabilitycgroup: bound memory.swap.max with memory.max (zram made the cap escapable)
Paul Campbell d86a5c16
-
rails-poc-hostname-postscriptspec: Rails PoC postscript — hostname configuration closed, edge hostnames live
Paul Campbell with claude 6e189a5c
-
instances-served-byinstances API: served_by — observed per-instance placement from control/edges (#337)
Paul Campbell with claude 9ee32f64
-
reliabilityMemory pressure containment: edge wall, per-app caps, memwatch, module alarm
Paul Campbell c2054152
-
rails-behind-edge-poc-specdocs: Rails-behind-the-edge PoC — design record + implementation plan
Paul Campbell with claude 2ca7d60f
-
box-machine-joinThe box tells us which machine it is
Paul Campbell with claude eb69ae64
-
runbook-r1-three-deliveriesR1 is three deliveries, not one — the root binary carries the adoption fix and roll-console.sh never touches it.
Paul Campbell with claude b0da3d86
-
domains-per-host-doorconsole: a per-host domains read, so a refresh is not a deployment-wide scan (#299)
Paul Campbell with claude c135cccc
-
console-as-an-appThe console is an app: carlos deploy -app console, and a rollback that leaves the box running.
Paul Campbell with claude carlos apps fd4b8f4a
-
ses-event-pathCount deliveries, and say when a topic is refused. Closes the first two of #270.
Paul Campbell with claude 0489037c
-
custom-domains-manageddomains: managed custom-domain connections — one state, structured records, capability discovery, and platform-provisioned certs (#299)
Paul Campbell with claude 039c0645
-
mail-configset-reconcileVerify reconciles the configuration set in both directions, closing #272.
Paul Campbell with claude 72ed99ec
-
mail-refresh-policiesGrant before bind: domains add must not 554 the app it repairs.
Paul Campbell with claude 0d3cf9de
-
pipelines-v2-residualspipelines v2 follow-ups: ratchet-backed bake verdicts, one-channel canary visibility, execution re-checks
Paul Campbell with claude 1fb7fecb
-
arch-legibilityarch page: alarms ride the node they watch, text fits its box, BYO boxes carry no price
Paul Campbell with claude 35666a40
Release notes
CLI flag conventions
The documented face of every carlos command now says --app. Both spellings have always parsed identically — Go's flag package treats -app and --app the same — so this release changes what the tool teaches, not what it accepts: usage pages, docs, and error messages all show the double-dash form, and the four flags you type all day gain short aliases:
--app, -a --channel, -c
--environment, -e --version, -v
The old single-dash spellings (-app, -channel, …) keep working forever; nothing you have scripted breaks. Every command's -h page is now generated from the live flag set through one usage printer, so a usage page can no longer drift from what the parser actually accepts. (#321)
Licence
The platform source is now MPL-2.0, following the redaction pass ahead of the repository going public. (#317)
For operators
The same binary is the edge, the host agent, and the console, so this tag also carries fleet-side work:
- Non-issuer certificate backfill (#320, #318): certsync backfills certificates into
control/certs/on every contending box, not just the issuance winner, with identity settle stamps — a box that never wins issuance still converges the certificates it serves. - Delegated customer wildcards on every edge (#311, #305): the edges file publishes delegated wildcards and every edge loads them, closing the last name-scope gap for serving custom names through region edges.
- Fleet architecture page (#237): the console renders
/fleet/architecture, an architecture diagram drawn from a provider-neutral inventory of the fleet.
Nothing in this tag changes what existing scripts parse — -app and friends behave exactly as before.
Changes
5-
cli-flagsCLI flag conventions: --app canonical, four short aliases, one usage printer
Paul Campbell with claude carlos auth carlos apps carlos ship carlos promote carlos deploy 4235e9fd
-
nonissuer-cert-backfillcertsync: backfill on every contending box; identity settle stamps (#318)
Paul Campbell with claude 9f3cf41e
-
fleet-diagramFleet architecture diagram: /fleet/architecture over a provider-neutral inventory
Paul Campbell with claude 65c6956e
-
open-source: MPL-2.0 licence and redaction pass ahead of going public (#317)
Paul Campbell with claude 2adc71f3
-
delegated-wildcards-deploymentedges file: delegated customer wildcards are published and loaded on every edge (#305)
Paul Campbell with claude 2aaf747b
Release notes
carlos economics backhaul
What serving through region edges costs the platform. When a request lands on a region edge and is carried on to the account's home box, the inter-region leg is a cost the platform absorbs — it sits inside the account's egress total, never on top of it, and appears in nobody's bill. This verb is the operator's view of that leg:
carlos economics backhaul [-period mtd|last|7d]
Per account: bytes backhauled, the share of that account's egress it represents, and what the leg comes to at the rate card's inter-region $/GB. The header shows the period's coverage (days of meters present) so a partial month reads as one. Backhaul meters are a subset of the egress meters and are never counted as usage. Operator only — a non-operator's token gets the same bare 404 an unknown route gets. (#288, #284)
carlos economics with no sub-verb now lists both bill and backhaul.
Multi-region ingress, hardened
The same binary is the edge and the host agent, so this tag also carries the steering work that has been rolling out across the fleet:
- Custom domains through any edge (#287): the edges file publishes attached custom domains under their own names, aliases are marked on the wire, routes win collisions, and the config layer denies entry for names that must not be published.
- Wildcard parents (#300, #290): derived from the deployment's hosts — provisioned routes as well as console-minted ones — with the class mark on the wire, a serialized refresh, and an async wake that is blind to catch-alls.
- Per-box domain health stamps (#303, #304): run on every box again, once per tick, never on a fleet box, inert without an apps domain; a resolver failure never overwrites a DNS verdict.
- Certificate backfill (#291, #297): the issuer backfills pre-existing certificates into
control/certs/, with the settled stamp pinned on the bucket side. - Domains reconcile is a housekeeper duty (#289): one writer per deployment.
- Snapshot fingerprint ignores the box's own scheduling stamps (#207), ending a churn where every tick looked like a change.
Docs
Two docs sites (carlosframework.com/docs, carloku.com/docs) now build from a corpus in this repo, with a gate that holds the CLI reference to main.go's dispatch switch — every command must have a page, every fence a language, every link a target.
carlos economics backhaul needs a console running this build or later; everything else in this tag is fleet-side and already rolled.
Changes
9-
hop-readereconomics: what backhaul costs us — meters, pages, API and CLI (#288)
Paul Campbell with claude carlos economics 845a850c
-
aliases-in-edges-fileedges file: publish attached custom domains under their own names (#287)
Paul Campbell with claude 5e9b918c
-
domains-health-per-boxdomains: the per-box health stamps run on every box again (#303)
Paul Campbell with claude 6340c9e1
-
docsdocs: carlosframework.com/docs — the corpus, six gates, and the CLI reference
Paul Campbell with claude your apps carlos auth carlos apps carlos ship carlos promote e9628b7d
-
wildcard-parents-deploymentedge: wildcard parents are derived from the deployment's hosts, not the box's (#300)
Paul Campbell with claude da9a7eeb
-
snapshot-fingerprint-churnregistry: SnapshotFingerprint ignores the box's own scheduling stamps (#207)
Paul Campbell with claude cbb65607
-
cert-backfillcertsync: the issuer backfills pre-existing certs into control/certs/ (#291)
Paul Campbell with claude 3e8a6759
-
wildcard-parents-provisionededge: wildcard parents from provisioned routes too (region edges served no wildcards)
Paul Campbell with claude d6cd0e90
-
domains-loop-housekeeper-dutyhost: the domains reconcile is a housekeeper duty (one writer per deployment)
Paul Campbell with claude d7eba3e5
Release notes
A static site gets a URL from the CLI alone
carlos deploy -kind static with no -host now mints the app's own platform hostname — <app>.<sqid>.<apps-domain> — and the static route record that serves it. Publishing a site no longer requires owning a domain or pointing DNS at anything:
carlos apps create -app mysite
carlos deploy -kind static ./dist
Everything it needs was already there: DNS under the apps domain resolves to the edge at any depth, and the edge derives its own per-account wildcard certificate from the live route table. The missing piece was a record, and now the CLI writes one.
-host still does exactly what it did — it now means "serve on this hostname instead of the app's own", and remains the answer for a domain you control.
carlos instances set-channel
The only door onto which release channel a route follows. A route's channel lives in its instance record, which the box converges from every pass, so carlos route -channel on a box is reverted within seconds — and until now nothing else could change it. A route that landed on the wrong channel had a URL that served nothing and no way back.
carlos instances set-channel -app <a> -host <h> -channel <c>
A move must clear the rules of both channels it touches, each at its strictest, because a move can achieve a promotion: with production requiring approvals and edge requiring none, moving the production route onto edge would otherwise serve unreviewed code from a guarded URL with nobody's approval. Gated moves are proposed and confirmed in the console, exactly like a promote.
carlos instances create -kind
instance (default) | service | static — exposing the route class the record shape has always carried.
carlos schedule
Recurring and one-shot work per app, owned by the platform rather than by a
box's crontab: carlos schedule ls | set | rm | run. Landed in #285 and
included in this tag; boxes and consoles are already rolled for it.
Requires a console running this build or later for set-channel; the static mint works against any console with a platform apps domain configured.
Changes
7-
static-cliA static site gets a URL from the CLI, and a route's channel can change
Paul Campbell with claude ee76d394
-
cronScheduled work: recurring schedules and one-shot timers as a platform concern
Paul Campbell with claude 2fb300b1
-
egress-and-minting-rulingsmulti-region: backhaul egress ruling (cap + hop metering) and the #277 cert-gate fix
Paul Campbell with claude 6a861ce1
-
retire-github-ciRetire the GitHub workflow: amadan CI is the gate now
Paul Campbell with claude 1010be20
-
amadan-ci-minioamadan CI: port the minio-contract job, without a container runtime
Paul Campbell with claude cd47f38f
-
amadan-ci-one-definitionamadan CI: one definition of the gate, so gofmt is actually checked
Paul Campbell with claude ae6a1824
-
amadan-ci-cross5amadan CI: cross-compile all five targets, not three
Paul Campbell with claude a0e1b911
Release notes
Tenant email — carlos email
An app on CARLOS can now send mail without running an MTA or holding a cloud key. The platform mints a sending identity, publishes DKIM, SPF and DMARC where it owns the zone, and delivers working SMTP credentials as config.
carlos email enable -app <app>
That is the whole walk: declare, provision the domain, wait for verification, deliver. The identity defaults to the app's own host, so the signing domain matches the domain of the links inside the mail. Credentials arrive as CARLOS_SMTP_HOST, _PORT, _USER, _PASS, _FROM (rename the set with -env-prefix). Transport is submission on 587 with STARTTLS.
For a customer's own domain, -domain mail.example.com prints the record set for the zone's owner to publish and polls until SES confirms it.
The rest of the surface:
| Verb | What it does |
|---|---|
carlos email status |
What is declared, which domains verified, what was delivered |
carlos email test -to <addr> |
Sends a real message through a throwaway credential, then revokes it |
carlos email domains add |
Add a second sending domain |
carlos email credentials create|list|revoke |
Standalone credentials for something not on CARLOS; the password is shown once |
carlos email rotate [-finish] |
Two-phase key rotation |
carlos email pause|resume |
A deployment operator's abuse brake |
Three things worth knowing
- A freshly minted credential does not work for the first minute or two. SES's SMTP endpoint does not see a new IAM access key immediately, and the symptom is
535 Authentication Credentials Invalid— which reads exactly like a wrong password and is not one.carlos email testnow waits this out; an app's own first sends afterenablewill still meet it. - DMARC passes on the DKIM rail alone. Records are published with
adkim=s; aspf=s, and that strictness is what stops one tenant's signature authenticating another tenant's From address on a shared domain. SPF authenticates but does not align, because the envelope sender is a region-qualified subdomain. So never turn off DKIM signing on a sending identity, and treatp=rejectas safe but unforgiving. - The MAIL FROM subdomain carries its region forever, fixed at first verification. On a custom domain it lives in the customer's zone — the one record CARLOS cannot republish for them.
Also in this release
- Multi-region steering is member-settable and pool-railed.
carlos email statusnames a verified domain that emits no SES events, rather than showing counts that can only ever be zero.
Changes
9-
fix-configset-policyGrants the configuration set the credential sends through, closing #271.
Paul Campbell with claude 04dece9d
-
multi-region-steeringconsole: repair the #259 merge (compile fix)
Paul Campbell with claude a87affbd
-
multi-region-steeringMulti-region steering: latency DNS, health checks, the probe (#238 Part 4)
Paul Campbell with claude ddc2fcc4
-
ses-ingest-fixemail status names a verified domain that emits no SES events, and fixes a latent nil-deref on a nil RegionState.
Paul Campbell with claude ab58c524
-
console-mail-cardConsole Email card on the app Settings tab, mirroring StoreCard.
Paul Campbell with claude c25cd5f6
-
email-followupsFixes carlos email test, which could not succeed at all, and corrects two spec statements the first live send disproved.
Paul Campbell with claude d64deac0
-
emailTenant email sending for CARLOS: SMTP credentials issued by the platform, backed by SES multi-tenancy.
Paul Campbell with claude fe1a31ab
-
docs: AGENTS.md is the canonical agent-instructions file (#260)
Paul Campbell with claude 8fb52b27
-
console: ship budget is 2 a minute, and a refusal says how long (#262)
Paul Campbell with claude deccd44f
Release notes
Release pipelines: apps start with one edge channel; carlos pipeline (show / init-from-template / add / set / remove) opts into multi-channel pipelines with per-channel bake windows, passkey and N-member approval rules. carlos promote/rollback propose gated actions and print where to finish them; -hotfix now works over the API (order bypass only — rules always apply); carlos deploy resolves a pipelined app's entry channel and treats a pending proposal as success, not failure.
Built from platform tag v0.11.0 (main a347034). SHA256SUMS.txt is signed (SHA256SUMS.txt.sig) for carlos update. Windows remains client-only (zip; no self-update).
Changes
7-
edge-beta-stableRelease pipelines v2 — one channel by default, pipelines opt-in
Paul Campbell with claude a347034f
-
multi-region-steering-planplan: multi-region steering (plan 3 of 3, spec Part 4)
Paul Campbell with claude d662f1b6
-
multi-region-backhaulMulti-region backhaul: home maps, mesh key, one-hop dialing, serving classes (#238 Part 3)
Paul Campbell with claude 920d5994
-
multi-region-backhaul-planplan: multi-region backhaul (plan 2 of 3, spec Part 3)
Paul Campbell with claude eab8c788
-
multi-region-ingress-specMulti-region stage 1-2: carry #245 to main
Paul Campbell with claude 66dbc05f
-
multi-region-ingress-specspec: multi-region ingress — TLS at every edge (#238)
Paul Campbell with claude 67fb71d5
-
ci: run the gate on amadan too, with the cross-compiles one per shard (#233)
Paul Campbell d9a643fd
Release notes
Windows
carlos now runs on Windows as a client: carlos login, ship, deploy,
logs — everything that talks to a console or a bucket — from a Windows
workstation against a Linux fleet. Download carlos-windows-amd64.zip (or
-arm64), unpack carlos.exe onto your PATH, and check it against
SHA256SUMS.txt.
Two things to know:
carlos updatedoes not self-replace on Windows. Windows cannot rename a new binary over a running.exe, socarlos updatetells you when you're behind and hands you the zip URL instead of swapping itself.- Your credentials file is not permission-protected on Windows. On Linux and
macOS
~/.carlos/credentialsis written0600; the equivalent mode means nothing on%USERPROFILE%\.carlos\credentials. Don'tcarlos loginon a shared machine.
Windows cannot BE a box — carlos agent and the root-side passes need unix
sockets, flock and systemd, and refuse there rather than pretending.
Also in this release
105 commits since v0.9.0, including:
- Service principals (#227) — non-human members that deploy.
- Edge response compression (#224, #230) — gzip on the shared edge.
- Logs terminal pane (#209) in the console.
- SQLite corruption defence (#200) and replica/hibernate freshness work (#211, #214, #213).
- Wake single-flight (#199), fleet claims (#215), economics account names (#203).
Verifying
Every artifact's checksum is in SHA256SUMS.txt, signed with the CLI-update key
as SHA256SUMS.txt.sig — the same signature carlos update checks against the
public key embedded in the binary.
sha256sum -c SHA256SUMS.txt --ignore-missing
Changes
20-
windows-releasewindows: a client-only carlos, behind per-OS boundaries
Paul Campbell with claude 4167d5b4
-
service-rolesService principals: a console API caller that is not a person
Paul Campbell with claude e934cb51
-
specs: app trust classes + private instances, ahead of their code (#231)
Paul Campbell with claude 59d2d435
-
fix-gzip-verify-commanddocs: gzip verify command needs a GET, not curl -I
Paul Campbell with claude 377d533f
-
gzip-assetsEdge response compression (gzip)
Paul Campbell with claude 09e6b5e5
-
logs-terminal-paneconsole: the Logs tab is a terminal, not a table
Paul Campbell with claude 89b6bbc2
-
worktree-184-wake-singleflightactivator: failed wakes are singleflight — the initiator waits on its own entry (#184)
Paul Campbell with claude d7077d17
-
corruption-doc-updatedocs: record the currency question and the cutover blocker
Paul Campbell with claude f5c5d07a
-
fleet-claims-onlylitestream: the glob proposes, the registry disposes
Paul Campbell with claude d63a566c
-
hibernate-freshnesshibernate-verify: the same currency question as the box-wide drill
Paul Campbell with claude c2466bf6
-
unit-tenant-db-treeslitestream: unit-tenant DB trees, and refuse to shrink the replication set
Paul Campbell with claude dd04065e
-
titogo-bugsRoute-scoped config delivery: exec_delivery per environment, fast rebinding convergence, carlos routes
Paul Campbell with claude 5bef643f
-
replica-freshnessrestore-verify: prove the replica is CURRENT, not merely restorable
Paul Campbell with claude 0ed1ed12
-
claudemd-merge-ruleCLAUDE.md: agents may merge a PR; the rule is about how work reaches main
Paul Campbell with claude b77856a8
-
verify-tmp-rationaleverify drills: correct the tmpfs rationale with what the box measured
Paul Campbell with claude c80b67ef
-
verify-tmp-on-diskverify drills: restore to disk, because tmpfs files are memory
Paul Campbell with claude 72a0c10f
-
sqlite-corruption-defencedurability: drill the replicas nobody drilled, check what we restore
Paul Campbell with claude 104e261a
-
econ-account-namesconsole: economics pages show account names, sqids muted
Paul Campbell with claude 3f28e9f9
-
business-modelCarloku business model: the ladder, the pool, fleet pricing
Paul Campbell with claude c4fb7309
-
gofmt: blank line before the stamped-units banner in agent_test.go (#188)
James Adam 8371cf89
Release notes
The project-defaults release: carlos deploy, alone, is the whole flow (platform#185).
- Zero-arg
carlos deploy: resolves your account and app (offering to create one — named after your directory — in a fresh project), asks for the artifact once, and offers to save it all to.carlos/config. Every deploy after that is one word. - Omitted
-appresolves everywhere: every app-scoped command uses your project's saved app, your account's only app, or asks — same rules-accountgained in v0.7.0. Scripts keep exact errors; explicit flags always win. - Channel ambiguity in
deployis now a numbered choice at a terminal instead of "pass -channel". - Hardening: project-config artifacts are confined to the project tree (a committed config can never ship files from outside your checkout), and save prompts only ever cover what you actually chose.
Built from platform tag v0.9.0. SHA256SUMS.txt is signed (SHA256SUMS.txt.sig); carlos update from v0.8.0 verifies and installs this release.
Changes
11-
worktree-project-defaultsProject defaults: zero-arg carlos deploy, resolved -app, saved state in .carlos
Paul Campbell with claude f906a303
-
worktree-domain-attachDomain attach: self-serve custom domains from Settings, CLI and deploy (#82)
Paul Campbell with claude c42ec0c3
-
ha-posture-specdocs: HA posture ladder + multi-upstream addr routes — design record
Paul Campbell with claude 729cffb0
-
ha-snapshothost: registry snapshot to bucket + auto-recovery alarm (HA rung 0/1)
Paul Campbell with claude 58e65c63
-
multi-upstream-routesedge: multi-upstream health-checked addr routes (#152)
Paul Campbell with claude a49a7cf6
-
worktree-route-recordsroute records: a route's desired state lives in the bucket (#123, #130)
Paul Campbell with claude d754d04e
-
claim-derived-wildcardsClaim-derived wildcard state: delegated parents, catch-all aliases, capability door (Plan C)
Paul Campbell with claude c16f5574
-
unit-economicsUnit economics: metering, cost/profit dashboards, scenarios, CE bill reconcile
Paul Campbell with claude 82832041
-
worktree-route-hostnamesroute hostnames: attach/detach an extra public hostname on an existing route (#151)
Paul Campbell with claude 8f363775
-
worktree-woodstar-carlokuWoodstar → Carloku migration: spec + Plans A/B (docs)
Paul Campbell with claude e03d95b1
-
edge-delegated-wildcardsedge: delegated-challenge wildcard certs (customer domains, zero customer DNS knowledge)
Paul Campbell b56213fd
Release notes
The proactive release: when carlos can see both the problem and the fix, it offers the fix (platform#160, #161, #162).
- Moved consoles are explained, not numbered: a permanently-redirected console produces
this console has moved: old -> new, an offer to log in to the new home, and an offer to repoint your.carlos/config— never again "unexpected response (status 308)". Redirects are never silently followed (a cross-host follow used to drop your credentials into a mystery 401). - Missing logins are offered: run any command while logged out and, at a terminal, the CLI runs the login right there and then continues your command. Scripts keep the exact errors they've always matched.
carlos update: a once-a-day muted hint when a newer release exists, and a verb that updates a plain-binary install after verifying the release's signed checksum list (ed25519 key embedded in the binary) — brew and apt installs are handed to their package manager.update_check: "off"in.carlos/configorCARLOS_NO_UPDATE_CHECKopts out.
This release introduces SHA256SUMS.txt.sig: the checksum list is signed with the CARLOS CLI-update key from here on.
Built from platform tag v0.8.0. Static binaries, no dependencies.
Changes
1-
worktree-proactive-cliProactive CLI: moved consoles explained, logins offered, self-update (#160 #161 #162)
Paul Campbell with claude e52d8ecc
Release notes
The account-discovery release: carlos now finds your account instead of making you guess it (platform#157).
- Omitted
-accountresolves itself (signed-in mode): your one account is used automatically; with several you get an interactive chooser — which can save the pick as the project default in.carlos/config— or, in scripts, an error that lists your accounts. carlos accounts listnow works signed-in from any machine: your accounts as NAME / SQID / ROLE, no box access needed.carlos auth whoamiprints your memberships alongside your identity..carlos/configgains anaccountkey (a console+account pair, honored only for that console); config rewrites now preserve keys written by newer versions.
Built from platform tag v0.7.0. Static binaries, no dependencies; debs install with apt install ./carlos_0.7.0_<arch>.deb or from the apt repo.
Changes
3-
worktree-account-defaultCLI: default -account to your own account; membership discovery (#157)
Paul Campbell with claude 9d1084ec
-
worktree-fleet-apiFleet API surface: the deployment bucket behind the edge (#73)
Paul Campbell with claude a73539fe
-
dashboard-truth-and-scaleDashboard truth + scale: honest health, route-granular mismatch banner, instance list controls
Paul Campbell with claude fb590565
Release notes
Built from carlosframework/platform @ v0.6.0 (79f6fc2). Verify with SHA256SUMS.txt. See the repo README for install instructions.
Highlights: carlos logs — an app's merged log timeline (its own output + platform events: wakes, restarts, and why a wake failed) with time/stream/instance/level/grep/field filters and -f live follow; carlos deploy timeout reports now include the wake reason. Debian packages included.
Changes
18-
deploy-hint-wake-reasondeploy: timeout report carries the wake reason and names carlos logs (#131)
Paul Campbell with claude 79f6fc27
-
worktree-customer-fleetsCustomer fleets: account-attached compute (v1)
Paul Campbell with claude 00c33444
-
worktree-releases-retentionreleases retention: ambient prune for shipped releases (#136)
Paul Campbell with claude e816eba6
-
object-storage-primitiveobjstore: object-storage primitive (#55)
Paul Campbell with claude b7b7a16d
-
carlos-logscarlos logs: an app's merged log timeline with no box access (#131, #78)
Paul Campbell with claude db76025d
-
console-critique-and-ignorekeep the console clarity critique; ignore the root binary and worktrees
Paul Campbell with claude ca7c86b3
-
console-running-and-flowconsole: retire "Machines", and draw the release path as a path
Paul Campbell with claude bdadb3f5
-
worktree-versions-sort-then-fetchconsole/CLI releases: rank versions by manifest stamp before reading manifests
Paul Campbell with claude 8f64abd6
-
console-clarity-batchconsole: clarity batch — health verdict, safety delay, progressive reveal (P0s+P1s)
Paul Campbell with claude a86de88c
-
worktree-deploy-url-outputcarlos deploy: name the destination URL on every path
Paul Campbell with claude 11670ef5
-
worktree-metrics-instances-fixesconsole + agent: instances page gets real readings for exec-backed apps, stops flapping, stops paying the sweep
Paul Campbell with claude 9668d302
-
worktree-issues-69-70-db-pathregistry+cli: db_path rewrites reach running edges; relative -db refused on exec routes
Paul Campbell with claude 934414c8
-
worktree-exec-instance-metricsagent: exec-backed instances get per-instance metrics (#118)
Paul Campbell with claude 5695e88d
-
claude-md-small-thingsCLAUDE.md: deploy reality after the small-things batch
Paul Campbell with claude 332aecaf
-
static-headerStatic routes carry X-Carlos-Version; carlos deploy watches static apps (#112)
Paul Campbell with claude 916cd6b3
-
restart-verbcarlos restart: cycle an app's processes with no box access (#113)
Paul Campbell with claude de23f6ae
-
route-unitRoutes learn the systemd unit that owns their process; adoption cycles it (#110)
Paul Campbell with claude c8b2eed2
-
small-residualsSmall residuals: #58 sibling back-fill, syncable anti-drift, trash serial bumps, concurrent deploy watch
Paul Campbell with claude 40469637
Release notes
carlos deploy — seconds to live
One command from working tree to serving URL: carlos deploy -app <a> <binary-or-site-dir> ships, promotes to the channel your instances follow, and waits until the URL provably serves the new build (the edge's new X-Carlos-Version header, required over 2xx — exit 0 means live). -version defaults to your git short HEAD. On a bake-held production channel it ships, promotes, prints the hold, and exits without waiting — never a bake bypass.
Platform-side (live on CARLOS deployments running ≥ 1fba18f): promotes converge in seconds on every non-baking channel, warm instances restart onto the new build automatically, and brand-new instances stage at first request instead of 503ing.
Also in this release (from #107): carlos releases, version targets (carlos version target), -label/-notes on ship, and semver tags cut when a release reaches stable.
New: Debian packages — carlos_0.5.0_{amd64,arm64}.deb; install with sudo apt install ./carlos_0.5.0_arm64.deb. Homebrew: brew install carlosframework/tap/carlos.
Changes
29-
carlos-deploy-docsdocs: deploy reality — seconds-to-live convergence, console restart caveat
Paul Campbell with claude 7a3d8c15
-
worktree-carlos-deploycarlos deploy: seconds-to-live for every non-baking channel
Paul Campbell with claude · James Adam with claude 1fba18ff
-
worktree-release-versioning-specRelease versioning: targets, labeled iterations, tags with changelogs
Paul Campbell with claude 1c9381d2
-
worktree-instance-socket-consumersInstance-socket consumers: blessed cross-user story for /run/carlos (issue #103)
Paul Campbell with claude 32dec0b9
-
worktree-console-carloku-hostconsole: CONSOLE_REDIRECT_HOSTS — retired hosts 301/308 to the canonical origin
Paul Campbell with claude edbfbc43
-
worktree-console-app-pagesConsole app pages v2: dashboard overview, human ladder, confirm cards, fast instances table, real settings
Paul Campbell with claude dc6a6c34
-
console: send the reader at the API-backed verb, not box-local carlos add (#99)
James Adam with claude 82dbca9d
-
s3compat: one home for S3-compatible quirks; fix CAS on Ceph RGW (#92)
James Adam with claude 6a52ae09
-
lease: honour CARLOS_S3_ENDPOINT, so hibernation (and instance provisioning) works off AWS (#88)
James Adam with claude f3001017
-
CLI: colour the output, but only ever on a terminal (#93)
James Adam with claude 084b86ff
-
echoapp: accept --db, so the reference tenant can boot exec-backed
James Adam with claude 535038f4
-
clearer-command-displaycarlos: group the top-level command list by role
James Adam with claude 9553b7bf
-
ci-build-gateci: run the build gate on every PR, including a darwin compile
James Adam with claude 38b49990
-
worktree-tito-console-rerollhost: fix darwin build — Statfs Bsize is uint32 there
Paul Campbell with claude 40937553
-
worktree-console-redesignconsole: carloku reskin + Heroku-style IA — sections, tabs, and a settings page of one's own
Paul Campbell with claude b918b56f
-
issue-66-api-go-liveConsole API + CLI: bring an app live on its platform domain with a login alone (#66)
Paul Campbell with claude dd87bf67
-
worktree-api-cli-ruleCLAUDE.md: day-to-day admin via API/CLI, direct AWS only for platform work
Paul Campbell with claude 91d03117
-
merge: carlos apps create — app creation over the console API, rate limited (#52)
Paul Campbell with claude 1c32d739
-
merge: per-account wildcard DNS-01 certs — instant TLS for new app hostnames (#60)
Paul Campbell with claude 7302bad8
-
merge: raspberry pi instance host — region pi on the dev platform (#59)
Paul Campbell with claude 7ea697f6
-
merge: app deletion — the trash, the 30-day cooloff, and the ceremonial purge (#56)
Paul Campbell with claude f11e8c5b
-
merge: instance provisioning — placing an instance is a data write, never host surgery (#54)
Paul Campbell with claude 749fc22c
-
merge: app capabilities — a closed vocabulary the platform materializes (#40)
Paul Campbell with claude 09b084d5
-
merge: only a hibernating instance may render as asleep (#30)
Paul Campbell with claude 36ff0206
-
worktree-remote-host-agentRemote host-agent: tunnel route backing, heartbeat metrics, off-cloud bootstrap (#53)
Paul Campbell with claude d6e7d08b
4 more
-
worktree-config-console-apiconfig: env/secrets through the console API, and fast convergence — both halves (issues #43, #44)
Paul Campbell with claude 28874d56
-
worktree-console-default-configcarlos: settable default consoles (~/.carlos/config + per-project .carlos/config)
Paul Campbell with claude 761d3d01
-
merge: console bake controls — the production flag and fast-track (#47)
Paul Campbell with claude 088358d7
-
merge: account names as addresses — /a/amadan resolves, ambiguity is loud, -account-id never guesses (#46)
Paul Campbell with claude 6d5f71ab
Release notes
carlos v0.4.0 — the CARLOS platform binary (edge, host agent, operator CLI). Built from carlosframework/platform @ v0.4.0. Verify with SHA256SUMS.txt. See the README for install instructions.
Supersedes v0.3.0, which was built from a commit predating the console-API CLI merge.
The headline: deploys need no bucket access and no keys in the terminal.
carlos auth login -console https://<your-deployment-console>
carlos ship -account <acct> -app <app> -version <sha> ./<binary>
carlos promote -account <acct> -app <app> <sha> canary/<name>
A logged-in terminal ships and promotes through the console API; the console signs server-side and your account membership is the authorization. channels and rollback work the same way. The direct bucket mode (CARLOS_DEPLOYMENT_BUCKET + signing key, root or scoped) remains for operators and CI, and promote -hotfix is deliberately operator-only.
Also since v0.3.0: host & process monitoring, external-socket advisory, open-ledgers primitive, follow-up hardening.
Changes
8-
ledger-primitiveOpen-ledgers primitive: hash-chained ledger streams, console API writes, fail-closed edge serving
Paul Campbell with claude 3b8e3238
-
infra/region-host: never let a floating AMI replace a live host (#38)
Paul Campbell with claude 0cd91622
-
spec + plan: open ledgers — status.carlosframework.com's full ledger set on a platform primitive (#31)
Paul Campbell with claude 114255c8
-
merge: follow-up fixes — the bake clock leaves /opt, 1xx stops killing the cache, purges ride a host index, unit tenants learn the channel (#33)
Paul Campbell with claude cc933026
-
merge: external-socket advisory — a stray process serving an exec route's socket is now loud (#28)
Paul Campbell with claude b8e930b5
-
merge: host & process monitoring — agent sampler, alerts, operator + owner dashboards (#23)
Paul Campbell with claude 98348152
-
merge: CLI through the console API — carlos ship/promote without seeing the infrastructure (#25)
Paul Campbell with claude 7eb397eb
-
framework design doc: record §4 package-per-directory resolution (#21)
Paul Campbell with claude a8b4ad47
Release notes
Superseded by v0.4.0 — this build was cut from a commit predating the console-API CLI merge, so it lacks
ship/promotethrough the console (bucket-free deploys). Use v0.4.0.
carlos v0.3.0 — the CARLOS platform binary (edge, host agent, operator CLI). Built from carlosframework/platform @ v0.3.0. Verify with SHA256SUMS.txt.
Highlights since v0.1.0:
carlos auth login -console <url>— log a terminal in to a deployment's console.whoami/logoutround it out.ship/promote/channels/rollbacktake-account <sqid|name>— deploys are account-scoped; promote climbs the ladder canary → edge → beta → stable.accounts,env,secretsverbs; scoped release signing keys (release-keygen -scope).
Changes
44-
merge: scoped signing keys — a key that can reach edge cannot touch stable
Paul Campbell with claude b60b18af
-
spec: scoped signing keys — a key that can reach edge cannot touch stable
Paul Campbell with claude f1cc9146
-
merge: opt-in exec config delivery — the app-supervised shape (issue #18, platform half)
Paul Campbell with claude eced477d
-
edge: Carlos-Purge-Host — same-app+account cross-host purge override (#24)
Paul Campbell with claude 5f3b8929
-
rastrillo-ui-addendumspec: rastrillo UI addendum — app shape, reactivity, icons, WCAG 2.2 AA
Paul Campbell with claude dc80c657
-
accounts: a legacy-source migration never moves a qualified pointer backwards
Paul Campbell with claude b1bb191f
-
spec: unit-tenant purge channel — Carlos-Purge response header design (#19)
Paul Campbell with claude be5a9993
-
edge: Carlos-Purge response-header purge channel (#22)
Paul Campbell with claude 8bc97547
-
merge: retire the legacy read-fallback — the runtime reads qualified keys only
Paul Campbell with claude 0ca02f6c
-
edge: per-entry Vary storage — mixed Vary schemes coexist per URL (#20)
Paul Campbell with claude 6846d9af
-
merge: canary TTL — expiry is visibility, never a gate (spec §5)
Paul Campbell with claude 3c7c7bc3
-
carlos env/secrets: exec-backend delivery — the instance-fleet shape (#16)
Paul Campbell 079b0857
-
merge: environments — named config bundles, bound per route (pipelines slice 2)
Paul Campbell with claude 6c8d5fdb
-
merge: edge cache follow-ups — the header class swept, a real Close race, and an honest deferral (#12)
Paul Campbell c8038ae6
-
spec+plan: environments layer on app-config — pipelines slice 2
Paul Campbell with claude c0823de3
-
merge: edge cache-before-wake — bots shouldn't wake hibernated instances (#10)
Paul Campbell with claude 41d99f4e
-
route: a verb to move a route's channel subscription, safely
Paul Campbell with claude de07dac9
-
carlos env/secrets: bucket-backed app config, encrypted at rest (#9)
Paul Campbell 68d06629
-
docs: CLAUDE.md — delegation policy and the rules this repo has paid for
Paul Campbell with claude 98377f22
-
plan: pipelines slice 1 — the ladder, enforced and visible
Paul Campbell with claude a106a581
-
spec: pipelines — channels are maturity, environments are glue
Paul Campbell with claude 6258137e
-
release: pin that canary never jumps to stable
Paul Campbell with claude 97f0561e
-
pipelines slice 1: the ladder, enforced and visible (#11)
Paul Campbell with claude 701bbd40
-
console: passkey step-up for sensitive actions, and account deletion that sticks (#7)
Paul Campbell with claude 13f7ece4
-
accounts: name the legacy key space, so ops apps can leave it (#8)
Paul Campbell with claude 84b40e36
19 more
-
merge: vendor Lucide for the console's chrome
Paul Campbell with claude 771c2f0a
-
merge: carlos auth login — the terminal gets an identity
Paul Campbell with claude cecc01a7
-
spec: passkey step-up via fresh Keymail auth — a stolen session should not be enough
Paul Campbell with claude abd6bcb0
-
merge: the account switcher becomes a dropdown; New account gets its own screen
Paul Campbell with claude 67cccf2a
-
merge: backfill no longer undoes migrations; accounts create requires an owner
Paul Campbell with claude a30a45da
-
merge: membership tooling + sequential account ids
claude fc94c671
-
spec: account ids are sequential — 40-bit random gave 9-char sqids
Paul Campbell with claude 4875560d
-
merge fix: the fast-adopt test learns the account argument
Paul Campbell with claude 5b4e8ffe
-
feat: fast-adopt canary channels every few seconds, not hourly
Paul Campbell with claude 6dce4e88
-
merge: multi-account — accounts as projects, memberships, account-scoped app identity
Paul Campbell with claude 68d6a91c
-
plan: multi-account — eight tasks, read-fallback, migration as a verb
Paul Campbell with claude 0b8caeaa
-
spec: multi-account — accounts as projects, console-minted durable ids, account-scoped app identity
Paul Campbell with claude 81662fb9
-
merge: domains — platform domains, DNS/TLS health, console Domains section
Paul Campbell with claude 5bbf4eed
-
spec: canary minting is static-only; durable account ids gate the rollout
Paul Campbell with claude 02da0129
-
spec: record path routing as future work — the /blog case forces it eventually
Paul Campbell with claude 80d6811b
-
plan: woodstar → flagship (recon complete, execution deferred behind multi-account)
Paul Campbell with claude 3481167c
-
plan: domains — six tasks, frozen sqids, reconciler seams
Paul Campbell with claude 1e1f0481
-
plan: design a platform-dev environment in the repurposed kass AWS account
Paul Campbell with claude 54b487ec
-
spec: domains — account-sqid platform domains, custom-domain health, bucket-manifest accounts
Paul Campbell with claude 81c53beb
Changes
50-
spec + plan: open ledgers — status.carlosframework.com's full ledger set on a platform primitive (#31)
Paul Campbell with claude 114255c8
-
merge: follow-up fixes — the bake clock leaves /opt, 1xx stops killing the cache, purges ride a host index, unit tenants learn the channel (#33)
Paul Campbell with claude cc933026
-
merge: external-socket advisory — a stray process serving an exec route's socket is now loud (#28)
Paul Campbell with claude b8e930b5
-
merge: host & process monitoring — agent sampler, alerts, operator + owner dashboards (#23)
Paul Campbell with claude 98348152
-
merge: CLI through the console API — carlos ship/promote without seeing the infrastructure (#25)
Paul Campbell with claude 7eb397eb
-
framework design doc: record §4 package-per-directory resolution (#21)
Paul Campbell with claude a8b4ad47
-
merge: scoped signing keys — a key that can reach edge cannot touch stable
Paul Campbell with claude b60b18af
-
spec: scoped signing keys — a key that can reach edge cannot touch stable
Paul Campbell with claude f1cc9146
-
merge: opt-in exec config delivery — the app-supervised shape (issue #18, platform half)
Paul Campbell with claude eced477d
-
edge: Carlos-Purge-Host — same-app+account cross-host purge override (#24)
Paul Campbell with claude 5f3b8929
-
rastrillo-ui-addendumspec: rastrillo UI addendum — app shape, reactivity, icons, WCAG 2.2 AA
Paul Campbell with claude dc80c657
-
accounts: a legacy-source migration never moves a qualified pointer backwards
Paul Campbell with claude b1bb191f
-
spec: unit-tenant purge channel — Carlos-Purge response header design (#19)
Paul Campbell with claude be5a9993
-
edge: Carlos-Purge response-header purge channel (#22)
Paul Campbell with claude 8bc97547
-
merge: retire the legacy read-fallback — the runtime reads qualified keys only
Paul Campbell with claude 0ca02f6c
-
edge: per-entry Vary storage — mixed Vary schemes coexist per URL (#20)
Paul Campbell with claude 6846d9af
-
merge: canary TTL — expiry is visibility, never a gate (spec §5)
Paul Campbell with claude 3c7c7bc3
-
carlos env/secrets: exec-backend delivery — the instance-fleet shape (#16)
Paul Campbell 079b0857
-
merge: environments — named config bundles, bound per route (pipelines slice 2)
Paul Campbell with claude 6c8d5fdb
-
merge: edge cache follow-ups — the header class swept, a real Close race, and an honest deferral (#12)
Paul Campbell c8038ae6
-
spec+plan: environments layer on app-config — pipelines slice 2
Paul Campbell with claude c0823de3
-
merge: edge cache-before-wake — bots shouldn't wake hibernated instances (#10)
Paul Campbell with claude 41d99f4e
-
route: a verb to move a route's channel subscription, safely
Paul Campbell with claude de07dac9
-
carlos env/secrets: bucket-backed app config, encrypted at rest (#9)
Paul Campbell 68d06629
-
docs: CLAUDE.md — delegation policy and the rules this repo has paid for
Paul Campbell with claude 98377f22
25 more
-
plan: pipelines slice 1 — the ladder, enforced and visible
Paul Campbell with claude a106a581
-
spec: pipelines — channels are maturity, environments are glue
Paul Campbell with claude 6258137e
-
release: pin that canary never jumps to stable
Paul Campbell with claude 97f0561e
-
pipelines slice 1: the ladder, enforced and visible (#11)
Paul Campbell with claude 701bbd40
-
console: passkey step-up for sensitive actions, and account deletion that sticks (#7)
Paul Campbell with claude 13f7ece4
-
accounts: name the legacy key space, so ops apps can leave it (#8)
Paul Campbell with claude 84b40e36
-
merge: vendor Lucide for the console's chrome
Paul Campbell with claude 771c2f0a
-
merge: carlos auth login — the terminal gets an identity
Paul Campbell with claude cecc01a7
-
spec: passkey step-up via fresh Keymail auth — a stolen session should not be enough
Paul Campbell with claude abd6bcb0
-
merge: the account switcher becomes a dropdown; New account gets its own screen
Paul Campbell with claude 67cccf2a
-
merge: backfill no longer undoes migrations; accounts create requires an owner
Paul Campbell with claude a30a45da
-
merge: membership tooling + sequential account ids
claude fc94c671
-
spec: account ids are sequential — 40-bit random gave 9-char sqids
Paul Campbell with claude 4875560d
-
merge fix: the fast-adopt test learns the account argument
Paul Campbell with claude 5b4e8ffe
-
feat: fast-adopt canary channels every few seconds, not hourly
Paul Campbell with claude 6dce4e88
-
merge: multi-account — accounts as projects, memberships, account-scoped app identity
Paul Campbell with claude 68d6a91c
-
plan: multi-account — eight tasks, read-fallback, migration as a verb
Paul Campbell with claude 0b8caeaa
-
spec: multi-account — accounts as projects, console-minted durable ids, account-scoped app identity
Paul Campbell with claude 81662fb9
-
merge: domains — platform domains, DNS/TLS health, console Domains section
Paul Campbell with claude 5bbf4eed
-
spec: canary minting is static-only; durable account ids gate the rollout
Paul Campbell with claude 02da0129
-
spec: record path routing as future work — the /blog case forces it eventually
Paul Campbell with claude 80d6811b
-
plan: woodstar → flagship (recon complete, execution deferred behind multi-account)
Paul Campbell with claude 3481167c
-
plan: domains — six tasks, frozen sqids, reconciler seams
Paul Campbell with claude 1e1f0481
-
plan: design a platform-dev environment in the repurposed kass AWS account
Paul Campbell with claude 54b487ec
-
spec: domains — account-sqid platform domains, custom-domain health, bucket-manifest accounts
Paul Campbell with claude 81c53beb
Release notes
First tagged release of carlos — the CARLOS platform binary (edge, host agent, operator CLI). Built from carlosframework/platform @ v0.1.0. Verify with SHA256SUMS.txt. See the README for install instructions.
Changes
40-
plan: implementation plan for the platform-dev environment
Paul Campbell with claude 1d67c651
-
plan: design a platform-dev environment in the repurposed kass AWS account
Paul Campbell with claude df6ded21
-
depth-console-statusTenant hibernation + unix-socket upstreams, console slice 3, fleet status spec
Paul Campbell with claude 6736599f
-
plan: keymail overnight prep folded in — K0 PR open, K1 committed, K3 rehearsal verified; two cutover blockers named
Paul Campbell with claude b11e511f
-
plan: CARLOS framework design — event-driven writes, crypto core, manifest UI (#2)
Paul Campbell with claude 4d15d766
-
infra/region-host: optional extra_ingress rules (keymail MX needs tcp/25)
claude 324617bf
-
plan: keymail → flagship migration — recon, CARLOS fit, rehearsal + cutover
Paul Campbell with claude 17bcc6a0
-
console: app-internal instance visibility — the /.carlos/instances contract
Paul Campbell with claude 3e9ae1c9
-
console: audit table — the store remembers what owners did
Paul Campbell with claude e22284c0
-
feat: carlos-app@ tenant template — DynamicUser + full sandbox by default
Paul Campbell with claude 8c15d9f3
-
feat: console slice 2 — claim apps, promote, rollback from the browser
Paul Campbell with claude 8d8c6178
-
console: one-button Sign in with Keymail — no address entry
Paul Campbell with claude 3a715183
-
feat: platform console slice 1 — sign up/in with Keymail, read-only apps dashboard
Paul Campbell with claude 492ebf66
-
infra: deployment roots move to carlosframework/platform-infrastructure
Paul Campbell with claude a91a7ae4
-
Platform marketing site live; infra refactored into reusable modules
Paul Campbell with claude 63a8a16c
-
infra: note platform.carlosframework.com managed in personal DNSimple account
Paul Campbell with claude 1c11de8a
-
Kass cut over to the flagship; oncarlos.com registered and wildcarded
Paul Campbell with claude 71df9f8c
-
fix: rehearsal lessons — route-before-adopt, per-host live link, /data 711, ship keys binaries by target
Paul Campbell with claude f4523b66
-
infra: rehearsal + promote scripts; state and operator queues updated
Paul Campbell with claude 30180792
-
infra: bootstrap-box + provision-keys operator scripts (both boxes live)
Paul Campbell with claude d8ee5570
-
feat: ship -kind static packs the site dir deterministically
Paul Campbell with claude 2024e502
-
feat: static serving class, carlos vet, end-to-end smoke; flagship mail applied
Paul Campbell with claude ede3ba44
-
feat: host verbs — bootstrap, agent, adopt; tito svc-pdf ASCII fix
Paul Campbell with claude bf2f8b69
-
infra: tito operator queue + cutover checklist
Paul Campbell with claude 2ed6993c
-
infra: stage Kass secrets-copy script in the operator queue
Paul Campbell with claude 6d5f1176
15 more
-
feat: wire add/remove/instances, ship/promote/channels/rollback, ops verbs
Paul Campbell with claude 67c944fa
-
feat: activator, releases/channels, fleet ops (ported from Eleven + titogo)
Paul Campbell with claude 845ffd40
-
infra: flagship SES multi-tenant mail (Kass first) + operator queue
Paul Campbell with claude 9be1c805
-
infra: tito host-init script (was missing from the module)
Paul Campbell with claude 4c610fbe
-
feat: edge — host router with unix and TCP upstreams, ACME, live reload
Paul Campbell with claude 6f8bb910
-
feat: lease — single-writer S3 lease + litestream replication (from Eleven)
Paul Campbell with claude f374052b
-
deps: pin litestream, aws-sdk-go-v2, x/crypto at Eleven's proven versions
Paul Campbell with claude 7bb6929c
-
feat: registry — routes table with activator and placement columns
Paul Campbell with claude 9f98be56
-
feat: carlos binary scaffold with subcommand dispatch
Paul Campbell with claude d2d3ed5b
-
Add implementation roadmap and Plans A/B/C
Paul Campbell with claude 4e0e131a
-
Add static serving class: platform-hosted static sites
Paul Campbell with claude e8d056df
-
Confirm flagship account: Keymail's 271376211898, root email to move
Paul Campbell with claude eb55b1ad
-
Regions become a per-deployment registry, not platform constants
Paul Campbell with claude 34a6c1e0
-
Assimilate Tito production infra spec; add deployment topology
Paul Campbell with claude 1d76bdb8
-
Add CARLOS platform design spec
Paul Campbell with claude 57b20bf7