@remits/remits-cli 0.1.133 → 0.1.135

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remits/remits-cli",
3
- "version": "0.1.133",
3
+ "version": "0.1.135",
4
4
  "description": "Local CLI for auth, component sync, and live test execution against Remits",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -72,11 +72,25 @@ reference named after it.
72
72
  nothing about what you are working on, and every one of those entries shadows committed source until
73
73
  it expires. Keep the full stage for a deliberate complete snapshot or a "what is stale here?" reset.
74
74
  (`development-loop.md`)
75
+ - **`components commit` internally merge-stages for compile validation.** Its first phase uses changed-only
76
+ merge semantics so the server can compile the changed runtime source before git writes. That does not
77
+ reconcile or clean the lane, and its stage packet is not proof that the lane equals your workset. Use
78
+ `components stage --workset` for behavioral verification before landing. (`component-integrity.md`,
79
+ `component-resolution.md`)
75
80
  - **Give each agent its own lane: `remits-cli workspace use --auto`.** Without a workspace you are in
76
81
  the SHARED lane, where a full stage replaces what another agent is testing rather than merging with
77
82
  it. Each agent works in its own **clone**, never a same-branch worktree: worktrees share the branch
78
83
  ref, so one agent's pull moves `HEAD` under the others, and `components commit` refuses there.
79
- (`component-resolution.md`)
84
+ A supervised `agent serve` ticket worker is the narrow exception: it may use a per-ticket worktree under
85
+ one ticket, one lease, one staging workspace and an explicit freshness check. (`component-resolution.md`,
86
+ `support-tickets.md`)
87
+ - **Use the full vocabulary in reports and handoffs.** Say **git branch** / `branchName` for the
88
+ checkout and staging namespace, **staging lane** for the account+user+git branch+workspace Redis
89
+ overlay, **component branch** / `variantBranch` for durable `ComponentVariant` overlays, **data lane**
90
+ for test/prod records, and **source layer** for staged/variant/trunk. Do not collapse these to
91
+ "branch" or "verified"; say what was actually proven: Test pass, browser journey, corpus measurement,
92
+ sync mutation, or ticket lifecycle state. (`component-resolution.md`, `branch-variants.md`,
93
+ `development-loop.md`, `support-tickets.md`)
80
94
  - **Land only from trunk or a real variant branch.** A per-agent/feature branch (`components status` says
81
95
  `FEATURE BRANCH … [subscription-fallback]`) is safe to stage and run from — it resolves the same world
82
96
  as its target — but `components commit`/`sync` refuse it. Merge into the branch it resolves and land
@@ -87,10 +101,11 @@ reference named after it.
87
101
  behind trunk produces, because it still physically carries old copies of files nobody touched.
88
102
  (`component-integrity.md`, `branch-variants.md`)
89
103
  - **`stage` is always safe. `components commit` on trunk is the most dangerous command in the CLI.**
90
- It is not a convenience wrapper: it `git add -A`, commits, pushes, and then reconciles the whole
91
- pushed repo into the live component database — creating, updating, renaming, and **hard-deleting**
92
- rows. Prefer the observable `git commit → git push → components sync → git pull`. On trunk it refuses
93
- before any git write unless you pass `--yes`. (`component-integrity.md`)
104
+ It is not a convenience wrapper: it merge-stages/compile-validates changed source, then `git add -A`,
105
+ commits, pushes, and reconciles the whole pushed repo into the live component database — creating,
106
+ updating, renaming, and **hard-deleting** rows. Prefer the observable
107
+ `git commit → git push → components sync → git pull`. On trunk it refuses before any git write unless
108
+ you pass `--yes`. (`component-integrity.md`)
94
109
  - **After anyone lands, ask whether your lane is stale: `remits-cli components status`.** A landing clears
95
110
  only the lander's lane; yours keeps shadowing their new rows with content staged from the old base.
96
111
  `LANDED SINCE YOUR BASE` / `STALE OVERLAY` mean pull, re-stage, then verify — a pass against a stale
@@ -160,6 +160,40 @@ link carries what?"
160
160
  4. Check the resolved layer, not the source text: `testComponentSource`, or the `variant:<id>:<hash>`
161
161
  compile signature (`branch-variants.md` → *Diagnosing a variant*).
162
162
 
