@tikoci/centrs 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -2
- package/GLOSSARY.txt +87 -0
- package/README.md +25 -9
- package/SECURITY.md +3 -3
- package/commands/AGENTS.md +3 -2
- package/commands/api/AGENTS.md +212 -0
- package/commands/api/README.md +177 -0
- package/commands/api/examples.md +428 -0
- package/commands/btest/README.md +56 -31
- package/commands/btest/examples.md +35 -10
- package/commands/check/README.md +371 -53
- package/commands/check/examples.md +390 -0
- package/commands/devices/README.md +177 -37
- package/commands/devices/examples.md +148 -0
- package/commands/execute/README.md +48 -7
- package/commands/execute/examples.md +90 -6
- package/commands/retrieve/README.md +37 -51
- package/commands/retrieve/examples.md +40 -9
- package/commands/settings/README.md +286 -22
- package/commands/settings/examples.md +408 -0
- package/commands/terminal/README.md +6 -0
- package/commands/transfer/README.md +32 -2
- package/commands/transfer/examples.md +66 -0
- package/docs/CONSTITUTION.md +40 -15
- package/docs/MATRIX.md +69 -142
- package/docs/errors/README.md +2 -1
- package/docs/errors/cdb/empty-selection.md +19 -0
- package/docs/errors/input/incomplete-gps.md +9 -0
- package/docs/errors/input/invalid-altitude.md +9 -0
- package/docs/errors/input/invalid-bbox.md +9 -0
- package/docs/errors/input/invalid-coordinate.md +9 -0
- package/docs/errors/input/invalid-radius.md +9 -0
- package/docs/errors/internal/settings-failed.md +9 -0
- package/docs/errors/routeros/btest-connection-count-single-stream.md +22 -0
- package/docs/errors/routeros/btest-udp-tx-size-ignored.md +15 -0
- package/docs/errors/settings/consequential-value.md +26 -0
- package/docs/errors/settings/invalid-boolean.md +21 -3
- package/docs/errors/settings/invalid-format.md +18 -3
- package/docs/errors/settings/invalid-integer.md +18 -3
- package/docs/errors/settings/invalid-timeout.md +20 -3
- package/docs/errors/settings/invalid-via.md +22 -3
- package/docs/errors/settings/reserved-key.md +29 -0
- package/docs/errors/settings/skip-env-file-active.md +25 -0
- package/docs/errors/settings/unknown-key.md +25 -0
- package/docs/errors/usage/fanout-not-supported.md +16 -0
- package/docs/errors/usage/invalid-method.md +23 -0
- package/package.json +9 -9
- package/src/api-fanout.ts +454 -0
- package/src/api.ts +1627 -0
- package/src/btest.ts +61 -1
- package/src/cli/api.ts +660 -0
- package/src/cli/btest.ts +20 -2
- package/src/cli/common.ts +75 -0
- package/src/cli/devices.ts +235 -6
- package/src/cli/discover.ts +3 -1
- package/src/cli/execute.ts +107 -6
- package/src/cli/mcp.ts +8 -1
- package/src/cli/retrieve.ts +135 -90
- package/src/cli/selection.ts +200 -0
- package/src/cli/settings.ts +286 -0
- package/src/cli/terminal.ts +22 -7
- package/src/cli/transfer.ts +171 -47
- package/src/cli.ts +29 -0
- package/src/core/error-catalog.ts +69 -0
- package/src/core/fanout.ts +301 -0
- package/src/core/inspect.ts +170 -0
- package/src/devices.ts +212 -20
- package/src/discover.ts +7 -2
- package/src/execute-fanout.ts +438 -0
- package/src/execute.ts +134 -70
- package/src/index.ts +166 -9
- package/src/mcp/config.ts +12 -2
- package/src/mcp/tools.ts +137 -2
- package/src/protocols/adapter.ts +357 -9
- package/src/protocols/btest-session.ts +279 -46
- package/src/protocols/btest.ts +6 -2
- package/src/protocols/index.ts +11 -5
- package/src/protocols/native-api.ts +223 -30
- package/src/resolver/cdb.ts +10 -2
- package/src/resolver/comment-kv.ts +58 -4
- package/src/resolver/config-file.ts +136 -0
- package/src/resolver/facts.ts +78 -0
- package/src/resolver/geo.ts +453 -0
- package/src/resolver/index.ts +46 -0
- package/src/resolver/mac.ts +12 -3
- package/src/resolver/selection.ts +304 -0
- package/src/resolver/settings.ts +54 -5
- package/src/resolver/target.ts +20 -2
- package/src/retrieve-fanout.ts +232 -268
- package/src/retrieve.ts +69 -94
- package/src/settings.ts +1078 -0
- package/src/terminal.ts +11 -1
- package/src/transfer-fanout.ts +527 -0
- package/src/transfer.ts +61 -11
- package/commands/stream/README.md +0 -70
package/docs/MATRIX.md
CHANGED
|
@@ -24,130 +24,68 @@ A cell advances only with the matching evidence in the same change.
|
|
|
24
24
|
| Command | rest-api | native-api | ssh | mac-telnet | snmp | mndp | romon | winbox-terminal |
|
|
25
25
|
| -------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ---------------- |
|
|
26
26
|
| retrieve | `CHR-passed` | `CHR-passed` | — | — | `not-started` | — | — | — |
|
|
27
|
-
|
|
|
27
|
+
| api | `CHR-passed` | `CHR-passed` | — | — | — | — | — | — |
|
|
28
28
|
| execute | `CHR-passed` | `CHR-passed` | `CHR-passed` | `CHR-passed` | — | — | `not-started` | `not-started` |
|
|
29
29
|
| terminal | — | — | `CHR-passed` | `CHR-passed` | — | — | — | — |
|
|
30
30
|
| transfer | `CHR-passed` | `CHR-passed` | `CHR-passed` | — | — | — | — | — |
|
|
31
31
|
| devices | — | — | — | — | — | — | — | — |
|
|
32
32
|
| discover | — | — | — | — | — | `CHR-passed` | — | — |
|
|
33
|
-
| check | `
|
|
33
|
+
| check | `designed` | `designed` | `designed` | `designed` | `not-started` | `not-started` | `not-started` | `not-started` |
|
|
34
34
|
| settings | — | — | — | — | — | — | — | — |
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`commands/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
`
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
`
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`commands/transfer/README.md`.
|
|
80
|
-
|
|
81
|
-
`execute / ssh` is `CHR-passed` (the second SSH consumer): a per-command batch
|
|
82
|
-
client (`SshExecClient` in `src/protocols/ssh.ts` — one `ssh user@host "<cmd>"`
|
|
83
|
-
per command, sharing `sftp.ts`'s host-`ssh` plumbing) behind the `SshExecAdapter`
|
|
84
|
-
console transport (execute-only, like mac-telnet; structured reads/inspect
|
|
85
|
-
unsupported). It reuses the mac-telnet `:put [:parse …]` gate verbatim. Green via
|
|
86
|
-
`test/integration/execute-ssh.test.ts` (S1–S4) + `test/unit/ssh.test.ts`; the
|
|
87
|
-
no-PTY / clean-output / `:parse` wire grounding lives in the `src/protocols/ssh.ts`
|
|
88
|
-
header and `commands/execute/README.md`.
|
|
89
|
-
|
|
90
|
-
`terminal / ssh` is `CHR-passed` (the third and last SSH consumer): it execs the
|
|
91
|
-
host `ssh` with inherited stdio (`buildSshTerminalArgv` in `src/terminal.ts`,
|
|
92
|
-
reusing `sshCommonOptions`) and lets the OS relay RouterOS's already-clean no-PTY
|
|
93
|
-
console — no screen emulation. No `-t` is passed (`-tt` hangs RouterOS);
|
|
94
|
-
`runTerminal` returns `ssh`'s exit code. A host target defaults to ssh, a MAC
|
|
95
|
-
target to mac-telnet. Green via `test/integration/terminal-ssh.test.ts` (TS1/TS2),
|
|
96
|
-
with argv unit-tested in `test/unit/terminal.test.ts`. **All three SSH cells
|
|
97
|
-
(transfer/execute/terminal) are `CHR-passed`.** The no-PTY / exit-code semantics are documented in
|
|
98
|
-
`src/terminal.ts`; the no-multi-line-brace limitation is in
|
|
99
|
-
`commands/terminal/README.md`.
|
|
100
|
-
|
|
101
|
-
`fetch` (centrs-as-HTTP-server + `/tool/fetch`) is a **deferred, explicit-only
|
|
102
|
-
method within the rest-api/native-api cells**, not a grid column — it needs
|
|
103
|
-
inbound reachability (router → centrs) so it is never auto-selected.
|
|
104
|
-
|
|
105
|
-
`settings` is `designed` and transport-less (like `devices`), so its grid row
|
|
106
|
-
stays `—`. `commands/settings/README.md` describes the `centrs.env` + `__default__`
|
|
107
|
-
front-end (interactive first-time setup plus `settings get/set/reset/print`); no
|
|
108
|
-
code yet.
|
|
109
|
-
|
|
110
|
-
### Transport-base readiness (below the command grid)
|
|
36
|
+
## Status pointers
|
|
37
|
+
|
|
38
|
+
Detailed command contracts live in `commands/<name>/README.md`; example evidence
|
|
39
|
+
lives in `commands/<name>/examples.md` and the named integration tests. Keep this
|
|
40
|
+
section short enough that the grid remains the status surface.
|
|
41
|
+
|
|
42
|
+
- `devices` is transport-less, so its row stays `—`; command state is
|
|
43
|
+
`CHR-passed` by fixture-backed integration tests in `test/integration/devices.test.ts`.
|
|
44
|
+
- `settings` is transport-less, so its row stays `—`; command state is
|
|
45
|
+
`CHR-passed` by fixture-backed integration tests in `test/integration/settings.test.ts`.
|
|
46
|
+
- `retrieve`, `api`, `execute`, and `transfer` share the target-selection and
|
|
47
|
+
fan-out contracts from `docs/CONSTITUTION.md`; command-specific boundaries and
|
|
48
|
+
evidence are in their command READMEs and integration tests.
|
|
49
|
+
- There is no `update` command. RouterOS CLI-shaped writes ride `execute`; the
|
|
50
|
+
structured operation surface is `api`.
|
|
51
|
+
- `api --stream` absorbs the former `stream`/`tail` surface; native-api stream
|
|
52
|
+
details are in `commands/api/README.md` and `src/protocols/native-api.ts`.
|
|
53
|
+
- `discover / mndp` is grounded by `commands/discover/README.md`,
|
|
54
|
+
`src/data/mndp.ts`, `src/data/mndp-cache.ts`, and
|
|
55
|
+
`test/integration/discover.test.ts`.
|
|
56
|
+
- `check` is `designed` (`commands/check/README.md`): a reach + health battery
|
|
57
|
+
whose reads ride the execute-capable transports (rest-api/native-api/ssh/
|
|
58
|
+
mac-telnet), so those four cells are `designed`; `snmp` and `romon`/
|
|
59
|
+
`winbox-terminal` stay `not-started`. Its per-host fan-out is the machinery the
|
|
60
|
+
IP-scan discovery (#149) will iterate; the L2-default timing evidence (#136) is
|
|
61
|
+
recorded in the README before the cells advance past `designed`.
|
|
62
|
+
- `transfer / ssh` means the SFTP-backed transfer method. Deferred file-transfer
|
|
63
|
+
methods such as `scp`, `fetch`, and `ftp` are tracked in
|
|
64
|
+
`commands/transfer/README.md`; `fetch` is not a grid column.
|
|
65
|
+
- SSH grounding for `execute` and `terminal` lives in
|
|
66
|
+
`commands/execute/README.md`, `commands/terminal/README.md`,
|
|
67
|
+
`src/protocols/ssh.ts`, `src/protocols/sftp.ts`, and `src/terminal.ts`.
|
|
68
|
+
- MAC-Telnet grounding for `execute` and `terminal` lives in
|
|
69
|
+
`commands/execute/README.md`, `commands/terminal/README.md`, and the
|
|
70
|
+
`src/protocols/mac-telnet*.ts` module headers.
|
|
71
|
+
- Transport wire-format and delivery caveats belong in `src/protocols/*.ts`
|
|
72
|
+
module headers. Do not expand this file with per-packet or per-router findings.
|
|
73
|
+
|
|
74
|
+
Beyond the grid: post-`CHR-passed` hardening, ergonomics, and research work is
|
|
75
|
+
tracked in GitHub issues (`dry-july` and successors). Those issues may point back
|
|
76
|
+
to this matrix for current status, but they are not additional cell states.
|
|
77
|
+
|
|
78
|
+
### Transport-base readiness
|
|
111
79
|
|
|
112
80
|
The grid above tracks command cells. The transports those cells ride are
|
|
113
81
|
implemented and grounded in their `src/protocols/*.ts` **module headers** — the
|
|
114
|
-
single home for wire-format, auth, and delivery facts
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
`test/unit/native-api.test.ts`, `test/integration/native-api.test.ts`
|
|
122
|
-
(transport), and `test/integration/native-api-retrieve.test.ts` (command).
|
|
123
|
-
- **mac-telnet** (`src/protocols/mac-telnet.ts` + `mtwei.ts` +
|
|
124
|
-
`mac-telnet-console.ts` + `MacTelnetAdapter` in `adapter.ts`): packet/control
|
|
125
|
-
codec, session state machine, both auth methods (classic MD5 + MTWEI EC-SRP),
|
|
126
|
-
the interactive-console reader, and the UDP datagram transport with route
|
|
127
|
-
discovery. The deep findings — auth (MTWEI-required / MD5-refused /
|
|
128
|
-
`END_AUTH`≠success), console (ANSI terminal-size probe, ~10s prime stall,
|
|
129
|
-
one-time license gate, `:put [:parse]` syntax+semantic gate, silent writes),
|
|
130
|
-
reliability (byte-counter retransmit + empty-ACK keepalive), and the
|
|
131
|
-
real-device UDP-delivery facts (real egress MAC required; broadcast-only reply;
|
|
132
|
-
per-NIC directed-broadcast reach via `discoverMacTelnetRoute`; bind `0.0.0.0`)
|
|
133
|
-
— are documented in those module headers. Two cells are `CHR-passed`:
|
|
134
|
-
- **`execute / mac-telnet`**: `executeEnvelope` (resolver → `MacTelnetAdapter` →
|
|
135
|
-
UDP transport) runs reads, REST-verified writes, and the validation-reject
|
|
136
|
-
path. Green via `test/integration/mac-telnet-console.test.ts` (examples
|
|
137
|
-
19–21); transport/auth alone via `test/integration/mac-telnet.test.ts` (MTWEI
|
|
138
|
-
login + MD5 refusal). Unit: `test/unit/{mtwei,mac-telnet,mac-telnet-console}.test.ts`.
|
|
139
|
-
- **`terminal / mac-telnet`**: the interactive relay over the same console
|
|
140
|
-
reader (`MacTelnetConsole.attachInteractive`), orchestrated in
|
|
141
|
-
`src/terminal.ts` over an injectable `TerminalIo`, reusing the execute
|
|
142
|
-
resolver and the shared `resolveMacTelnetRoute`. Green via
|
|
143
|
-
`test/integration/terminal-mac-telnet.test.ts` (T1–T3) driving the real
|
|
144
|
-
`centrs terminal` binary through the subprocess harness.
|
|
145
|
-
- **Evidence caveat:** the CHR integration runs over the quickchr
|
|
146
|
-
`socket-connect` **L2 bridge** (`test/integration/mactelnet-l2-bridge.ts`), so
|
|
147
|
-
the real `createUdpMacTelnetTransport` egress/broadcast path is *not* exercised
|
|
148
|
-
in CI — the RB1100AHx4 / RouterOS 7.24beta1 real-device run grounded the
|
|
149
|
-
UDP-delivery facts (and caught the synthetic-source-MAC break). A full-TTY
|
|
150
|
-
`terminal` test (real PTY via `script(1)`/node-pty) is likewise deferred.
|
|
82
|
+
single home for wire-format, auth, and delivery facts.
|
|
83
|
+
|
|
84
|
+
| Transport | Status pointer |
|
|
85
|
+
| --------- | -------------- |
|
|
86
|
+
| native-api | Used by `retrieve`, `api`, `execute`, and `transfer`; wire facts in `src/protocols/native-api.ts`. |
|
|
87
|
+
| ssh / sftp | Used by `transfer`, `execute`, and `terminal`; facts in `src/protocols/ssh.ts`, `src/protocols/sftp.ts`, and `src/terminal.ts`. |
|
|
88
|
+
| mac-telnet | Used by `execute` and `terminal`; facts in `src/protocols/mac-telnet.ts`, `src/protocols/mac-telnet-console.ts`, `src/protocols/mtwei.ts`, and `src/protocols/adapter.ts`. |
|
|
151
89
|
|
|
152
90
|
### Frontend surfaces (orthogonal to the command grid)
|
|
153
91
|
|
|
@@ -156,9 +94,9 @@ core and carry their own state, tracked here:
|
|
|
156
94
|
|
|
157
95
|
| Surface | State | Spec | Notes |
|
|
158
96
|
| ------- | ----- | ---- | ----- |
|
|
159
|
-
| api
|
|
97
|
+
| ts-api | `CHR-passed` | `src/index.ts` | Root TypeScript library surface; everything else adapts it. |
|
|
160
98
|
| cli | `coded` | `src/cli/` | `retrieve`/`execute`/`transfer`/`terminal`/`devices`/`discover`/`btest` wired. |
|
|
161
|
-
| mcp | `CHR-passed` | `commands/mcp/` | Scoped-verb stdio MCP server;
|
|
99
|
+
| mcp | `CHR-passed` | `commands/mcp/` | Scoped-verb stdio MCP server; details in `commands/mcp/README.md` and `test/integration/mcp.test.ts`. |
|
|
162
100
|
| tui | `not-started` | `src/tui.ts` | Stub. |
|
|
163
101
|
| proxy | `not-started` | `src/webproxy.ts` | Stub. |
|
|
164
102
|
|
|
@@ -170,28 +108,17 @@ are documented in `commands/mcp/README.md` and `commands/mcp/examples.md`.
|
|
|
170
108
|
|
|
171
109
|
### Peer measurement (`btest`) — orthogonal to the command grid
|
|
172
110
|
|
|
173
|
-
`btest` is the MikroTik
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
from the `:parse` / `/console/inspect` gate. v1 scope (decided with the user):
|
|
177
|
-
**both** client and server, **EC-SRP5 + unauthenticated**, **TCP and UDP** (legacy
|
|
178
|
-
pre-6.43 double-MD5 is out of scope).
|
|
111
|
+
`btest` is the MikroTik bandwidth test (peer measurement, TCP/UDP port 2000),
|
|
112
|
+
not a RouterOS-command transport. It sits outside the command×protocol grid as
|
|
113
|
+
its own capability axis and is exempt from the RouterOS command-validation gate.
|
|
179
114
|
|
|
180
115
|
| Mode | State | Evidence |
|
|
181
116
|
| -------------- | ------------ | -------- |
|
|
182
|
-
| btest / server | `CHR-passed` |
|
|
183
|
-
| btest / client | `CHR-passed` |
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
orchestrator + CLI, and the honest grounding caveat (the server gets direct CHR
|
|
188
|
-
evidence over the QEMU SLIRP gateway `10.0.2.2`; the client gets direct CHR
|
|
189
|
-
evidence over a host→guest `tcp:2000` forward — TCP only; UDP-receive is a soft
|
|
190
|
-
smoke test and UDP client→CHR-server stays loopback/transitive over the SLIRP
|
|
191
|
-
reverse path; TCP `connection-count > 1` fan-out is deferred; NDJSON is not
|
|
192
|
-
adopted) are documented in `commands/btest/README.md` and the
|
|
193
|
-
`src/protocols/btest.ts`, `src/protocols/btest-session.ts`, and
|
|
194
|
-
`src/protocols/ec-srp5.ts` module headers.
|
|
117
|
+
| btest / server | `CHR-passed` | `test/integration/btest.test.ts`; details in `commands/btest/README.md`. |
|
|
118
|
+
| btest / client | `CHR-passed` | `test/integration/btest-client.test.ts`; details in `commands/btest/README.md`. |
|
|
119
|
+
|
|
120
|
+
Wire, auth, TCP/UDP, and CI caveats live in `commands/btest/README.md` and the
|
|
121
|
+
`src/protocols/btest*.ts` / `src/protocols/ec-srp5.ts` module headers.
|
|
195
122
|
|
|
196
123
|
## Priority order
|
|
197
124
|
|
|
@@ -199,18 +126,18 @@ Do not start a later item until the earlier cell or dependency checkpoint has
|
|
|
199
126
|
matching evidence. The grid above is the live status; per-item detail lives in
|
|
200
127
|
the linked `commands/<name>/`.
|
|
201
128
|
|
|
202
|
-
1. **retrieve / rest-api** — `CHR-passed
|
|
129
|
+
1. **retrieve / rest-api** — `CHR-passed` (`commands/retrieve/`).
|
|
203
130
|
2. **CDB resolution + metadata overrides** — `CHR-passed` (`commands/devices/`).
|
|
204
|
-
3. **CDB groups +
|
|
205
|
-
4. **execute / native-api + rest-api** — `CHR-passed` (`commands/execute/`).
|
|
131
|
+
3. **CDB groups + fan-out** — `CHR-passed` (`commands/devices/`, fan-out core).
|
|
132
|
+
4. **execute / native-api + rest-api** — `CHR-passed` (`commands/execute/`).
|
|
206
133
|
5. **devices** (CDB mutation + provenance) — `CHR-passed` (`commands/devices/`).
|
|
207
134
|
6. **retrieve / snmp** — `not-started` (future: SNMP OID/MIB reads + MikroTik MIB cache).
|
|
208
|
-
7. **ssh** for transfer/execute/terminal —
|
|
209
|
-
8. **mac-telnet** for execute/terminal — both `CHR-passed
|
|
135
|
+
7. **ssh** for transfer/execute/terminal — all three `CHR-passed`.
|
|
136
|
+
8. **mac-telnet** for execute/terminal — both `CHR-passed`.
|
|
210
137
|
9. **RoMON / WinBox Terminal for execute** — `not-started` (see Open questions).
|
|
211
138
|
10. **discover / mndp** — `CHR-passed` (`commands/discover/`).
|
|
212
|
-
11. **MCP, TUI, proxy** —
|
|
213
|
-
12. **btest (peer measurement)** — server
|
|
139
|
+
11. **MCP, TUI, proxy** — MCP `CHR-passed`; TUI/proxy `not-started`.
|
|
140
|
+
12. **btest (peer measurement)** — server and client both `CHR-passed`.
|
|
214
141
|
|
|
215
142
|
## Open questions (decisions needed before the affected cell can advance)
|
|
216
143
|
|
package/docs/errors/README.md
CHANGED
|
@@ -50,7 +50,8 @@ Codes are slash-namespaced `family/slug`. The families and where they originate:
|
|
|
50
50
|
- `routeros/*` — RouterOS-surfaced faults mapped by the grounded vocabulary in
|
|
51
51
|
`src/core/routeros-errors.ts` (REST `detail` and native-api `!trap`, identical
|
|
52
52
|
on CHR 7.23).
|
|
53
|
-
- `settings/*` — settings/value parsing (`src/resolver/settings.ts`)
|
|
53
|
+
- `settings/*` — settings/value parsing (`src/resolver/settings.ts`) and the
|
|
54
|
+
`centrs settings` command's own registry/refusal rules (`src/settings.ts`).
|
|
54
55
|
- `target/*` — turning a `<router>` into a transport endpoint.
|
|
55
56
|
- `transport/*` — connection, TLS, DNS, and timeout plumbing.
|
|
56
57
|
- `usage/*` — how a command was invoked (arity, conflicting flags, confirmation).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# `cdb/empty-selection`
|
|
2
|
+
|
|
3
|
+
The target selection matched no CDB records.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
A fan-out selection involving `--where` / `--all` / `--default` / positionals (on
|
|
8
|
+
its own or mixed with `--group`) resolved to zero targets. This is reported as a
|
|
9
|
+
warning on an `ok: true` fan-out envelope with `summary { total: 0, ok: 0, failed:
|
|
10
|
+
0 }`, not a hard failure — there was simply nothing to run.
|
|
11
|
+
|
|
12
|
+
A **group-only** empty (bare `--group`, no other selector) is reported as
|
|
13
|
+
[`cdb/empty-group`](empty-group.md) instead, naming the group that matched nothing;
|
|
14
|
+
this page covers every other empty selection.
|
|
15
|
+
|
|
16
|
+
Check the selector: run `centrs devices list` (and `centrs devices groups`) to see
|
|
17
|
+
the registered records, groups, and the facts a `--where <attr>=<value>` can match.
|
|
18
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Target selection) for the
|
|
19
|
+
selector grammar.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `input/incomplete-gps`
|
|
2
|
+
|
|
3
|
+
lat/lon (or a --gps tuple) were not given as a complete pair.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `input/incomplete-gps`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `input/invalid-altitude`
|
|
2
|
+
|
|
3
|
+
The altitude is not a number, or altitude-type is not MSL/AGL.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `input/invalid-altitude`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `input/invalid-bbox`
|
|
2
|
+
|
|
3
|
+
The --bbox is not four lat-first corners with south<=north and west<=east.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `input/invalid-bbox`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `input/invalid-coordinate`
|
|
2
|
+
|
|
3
|
+
The latitude or longitude is not a number in its valid range.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `input/invalid-coordinate`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `input/invalid-radius`
|
|
2
|
+
|
|
3
|
+
The --near radius is not a number with an optional m/km/mi/ft suffix.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `input/invalid-radius`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# `internal/settings-failed`
|
|
2
|
+
|
|
3
|
+
The settings command failed with an unexpected internal error.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) for the centrs error
|
|
8
|
+
contract. This stub will be expanded with the typical trigger and remediation
|
|
9
|
+
for `internal/settings-failed`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# `routeros/btest-connection-count-single-stream`
|
|
2
|
+
|
|
3
|
+
A **warning** (not a failure): `centrs btest client --protocol tcp
|
|
4
|
+
--connection-count <n>` opened **fewer** TCP data connections than `n`. centrs
|
|
5
|
+
does implement the multi-connection fan-out — it opens the extra connections that
|
|
6
|
+
join the test with the server-negotiated session token — but it falls back to a
|
|
7
|
+
single stream when the server negotiates **no** token. The common case is an
|
|
8
|
+
**authenticated (EC-SRP5)** session: centrs does not yet capture the post-auth
|
|
9
|
+
session token, so authenticated tests stay single-stream. A secondary connection
|
|
10
|
+
that fails mid-handshake also reduces the realized count.
|
|
11
|
+
|
|
12
|
+
The warning reports both the requested and the actually-active connection count.
|
|
13
|
+
|
|
14
|
+
## Workaround
|
|
15
|
+
|
|
16
|
+
- For full multi-stream throughput, run the test **unauthenticated**
|
|
17
|
+
(`/tool/bandwidth-server` with `authenticate=no`), where centrs negotiates the
|
|
18
|
+
token and opens all `n` connections.
|
|
19
|
+
- Or run several `centrs btest client` processes in parallel and sum their
|
|
20
|
+
throughput.
|
|
21
|
+
|
|
22
|
+
See `docs/CONSTITUTION.md` for the centrs error/warning contract.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# `routeros/btest-udp-tx-size-ignored`
|
|
2
|
+
|
|
3
|
+
A non-fatal warning. For UDP `--direction both`, the btest wire protocol carries
|
|
4
|
+
a **single** `tx-size` field, so the client and the server transmit with the
|
|
5
|
+
same packet size. centrs maps `--local-udp-tx-size` to that field and discards
|
|
6
|
+
`--remote-udp-tx-size`. This warning fires only when both flags are set to
|
|
7
|
+
different values, so you know which size the session actually used.
|
|
8
|
+
|
|
9
|
+
## Fix
|
|
10
|
+
|
|
11
|
+
Drop `--remote-udp-tx-size` for `--direction both`, or set both flags to the
|
|
12
|
+
same value. To size each direction independently, run two sessions:
|
|
13
|
+
`--direction transmit` (uses `--local-udp-tx-size`) and `--direction receive`
|
|
14
|
+
(uses `--remote-udp-tx-size`). See `commands/btest/README.md` and
|
|
15
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# `settings/consequential-value`
|
|
2
|
+
|
|
3
|
+
`settings set` accepted a syntactically valid value with a real, non-obvious consequence (e.g. a global --insecure default, or a transfer-via value gated elsewhere).
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
This is a warning, not a failure — the envelope is still `ok: true` and the
|
|
8
|
+
value is written. `centrs settings set` emits it for exactly two keys today
|
|
9
|
+
(the `warn` callback on the matching `SettingsKeyDef` in `src/settings.ts`):
|
|
10
|
+
|
|
11
|
+
- `insecure` set to any truthy spelling (`true`, `yes`, `on`, `1`) makes
|
|
12
|
+
every command run without an explicit `--insecure`/`--no-insecure`
|
|
13
|
+
override trust RouterOS's self-signed TLS certificate or unknown SSH host
|
|
14
|
+
key globally, not just for one invocation. See the `insecure` row in
|
|
15
|
+
`commands/settings/README.md`'s "Known settings keys" table.
|
|
16
|
+
- `transfer-via` set to `ftp` is accepted here — `ftp` is a syntactically
|
|
17
|
+
valid `CENTRS_TRANSFER_VIA` value — but `transfer` still rejects it at
|
|
18
|
+
call time with [`settings/unsafe-protocol-blocked`](unsafe-protocol-blocked.md)
|
|
19
|
+
unless `ALLOW_UNSAFE_PROTOCOLS` also includes `ftp`. The warning exists so
|
|
20
|
+
the write doesn't silently look like it "worked" when the value won't
|
|
21
|
+
actually take effect anywhere else yet.
|
|
22
|
+
|
|
23
|
+
There is nothing to fix in the sense of retrying with different input — the
|
|
24
|
+
value you asked for was written as requested. Run `centrs settings set
|
|
25
|
+
insecure false` or pick a different `transfer-via` value if the consequence
|
|
26
|
+
wasn't intended. See example 24 in `commands/settings/examples.md`.
|
|
@@ -4,6 +4,24 @@ A boolean-like setting received a non-boolean value.
|
|
|
4
4
|
|
|
5
5
|
## Fix
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`centrs settings set <attr> <value>` throws this for the three boolean-typed
|
|
8
|
+
managed keys — `mcp-allow-adhoc`, `validate`, `insecure` — when `<value>`
|
|
9
|
+
isn't one of the spellings the shared parser (`parseBoolean` in
|
|
10
|
+
`src/resolver/settings.ts`) accepts: `true`/`false`, `yes`/`no`, `on`/`off`,
|
|
11
|
+
or `1`/`0`, case-insensitively. Anything else — `maybe`, `2`, an empty
|
|
12
|
+
string — fails with a remediation listing the accepted spellings.
|
|
13
|
+
|
|
14
|
+
This isn't a `settings`-only rule: `parseBoolean` backs every `CENTRS_*`
|
|
15
|
+
boolean setting across the app, so the same error and message shape appears
|
|
16
|
+
whenever any command resolves a boolean env var to an unrecognized value,
|
|
17
|
+
not just through `settings set`.
|
|
18
|
+
|
|
19
|
+
One canonicalization detail worth knowing even though it isn't what triggers
|
|
20
|
+
this error: once a boolean value *does* validate, `settings set` always
|
|
21
|
+
writes the canonical `1` or `0` to `centrs.env`, never `true`/`false` —
|
|
22
|
+
`CENTRS_MCP_ALLOW_ADHOC`'s reader in `src/mcp/config.ts` checks the literal
|
|
23
|
+
string `"1"` rather than reusing `parseBoolean`, so writing `1`/`0`
|
|
24
|
+
uniformly is what satisfies every reader. Retry `set` with one of the
|
|
25
|
+
accepted spellings above; see
|
|
26
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Settings precedence) for how
|
|
27
|
+
this value feeds into the resolver chain.
|
|
@@ -4,6 +4,21 @@ An unsupported output format was requested.
|
|
|
4
4
|
|
|
5
5
|
## Fix
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`centrs settings set format <value>` throws this when `<value>` isn't one of
|
|
8
|
+
`text`, `json`, or `yaml` — the same `{text, json, yaml}` set every
|
|
9
|
+
command's own `--format` flag (and `CENTRS_FORMAT`) validates against
|
|
10
|
+
(`retrieveOutputFormats` and its `execute`/`transfer`/`api` counterparts).
|
|
11
|
+
`centrs settings set format xml` is the canonical trigger; see example 14 in
|
|
12
|
+
`commands/settings/examples.md`. A failed `set` never partially writes — the
|
|
13
|
+
file is unchanged.
|
|
14
|
+
|
|
15
|
+
`format` is the one managed key without a single universal built-in
|
|
16
|
+
default: `retrieve`/`execute`/`transfer` default to `text`, but `api`
|
|
17
|
+
defaults to `json`. Because of that, `centrs settings print`/`get format`
|
|
18
|
+
can't report one scalar default when the key is unset — it reports a
|
|
19
|
+
`perCommandDefault` map (`{ retrieve: "text", execute: "text", transfer:
|
|
20
|
+
"text", api: "json" }`) instead, so this is the one key where "unset" looks
|
|
21
|
+
different in the output shape than every other key.
|
|
22
|
+
|
|
23
|
+
See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Settings precedence) for
|
|
24
|
+
where `format` sits in the resolver chain once a value is set.
|
|
@@ -4,6 +4,21 @@ An integer setting received a non-integer or out-of-range value.
|
|
|
4
4
|
|
|
5
5
|
## Fix
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`centrs settings set max-results <value>` and `centrs settings set port
|
|
8
|
+
<value>` both throw this when `<value>` fails the shared positive-integer
|
|
9
|
+
rule (`resolveOptionalIntegerSetting` in `src/resolver/settings.ts`):
|
|
10
|
+
`Number.isInteger(n) && n > 0`. `0`, negative numbers (`-1`), and
|
|
11
|
+
non-numeric strings (`abc`) are all rejected the same way — `centrs settings
|
|
12
|
+
set max-results 0` is the canonical trigger (example 20 in
|
|
13
|
+
`commands/settings/examples.md`).
|
|
14
|
+
|
|
15
|
+
This validator isn't specific to `settings` — `resolveOptionalIntegerSetting`
|
|
16
|
+
is the shared helper every `CENTRS_*` integer setting resolves through
|
|
17
|
+
(`max-results`, `port`, and any future integer key), so the same code and
|
|
18
|
+
message shape appear whenever an integer env var, CLI flag, or `centrs.env`
|
|
19
|
+
line resolves to a non-positive or non-numeric value anywhere in the app,
|
|
20
|
+
not only through `settings set`.
|
|
21
|
+
|
|
22
|
+
A failed `set` never partially writes; re-run with a positive integer. See
|
|
23
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Settings precedence) for how
|
|
24
|
+
this value feeds into the resolver chain.
|
|
@@ -4,6 +4,23 @@ A timeout setting received an invalid value.
|
|
|
4
4
|
|
|
5
5
|
## Fix
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
`centrs settings set timeout <value>` throws this when `<value>` doesn't
|
|
8
|
+
match the shared duration grammar (`parseDuration` in
|
|
9
|
+
`src/resolver/settings.ts`): a bare integer (milliseconds) or an integer
|
|
10
|
+
with a `ms`/`s`/`m` suffix — `500ms`, `5s`, `1m`. Anything else, like
|
|
11
|
+
`not-a-duration` (example 22 in `commands/settings/examples.md`), fails.
|
|
12
|
+
`settings.ts` layers one more rule on top for `timeout` specifically: even a
|
|
13
|
+
syntactically valid duration that parses to `0` is rejected — a zero timeout
|
|
14
|
+
isn't a meaningful value to set.
|
|
15
|
+
|
|
16
|
+
Like the other typed-value codes here, this isn't `settings`-exclusive:
|
|
17
|
+
`parseDuration` backs `CENTRS_TIMEOUT` and every command's own `--timeout`
|
|
18
|
+
flag, so the same failure shape shows up anywhere a duration string is
|
|
19
|
+
resolved, not just through `settings set`.
|
|
20
|
+
|
|
21
|
+
One write detail worth knowing: `settings set timeout` writes the
|
|
22
|
+
**canonical parsed milliseconds**, not the raw suffixed string you typed —
|
|
23
|
+
`centrs settings set timeout 5s` writes `CENTRS_TIMEOUT=5000` to
|
|
24
|
+
`centrs.env`, not `CENTRS_TIMEOUT=5s`. See
|
|
25
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Settings precedence) for how
|
|
26
|
+
this value feeds into the resolver chain.
|
|
@@ -4,6 +4,25 @@ An unsupported protocol identifier was supplied to --via.
|
|
|
4
4
|
|
|
5
5
|
## Fix
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
This one code covers two different value sets, because `settings` reuses it
|
|
8
|
+
for two different keys. `centrs settings set via <value>` requires one of
|
|
9
|
+
the protocol identifiers in `plannedProtocols` (`src/protocols/index.ts`):
|
|
10
|
+
`rest-api`, `native-api`, `ssh`, `snmp`, `mndp`, `mac-telnet`, `romon`,
|
|
11
|
+
`winbox-terminal` — `centrs settings set via carrier-pigeon` is the
|
|
12
|
+
canonical trigger (example 21 in `commands/settings/examples.md`).
|
|
13
|
+
`centrs settings set transfer-via <value>` reuses the same error code but
|
|
14
|
+
validates against a completely different set: `auto`, `rest`/`rest-api`,
|
|
15
|
+
`native`/`native-api`, `sftp`, `scp`, `fetch`, `ftp`. Unlike `CENTRS_VIA`,
|
|
16
|
+
which has a per-device `via=` comment-kv counterpart, `CENTRS_TRANSFER_VIA`
|
|
17
|
+
has none — `transfer` reads only the env var.
|
|
18
|
+
|
|
19
|
+
The same validation backs `retrieve`/`execute`/`api`'s own `--via` flag more
|
|
20
|
+
broadly, so the identical code and message shape appear there too, not only
|
|
21
|
+
through `settings set`.
|
|
22
|
+
|
|
23
|
+
`transfer-via ftp` is syntactically valid against the `transfer-via` set
|
|
24
|
+
above — it does **not** trigger this error — but it does trigger a separate
|
|
25
|
+
warning, [`settings/consequential-value`](consequential-value.md), because
|
|
26
|
+
`transfer` still rejects `ftp` at call time unless `ALLOW_UNSAFE_PROTOCOLS`
|
|
27
|
+
also opts in. See [`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Protocol
|
|
28
|
+
selection) for the full `via` vocabulary.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `settings/reserved-key`
|
|
2
|
+
|
|
3
|
+
`settings set`/`reset` refused a credential-shaped or self-referential CENTRS_* key.
|
|
4
|
+
|
|
5
|
+
## Fix
|
|
6
|
+
|
|
7
|
+
`centrs settings set <attr> <value>` and `centrs settings reset <attr>` refuse
|
|
8
|
+
five keys outright: `password`, `username`, `cdb-password`, `skip-env-file`,
|
|
9
|
+
and `run-fast-integration` (the `settingsRefusedKeys` list in
|
|
10
|
+
`src/settings.ts`). Each is refused for a different reason, not a blanket
|
|
11
|
+
policy: `password`/`username` are credential-shaped and belong on the
|
|
12
|
+
`__default__` CDB record — run `centrs devices add __default__ --user …
|
|
13
|
+
--password …` instead of duplicating a secret into a second, unencrypted
|
|
14
|
+
file. `cdb-password` is the CDB's own decrypt password; writing it beside the
|
|
15
|
+
encrypted CDB it unlocks would defeat the encryption, so pass
|
|
16
|
+
`--cdb-password` per invocation or export `CENTRS_CDB_PASSWORD` in the
|
|
17
|
+
calling shell instead. `skip-env-file` is self-referential — a line in
|
|
18
|
+
`centrs.env` that says "ignore this file" is a no-op by construction, since
|
|
19
|
+
the file has to be read to find it. `run-fast-integration` is a CI/test
|
|
20
|
+
signal `bun run test:integration` sets, never a human preference.
|
|
21
|
+
|
|
22
|
+
`settings get`/`settings print` still work read-only on all five keys — this
|
|
23
|
+
error is specific to the write path (`set`/`reset`). A read of `cdb-password`
|
|
24
|
+
or `password` redacts the value rather than refusing outright; see
|
|
25
|
+
[`settings/unknown-key`](unknown-key.md) for the different case of a token
|
|
26
|
+
that isn't a recognized setting at all. See examples 17 and 29 in
|
|
27
|
+
`commands/settings/examples.md`, and
|
|
28
|
+
[`docs/CONSTITUTION.md`](../../CONSTITUTION.md) (Identity and CDB) for why
|
|
29
|
+
credentials route through `devices` rather than `centrs.env`.
|