workbite 0.1.18 → 0.1.20

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.
@@ -1,208 +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.
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.