163
+ ### CLI tool account roles
164
+
165
+ Generic `remits-cli tools` / `remits-cli tool` calls have three account roles. Keep them separate in
166
+ commands and reports:
167
+
168
+ - `--account-id` is the **repo/scope account**. It is the account whose checkout/context you are working
169
+ from and the ceiling for scoped discovery.
170
+ - `--as-account` is the **execution account**. Use it when a tool should resolve components, branch
171
+ subscriptions and staging exactly as a reachable subscriber/client account.
172
+ - `--target-account` / `--target-account-id` is the **data target**. Use it when a tool operates on records
173
+ in another account but should not change component resolution. It is delivered to the tool as
174
+ `input.accountId` and `input.targetAccountId` (an explicit `--input` value wins), because `input.accountId`
175
+ is the key the platform's account-targeting tools actually read.
176
+
177
+ A target alone does not move the run. `--target-account 36` changes which records the tool touches;
178
+ component resolution, the branch subscription and the staging lane still belong to `--account-id`. When the
179
+ work should resolve as the other account — any subscriber or client account — pass `--as-account 36` as
180
+ well. If that is refused, the account is not reachable downward from anything you hold; ask for access
181
+ rather than reaching it through `input.accountId`, which no longer changes execution.
182
+
183
+ Legacy `input.accountId` still reaches tools as their target input, but it no longer silently turns the
184
+ whole CLI command into that account when a repo/scope account is present. The CLI says so on stderr and in
185
+ `warnings[]` in the response, so `--json` callers see it too.
186
+
187
+ The response `world` block is the truth: read `repoAccountId`, `executionAccountId`, `targetAccountId`,
188
+ `componentOwnerAccountId`, `componentBranch`, `workspace`, and `dataMode` before attaching the result to a
189
+ verification claim. `world.accountId` is the **execution** account — the same thing a verification manifest's
190
+ `accountId` declares — while the account a command was addressed to is `repoAccountId`/`checkoutAccountId`.
191
+
192
+ The `component world:` line names the branch AND why it applies (`via subscription`, `via
193
+ branch-has-variants`, `via explicit`, `via subscription-fallback`). That reason comes from the platform, not
194
+ from the CLI comparing two fields: an explicit `--variant-branch` probe REPLACES the subscription and a
195
+ variant branch's working tree decides before any edge is read, even when all three name the same branch.
196
+
163
197
  ### The same block answers the non-branch questions
164
198
 
165
199
  - *"Why are this account's documents not where I expect?"* → compare `databaseName` vs
@@ -54,6 +54,10 @@ account, not from what you named your git branch:
54
54
  | **a variant branch** (it has committed variants, or an account subscribes to it — e.g. `forked`) | that branch | trunk + **that branch's** overlays | **`ComponentVariant` overlays on that branch only** — never touches trunk rows |
55
55
  | **any other branch** (`codex/x`, `feature/y`) | that branch | the **same world as trunk**: trunk + the account's subscribed branch (`forked` for its subscriber) | **refused** (`feature_branch_landing`) — merge into the branch it resolves and land from there |
56
56
 
57
+ Use those names in handoffs: **git branch** for the checkout, **staging lane** for the temporary
58
+ account/user/git branch/workspace overlay, and **component branch** for the durable variant world. A
59
+ support ticket, component branch, and git branch can all be different at the same time.
60
+
57
61
  A branch like that is a **feature branch**, and it is safe to *run* from: stage only the components you edited,
58
62
  and runs still resolve every `forked` overlay for the subscriber. Do **not** stage untouched components to
59
63
  "restore" something reported missing — check `components status` first. It is never a place to *land* from.
@@ -139,9 +143,9 @@ and still names the owner, run the first repair sync with an explicit subscriber
139
143
  it. `--variant-branch none` (or `trunk`) forces production/subscription semantics without leaving the
140
144
  branch.
141
145
 
142
- Both work on `remits-cli test run` and `remits-cli token`; `--variant-branch` also works on
143
- `remits-cli tools` and `remits-cli tool`, so tests, browser URLs, tool discovery, and tool execution can
144
- all inspect the same committed variant world.
146
+ Both work on `remits-cli test run`, `remits-cli token`, `remits-cli tools`, `remits-cli tool`, and
147
+ `remits-cli corpus`, so tests, browser URLs, tool discovery, tool execution, and corpus operations can all
148
+ inspect the same committed variant world.
145
149
 
146
150
  The strongest end-to-end proof for a UI-visible variant is a token, not a log line:
147
151
 
@@ -368,8 +372,9 @@ The analogous hazard is different, and you must still respect it:
368
372
  `writes` in `--summary`) for what this sync actually changes, and `storedCurrent: true` on an entry for
369
373
  an overlay that is already stored as-is. Existing overlay ids appear as `variantId`; an `unchanged` row with `pruned:true` means the
370
374
  branch has converged back to trunk and the overlay would be removed. It is rejected on trunk, and
371
- `components commit --dry-run` is unsupported because `commit` performs compile validation and local git
372
- writes before syncing.
375
+ `components commit --dry-run` is unsupported because `commit` first merge-stages changed source for
376
+ compile validation, then performs local git writes before syncing. That internal stage does not
377
+ reconcile the lane; use `components stage --workset` before behavioral verification.
373
378
  - **The sync refuses a wholesale removal.** Above roughly a third of a kind — or **100% of a kind at any
374
379
  size** — it aborts that kind, reports why, and points at a rebase. Rebasing is almost always the real
375
380
  fix. Only when the removals are genuinely deliberate, re-run with `--force-tombstones`.
@@ -59,7 +59,7 @@ Do not assume `--data-mode prod` implies the deployed prod host, or that `--data
59
59
  for quick investigation tools:
60
60
 
61
61
  ```bash
62
- remits-cli tool --name "mcp_account_view" --input '{"accountId": 37}' --data-mode prod
62
+ remits-cli tool --account-id 21 --target-account 37 --name "mcp_account_view" --input '{"accountId": 37}' --data-mode prod
63
63
  ```
64
64
 
65
65
  **There are two independent async mechanisms — do not confuse or stack them:**
@@ -75,14 +75,16 @@ remits-cli tool --name "mcp_account_view" --input '{"accountId": 37}' --data-mod
75
75
  for long tools that do **not** have their own async mode. Its start response carries `callId`,
76
76
  `status:"running"`, `threadGroupingId`, `accountId`, `branchName`, and `dataMode` — but **not** any
77
77
  tool-specific ids, because the tool has not run yet; those arrive inside the `result` of the polled
78
- completed status.
78
+ completed status. The start, status and completed responses all carry a `world` block naming the
79
+ repo/scope account, execution account, target account when any, data lane, branch/workspace, component
80
+ branch, staging lane and component source/signature when known.
79
81
 
80
82
  For `mcp_run_action` / `mcp_run_agent`, prefer mechanism (1) alone — it already makes the call non-blocking
81
83
  **and** returns the run ids up front. Pass your own `actionRunId`/`agentRunId` so you can poll it
82
84
  deterministically:
83
85
 
84
86
  ```bash
