workbite 0.1.12 → 0.1.13

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": "workbite",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "WorkBite (Work Stack + StackBite) verified native suite installer and launcher",
5
5
  "license": "UNLICENSED",
6
6
  "engines": {
package/release.json CHANGED
@@ -1,24 +1,17 @@
1
1
  {
2
- "schema": "workbite.release.v1",
3
- "product": "WorkBite",
4
- "version": "0.1.12",
5
- "launcherVersion": "0.1.12",
6
- "repository": "Shinick-Han/WorkBite-releases",
7
- "tag": "v0.1.12",
2
+ "launcherVersion": "0.1.13",
8
3
  "platforms": {
9
4
  "windows-x64": {
10
- "asset": "workbite-0.1.12-windows-x64.zip",
11
- "sha256": "ac0d1670e2d297d2e15536a2367305707da64160aee69c08c226db6700c1659f",
12
- "size": 97572683,
13
- "bundleSha256": "75ae1ce02f0a7721020d8b589be293b870515dd77374c7bdd40aa8f9a14385ad",
14
- "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.12/workbite-0.1.12-windows-x64.zip"
15
- },
16
- "linux-x64": {
17
- "asset": "workbite-0.1.12-linux-x64.tar.gz",
18
- "sha256": "36630e7c11096df8dc5ef720ecfdada286037c696fe61d787903c8922c23c5ce",
19
- "size": 81937308,
20
- "bundleSha256": "d83eeea345571a02ef1f54c0b2eef1a50b7c711d176d52beaff13470dbfe31f8",
21
- "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.12/workbite-0.1.12-linux-x64.tar.gz"
5
+ "asset": "workbite-0.1.13-windows-x64.zip",
6
+ "bundleSha256": "61886b62c848d3342580b27eb6ca76acac4bd2c608b67684139434893602d7d1",
7
+ "sha256": "061fb2b08470c9f39afc5d109abb2521e4ba137455aaebd75a7b2b1b8ccc36f5",
8
+ "size": 97782408,
9
+ "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.13/workbite-0.1.13-windows-x64.zip"
22
10
  }
23
- }
11
+ },
12
+ "product": "WorkBite",
13
+ "repository": "Shinick-Han/WorkBite-releases",
14
+ "schema": "workbite.release.v1",
15
+ "tag": "v0.1.13",
16
+ "version": "0.1.13"
24
17
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: workbite-native
3
- description: Read and record WorkBite Tasks through the installed `workbite agent` CLI or `workbite mcp` tools - check the bound workspace, list Tasks, read a Task's context, and, when the user asks for it (including a standing request made mid-work), create Tasks, update a Task's detail/status and append observable checkpoints with stable intent IDs. Use for WorkBite / Work Stack task and context requests in a WorkBite install; never route them to a separately installed `workstack`.
3
+ description: Read and record WorkBite Tasks through the installed `workbite agent` CLI or `workbite mcp` tools - check the bound workspace, list Tasks, read a Task's context, and, when the user asks for it (including a standing request made mid-work), create Tasks, update advertised Task fields and append observable checkpoints with stable intent IDs. Use advertised export/import for explicitly requested Task graph transfers. Use for WorkBite / Work Stack task and context requests in a WorkBite install; never route them to a separately installed `workstack`.
4
4
  ---
5
5
 
6
6
  # WorkBite native Tasks
@@ -14,6 +14,11 @@ install, the Store files, or raw HTTP instead.
14
14
 
15
15
  Exact argv, packets, envelopes and refusals: [references/commands.md](references/commands.md).
16
16
  Read it before the first write in a session, and for MCP tool use.
17
+ For field types, nested-array replacement and create/update examples, read
18
+ [references/task-fields.md](references/task-fields.md). For an explicitly
19
+ requested cross-workspace Task transfer, read
20
+ [references/transfer.md](references/transfer.md). Transfer is capability-gated
21
+ unreleased source; this Skill does not upgrade an installed bundle.
17
22
 
18
23
  ## Bind: one workspace, path + UUID
19
24
 
@@ -46,8 +51,17 @@ the default binding.
46
51
  intent exists, perform the writes it covers without asking again per write.
47
52
  It does not extend to other Tasks, other workspaces or other kinds of
48
53
  change.
54
+ - Probe `workbite agent capabilities` before writes. The installed command's
55
+ `packet_schema` is authoritative for every field and type, including
56
+ `changes.properties` for update. A command name alone does not prove field
57
+ support. If the schema is absent, use only that command's documented
58
+ original fields; report unavailable additions. Never use legacy `apply`,
59
+ another install or direct Store access to bypass an unavailable field.
49
60
  - Create as many Tasks as the user's intent calls for, each with its own
50
- intent ID. `follows_task_id` is optional provenance only.
61
+ intent ID. There is no five-Task reapproval cap; a transport size limit is
62
+ not a limit on the number of user-requested Tasks. `follows_task_id` is
63
+ optional provenance only. Existing targets must be named by the user or
64
+ unambiguously covered by the standing request; do not pick unrelated Tasks.
51
65
  - Never mark a Task `done` or `dropped` on your own judgement; set status only
52
66
  when the user asked for that status or the requested outcome is that status.
53
67
 
@@ -67,7 +81,8 @@ the default binding.
67
81
 
68
82
  - One logical write = one stable intent ID (`[A-Za-z0-9._:-]{8,128}`), chosen
69
83
  before sending and kept with its packet, e.g. `wb.create.20261013.login-bug`.
70
- A replay of the same ID + identical packet returns the original result; a
84
+ Receipt lookup precedes revision CAS: a replay of the same ID + identical
85
+ packet returns the original result even after later edits; a
71
86
  different packet under a used ID is `idempotency_conflict`.
72
87
  - `revision_conflict`: re-read context; re-issue against the current revision
73
88
  with a new intent ID only if the change still fits what the user asked and
@@ -21,8 +21,8 @@ workbite agent [--workspace ABS --workspace-uid UUID] <command> ...
21
21
  - `--workspace` (absolute path) and `--workspace-uid` (the workspace's UUID)
22
22
  are given together or not at all.
23
23
  - Without them, a read binds the workspace saved by the last successful
24
- `workbite open`. Writes (`tasks create`, `tasks update`, `checkpoint`)
25
- refuse without the explicit pair. Use the default only for discovery
24
+ `workbite open`. Writes (`tasks create`, `tasks update`, `checkpoint`,
25
+ import apply/rollback) refuse without the explicit pair. Use the default only for discovery
26
26
  (`capabilities`, the first `status`, `tasks list`); once `status` has
27
27
  named the workspace, pass the pair on `context` and `operation-status` too.
28
28
  - The binding is checked before every call: the workspace descriptor must
@@ -59,12 +59,21 @@ workbite agent [--workspace ABS --workspace-uid UUID] <command> ...
59
59
  entries. `--view` is `core-v1` (default), `planning-v1`, `planning-v2` or
60
60
  `resume-v1`, when the native client lists it.
61
61
 
62
+ ## Advertised fields and transfer commands
63
+
64
+ Probe `workbite agent capabilities` before using new fields or transfer
65
+ commands. Task fields require the exact command's `packet_schema`; MCP
66
+ `tools/list` must agree. See [task-fields.md](task-fields.md) for field types
67
+ and full packets, and [transfer.md](transfer.md) for unreleased,
68
+ capability-gated export/import preview/apply/status/rollback. A refusal never
69
+ authorizes legacy apply, raw HTTP or another install.
70
+
62
71
  ## Packets
63
72
 
64
73
  Exactly one JSON object from `--input-file FILE` or `--stdin` (one is
65
74
  required; they are exclusive), valid UTF-8 of at most 32768 bytes, with only
66
- the keys listed below. Write it without a BOM. A packet never names a
67
- workspace. The launcher checks size and UTF-8 and hands the text to the native
75
+ the keys admitted by the advertised `packet_schema`. Write it without a BOM.
76
+ A packet never names a workspace. The launcher checks size and UTF-8 and hands the text to the native
68
77
  client as stdin; the packet never travels in argv.
69
78
 
70
79
  `tasks create`:
@@ -73,9 +82,10 @@ client as stdin; the packet never travels in argv.
73
82
  {"title": "Fix login redirect loop", "detail": "Seen on /settings after token refresh.", "follows_task_id": "T-0004"}
74
83
  ```
75
84
 
76
- `title` is required and non-empty; `detail` and `follows_task_id` are
77
- optional. `follows_task_id` is provenance in the receipt only (no parent or
78
- dependency). One intent ID creates at most one Task.
85
+ `title` is required and nonblank; `detail` and `follows_task_id` are
86
+ original optional fields. Additional fields require `packet_schema`; see
87
+ [task-fields.md](task-fields.md). `follows_task_id` is receipt provenance only
88
+ (no parent or dependency). One intent ID creates at most one Task.
79
89
 
80
90
  `tasks update`:
81
91
 
@@ -84,8 +94,9 @@ dependency). One intent ID creates at most one Task.
84
94
  ```
85
95
 
86
96
  `expected_revision` is the integer from a fresh `context`. `changes` is a
87
- non-empty subset of `detail` (string) and `status` (`open`, `started`, `done`,
88
- `dropped`). Title, priority, due date and relations are not writable.
97
+ non-empty object matching the advertised schema. The original subset is
98
+ `detail`/`status`; additions require explicit field/type advertisement.
99
+ See [task-fields.md](task-fields.md).
89
100
 
90
101
  `checkpoint`:
91
102
 
@@ -113,7 +124,8 @@ apart later, for example `wb.create.20261013.login-bug`,
113
124
  and `meta.replayed`. `tasks create` / `tasks update` add `data.receipt`
114
125
  (`operation`, `result` `created` / `applied` / `no_change`, `task_id`,
115
126
  `before_revision`, `after_revision`, `committed_at`) and `data.task`. A
116
- replay returns the original snapshot: read `context` for current state.
127
+ receipt lookup precedes revision CAS. A replay returns the original snapshot
128
+ even after later edits: read `context` for current state.
117
129
  If `data.omitted` names `task` or `receipt`, they were dropped for size;
118
130
  `commit_state` still settles the write.
119
131
  - A write whose answer was lost or timed out exits 1 with a stderr message
@@ -181,8 +193,8 @@ or mistyped arguments are refused before anything runs.
181
193
  | `workbite_status` | no | `workspace_uid` |
182
194
  | `workbite_tasks_list` | no | `workspace_uid`, `status`, `limit`, `offset` |
183
195
  | `workbite_context` | no | `workspace_uid`, **`task_id`**, `view`, `fingerprint`, `if_fingerprint` |
184
- | `workbite_tasks_create` | yes | **`workspace_uid`**, **`intent_id`**, **`title`**, `detail`, `follows_task_id` |
185
- | `workbite_tasks_update` | yes | **`workspace_uid`**, **`intent_id`**, **`task_id`**, **`expected_revision`**, **`changes`** (`{detail?, status?}`) |
196
+ | `workbite_tasks_create` | yes | **`workspace_uid`**, **`intent_id`**, **`title`**, `detail`, `follows_task_id`, other advertised create fields |
197
+ | `workbite_tasks_update` | yes | **`workspace_uid`**, **`intent_id`**, **`task_id`**, **`expected_revision`**, **`changes`** (advertised update fields) |
186
198
  | `workbite_checkpoint` | yes | **`workspace_uid`**, **`intent_id`**, **`task_id`**, **`date`**, **`done`**, **`next`**, **`blockers`** |
187
199
  | `workbite_operation_status` | no | `workspace_uid`, **`intent_id`** |
188
200
 
@@ -196,4 +208,6 @@ or mistyped arguments are refused before anything runs.
196
208
  `commit_unknown` (with `meta.commit_state: "unknown"` and the `intent_id`
197
209
  for `workbite_operation_status`). Calls run one at a time and are never
198
210
  retried.
211
+ - Transfer tool names and exact preview/apply/status/rollback argument rules:
212
+ [transfer.md](transfer.md). They require actual native capability support.
199
213
  - No tool runs shells, raw RPC, deletes or policy changes.
@@ -0,0 +1,208 @@
1
+ # Advertised Task packet fields
2
+
3
+ Use a field only when the exact installed command's `packet_schema` admits
4
+ it: create's `properties`, or update's `properties.changes.properties`.
5
+ Probe the launcher and running owner selected by the Skill. A command key,
6
+ version, this reference or an MCP tool name alone does not prove support.
7
+ MCP `tools/list` must expose matching types too. With no schema, retain only
8
+ the documented original subset (create: title/detail/follows_task_id;
9
+ update: detail/status). Report missing requested fields; never silently omit
10
+ them or use legacy apply, another install or direct Store access.
11
+
12
+ These additive fields are unreleased source work, not a claim about any
13
+ installed bundle. The nested extension below is the NESTED FIELDS CONTRACT;
14
+ the native domain source implements these structures. Matching
15
+ Python/client/MCP completion and advertisements remain required before
16
+ claiming cross-implementation support. A working-source edit alone is not a
17
+ completed capability.
18
+
19
+ ## Normal fields
20
+
21
+ | Field | JSON value and meaning |
22
+ |---|---|
23
+ | `title` | Nonblank string; required on create. No string coercion. |
24
+ | `detail` | String, including empty string; no null or coercion. |
25
+ | `status` | `open`, `started`, `done`, `dropped`; only the status the user requested. |
26
+ | `priority` | `P0`, `P1`, `P2`, `P3`. |
27
+ | `due`, `scheduled` | Real ISO calendar date `YYYY-MM-DD`, or null to clear. |
28
+ | `estimate_minutes` | Integer 1–1440, or null to clear; booleans/fractions are invalid. |
29
+ | `tags` | Array of strings, normalized by the owner; `[]` clears. |
30
+ | `parent_id` | Existing Task ID, or null to clear; no self-parenting/cycles. |
31
+ | `dependencies` | Array of existing Task IDs, with graph validation; `[]` clears. |
32
+ | `objective_ids` | Array of existing Objective IDs; `[]` clears Task links. |
33
+ | `key_result_refs` | Array of exact `{objective_id, key_result_id}` string pairs, each an existing valid pair; `[]` clears. |
34
+ | `follows_task_id` | Optional existing Task ID on create only: receipt provenance, never a parent/dependency. |
35
+
36
+ Omission leaves a field unchanged on update and uses owner defaults on
37
+ create. Null clears only nullable fields; arrays use `[]`, never null.
38
+ Owner validation and normalization decide valid references, deduplication
39
+ and relationships. Task linking does not authorize Objective/Key Result CRUD.
40
+
41
+ `id`, `uid`, `created`, `created_at`, `updated_at`, `revision`, `status_fact_id`, actor
42
+ identity, audit and status facts are generated/protected. Do not inject them
43
+ or source history through ordinary packets. An explicitly requested create
44
+ status bootstraps fresh local status facts and audit; it cannot forge old
45
+ history. Normalized values appear in the committed `data.task` projection
46
+ when advertised, subject to the envelope's `data.omitted` size reporting.
47
+
48
+ ## Complete create example
49
+
50
+ Only send this when all fields are advertised and the referenced records
51
+ exist in the verified workspace. Replace example values with the user's
52
+ requested values. Choose one stable intent ID before sending.
53
+
54
+ ```json
55
+ {
56
+ "title": "Verify login redirect",
57
+ "detail": "Cover refresh and return-to behavior.",
58
+ "status": "started",
59
+ "priority": "P1",
60
+ "due": "2026-10-20",
61
+ "scheduled": "2026-10-16",
62
+ "estimate_minutes": 45,
63
+ "tags": ["auth", "regression"],
64
+ "parent_id": "T-0001",
65
+ "dependencies": ["T-0002"],
66
+ "objective_ids": ["O-0001"],
67
+ "key_result_refs": [{"objective_id": "O-0001", "key_result_id": "KR-0001"}],
68
+ "follows_task_id": "T-0002"
69
+ }
70
+ ```
71
+
72
+ One intent creates at most one Task. A user-requested batch has one logical
73
+ write/intent per Task, with no five-Task reapproval cap. This is not an atomic
74
+ multi-Task import: use an advertised transfer operation for a whole graph.
75
+
76
+ ## Complete update example
77
+
78
+ Read context for `T-0003` first and use its actual revision. This example
79
+ updates every normal field and demonstrates clearing nullable/array fields.
80
+
81
+ ```json
82
+ {
83
+ "task_id": "T-0003",
84
+ "expected_revision": 4,
85
+ "changes": {
86
+ "title": "Verify login return-to behavior",
87
+ "detail": "Add a regression for the reported redirect.",
88
+ "status": "open",
89
+ "priority": "P2",
90
+ "due": null,
91
+ "scheduled": "2026-10-17",
92
+ "estimate_minutes": null,
93
+ "tags": [],
94
+ "parent_id": null,
95
+ "dependencies": [],
96
+ "objective_ids": [],
97
+ "key_result_refs": []
98
+ }
99
+ }
100
+ ```
101
+
102
+ `changes` is nonempty. Never put `follows_task_id` in update. The ordinary
103
+ packet limit stays 32768 UTF-8 bytes, without BOM or duplicate JSON keys.
104
+ The transfer archive limit does not enlarge ordinary Task packets.
105
+
106
+ ## Notes and subtasks extension
107
+
108
+ These fields require explicit intent to replace the entire array, plus the
109
+ same Task revision CAS and durable receipt as other fields. Each array has
110
+ at most 128 items; `[]` clears it, null is invalid, and omission leaves it
111
+ unchanged on update (empty arrays by default on create). These are replacement
112
+ arrays, not append operations or partial child patches: include every note
113
+ or subtask the user wants retained. Read the current array before replacing
114
+ it; a bounded view that omitted it cannot establish what must be preserved.
115
+
116
+ | Field/item | Exact admitted structure |
117
+ |---|---|
118
+ | `notes` | Array of objects with required `text` and optional `date`; no other keys. |
119
+ | note `text` | Nonblank string without NUL, trimmed by the owner. |
120
+ | note `date` | Real ISO calendar date `YYYY-MM-DD`; omitted means the owner's current civil day. Null is invalid. |
121
+ | `subtasks` | Array of objects with required `title` and optional `id`, `priority`, `status`; no other keys. |
122
+ | subtask `title` | Nonblank string without NUL, trimmed by the owner. |
123
+ | subtask `id` | Optional canonical `S-[1-9][0-9]*`, numeric suffix at most 9007199254740991; no leading zeros, unique within this parent's replacement array. |
124
+ | subtask `priority` | Optional `P0`/`P1`/`P2`/`P3`, default `P2`. |
125
+ | subtask `status` | Optional `open`/`started`/`done`/`dropped`, default `open`. |
126
+
127
+ Omitted Subtask IDs allocate deterministically, in input order, above the
128
+ maximum of IDs in the parent's existing array and explicitly supplied IDs.
129
+ Keep a retained subtask's ID explicitly; omitting it requests allocation,
130
+ not title matching. This is a parent-scoped display ID, not permission to
131
+ supply a Task ID/UUID, status fact or audit identity. Exhaustion refuses.
132
+ There is no claim of a separate durable Subtask high-water beyond that
133
+ existing/supplied-array rule.
134
+
135
+ A supplied note date is user note data, never evidence of when the local
136
+ system performed an action. Defaults resolve only after durable receipt
137
+ lookup: an identical same-intent replay on another day retains the original
138
+ note dates and allocated IDs. Normalized arrays appear in new committed
139
+ Task projections; older stored receipts can lack the new arrays.
140
+
141
+ When the user requested this content, a small create packet is:
142
+
143
+ ```json
144
+ {
145
+ "title": "Check redirect behavior",
146
+ "notes": [{"text": "User reported the refresh case."}],
147
+ "subtasks": [{"title": "Reproduce refresh"}]
148
+ }
149
+ ```
150
+
151
+ After reading `T-0003` and its actual revision, a whole-array replacement is:
152
+
153
+ ```json
154
+ {
155
+ "task_id": "T-0003",
156
+ "expected_revision": 4,
157
+ "changes": {
158
+ "notes": [{"text": "Confirmed the reported case.", "date": "2026-10-15"}],
159
+ "subtasks": [
160
+ {"id": "S-2", "title": "Reproduce refresh", "priority": "P1", "status": "done"},
161
+ {"title": "Verify return-to URL", "priority": "P2", "status": "open"}
162
+ ]
163
+ }
164
+ }
165
+ ```
166
+
167
+ Here an omitted ID is above both existing IDs and `S-2`; it is not necessarily
168
+ `S-3` if the current parent already has a higher ID. A subtask marked done
169
+ does not change the parent Task status. Code completion, dates, or child
170
+ statuses never authorize an automatic parent done transition.
171
+
172
+ ## Observable field-change audit extension
173
+
174
+ The NESTED contract also requires bounded `field_changes` on the existing
175
+ `task.created`/`task.updated` activity event types for normal and nested
176
+ fields: each changed field has `before` and `after` observations. The owner
177
+ creates audit identity/time and status facts; callers never send those fields
178
+ in a Task packet. Large values may be represented by bounded digest/truncation
179
+ evidence instead of full content. Do not claim arbitrary historical values
180
+ can be recovered from such an event. A normalized no-change write still has
181
+ its own durable receipt and must not be presented as a new status transition.
182
+ This describes the extension contract, not completed cross-implementation
183
+ proof until the corresponding owner candidates pass review/integration.
184
+
185
+ ## CAS, replay and uncertain receipts
186
+
187
+ An update's `expected_revision` is compare-and-swap (CAS). On a definite
188
+ `revision_conflict`, re-read; if the intended change remains valid without
189
+ overwriting someone else's change, send a new revision/packet with a new
190
+ intent ID. Existing user intent continues to apply.
191
+
192
+ Receipt lookup precedes CAS. Same intent + identical packet returns the
193
+ original committed snapshot even after later edits. Read context for current
194
+ state. Different content under that intent is `idempotency_conflict`.
195
+
196
+ A fresh intent is a distinct logical operation, not replay or content-based
197
+ deduplication. A fresh create can create another Task with identical text.
198
+ A fresh update rechecks CAS and recomputes omitted dates/IDs against current
199
+ state; it can be rejected or change values. Do not assume identical content
200
+ under different intents must yield no_change. Never use a fresh intent to
201
+ force an unresolved same-intent write through.
202
+
203
+ On response loss or `commit_unknown`, retain the same intent and packet
204
+ bytes, stop writing and read `operation-status`. `committed` settles it;
205
+ `unknown` never means not written. Only `reason: no_receipt` permits an
206
+ identical resend under the same intent. Never change its packet or switch to
207
+ a new intent to force an unknown write through. A checkpoint's unknown
208
+ outcome is reported without appending a replacement checkpoint.
@@ -0,0 +1,204 @@
1
+ # Task graph transfer (unreleased source)
2
+
3
+ Use this workflow only for an explicitly requested cross-workspace Task
4
+ transfer, and only when the installed native client advertises each exact
5
+ command and flag. This reference describes additive source work; it is not
6
+ a release or installation claim. An unavailable command, owner route or
7
+ required proof stops that operation. Do not emulate it with per-Task writes,
8
+ raw HTTP, file copies or legacy apply. Never start an owner or backend to
9
+ make a transfer command work.
10
+
11
+ ## Bind and preview
12
+
13
+ Read source and destination status separately. Record each absolute workspace
14
+ path and independently verified UID; Task display IDs alone do not identify
15
+ a workspace. The source and destination each need their already running,
16
+ verified WorkBite owner. Bind the explicit pair on every command below.
17
+ `SOURCE_ABS`, `SOURCE_UUID`, `TARGET_ABS`, `TARGET_UUID` and digest placeholders
18
+ must be replaced with the verified values. Files contain private workspace
19
+ data; choose a private local destination and do not publish them.
20
+
21
+ ```text
22
+ workbite agent --workspace SOURCE_ABS --workspace-uid SOURCE_UUID export --output tasks-transfer.json
23
+ workbite agent --workspace TARGET_ABS --workspace-uid TARGET_UUID import --input-file tasks-transfer.json --mode new --dry-run
24
+ ```
25
+
26
+ Export options `--include-history` and `--redact` are used only when
27
+ advertised and appropriate to the requested result. Check the actual export
28
+ projection before claiming redacted content can reproduce an unredacted
29
+ workspace. Current `--redact` replaces Task titles, Objective text/quarter,
30
+ and Key Result text/target, clears Task detail/tags/notes/subtasks, and keeps
31
+ IDs, graph links, statuses and numeric progress. It refuses
32
+ `--include-history` together with `--redact`. The remaining graph and IDs may
33
+ still identify the source. `--include-history` projects observable event
34
+ IDs/types/Task IDs/timestamps and planning-status facts, excluding the private
35
+ idempotency ledger and opaque event details. Default export does not promise
36
+ full history. Output is validated and published privately/atomically; an existing output file is refused,
37
+ not overwritten. Without `--output`, inspect the advertised stdout form.
38
+
39
+ The UTF-8 envelope format is `workbite.task-transfer.v1`, containing
40
+ `source_workspace_uid`, `tasks`, `objectives` (including Key Results), optional
41
+ `source_history` and `source_digest`. The source digest binds the canonical
42
+ payload with its own `source_digest` member excluded. Do not hand-edit an
43
+ archive and assume its digest remains valid.
44
+ The entire archive AND HTTP import body must fit the advertised transfer
45
+ limit (at most 1 MiB); wrapper overhead counts. The archive admits at most
46
+ 1000 Tasks and at most 1000 Objectives, with validated Key Results.
47
+ The whole graph is one atomic batch, with no silent chunking or partial
48
+ imports. Ordinary Task packets remain limited to 32768 bytes.
49
+
50
+ `--dry-run` is read-only: it records no intent and changes no Task, Objective
51
+ or authority document. Inspect its mapping, conflicts and normalized plan,
52
+ including `source_digest`, `plan_digest` and `expected_snapshot_digest`.
53
+ The target snapshot digest covers every canonical authority document,
54
+ excluding only transfer receipt rows (`method: TRANSFER`) from
55
+ `activity.json`'s idempotency list to avoid hashing the receipt into itself.
56
+ It retains activity events, planning facts, allocator state, other intents
57
+ and authority timestamps; it is not a transport/time-based freshness token.
58
+ Never invent these proofs. Re-preview after a target change.
59
+
60
+ - `--mode new` requires an empty target Task collection. Preservation of
61
+ display IDs (`--preserve-ids`) is permitted only in that empty target;
62
+ local UUIDs and status/audit facts are still generated afresh. Retained
63
+ display-ID high-water can also refuse preservation in an empty roster.
64
+ - `--mode merge` appends distinct Tasks with generated target IDs through the
65
+ reviewed mappings and reports conflicts; it never silently overwrites
66
+ existing records. Review Objective and Key Result mapping as well as
67
+ parent/dependency links. An unresolved mapping
68
+ or conflict must be resolved by a supported plan, not guessed by the agent.
69
+ The current source appends fresh Objectives and Key Results with its
70
+ generated ID map. It does not reconcile them with existing target
71
+ Objectives, support caller-supplied mappings, or deduplicate repeat
72
+ archives under a new intent. Do not claim those features are implemented.
73
+
74
+ ## Apply exactly the previewed plan
75
+
76
+ Explicit user intent for the transfer authorizes its preview/apply sequence;
77
+ there is no extra per-Task approval or five-Task cap. If preview exposes an
78
+ ambiguity outside that intent, resolve it before applying. Keep the archive,
79
+ mode and `--preserve-ids` choice identical between preview and apply.
80
+
81
+ ```text
82
+ workbite agent --workspace TARGET_ABS --workspace-uid TARGET_UUID import --input-file tasks-transfer.json --mode new --intent-id wb.import.20261015.demo --plan-digest sha256:PLAN_HEX --expected-snapshot-digest sha256:TARGET_HEX --id-map imported-ids.json
83
+ ```
84
+
85
+ Use the actual preview's 64-hex digests, not these placeholders. `--id-map`
86
+ requests a private validated output artifact, not an input mapping or
87
+ permission to overwrite an existing file. A failed local output publication
88
+ does not prove the authority write failed; preserve the intent and inspect
89
+ import status. Never re-import under a new intent just to regenerate a file.
90
+
91
+ Apply binds one stable intent to the archive's `source_digest`, mode,
92
+ `plan_digest` and expected target snapshot. Full Task/Objective/Key Result
93
+ schema and the complete graph must be validated before effects, including
94
+ late cycles and unresolved references. Two-pass ID remapping occurs only in
95
+ a staged/private reducer snapshot. All authority changes, batch receipt and
96
+ source provenance commit in one native owner transaction. A partial external
97
+ per-Task commit is not an admitted implementation of this workflow.
98
+
99
+ ## Status, replay and rollback
100
+
101
+ ```text
102
+ workbite agent --workspace TARGET_ABS --workspace-uid TARGET_UUID import-status --intent-id wb.import.20261015.demo
103
+ ```
104
+
105
+ Import status is read-only and bound to that workspace and intent. A
106
+ committed receipt, rather than similar-looking Tasks or process exit alone,
107
+ settles the outcome. Preserve the returned import ID, ID map and resulting
108
+ `receipt.after_snapshot_digest` for observation and a possible separately
109
+ requested rollback. Receipt lookup precedes snapshot CAS: an identical replay returns the original
110
+ receipt even after later edits. Changed content under the same intent is an
111
+ idempotency conflict. A fresh intent is a new operation: importing the same
112
+ archive under another intent can append another mapped graph. The ordinary
113
+ same-intent idempotency guarantee is not arbitrary fresh-intent deduplication.
114
+ Never change intent merely to retry a lost answer or regenerate an output file.
115
+
116
+ On timeout, lost, unreadable or oversized bounded response, `commit_unknown`
117
+ or an unknown import status, stop writes and retain the exact intent, archive
118
+ and proof values. Recover by reading `import-status` with that original intent;
119
+ a response bound can hide a successful commit. Unknown never means not
120
+ committed. Do not resend automatically or choose a fresh intent.
121
+ Only retry the identical operation if the advertised recovery contract
122
+ explicitly permits it for the observed reason. Task `operation-status` is not
123
+ a substitute for `import-status`.
124
+
125
+ Rollback needs explicit user intent for undoing the exact owned import, its
126
+ `import_id`, and the expected current snapshot digest from that receipt or
127
+ an advertised read. Use a separate stable rollback intent:
128
+
129
+ ```text
130
+ workbite agent --workspace TARGET_ABS --workspace-uid TARGET_UUID import-rollback --intent-id wb.rollback.20261015.demo --import-id IMPORT_ID --expected-snapshot-digest sha256:CURRENT_HEX
131
+ ```
132
+
133
+ Rollback requires the unique retained import receipt bound to its original
134
+ intent and workspace, complete source archive/digest and ID map evidence,
135
+ and the retained pre-import graph/status snapshot. The current authority
136
+ snapshot must exactly match that import receipt's `after_snapshot_digest`
137
+ under snapshot CAS: even an unrelated authority edit prevents rollback.
138
+ Missing or incomplete proofs refuse rollback. Do not manually delete imported
139
+ records or restore raw files. Successful rollback preserves display-ID
140
+ high-water and idempotency fences, and appends a durable
141
+ rollback receipt. It does not erase evidence or rewind authority history.
142
+ The native source status route also observes retained rollback receipts by
143
+ rollback intent; verify `receipt.operation` is `tasks.import-rollback`:
144
+
145
+ ```text
146
+ workbite agent --workspace TARGET_ABS --workspace-uid TARGET_UUID import-status --intent-id wb.rollback.20261015.demo
147
+ ```
148
+
149
+ Use this only when the installed status contract supports rollback receipts.
150
+ Otherwise report the uncertainty and keep the intent; do not invent a
151
+ recovery command or retry the mutation.
152
+
153
+ ## Data fidelity and authority
154
+
155
+ Transfer preserves admitted normal Task metadata, Task graph relationships,
156
+ Objective/Key Result links and explicit source-to-target ID mappings. Target
157
+ UUIDs, actor identities, status facts and audit records belong to the target
158
+ owner and must not be blindly injected from source records. Source timestamps
159
+ and provenance remain source-only evidence. Optional `source_history` is an
160
+ archived source record, never a claim that those actions occurred locally.
161
+ The current transfer source validates and preserves nonempty Task notes and
162
+ subtasks using the same nested-array rules as ordinary Task writes (at most
163
+ 128 items per array). Supplied note dates remain user data. Supplied Subtask
164
+ display IDs remain scoped to each newly generated target parent; omitted IDs
165
+ are allocated within that parent. No source Task UUID or status fact is
166
+ installed as target authority. This source behavior still requires reviewed
167
+ integration and matching installed capability proof before use. Use official
168
+ backup/restore when required fidelity is outside the transfer schema. Source
169
+ evidence enters only through that closed schema.
170
+ Do not import arbitrary Capture, worklog, attachment or runtime state unless
171
+ a future advertised schema explicitly supports it.
172
+
173
+ A Task transfer is not a full-fidelity workspace relocation or backup restore.
174
+ For full workspace/history recovery, use the component's official backup /
175
+ restore procedure appropriate to its storage format, under separate explicit
176
+ operator authorization and its owner-stop/lease/identity requirements. This
177
+ Skill does not run restore or copy SSOT files. Moving a folder, installing a
178
+ new bundle or refreshing a Skill is not part of transfer.
179
+
180
+ ## MCP and native transport
181
+
182
+ For MCP, use a transfer tool only if the running server's `tools/list`
183
+ advertises it, with exactly its input schema and bound workspace UID. The
184
+ source tool names are `workbite_export`, `workbite_import`,
185
+ `workbite_import_status` and `workbite_import_rollback`. Import takes the
186
+ archive object and `mode`, `dry_run`, optional `preserve_ids`; apply adds
187
+ `intent_id`, `plan_digest`, `expected_snapshot_digest`. Keep those values
188
+ identical to preview. Preview takes no intent/proofs. Tool names in source
189
+ alone do not prove that the installed native client or
190
+ running owner implements them. There is no raw HTTP or shell workaround.
191
+
192
+ The npm launcher owns bounded input-file reads and private output files; the
193
+ native client consumes the archive via its existing stdin envelope. Only the
194
+ native owner implements the authority HTTP routes:
195
+
196
+ | Route | Method and body/query |
197
+ |---|---|
198
+ | `/api/v1/agent/tasks/export` | GET: `workspace_uid`, `include_history`, `redact` |
199
+ | `/api/v1/agent/tasks/import` | POST: `workspace_uid`, `archive`, `mode`, `dry_run`, `preserve_ids`, `plan_digest`, `expected_snapshot_digest`; preview proofs may be null |
200
+ | `/api/v1/agent/tasks/import-status` | GET: `workspace_uid`, `intent_id` |
201
+ | `/api/v1/agent/tasks/import-rollback` | POST: exactly `workspace_uid`, `import_id`, `expected_snapshot_digest`; the new rollback intent is only the idempotency header |
202
+
203
+ `Idempotency-Key` is present only on import apply and rollback. These are
204
+ implementation seams, not instructions to call HTTP from the Skill.