| 1 | # `carlos db` region forward: copy record |
| 2 | |
| 3 | Every user-facing string the db region forward plans write (spec |
| 4 | `2026-10-22-db-region-forward-design.md` §10): console refusals, the CLI's |
| 5 | sentences, the audit details and the docs prose. The gate is |
| 6 | `approved_db_forward_copy_test.go` at the repo root. It reuses the moves |
| 7 | gate's parser, so the format is the moves record's: one table per heading, |
| 8 | columns id, file, text, status. |
| 9 | |
| 10 | The rules: |
| 11 | |
| 12 | - A row is `pending` until Paul approves it in the copy review (the |
| 13 | `copy-review` skill). His edits are applied to the text here verbatim and |
| 14 | the row becomes `approved`. |
| 15 | - No pending string reaches code or docs. The task that writes a row's |
| 16 | text adds its id to `dbForwardCopyBuilt` in the gate in the same commit, |
| 17 | and from then on the gate fails unless the row is `approved` and its |
| 18 | text is in the file it names. |
| 19 | - In a Go file the text is one string literal, or one `fmt.Sprintf`, |
| 20 | `fmt.Errorf` or `errors.New` format, equal to the row with a format verb |
| 21 | where the row has a `<placeholder>`. No trailing newline inside the |
| 22 | literal. |
| 23 | - A table cell holds one line, so a row's text writes a paragraph break as |
| 24 | `\n\n`. In `docs/site/cli.md` each paragraph of a row is one line. |
| 25 | - No em dashes. A full stop and a new sentence instead, continuing in lower |
| 26 | case. Docs prose keeps the CLI page's sentence case. |
| 27 | - Ids are not renumbered. DBF-17 to DBF-20, DBF-23 and DBF-24 are plan 3's |
| 28 | pull rows; DBF-25 to DBF-29 stay free. |
| 29 | |
| 30 | Placeholders: `<host>` the instance's hostname; `<region>` a placement code |
| 31 | such as uk; `<size>` and `<cap>` byte sizes as the CLI prints them; `<n>` a |
| 32 | count of bytes; `<sha>` the first 16 hex digits of a SHA-256; `<time>` an |
| 33 | RFC 3339 time. |
| 34 | |
| 35 | ## Console (plan 2) |
| 36 | |
| 37 | | id | file | text | status | |
| 38 | |---|---|---|---| |
| 39 | | DBF-1 | internal/console/apidbforward.go | <host> keeps its data in region <region>. no server in that region can read databases yet, so carlos db cannot read it for now. | approved | |
| 40 | | DBF-2 | internal/console/apidbforward.go | <host> keeps its data in region <region>. no server in that region is answering right now. try again in a few minutes. | approved | |
| 41 | | DBF-9 | internal/console/apidbforward.go | too many database reads are already running. wait a minute and try again. | approved | |
| 42 | | DBF-10 | internal/console/apidbforward.go | <host> is moving between regions. read its database once the move has finished. | approved | |
| 43 | | DBF-14 | internal/console/apidbforward.go | <host> keeps its data in region <region>. this version of carlos cannot read it from there. run carlos update, then try again. | approved | |
| 44 | | DBF-21 | internal/console/apidbforward.go | forwarded a database query to region <region>. the query was <n> bytes, sha256 <sha> (cli) | approved | |
| 45 | | DBF-22 | internal/console/apidbforward.go | forwarded a database query to region <region>, as of <time>. the query was <n> bytes, sha256 <sha> (cli) | approved | |
| 46 | |
| 47 | ## CLI (plan 2) |
| 48 | |
| 49 | | id | file | text | status | |
| 50 | |---|---|---|---| |
| 51 | | DBF-3 | dbforward.go | no server in region <region> started the read within 60 seconds. try again in a few minutes. | approved | |
| 52 | | DBF-4 | dbforward.go | the database for <host> is <size> once restored. carlos db can query at most <cap> in region <region>. | approved | |
| 53 | | DBF-5 | dbforward.go | the server in region <region> does not have room to restore <host>'s database right now. try again later. | approved | |
| 54 | | DBF-6 | dbforward.go | the result was cut off at 64 MB. narrow the query with WHERE or LIMIT and run it again. | approved | |
| 55 | | DBF-7 | dbforward.go | the query ran for 5 minutes and was stopped. narrow it and run it again. | approved | |
| 56 | | DBF-8 | dbforward.go | <host> keeps its data in region <region>. carlos db pull cannot fetch a copy from there yet. carlos db query can read it. | approved | |
| 57 | | DBF-11 | dbforward.go | reading a copy of <host>'s database in region <region>. | approved | |
| 58 | | DBF-12 | dbforward.go | the read of <host>'s database in region <region> did not finish, so nothing was printed. try again. | approved | |
| 59 | | DBF-13 | dbforward.go | the answer from region <region> was invalid, so carlos db printed nothing. try again. | approved | |
| 60 | | DBF-15 | dbforward.go | <host> changed while the read was waiting. try again. | approved | |
| 61 | | DBF-16 | dbforward.go | <host> is moving between regions. read its database once the move has finished. | approved | |
| 62 | | DBF-32 | dbforward.go | this query cannot be sent to region <region>, because it contains invalid UTF-8 or the replacement character U+FFFD. fix the query and run it again. | approved | |
| 63 | |
| 64 | ## Pull (plan 3) |
| 65 | |
| 66 | Approved by Luna on 2026-10-23: DBF-18, DBF-19, DBF-20 and DBF-24 as drafted, DBF-17 and DBF-23 rewritten. |
| 67 | DBF-23 replaces DBF-30 on the CLI page; DBF-30 stays here, approved, and leaves the built list. |
| 68 | |
| 69 | | id | file | text | status | |
| 70 | |---|---|---|---| |
| 71 | | DBF-17 | dbforward.go | the database for <host> has <size> of files to fetch. carlos db pull can fetch at most <cap> from region <region>. | approved | |
| 72 | | DBF-18 | dbforward.go | fetching a copy of <host>'s database from region <region>. | approved | |
| 73 | | DBF-19 | internal/console/apidbforward.go | forwarded a database pull to region <region> (cli) | approved | |
| 74 | | DBF-20 | internal/console/apidbforward.go | forwarded a database pull to region <region>, as of <time> (cli) | approved | |
| 75 | | DBF-23 | docs/site/cli.md | If the app has more than one instance, name one with `--instance`. Only instances that sleep have a database copy. An instance on your own fleet or in a pool cannot be read this way, and the command says which.\n\nWhen an instance keeps its data in a different region from the console's, `carlos db query` runs in that region. A server there restores the copy, runs your query and sends back only the rows. `carlos db pull` fetches the copy's files from there and restores them on your machine. Both are encrypted for your terminal on the way, so nothing in between can read them, and nothing is printed or saved until all of it has arrived and been checked. In that region, a query's copy can be at most 2 GB once restored, the query runs for at most 5 minutes, and the rows can total at most 64 MB. A pull can fetch at most 2 GB. | approved | |
| 76 | | DBF-24 | dbforward.go | the server in region <region> does not have room to prepare a copy of <host>'s database right now. try again later. | approved | |
| 77 | |
| 78 | ## Docs |
| 79 | |
| 80 | | id | file | text | status | |
| 81 | |---|---|---|---| |
| 82 | | DBF-30 | docs/site/cli.md | If the app has more than one instance, name one with `--instance`. Only sleeping instances have a database copy. An instance on your own fleet or in a pool cannot be read this way, and the command says which.\n\nWhen an instance keeps its data in a different region from the console's, `carlos db query` runs in that region. A server there restores the copy, runs your query and sends back only the rows. The rows are encrypted for your terminal on the way, so nothing in between can read them, and nothing is printed until all of them have arrived and been checked. In that region, the copy can be at most 2 GB once restored, the query runs for at most 5 minutes, and the rows can total at most 64 MB. `carlos db pull` cannot fetch a copy from another region yet. | approved | |
| 83 | | DBF-31 | docs/site/cli.md | `carlos system db-worker` runs on platform boxes only. systemd starts it for each forwarded database query. You never run it yourself. | approved | |
| 84 | |