85
- remits-cli tool --name "mcp_run_action" --input '{"accountId":49,"actionId":200,"executionMode":"async","actionRunId":"my-stable-run-id","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
87
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name "mcp_run_action" --input '{"actionId":200,"executionMode":"async","actionRunId":"my-stable-run-id","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
86
88
  ```
87
89
 
88
90
  Every tool response is saved in full to
@@ -93,6 +95,26 @@ or offloaded. Legacy flat `./.remits-cli/tool-responses/<callId>.json` files rem
93
95
  platform's OpenRouter model loop, where the AI client may offload large tool results before feeding
94
96
  context back to the model.
95
97
 
98
+ For cross-account workflows, keep the roles explicit:
99
+
100
+ - `--account-id` is the repo/scope account that bounds discovery and selects the local verification context.
101
+ - `--as-account` changes the execution account, so subscriber/component-branch resolution behaves as that
102
+ account.
103
+ - `--target-account` / `--target-account-id` names the tool's data target without changing component
104
+ resolution. It is sent as `input.accountId` **and** `input.targetAccountId` when `--input` omits them,
105
+ because that is the key the platform's account-targeting tools read (`mcp_run_action` resolves
106
+ `input.accountId` and otherwise falls back to the run scope). A value already in `--input` wins.
107
+ Legacy `input.accountId` on its own is still accepted as a target, but the CLI warns — on stderr and as a
108
+ `warnings[]` entry in the response, so `--json` callers see it too — when it differs from the scope account
109
+ and neither explicit flag was supplied.
110
+
111
+ **A target is not an execution account.** `--target-account` says which records the tool touches;
112
+ `--as-account` says which account's components, branch subscription and staging lane resolve. When the work
113
+ should run as the other account — the usual case for a subscriber or a client account — pass `--as-account`
114
+ too. The response `world` block is the check: `repoAccountId` / `executionAccountId` / `targetAccountId` are
115
+ three separate fields, and `world.accountId` is the EXECUTION account, matching what a verification manifest
116
+ declares.
117
+
96
118
  ### Hierarchy-scoped tool reads
97
119
 
98
120
  For read/discovery tools, the account resolved from the checkout/session is the **scope root**, not proof
@@ -112,7 +134,8 @@ Available flags:
112
134
  | Flag | Meaning |
113
135
  |---|---|
114
136
  | `--scope self|children|hierarchy` | Expand from the repo/session account for read/discovery. Exact-id lookups usually default to `children`; broad searches default to `self` unless widened. |
115
- | `--target-account-id ID` | Exact owner/execution account when already known. Required by mutating tools. |
137
+ | `--as-account ID` | Execute as this reachable account, so that account's subscription edge and component branch apply. |
138
+ | `--target-account ID` / `--target-account-id ID` | Exact owner/data target when already known; sent as `input.accountId` + `input.targetAccountId` unless `--input` already sets them. Required by mutating tools that operate on one account; does not by itself change component resolution — add `--as-account` for that. |
116
139
  | `--account-ids 1,2,3` | Explicit bounded owner list. The platform verifies every id against the scope root. |
117
140
  | `--anchor-account-id ID` | Path-disambiguation anchor for multi-parent account relationships. |
118
141
 
@@ -174,7 +197,8 @@ remits-cli agent status [--state idle|working|paused] [--ticket ID] [--activity
174
197
  remits-cli agent list [--account-id ID] [--json]
175
198
  remits-cli agent map [--account-ids 1,4] [--json] # who is EDITING which repository, from which checkout/branch/staging lane
176
199
  remits-cli agent inspect [--account-id ID] [--scope self|children] [--user-id ID|--user-email EMAIL] [--limit N] [--json]
177
- remits-cli activity inspect [--account-id ID] [--scope self|children] [--user-id ID|--user-email EMAIL] [--limit N] [--json]
200
+ remits-cli activity inspect [--account-id ID] [--scope self|children|related] [--workspace NAME] [--branch NAME] [--workstream ID] [--user-id ID|--user-email EMAIL] [--limit N] [--json]
201
+ remits-cli workstream status [--workstream ID|--workspace NAME] [--json]
178
202
  remits-cli agent release
179
203
  remits-cli ticket read|accept|status|progress|complete|release|reopen|assign|planning --ticket ID [--status S] [--resolution "..."] [--summary "..."] [--category C] [--assignee EMAIL] [--workstream VALUE] [--planned-in VALUE] [--board-stage VALUE] [--rank N] [--size VALUE] [--blocked-by VALUE] [--notes "..."]
180
204
  remits-cli ticket lease|unlease|force-unlease --ticket ID [--reason "..."] # force-unlease breaks SOMEBODY ELSE'S lease; operator only
@@ -235,8 +259,8 @@ head used different AI modes; `consistency` warns before calling a case unstable
235
259
  ```bash
