carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

carlos run: copy deck (approved by Paul, 2026-10-08)

Every user-facing string the carlos run series writes: CLI output, console refusals, the reasons a run is interrupted, usage lines and the docs prose. The gate is approved_run_copy_test.go at the repo root (Plan 1 Task 1). It reuses the moves gate's parser, so the format is the same: one table per heading, columns id, file, text, status.

The rules:

  • A row is pending until Paul approves it in the copy review (the copy-review skill). His edits are applied to the text here verbatim and the row becomes approved.
  • No task writes a row's text into code or docs while the row is pending. The task that writes it adds the id to runCopyBuilt in approved_run_copy_test.go in the same commit; from then on the gate fails unless the row is approved and its text is in the file it names.
  • In a Go file the text is one string literal, or one fmt.Sprintf, fmt.Errorf or errors.New format, equal to the row with %s or %d where the row has a <placeholder>. Never a trailing newline inside the literal: print with Fprintln. The one exception is a row whose file cell says "a fragment": its text is a piece of a larger literal (the top-level usage text), and the gate looks for it inside one.
  • No em dashes. A full stop and a new sentence instead. Console and CLI sentences start lower case after the first word, as the moves record's do.

Placeholders: <host> the instance's hostname; <app> the app; <id> a run id; <by> the caller's address; <kind> a route kind; <fleet> a fleet name; <name> a file's base name; <last> and <got> chunk sequence numbers; <detail> the box's member-safe wake error; <reason> one of the interrupted reasons below; <timeout> a duration such as 30m0s; <path> a local file path; <error> the operating system's error; <url> a console URL; <role> a quoted role word.

Plan 1: box foundation

| id | file | text | status | |---|---|---|---| | RUN-C1 | internal/activator/cmd.go | the instance hibernated | approved | | RUN-C2 | internal/activator/cmd.go | the instance was restarted | approved | | RUN-C3 | internal/activator/cmd.go | the instance moved to a new release | approved | | RUN-C4 | internal/activator/cmd.go | the instance's process exited | approved | | RUN-C5 | internal/activator/cmd.go | the instance lost its database lease | approved | | RUN-C6 | internal/activator/cmd.go | the instance was stopped for a move or a layout change | approved | | RUN-C7 | internal/activator/cmd.go | the instance was taken off this box | approved | | RUN-C8 | internal/activator/cmd.go | the box's agent stopped | approved | | RUN-C9 | internal/instanceexec/exec.go | usage: carlos instance-exec <run|seed|sidecar|cmd> <instance-id> | approved | | RUN-C10 | internal/instanceexec/exit.go | usage: carlos instance-exit <run|seed|sidecar|cmd> <instance-id> | approved | | RUN-C11 | docs/site/cli.md | ExecStart= of the four instance templates. | approved | | RUN-C12 | docs/site/cli.md | ExecStopPost= of the four instance templates. | approved | | RUN-C13 | internal/instanceexec/exec.go | instance-exec: role <role> is not run, seed, sidecar or cmd | approved | | RUN-C14 | internal/instanceexec/exit.go | instance-exit: role <role> is not run, seed, sidecar or cmd | approved |

Plan 2: record and console door

