run: Paul's follow-up copy (neutral example, --follow wording, two file-error fragments)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 files changed,
+11
−9
approved_run_copy_test.go+5 −5docs/site/cli.md+2 −2docs/superpowers/plans/2026-10-08-carlos-run-copy.md+4 −2
CI passed — run details
diff --git a/approved_run_copy_test.go b/approved_run_copy_test.go| index 5f073cd8b..fd238e849 100644 |
| --- a/approved_run_copy_test.go |
| +++ b/approved_run_copy_test.go |
| @@ -15,17 +15,17 @@ import ( |
| // parser and checked with its helpers, so "applied" means the same thing in |
| // both gates: |
| // |
| -// - TestRunCopyRecordIsComplete: the deck names exactly RUN-C1 to RUN-C83; |
| +// - TestRunCopyRecordIsComplete: the deck names exactly RUN-C1 to RUN-C85; |
| // - TestRunBuiltCopyIsApproved: an id in runCopyBuilt is an approved row |
| // (a string reaches code only after Paul has approved it); |
| // - TestRunBuiltCopyIsApplied: a built row's text is in the file it names; |
| // - TestRunCopyHasNoEmDash. |
| const runCopyRecordPath = "docs/superpowers/plans/2026-10-08-carlos-run-copy.md" |
| -// runCopyIDs is the deck's inventory: RUN-C1 to RUN-C83, pinned. |
| +// runCopyIDs is the deck's inventory: RUN-C1 to RUN-C85, pinned. |
| var runCopyIDs = func() []string { |
| - ids := make([]string, 0, 83) |
| - for i := 1; i <= 83; i++ { |
| + ids := make([]string, 0, 85) |
| + for i := 1; i <= 85; i++ { |
| ids = append(ids, "RUN-C"+strconv.Itoa(i)) |
| } |
| return ids |
| @@ -33,7 +33,7 @@ var runCopyIDs = func() []string { |
| // runCopyBuilt is every deck id whose text the code or docs now carry. The |
| // task that writes a row's text adds its id here in the same commit. |
| -var runCopyBuilt = []string{"RUN-C1", "RUN-C2", "RUN-C3", "RUN-C4", "RUN-C5", "RUN-C6", "RUN-C7", "RUN-C8", "RUN-C9", "RUN-C10", "RUN-C11", "RUN-C12", "RUN-C13", "RUN-C14", "RUN-C15", "RUN-C16", "RUN-C17", "RUN-C18", "RUN-C19", "RUN-C20", "RUN-C21", "RUN-C22", "RUN-C23", "RUN-C24", "RUN-C25", "RUN-C26", "RUN-C27", "RUN-C28", "RUN-C29", "RUN-C30", "RUN-C31", "RUN-C32", "RUN-C33", "RUN-C34", "RUN-C35", "RUN-C36", "RUN-C37", "RUN-C38", "RUN-C39", "RUN-C40", "RUN-C41", "RUN-C42", "RUN-C43", "RUN-C44", "RUN-C45", "RUN-C46", "RUN-C47", "RUN-C48", "RUN-C49", "RUN-C50", "RUN-C51", "RUN-C52", "RUN-C53", "RUN-C54", "RUN-C55", "RUN-C56", "RUN-C57", "RUN-C58", "RUN-C59", "RUN-C60", "RUN-C61", "RUN-C62", "RUN-C63", "RUN-C64", "RUN-C65", "RUN-C66", "RUN-C67", "RUN-C68", "RUN-C69", "RUN-C70", "RUN-C71", "RUN-C72", "RUN-C73", "RUN-C74", "RUN-C75", "RUN-C76", "RUN-C77", "RUN-C78", "RUN-C79", "RUN-C80", "RUN-C81", "RUN-C82", "RUN-C83"} |
| +var runCopyBuilt = []string{"RUN-C1", "RUN-C2", "RUN-C3", "RUN-C4", "RUN-C5", "RUN-C6", "RUN-C7", "RUN-C8", "RUN-C9", "RUN-C10", "RUN-C11", "RUN-C12", "RUN-C13", "RUN-C14", "RUN-C15", "RUN-C16", "RUN-C17", "RUN-C18", "RUN-C19", "RUN-C20", "RUN-C21", "RUN-C22", "RUN-C23", "RUN-C24", "RUN-C25", "RUN-C26", "RUN-C27", "RUN-C28", "RUN-C29", "RUN-C30", "RUN-C31", "RUN-C32", "RUN-C33", "RUN-C34", "RUN-C35", "RUN-C36", "RUN-C37", "RUN-C38", "RUN-C39", "RUN-C40", "RUN-C41", "RUN-C42", "RUN-C43", "RUN-C44", "RUN-C45", "RUN-C46", "RUN-C47", "RUN-C48", "RUN-C49", "RUN-C50", "RUN-C51", "RUN-C52", "RUN-C53", "RUN-C54", "RUN-C55", "RUN-C56", "RUN-C57", "RUN-C58", "RUN-C59", "RUN-C60", "RUN-C61", "RUN-C62", "RUN-C63", "RUN-C64", "RUN-C65", "RUN-C66", "RUN-C67", "RUN-C68", "RUN-C69", "RUN-C70", "RUN-C71", "RUN-C72", "RUN-C73", "RUN-C74", "RUN-C75", "RUN-C76", "RUN-C77", "RUN-C78", "RUN-C79", "RUN-C80", "RUN-C81", "RUN-C82", "RUN-C83", "RUN-C84", "RUN-C85"} |
| func mustParseRunRecord(t *testing.T) []copyRow { |
| t.Helper() |
diff --git a/docs/site/cli.md b/docs/site/cli.md| index 33c702a59..2b69a00f6 100644 |
| --- a/docs/site/cli.md |
| +++ b/docs/site/cli.md |
| @@ -474,14 +474,14 @@ which. |
| 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. |
| ```sh |
| -carlos run --app titogo --instance acme.go.tito.io --file checkins.csv -- import checkins.csv |
| +carlos run --app shop --instance shop.example.com --file orders.csv -- import orders.csv |
| ``` |
| Any person who is a member of the account can run a command. A service credential cannot. |
| Each --file is uploaded with the request and placed, under its own name, in the directory CARLOS_RUN_DIR names. Together they can come to 64 MB. The directory is deleted when the run ends. |
| -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 --follow picks its output up again. Output is kept until carlos has read all of it, and for 24 hours at most. |
| +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. |
| 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. |
diff --git a/docs/superpowers/plans/2026-10-08-carlos-run-copy.md b/docs/superpowers/plans/2026-10-08-carlos-run-copy.md| index bccd30d85..ea3915559 100644 |
| --- a/docs/superpowers/plans/2026-10-08-carlos-run-copy.md |
| +++ b/docs/superpowers/plans/2026-10-08-carlos-run-copy.md |
| @@ -118,9 +118,9 @@ error; `<url>` a console URL; `<role>` a quoted role word. |
| | 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 titogo --instance acme.go.tito.io --file checkins.csv -- import checkins.csv | 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 CARLOS_RUN_DIR 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 --follow picks its output up again. Output is kept until carlos has read all of it, and for 24 hours at most. | 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 an instance stop or an agent restart interrupted it, 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 | |
| @@ -129,3 +129,5 @@ error; `<url>` a console URL; `<role>` a quoted role word. |
| | 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 | |