236
260
  remits-cli token [--path <embeddablePathOrId>] [--data-mode test|prod] [--as-account <ID>] [--variant-branch <name|none>]
237
261
  remits-cli token inspect --token <token|tokenKey|URL> # inspect token metadata, safety/dataMode evidence, and full context
238
- remits-cli tools [--branch <name>] [--data-mode test|prod] [--variant-branch <name|none>]
239
- remits-cli tool --name <toolName> [--branch <name>] [--input "{...}"] [--data-mode test|prod] [--variant-branch <name|none>] [--timeout-ms 60000] [--async true --wait true]
262
+ remits-cli tools [--account-id <repoId>] [--as-account <executionId>] [--branch <name>] [--data-mode test|prod] [--variant-branch <name|none>]
263
+ remits-cli tool --name <toolName> [--account-id <repoId>] [--as-account <executionId>] [--target-account <targetId>] [--branch <name>] [--input "{...}"] [--data-mode test|prod] [--variant-branch <name|none>] [--timeout-ms 60000] [--async true --wait true]
240
264
  remits-cli tool status --call-id <callId> [--data-mode test|prod]
241
265
  remits-cli verify start --summary "..." [--manifest file.json] [--ticket ID] [--data-mode test|prod] # default: test
242
266
  remits-cli verify list [--max 50] [--json]
@@ -277,16 +301,47 @@ around in circles:
277
301
 
278
302
  ```bash
279
303
  remits-cli activity inspect --account-id 4 --scope children --data-mode test
304
+ remits-cli activity inspect --account-id 21 --scope related --workspace remits-fee-test-t-001r-172690b-r9 --data-mode prod
280
305
  remits-cli activity inspect --account-id 4 --scope children --user-email jason@example.com --json
306
+ remits-cli workstream status --workspace remits-fee-test-t-001r-172690b-r9
281
307
  remits-cli agent inspect --account-id 1742 --limit 50
282
308
  ```
283
309
 
284
310
  `--scope children` expands from the selected account to its hierarchy children, which is usually the right
285
- shape for platform-level review. `--user-id` / `--user-email` filters the stream to one CLI user when the
286
- platform can identify them from staged lanes, envelopes, tests, or live agent registration. `--json`
311
+ shape for platform-level review. `--scope related` follows component owners, staging lanes and verification
312
+ packet worlds out of the hierarchy — use it for split-world work where the repo account, component owner and
313
+ execution/data target differ.
314
+
315
+ **`--workspace`, `--branch` and `--workstream` NARROW `--scope related`.** With one of them the account set
316
+ becomes this account, its component owners, and only the accounts carrying matching evidence — not the whole
317
+ subtree — and the lanes, envelopes, test runs and corpus results are filtered to that workstream too. Without
318
+ one, `related` returns the subtree plus owners, which on a platform account is hundreds of accounts and an
319
+ arbitrary limit-bounded slice of their evidence. The response echoes what was applied as `filters`.
320
+
321
+ A related account is included only when the caller can already act on it, it is a descendant of the selected
322
+ account, or it is a component owner on that account's resolution path.
323
+ `--user-id` / `--user-email` filters the stream to one CLI user when the platform can identify them from
324
+ staged lanes, envelopes, tests, or live agent registration. `--json`
287
325
  returns the full structured payload for deeper analysis; the text view is intentionally compact and
288
326
  human-readable.
289
327
 
328
+ `remits-cli workstream status` is the local half. It keeps actor directories isolated but groups recent tool
329
+ response files, verification packets, call ids, envelope ids and world roles under one logical workstream id.
330
+ The id defaults to the current workspace; override it with `--workstream <id>` or `REMITS_WORKSTREAM_ID`.
331
+
332
+ The same id is stamped onto every verification packet world, so it joins the two halves:
333
+
334
+ ```bash
335
+ remits-cli workstream status --workstream fee-immediate
336
+ remits-cli activity inspect --scope related --workstream fee-immediate
337
+ ```
338
+
339
+ A campaign that spans several worlds is reported as several worlds, never merged into one line: the world
340
+ shown is the latest run's, with the distinct worlds listed beneath it.
341
+
342
+ > This is not a support ticket's `--workstream`, which is an account's own routing label (matched by
343
+ > `agent serve --serves`). Same flag name, unrelated namespaces.
344
+
290
345
  ### Verification envelopes
291
346
 
292
347
  Use a verification envelope for workflow-shaped work: concrete user journeys, browser-facing changes,
@@ -300,14 +355,15 @@ remits-cli components status
300
355
  remits-cli verify start --summary "Hosted upload updates an existing profile" --manifest acceptance.json
301
356
  ```
302
357
 
303
- An active envelope is stored per command world (`baseUrl + accountId + branch + workspace + dataMode`)
304
- inside the active local actor's mirror:
358
+ An active envelope is stored per command world (`baseUrl + accountId + git branch + workspace`)
359
+ inside the active local actor's mirror; **data mode is deliberately not part of the active pointer key**:
305
360
  `./.remits-cli/actors/<local-agent>/verification/active-contexts.json`. The legacy flat
306
361
  `./.remits-cli/verification/active` pointer is still understood for compatibility, but normal
307
362
  auto-attachment uses the actor-scoped context map, so one actor's localhost envelope does not silently
308
- capture another actor's production command. Stage/test/token/tool/sync commands attach evidence
309
- automatically while an envelope is active for that context. The explicit wrappers do the same thing and
310
- make the intent visible in terminal history:
363
+ capture another actor's production command. Stage/test/token/tool/sync commands run a server preflight
364
+ against the envelope's manifest/start world before attaching, and that is where test/prod mismatches are
365
+ refused or detached. The explicit wrappers do the same thing and make the intent visible in terminal
366
+ history:
311
367
 
312
368
  ```bash