| id | file | text | status | |---|---|---|---| | RUN-C15 | internal/console/apiruns.go | too many run requests. wait a minute and try again | approved | | RUN-C16 | internal/console/apiruns.go | <host> is not an instance of <app> | approved | | RUN-C17 | internal/console/apiruns.go | <host> is a <kind> route. carlos run works on instances | approved | | RUN-C18 | internal/console/apiruns.go | <host> is served from its own address, so the platform does not run its process | approved | | RUN-C19 | internal/console/apiruns.go | <host> does not sleep, so the platform does not run its process | approved | | RUN-C20 | internal/console/apiruns.go | <host> is a pooled instance. carlos run works on instances with a process of their own | approved | | RUN-C21 | internal/console/apiruns.go | <host> runs on your fleet <fleet>. carlos run works on platform boxes only | approved | | RUN-C23 | internal/console/apiruns.go | <host> is moving. run the command once the move has finished | approved | | RUN-C24 | internal/console/apiruns.go | <host> already has a run open: <id>, started by <by> | approved | | RUN-C25 | internal/console/apiruns.go | name the command to run after -- | approved | | RUN-C26 | internal/console/apiruns.go | a run takes at most 256 arguments | approved | | RUN-C27 | internal/console/apiruns.go | the arguments come to more than 64 KB | approved | | RUN-C28 | internal/console/apiruns.go | an argument holds a NUL byte | approved | | RUN-C29 | internal/console/apiruns.go | the timeout must be between 1 second and 6 hours | approved | | RUN-C30 | internal/console/apiruns.go | the files come to more than 64 MB | approved | | RUN-C31 | internal/console/apiruns.go | <name> is not a plain file name | approved | | RUN-C32 | internal/console/apiruns.go | two files are both named <name> | approved | | RUN-C33 | internal/console/apiruns.go | <host> is an import that is not committed yet. finish or abort the import first | approved | | RUN-C34 | internal/console/apiruns.go | the run request is malformed | approved | | RUN-C35 | internal/console/apiruns.go | could not record the run. try again | approved | | RUN-C36 | internal/console/apirunsfollow.go | <host> has no run <id> | approved | | RUN-C37 | internal/console/apirunsfollow.go | could not read the run. try again | approved | | RUN-C38 | internal/console/apirunsfollow.go | run <id> has not finished yet | approved | | RUN-C39 | internal/console/apirunsfollow.go | run <id> ended at chunk <last>, not <got> | approved | | RUN-C40 | internal/console/apirunsfollow.go | run <id> has already started | approved | | RUN-C41 | internal/console/apirunsfollow.go | run <id> has already ended | approved | | RUN-C42 | internal/console/apiruns.go | carlos run is not available on this console yet. it needs the host-claim launch protocol | approved | | RUN-C43 | internal/provision/run.go | a run is open on this instance: <id>. wait for it to finish or cancel it, then move the instance | approved | | RUN-C44 | internal/runs/runs.go | its box stopped reporting | approved | | RUN-C45 | internal/runs/runs.go | the box's agent restarted | approved | | RUN-C46 | internal/runs/runs.go | the command's unit went away | approved | | RUN-C82 | internal/runs/runs.go | the box could not start the command | approved |

Plan 4: the CLI and the docs