313
369
  remits-cli verify stage --workset
@@ -372,6 +428,11 @@ Common packet meanings:
372
428
  | `sync_mutation` | Durable source moved to trunk or variant and returned a sync SHA | The committed source behaves after staging is cleared |
373
429
  | `artifact` | A file/screenshot/note exists with path, size, and sha256 | The workflow consumed it |
374
430
 
431
+ Packet meanings do not widen just because they are attached to the same envelope. In summaries, keep the
432
+ proof noun: `passed` for a Test case, `measured` for corpus comparisons, `synced` for source movement,
433
+ `complete` for ticket lifecycle, and `verified` only for claims listed under `Verified` by
434
+ `remits-cli verify report`.
435
+
375
436
  Final claims should come from `remits-cli verify report`. Treat `Verified` as the acceptance boundary.
376
437
  `Additional evidence` is useful handoff context, but it does not satisfy a missing required packet unless
377
438
  the report lists it under `Verified`. If the report says `partially_verified`, stale, or missing evidence,
@@ -419,6 +480,9 @@ For tests specifically:
419
480
  nested `sync` (summary with `--summary`), and on failure `error` + `nextStep`. It stops at the first
420
481
  failed phase. `phase: "sync"` with `pushed: true` means the remote holds work the platform has not
421
482
  reconciled — follow `nextStep`; do not re-run `components commit`.
483
+ - The `stage` phase of `components commit` is changed-source compile validation. It merge-stages the
484
+ changed runtime source and intentionally leaves unrelated staged entries in the lane, so it is not a
485
+ substitute for `components stage --workset` when a clean workset lane is part of the proof.
422
486
  - `components commit` on trunk refuses before staging, committing, or pushing unless `--yes` is present —
423
487
  with or without `--safe`. Trunk has no dry-run plan, so nothing can preview the full repo-to-DB reconcile.
424
488
  - `components commit` refuses before any git write while its branch is checked out in another worktree
@@ -492,6 +556,10 @@ For tests specifically:
492
556
  shrink a lane inherited from an earlier full stage; the command warns when it retains entries that way.
493
557
  `--changed-only --replace-lane` is the explicit spelling of `--workset`.
494
558
 
559
+ `components commit` uses merge semantics only for its internal compile-validation stage. That packet says
560
+ the changed source compiled in the current overlay; it does not say the lane was reconciled or that
561
+ retained entries stopped shadowing committed source.
562
+
495
563
  An empty workset never clears a lane: `--workset` on a clean tree stages nothing and leaves the lane as
496
564
  it is. `--empty-workset clear` opts into the clear; `components clear --all` is the direct way.
497
565
 
@@ -43,6 +43,12 @@ than replacing it: a payload that only carries `source` inherits `path`, `object
43
43
  from the layer below. A staged edit made on a variant branch therefore layers over **that variant**, not
44
44
  over trunk.
45
45
 
46
+ Vocabulary matters because all three layers also carry branch-shaped fields. `branchName` is the git
47
+ branch / staging namespace. `componentBranch` or `variantBranch` is the committed `ComponentVariant`
48
+ overlay an account resolves. A **staging lane** is account + CLI user + git branch + workspace in Redis.
49
+ When writing a report, name the source layer and the branch kind explicitly; "the branch was verified"
50
+ does not tell the next agent what ran.
51
+
46
52
  Plus the compile cache:
47
53
 
48
54
  - **Compiled-closure cache (`BaseClosureDomain.CLOSURE_CACHE`).** An in-memory, **per-JVM-instance** Guava
@@ -209,6 +215,11 @@ local actors even if they intentionally use the same or different staging worksp
209
215
  `remits-cli doctor local-state` to see the active actor, state directory, legacy flat state, and other
210
216
  actor directories.
211
217
 
218
+ A local **workstream id** groups one logical proof campaign across those isolated actor directories without
219
+ flattening them. It defaults to the current workspace. Override it with `--workstream <id>` or
220
+ `REMITS_WORKSTREAM_ID` when several actors are collecting evidence for one task, then inspect the local
221
+ index with `remits-cli workstream status`.
222
+
212
223
  - `.remits-cli/workspace` is per-checkout and gitignored, so each clone keeps its own lane.
213
224
  - Precedence: `--workspace NAME` > `REMITS_WORKSPACE` > `.remits-cli/workspace` > shared default lane.
214
225
  - `--no-workspace` targets the shared lane for one command without clearing the file.
@@ -260,6 +271,11 @@ them, so the overlay IS the workset. That is the mode to iterate in.
260
271
  other staged entry alone. So it can never shrink a lane inherited from an earlier full snapshot — the
261
272
  overlay stays at 115 while you work on seven. The command warns when entries are retained that way.
262
273
 
274
+ `components commit` uses that same merge shape for its internal compile-validation stage before git
275
+ writes. Treat it as "compile the changed source in the current overlay", not "make the overlay equal my
276
+ workset". If lane cleanliness is part of the proof, run `components stage --workset` and verify before
277
+ the commit/sync path.
278
+
263
279
  Every count is `unknown` rather than `0` when it cannot be established. "git could not answer" and "git
264
280
  says nothing changed" are different facts and only one of them is a number.
265
281
 
@@ -84,6 +84,11 @@ command world. While active, `components stage`, `components status`, `test run`
84
84
  `--verify-envelope <id>` to name one explicitly or `--no-verify-envelope` when a command should not be
85
85
  attached.
86
86
 
87
+ When one human task spans several local actors, keep actor isolation but give the task one workstream id:
88
+ `--workstream <id>` or `REMITS_WORKSTREAM_ID`. It defaults to the current workspace, and
89
+ `remits-cli workstream status` shows the local response files, packet ids, actors and account roles for that
90
+ campaign without copying large payloads.
91
+
87
92
  `verify start` proves in the **test** lane unless you pass `--data-mode prod` (your session's lane does not
88
93
  decide it). One envelope is active per checkout world (host, account, git branch, workspace); the data lane
89
94
  is not part of that selection.
@@ -117,6 +122,12 @@ remits-cli verify report
117
122
  The report is the final-response source. It separates verified claims, missing evidence, stale packets,
118
123
  and the source/account/lane tuple, so do not replace it with a generic "verified" sentence.
119
124
 
125
+ Use proof-level words precisely in the final response and on tickets. A passing Test is Test proof in
126
+ the recorded world, a token is URL/resolution proof, a browser step is user-journey proof, a corpus
127
+ comparison is measurement proof, a sync packet is durable source movement, and a ticket `complete` is
128
+ lifecycle state. Only `verify report` decides which of those packets satisfy the manifest's `Verified`
129
+ section.
130
+
120
131
  For Test requirements, be specific enough for the evaluator to know what a pass means:
121
132
 
122
133
  ```json
@@ -403,6 +414,10 @@ If no relevant Test component exists yet, consider creating one. Test components
403
414
 
404
415
  New test files use the `new_` prefix (e.g., `new_MyTest.groovy`) and no `id:` in the sidecar — see "Creating a component that does not exist yet" in Step 2. Run them **by name** (`remits-cli test run --test "My Test"`) until a sync assigns an id and renames the file.
405
416
 
417
+ A `remits-cli corpus import` packet is fixture ingestion, not a measurement and not acceptance. Corpus
418
+ evidence begins when an evaluation Test actually runs those cases and records measurements; the report
419
+ still has to say whether the run used live AI, mocked AI, or a declared `withAiBudget(...)`.
420
+
406
421
  **How to write the Test itself is not a CLI concern** — what a suite can assert, how mocks behave across HTTP/relay boundaries, driving an embeddable in-process, and the front-stage-only rule all live in `guides/test-components.md`. Read that before authoring a suite.
407
422
 
408
423
  **Option B — Visual verification with Playwright** (for UI changes or when the user wants to "see it"):
@@ -592,6 +607,11 @@ unexpectedly, stop and inspect the repo-local session log before running any mut
592
607
  Use `remits-cli doctor local-state` first if you did not create the checkout; it names the active local
593
608
  actor and points at the actor-scoped session log/tool-response directories.
594
609
 
610
+ Its first phase internally stages changed runtime source with merge semantics for compile validation. That
611
+ is useful validation evidence, but it deliberately does not reconcile the lane or prove the overlay equals
612
+ your workset. Keep behavioral verification on the explicit loop: `components stage --workset`, then
613
+ `test run` or browser proof, then land.
614
+
595
615
  **Git is required for durable sync.** The platform syncs by pulling from the git remote (`GitHubClient.syncFromRepository`). If `git push` fails, the server has nothing new to sync. You can still **stage** and **test** without git — only durable sync requires it.
596
616
 
597
617
  **Landing is serial, and the platform now enforces it.** `components commit` takes a short exclusive
@@ -176,6 +176,27 @@ Before starting an investigation outside the confirmed current repo:
176
176
  4. Confirm whether you are in `CLIENT`, `PLATFORM`, or `PRODUCT` context
177
177
  5. Then continue with the investigation flow below
178
178
 
179
+ For generic tool/action probes in a split-world workstream, keep the account roles explicit. From a forked or
180
+ subscriber repo, use `--account-id <repo/scope>` for the checkout account, `--as-account <execution>` when
181
+ component resolution should run as a client/subscriber, and `--target-account <target>` for the account whose
182
+ records the tool operates on. Then read the printed `World:` block and saved response file; it names the
183
+ repo/scope account, execution account, target account, component owner, branch/workspace, data lane,
184
+ component branch, staging lane and source signature when known.
185
+
186
+ Use `activity inspect --scope related` when evidence spans accounts that are not in one hierarchy branch.
187
+ Always pass `--workspace`, `--branch` or `--workstream` with it: those NARROW the view to the accounts and
188
+ evidence carrying that workstream, and without one, `related` returns the whole subtree plus component owners
189
+ with an arbitrary limit-bounded slice of their evidence. The response echoes the applied `filters`.
190
+
191
+ `workstream status --workspace <workspace>` reviews the local actor-scoped files that belong to one proof
192
+ campaign. The workstream id is stamped onto every verification packet world, so the same id works on both
193
+ sides:
194
+
195
+ ```bash
196
+ remits-cli workstream status --workstream <id>
197
+ remits-cli activity inspect --scope related --workstream <id>
198
+ ```
199
+
179
200
  **Document-First** (most common — user reports a data issue):