| id | file | text | status | |---|---|---|---| | RUN-C22 | run.go | carlos run: <error> | approved | | RUN-C47 | run.go | usage: carlos run --app <app> --instance <host> [--file <path>]... [--timeout 30m] -- <arg>... | approved | | RUN-C48 | run.go | carlos run --app <app> --instance <host> --follow <id> | approved | | RUN-C49 | run.go | carlos run works through a console, and this shell is in direct bucket mode. unset CARLOSDEPLOYMENTBUCKET and CARLOSDEPLOYMENTDIR, then run carlos auth login --console <url> | approved | | RUN-C50 | run.go | --app and --instance name the instance to run against | approved | | RUN-C51 | run.go | --timeout must be between 1s and 6h | approved | | RUN-C52 | run.go | --follow takes a run id and no command after -- | approved | | RUN-C53 | run.go | could not read <path>: <error> | approved | | RUN-C54 | run.go | run <id> on <host>. to follow it again: carlos run --app <app> --instance <host> --follow <id> | approved | | RUN-C55 | run.go | <host>: not picked up within 60 seconds. the run did not start. try again | approved | | RUN-C56 | run.go | <host>: the box is not on the nested layout yet, so carlos run cannot run there | approved | | RUN-C57 | run.go | <host>: the box has host claims armed. carlos run cannot run there yet | approved | | RUN-C58 | run.go | <host>: the instance did not wake. <detail> | approved | | RUN-C59 | run.go | <host> was deleted and created again after this run was requested. the run did not start | approved | | RUN-C60 | run.go | <host> is an import that is not committed yet. the run did not start | approved | | RUN-C61 | run.go | <host>: the run was interrupted: <reason>. it may have done part of its work | approved | | RUN-C62 | run.go | <host>: the command timed out after <timeout> | approved | | RUN-C63 | run.go | <host>: the command was cancelled | approved | | RUN-C64 | run.go | <host>: the output passed 64 MB and was cut off there. the command ran on to its end | approved | | RUN-C65 | run.go | cancelling run <id>. press Ctrl-C again to stop waiting | approved | | RUN-C66 | run.go | <host>: run <id> was cancelled before it started | approved | | RUN-C67 | run.go | <host> has no run <id>, or this console has no carlos run yet | approved | | RUN-C83 | main.go (a fragment of the usage text) | run one of your app's commands against one instance, as that instance | approved | | RUN-C68 | docs/site/cli.md | ### carlos run | approved | | RUN-C69 | docs/site/cli.md | Runs one command of your app against one instance, as that instance: the same build, user, directories, database and environment it serves with. Output streams back to your terminal about a second behind, and carlos exits with the command's own status. | approved | | RUN-C70 | docs/site/cli.md | Any person who is a member of the account can run a command. A service credential cannot. | approved | | RUN-C71 | docs/site/cli.md | carlos run --app shop --instance shop.example.com --file orders.csv -- import orders.csv | approved | | RUN-C72 | docs/site/cli.md | Each --file is uploaded with the request and placed, under its own name, in the directory CARLOSRUNDIR names. Together they can come to 64 MB. The directory is deleted when the run ends. | approved | | RUN-C73 | docs/site/cli.md | The command runs for at most 30 minutes unless you pass --timeout, up to 6 hours. Ctrl-C cancels it on the box. A second Ctrl-C stops waiting, and the cancel still happens. If your terminal goes away the run carries on, and carlos run --app <app> --instance <host> --follow <id> picks its output up again. carlos prints that command when the run starts. Output is kept until carlos has read all of it, and for 24 hours at most. | approved | | RUN-C74 | docs/site/cli.md | A hibernating instance is woken first. A live one keeps serving, and the command opens the same database beside it. One run at a time per instance. carlos run needs the instance's box on the nested layout, and it is refused while the instance is moving. | approved | | RUN-C75 | docs/site/cli.md | carlos run exits with the command's own status, 128 plus the signal number when a signal ended it, 124 when it timed out, 125 when it was interrupted or the instance let go of it without a result, 130 when you cancelled it, 3 when the box refused it or did not pick it up within 60 seconds, and 2 when the console refused it. | approved | | RUN-C76 | docs/site/cli.md | Arguments are kept in the account's audit log, with who ran them. Never put a secret in an argument. Pass it in a --file, or keep it in the instance's environment. | approved | | RUN-C77 | docs/site/cli.md | A command started with carlos run gets the same environment, without CARLOSCONTROLSOCKET or CARLOS_PURGE, and three variables of its own: | approved | | RUN-C78 | docs/site/cli.md | the instance's database, the path --db names when the instance starts | approved | | RUN-C79 | docs/site/cli.md | this run's id | approved | | RUN-C80 | docs/site/cli.md | a directory holding the files passed with --file, under their own names. Always set, even with no files. Deleted after the run | approved | | RUN-C81 | docs/site/cli.md | Its arguments are exactly what followed --, after your binary. The platform adds nothing. It runs in the instance's data directory. On a cancel, a timeout or an instance stop it gets SIGTERM, then SIGKILL 20 seconds later. | approved | | RUN-C84 | run.go | not a regular file | approved | | RUN-C85 | run.go | the file changed while carlos was reading it | approved | | RUN-C86 | run.go | <host>: the instance no longer holds run <id>, and no result came back. it may have done part of its work | approved | | RUN-C87 | run.go | <host>: run <id> timed out before it started | approved |