180
201
  1. `mcp_account_view` — understand the account's schemas and components.
181
202
  2. `mcp_firestore_search` — find the document, capture its `object_id`.
@@ -274,8 +274,10 @@ Four things are worth knowing and are not obvious:
274
274
  - **A spawned local ticket worker owns its checkout grounding and already has its staging lane.** For
275
275
  repository work, `remits-cli agent serve` appends the local repository checkout, target branch and a
276
276
  suggested per-ticket worktree path. Before editing, create or choose an isolated worktree appropriate to
277
- the ticket. For a ticket with no component branch subscription, the target branch is the repository
278
- default before it is the launch checkout's current branch. The supervisor sets
277
+ the ticket. This is the supervised ticket-worker exception to the ordinary "one independent agent, one
278
+ clone" rule: the worker has one ticket, one edit lease, one target branch, and one freshness check. For
279
+ a ticket with no component branch subscription, the target branch is the repository default before it is
280
+ the launch checkout's current branch. The supervisor sets
279
281
  `REMITS_WORKSPACE=ticket-<id>` for you; if you choose a detached worktree, export
280
282
  `REMITS_GIT_BRANCH=<branch>` before running `remits-cli`. A worktree is a checkout-isolation tool, not
281
283
  a freshness proof: fetch, fast-forward and prove `HEAD...origin/<branch>` is `0 0` before the first
@@ -405,6 +407,11 @@ remits-cli ticket create --account-id 49 --subject "Vendor name lost on re-norma
405
407
  `--reference-id` makes it get-or-create, so a re-run — or another worker reaching the same conclusion
406
408
  — reconciles onto the same ticket instead of filing a duplicate.
407
409
 
410
+ `ticket complete` is lifecycle closure, not evidence by itself. If a ticket changed component behavior,
411
+ the resolution should cite the proof level that backs it: the `verify report` id, Test run id, browser
412
+ journey, corpus comparison, sync SHA, or the reason verification is intentionally missing. A completed
413
+ ticket can still be reopened when later evidence shows the claimed behavior was not proved.
414
+
408
415
  Marking and evidence, so the next reader does not repeat your work:
409
416
 
410
417
  ```bash
@@ -72,8 +72,8 @@ For long-running Action/Agent runners, use the tool's own async mode (`execution
72
72
  the `actionRunId`/`agentRunId` (and, for agents, `sessionId`) immediately:
73
73
 
74
74
  ```bash
75
- remits-cli tool --name "mcp_run_action" --input '{"accountId":37,"actionName":"Rebuild Invoice","executionMode":"async","actionInput":{"invoiceId":"abc"}}' --data-mode prod
76
- # poll by run id: {"controlAction":"status","accountId":37,"actionRunId":"<actionRunId>"}
75
+ remits-cli tool --account-id 21 --as-account 37 --target-account 37 --name mcp_run_action --input '{"actionName":"Rebuild Invoice","executionMode":"async","actionRunId":"my-stable-run-id","actionInput":{"invoiceId":"abc"}}' --data-mode prod
76
+ # poll by run id: --account-id 21 --as-account 37 --target-account 37 --input '{"controlAction":"status","actionRunId":"my-stable-run-id"}'
77
77
  ```
78
78
 
79
79
  For long tools that lack their own async mode, use the CLI transport async (`--async true`), optionally with
@@ -81,13 +81,24 @@ For long tools that lack their own async mode, use the CLI transport async (`--a
81
81
  (see `command-reference.md` → *Tool Execution Lifecycle*). Use `--timeout-ms <ms>` only to adjust the per-request client timeout; it is
82
82
  not a replacement for async mode on multi-minute workflows.
83
83
 
84
- **Account-id precedence for tool calls.** When the CLI and the tool input both carry an account id, the server resolves them in this order:
84
+ **Account roles for tool calls.** Keep the repo/scope account separate from the account whose data/runtime the
85
+ tool exercises:
85
86
 
86
- 1. Explicit `--account-id <ID>` flag — always wins. Use this when you want to be certain the tool runs against a specific account (and the user's session covers it).
87
- 2. `input.accountId` (or `input.account_id`) — the tool's per-call execution target.
88
- 3. The current repo's `account-info.json` / active session — the default fallback.
87
+ 1. `--account-id <ID>` is the repo/scope account that bounds discovery and verification.
88
+ 2. `--as-account <ID>` is the execution account, matching `test run --as-account`.
89
+ 3. `--target-account <ID>` is the tool/data target when the tool operates on a specific account but should not
90
+ change component resolution. It is sent as `input.accountId` and `input.targetAccountId` when `--input`
91
+ omits them — `input.accountId` is the key `mcp_run_action` and friends actually read, and without it they
92
+ fall back to the run scope.
89
93
 
90
- So from inside a parent account's repo you can target a child account just by setting `input.accountId`, or force it with `--account-id` if you need it to override whatever the tool input says. Verify with the `accountId` field in the response envelope.
94
+ A target does not move the run: pass `--as-account` too whenever the work should resolve as that account's
95
+ components, branch subscription and staging lane.
96
+
97
+ Legacy `input.accountId` (or `input.account_id`) is still accepted as an explicit target for older snippets,
98
+ but prefer flags for new work; the CLI warns on stderr and in `warnings[]` when it is used alone. The
99
+ response `world` block is the source of truth: check `repoAccountId`, `executionAccountId`,
100
+ `targetAccountId`, `componentBranch`, `workspace`, and `dataMode`. `world.accountId` is the execution
101
+ account.
91
102
 
92
103
  ### `mcp_account_view`
93
104
  Returns complete account structure — schemas, components, relationships.
@@ -414,7 +425,7 @@ staged-vs-DB provenance in the result.
414
425
  Describe the Action first when the input shape is not obvious. This does not execute the Action:
415
426
 
416
427
  ```bash
417
- remits-cli tool --name mcp_run_action --input '{"controlAction":"describe","accountId":743,"actionId":25,"includeInputSchema":true}' --data-mode prod
428
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"controlAction":"describe","actionId":25,"includeInputSchema":true}' --data-mode prod
418
429
  ```
419
430
 
420
431
  The describe response reports `hasInputSchema`, optional `inputSchema`, `inferredInputKeys`, and component
@@ -423,7 +434,7 @@ provenance. If `hasInputSchema:false`, treat `inferredInputKeys` as a best-effor
423
434
  Use direct mode only for quick Actions:
424
435
 
425
436
  ```bash
426
- remits-cli tool --name mcp_run_action --input '{"accountId":49,"actionId":200,"executionMode":"direct","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
437
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"actionId":200,"executionMode":"direct","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
427
438
  ```
428
439
 
429
440
  Use the tool's own async mode for long-running Action execution — it returns immediately with an
@@ -432,14 +443,14 @@ of the start response. Do **not** also pass the CLI `--async` flag; that only bu
432
443
  transport layer:
433
444
 
434
445
  ```bash
435
- remits-cli tool --name mcp_run_action --input '{"accountId":49,"actionId":200,"executionMode":"async","actionRunId":"my-stable-run-id","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
446
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"actionId":200,"executionMode":"async","actionRunId":"my-stable-run-id","actionInput":{"sourceDocumentId":"..."}}' --data-mode prod
436
447
  ```
437
448
 
438
449
  Then poll that run with another **regular tool call** carrying `controlAction:"status"` and the same
439
- `accountId` + `actionRunId`:
450
+ explicit account flags + `actionRunId`:
440
451
 
441
452
  ```bash
442
- remits-cli tool --name mcp_run_action --input '{"controlAction":"status","accountId":49,"actionRunId":"my-stable-run-id"}' --data-mode prod
453
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"controlAction":"status","actionRunId":"my-stable-run-id"}' --data-mode prod
443
454
  ```
444
455
 
445
456
  > This poll is a normal `remits-cli tool --name mcp_run_action` call — **not** `remits-cli tool status`,
@@ -448,12 +459,17 @@ remits-cli tool --name mcp_run_action --input '{"controlAction":"status","accoun
448
459
  > If you started the run with a different `userId`, include that same `userId` in the poll (the run's status
449
460
  > is keyed by account + user + `actionRunId`; it otherwise defaults to the current user).
450
461
 
462
+ `input.accountId` is still accepted by older tool implementations and legacy snippets, but it is no longer
463
+ the recommended way to describe cross-account work. Prefer `--account-id` for the repo/scope account and
464
+ `--as-account`/`--target-account` for the Action's execution/data account so verification packets and
465
+ `activity inspect --scope related` can report the split world without guessing.
466
+
451
467
  For job-style Actions only (`Action.job == true`), prefer `executionMode:"event"` when you want the durable
452
468
  Event lifecycle, Event status, and platform recovery behavior. Event mode is inherently async; poll it the
453
469
  same way (`controlAction:"status"` + `actionRunId`) — the status resolves the backing Event's terminal state:
454
470
 
455
471
  ```bash
456
- remits-cli tool --name mcp_run_action --input '{"accountId":49,"actionId":200,"executionMode":"event","actionRunId":"my-stable-run-id","actionInput":{}}' --data-mode prod
472
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --input '{"actionId":200,"executionMode":"event","actionRunId":"my-stable-run-id","actionInput":{}}' --data-mode prod
457
473
  ```
458
474
 
459
475
  Returned fields on the async/event start: `actionRunId`, `status:"running"`, `executionMode`,
@@ -482,10 +498,10 @@ turns up a run that is consuming resources and should not finish — the case th
482
498
 
483
499
  ```bash
484
500
  # the usual path: you found the event in mcp_record_listing / mcp_object_activity
485
- remits-cli tool --name mcp_run_action --data-mode prod --input '{"controlAction":"interrupt","accountId":49,"eventId":19102,"reason":"runaway extraction, 45min"}'
501
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --data-mode prod --input '{"controlAction":"interrupt","eventId":19102,"reason":"runaway extraction, 45min"}'
486
502
 
487
503
  # or stop a run you started yourself (executionMode:'event' only)
488
- remits-cli tool --name mcp_run_action --data-mode prod --input '{"controlAction":"interrupt","accountId":4,"actionRunId":"my-run-id"}'
504
+ remits-cli tool --account-id 21 --as-account 49 --target-account 49 --name mcp_run_action --data-mode prod --input '{"controlAction":"interrupt","actionRunId":"my-run-id"}'
489
505
  ```
490
506
 
491
507
  Aliases `cancel` / `stop` / `kill` all work. What you need to know before using it: