@picoai/tickets 0.2.0 → 0.3.0
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/.tickets/spec/AGENTS_EXAMPLE.md +5 -4
- package/.tickets/spec/TICKETS.md +293 -383
- package/.tickets/spec/profile/defaults.yml +29 -0
- package/.tickets/spec/version/20260317-tickets-spec.md +82 -0
- package/README.md +120 -185
- package/package.json +2 -1
- package/release-history.json +7 -0
- package/src/cli.js +308 -101
- package/src/lib/claims.js +66 -0
- package/src/lib/config.js +162 -0
- package/src/lib/constants.js +8 -2
- package/src/lib/listing.js +21 -84
- package/src/lib/planning.js +355 -0
- package/src/lib/projections.js +70 -0
- package/src/lib/repair.js +1 -1
- package/src/lib/validation.js +162 -2
package/.tickets/spec/TICKETS.md
CHANGED
|
@@ -6,180 +6,244 @@ This document defines the agent-first in-repo ticketing workflow with explicit o
|
|
|
6
6
|
|
|
7
7
|
- About TICKETS.md (may be overwritten): content inside `@picoai/tickets:managed` markers.
|
|
8
8
|
- This is where canonical, interoperable system rules live.
|
|
9
|
-
- `npx @picoai/tickets init --apply` may replace this section
|
|
9
|
+
- `npx @picoai/tickets init --apply` may replace this section.
|
|
10
10
|
- User-Owned Extensions (safe to customize): content inside `@picoai/tickets:user` markers.
|
|
11
|
-
- This is where teams add local policy, integrations, and reusable preferences.
|
|
11
|
+
- This is where teams add repo-local policy, integrations, and reusable preferences.
|
|
12
12
|
- Tooling should not overwrite this section.
|
|
13
|
+
- Repo-local machine overrides: `.tickets/config.yml`.
|
|
14
|
+
- This is the authoritative override surface for semantic mapping, defaults, and reporting preferences.
|
|
15
|
+
- Tooling should create it if missing, but should not overwrite it once present.
|
|
16
|
+
- Optional repo-local narrative overrides: `TICKETS.override.md`.
|
|
17
|
+
- This is for rationale, examples, and human-readable local policy.
|
|
18
|
+
- Tooling should not depend on it for machine behavior.
|
|
13
19
|
|
|
14
20
|
## Init and Apply Behavior
|
|
15
21
|
|
|
16
22
|
- `init`:
|
|
17
|
-
- creates missing repo assets
|
|
23
|
+
- creates missing repo assets, including `TICKETS.md`, `.tickets/config.yml`, and `.tickets/skills/tickets/SKILL.md`.
|
|
18
24
|
- `init --apply`:
|
|
19
|
-
- replaces the managed section
|
|
20
|
-
-
|
|
25
|
+
- replaces the managed section in `TICKETS.md`,
|
|
26
|
+
- updates the managed `## Ticketing Workflow` block in `AGENTS.md`,
|
|
27
|
+
- refreshes the repo skill projection at `.tickets/skills/tickets/SKILL.md`,
|
|
28
|
+
- preserves user-owned sections and repo-local override files.
|
|
21
29
|
|
|
22
30
|
---
|
|
23
31
|
|
|
24
32
|
<!-- @picoai/tickets:managed:start -->
|
|
25
33
|
## About TICKETS.md (May Be Overwritten by `init --apply`)
|
|
26
34
|
|
|
27
|
-
_This section mirrors current canonical `TICKETS.md` content to preserve behavior and compatibility._
|
|
35
|
+
_This section mirrors the current canonical `TICKETS.md` content to preserve behavior and compatibility._
|
|
28
36
|
|
|
29
37
|
This repository uses a repo-native ticketing system designed for **parallel, long-running agentic work** and normal human collaboration, without relying on external services or internet access.
|
|
30
38
|
|
|
31
|
-
|
|
39
|
+
`TICKETS.md` explains the workflow, file formats, planning model, and required tool usage for both humans and agents. If there is ever a conflict between this file and other docs, follow this file.
|
|
32
40
|
|
|
33
41
|
## Spec version
|
|
34
|
-
- `version`:
|
|
35
|
-
- `version_url`: `version/
|
|
36
|
-
- Local file: `/.tickets/spec/version/
|
|
42
|
+
- `version`: 3
|
|
43
|
+
- `version_url`: `version/20260317-tickets-spec.md`
|
|
44
|
+
- Local file: `/.tickets/spec/version/20260317-tickets-spec.md`
|
|
37
45
|
|
|
38
46
|
Version definitions live under `/.tickets/spec/version/`. Each spec file is self-contained and ends with a diff from the previous version.
|
|
39
47
|
|
|
40
|
-
##
|
|
41
|
-
- A lightweight, Markdown-first ticket format stored under `/.tickets/`.
|
|
42
|
-
- A merge-friendly history model: **append-only JSONL run logs**, one file per run, per ticket.
|
|
43
|
-
- A repo-local CLI (`npx @picoai/tickets`) that is the **single integration surface** for humans, agents, and IDE/agentic tooling.
|
|
48
|
+
## Canonical artifacts and precedence
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
Parallel, long-running agentic work fails in predictable ways:
|
|
47
|
-
- Agents lose context across runs/sandboxes.
|
|
48
|
-
- Ticket “state” can drift across branches before merge (eventual consistency).
|
|
49
|
-
- Shared mutable log files are merge-conflict hotspots.
|
|
50
|
-
- Agents can loop without clear “done” criteria or verification steps.
|
|
50
|
+
The system supports both doc-first and skill-first environments without changing behavior.
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
Authoritative precedence:
|
|
53
|
+
1. CLI/spec invariants (non-overridable)
|
|
54
|
+
2. Package-managed base workflow and defaults
|
|
55
|
+
3. Repo-local `.tickets/config.yml`
|
|
56
|
+
4. Optional `TICKETS.override.md`
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
+
Repo artifacts:
|
|
59
|
+
- `TICKETS.md`: primary operational and conceptual contract
|
|
60
|
+
- `.tickets/config.yml`: authoritative repo-local machine-readable overrides
|
|
61
|
+
- `.tickets/skills/tickets/SKILL.md`: repo skill projection with equivalent workflow semantics
|
|
62
|
+
- `TICKETS.override.md`: optional narrative companion for human-only local policy
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
## What this system is
|
|
65
|
+
- A lightweight, Markdown-first ticket format stored under `/.tickets/`
|
|
66
|
+
- A merge-friendly history model: append-only JSONL run logs, one file per run, per ticket
|
|
67
|
+
- A repo-local CLI (`npx @picoai/tickets`) that is the only state-changing integration surface
|
|
68
|
+
- A generic planning model that supports features, phases, milestones, and roadmap views without hardcoding those terms into execution semantics
|
|
60
69
|
|
|
61
|
-
##
|
|
70
|
+
## Non-negotiables
|
|
71
|
+
- Keep `ticket.md` stable and human-readable. Put history in run logs.
|
|
72
|
+
- Keep run logs append-only. Never rewrite or delete log lines.
|
|
73
|
+
- Use the repo-local CLI for automation. Do not invent parallel formats.
|
|
74
|
+
- Do not derive execution behavior from free-form labels alone. Use the planning primitives.
|
|
75
|
+
|
|
76
|
+
## Quickstart
|
|
62
77
|
|
|
63
78
|
### Initialize
|
|
64
|
-
Create the repo structure and templates (idempotent):
|
|
65
79
|
- `npx @picoai/tickets init`
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
-
|
|
74
|
-
- Optional flags to set front matter at creation:
|
|
75
|
-
- `--status todo|doing|blocked|done|canceled`
|
|
76
|
-
- `--priority low|medium|high|critical`
|
|
77
|
-
- `--label <label>` (repeatable)
|
|
78
|
-
- `--assignment-mode human_only|agent_only|mixed`
|
|
79
|
-
- `--assignment-owner <@user|team:...|agent:...>`
|
|
80
|
-
- `--dependency <ticket-id>` `--block <ticket-id>` `--related <ticket-id>` (repeatable)
|
|
81
|
-
- `--iteration-timebox-minutes <int>` `--max-iterations <int>` `--max-tool-calls <int>` `--checkpoint-every-minutes <int>`
|
|
82
|
-
- `--verification-command "<cmd>"` (repeatable)
|
|
83
|
-
- `--created-at <ISO8601 UTC>`
|
|
84
|
-
|
|
85
|
-
This prints the new ticket ID (a lowercase UUIDv7) and creates:
|
|
86
|
-
- `/.tickets/<ticket-id>/ticket.md`
|
|
87
|
-
- `/.tickets/<ticket-id>/logs/`
|
|
88
|
-
|
|
89
|
-
### Validate, then work
|
|
90
|
-
- `npx @picoai/tickets validate`
|
|
91
|
-
- Add `--all-fields` to also validate optional front-matter (priority, labels, assignment.owner, verification.commands) and include those in `--issues` reports.
|
|
80
|
+
- `npx @picoai/tickets init --apply`
|
|
81
|
+
|
|
82
|
+
Default `init` creates, if missing:
|
|
83
|
+
- `TICKETS.md`
|
|
84
|
+
- `AGENTS_EXAMPLE.md`
|
|
85
|
+
- `/.tickets/config.yml`
|
|
86
|
+
- `/.tickets/skills/tickets/SKILL.md`
|
|
87
|
+
- `/.tickets/spec/version/`
|
|
92
88
|
|
|
93
|
-
|
|
94
|
-
- `npx @picoai/tickets
|
|
89
|
+
### Create and validate a ticket
|
|
90
|
+
- `npx @picoai/tickets new --title "Short title"`
|
|
91
|
+
- `npx @picoai/tickets validate`
|
|
92
|
+
- `npx @picoai/tickets validate --issues --all-fields --output issues.yaml`
|
|
95
93
|
- `npx @picoai/tickets repair --issues-file issues.yaml --all-fields --non-interactive`
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
95
|
+
### Coordinate work
|
|
96
|
+
- `npx @picoai/tickets status --ticket <id> --status doing`
|
|
97
|
+
- `npx @picoai/tickets log --ticket <id> --summary "..." --machine --context "..."`
|
|
98
|
+
- `npx @picoai/tickets claim --ticket <id>`
|
|
99
|
+
- `npx @picoai/tickets plan --format json`
|
|
100
|
+
- `npx @picoai/tickets graph --view portfolio`
|
|
103
101
|
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
## Repository layout
|
|
103
|
+
- Canonical workflow guide: `TICKETS.md`
|
|
104
|
+
- Machine-readable overrides: `/.tickets/config.yml`
|
|
105
|
+
- Repo skill projection: `/.tickets/skills/tickets/SKILL.md`
|
|
106
|
+
- Ticket storage root: `/.tickets/<ticket-id>/`
|
|
107
|
+
- Ticket definition: `ticket.md`
|
|
108
|
+
- Run logs: `logs/<run_started>-<run_id>.jsonl`
|
|
109
|
+
|
|
110
|
+
## Core planning model
|
|
111
|
+
|
|
112
|
+
The planning model is intentionally generic. Agents, validators, and rollups operate on these primitives, not on human aliases.
|
|
113
|
+
|
|
114
|
+
Primitives:
|
|
115
|
+
- `planning.node_type`: `work`, `group`, `checkpoint`
|
|
116
|
+
- `planning.group_ids`: membership edges pointing from a child to one or more containing groups
|
|
117
|
+
- `planning.precedes`: sequencing edges
|
|
118
|
+
- `planning.lane`: coarse ordering bucket
|
|
119
|
+
- `planning.rank`: fine ordering within a lane or peer set
|
|
120
|
+
- `planning.horizon`: roadmap scope such as `current`, `next`, `later`
|
|
121
|
+
- `status`: execution lifecycle state
|
|
122
|
+
- `resolution`: terminal work outcome: `completed`, `merged`, `dropped`
|
|
123
|
+
- advisory `claim`: optional coordination state, stored in logs only
|
|
124
|
+
|
|
125
|
+
Interpretation:
|
|
126
|
+
- `dependencies` and `blocks` are hard execution constraints
|
|
127
|
+
- `planning.precedes` is sequence/order, not a hard dependency
|
|
128
|
+
- `group_ids` is the only persisted grouping edge; reverse membership and rollups are derived
|
|
129
|
+
- `lane`, `rank`, and `horizon` are generic ordering dimensions, not hardcoded PM vocabulary
|
|
130
|
+
- claims do not change `status`
|
|
131
|
+
|
|
132
|
+
### Default human semantic mapping
|
|
133
|
+
|
|
134
|
+
By default:
|
|
135
|
+
- `feature` -> `planning.node_type = group`
|
|
136
|
+
- `phase` -> `planning.lane`
|
|
137
|
+
- `milestone` -> `planning.node_type = checkpoint`
|
|
138
|
+
- `roadmap` -> `planning.horizon`
|
|
139
|
+
|
|
140
|
+
Repos may override these mappings in `.tickets/config.yml` without changing the core CLI or validation invariants.
|
|
141
|
+
|
|
142
|
+
### Worked example
|
|
106
143
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
144
|
+
```yaml
|
|
145
|
+
---
|
|
146
|
+
id: 0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d
|
|
147
|
+
version: 3
|
|
148
|
+
version_url: "version/20260317-tickets-spec.md"
|
|
149
|
+
title: "Feature Alpha"
|
|
150
|
+
status: doing
|
|
151
|
+
created_at: 2026-03-17T17:00:00Z
|
|
152
|
+
planning:
|
|
153
|
+
node_type: group
|
|
154
|
+
lane: build
|
|
155
|
+
rank: 1
|
|
156
|
+
horizon: current
|
|
157
|
+
---
|
|
158
|
+
```
|
|
110
159
|
|
|
111
|
-
|
|
112
|
-
- `npx @picoai/tickets log --ticket <id> --summary "Implemented validator." --machine --actor-id "agent:cursor (human:@alice)" --context "Acceptance criteria from ticket" "API schema v2"`
|
|
160
|
+
Child work ticket:
|
|
113
161
|
|
|
114
|
-
|
|
115
|
-
|
|
162
|
+
```yaml
|
|
163
|
+
planning:
|
|
164
|
+
node_type: work
|
|
165
|
+
group_ids: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d"]
|
|
166
|
+
lane: build
|
|
167
|
+
rank: 2
|
|
168
|
+
horizon: current
|
|
169
|
+
precedes: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6e"]
|
|
170
|
+
```
|
|
116
171
|
|
|
117
|
-
|
|
172
|
+
Checkpoint ticket:
|
|
118
173
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
174
|
+
```yaml
|
|
175
|
+
planning:
|
|
176
|
+
node_type: checkpoint
|
|
177
|
+
group_ids: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d"]
|
|
178
|
+
lane: launch
|
|
179
|
+
rank: 1
|
|
180
|
+
horizon: current
|
|
181
|
+
```
|
|
125
182
|
|
|
126
|
-
|
|
127
|
-
- `<ticket-id>` is a **lowercase UUIDv7** string.
|
|
128
|
-
- Tooling MUST NOT require the directory name to match the `id` in front matter (convention only).
|
|
183
|
+
Dropped child:
|
|
129
184
|
|
|
130
|
-
|
|
185
|
+
```yaml
|
|
186
|
+
status: canceled
|
|
187
|
+
resolution: dropped
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Claim log example:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{"version":3,"version_url":"version/20260317-tickets-spec.md","ts":"2026-03-17T17:05:00Z","run_started":"20260317T170500.000Z","actor_type":"agent","actor_id":"agent:codex","summary":"Acquired claim 0191c2d3-...","event_type":"claim","written_by":"tickets","claim":{"action":"acquire","claim_id":"0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5d00","holder_id":"agent:codex","holder_type":"agent","ttl_minutes":60,"expires_at":"2026-03-17T18:05:00Z","reason":""}}
|
|
194
|
+
```
|
|
131
195
|
|
|
132
196
|
## Ticket definition (`ticket.md`)
|
|
133
|
-
Ticket files are Markdown documents with YAML front matter and a Markdown body.
|
|
134
197
|
|
|
135
|
-
|
|
136
|
-
Front matter MUST start at the first line and be enclosed by `---`.
|
|
198
|
+
Ticket files are Markdown documents with YAML front matter and a Markdown body.
|
|
137
199
|
|
|
138
|
-
|
|
200
|
+
### Required front matter
|
|
139
201
|
- `id`: lowercase UUIDv7 string
|
|
140
|
-
- `version`: format version
|
|
141
|
-
- `version_url`:
|
|
202
|
+
- `version`: integer format version
|
|
203
|
+
- `version_url`: repo-local path to the spec
|
|
142
204
|
- `title`: string
|
|
143
205
|
- `status`: `todo|doing|blocked|done|canceled`
|
|
144
|
-
- `created_at`: ISO 8601
|
|
206
|
+
- `created_at`: ISO 8601 UTC timestamp
|
|
145
207
|
|
|
146
|
-
|
|
208
|
+
### Optional front matter
|
|
147
209
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
title: "Add tickets validate --issues"
|
|
154
|
-
status: todo
|
|
155
|
-
created_at: 2026-01-29T18:42:10Z
|
|
156
|
-
---
|
|
157
|
-
# Ticket
|
|
158
|
-
...
|
|
210
|
+
Assignment:
|
|
211
|
+
```yaml
|
|
212
|
+
assignment:
|
|
213
|
+
mode: mixed
|
|
214
|
+
owner: "agent:codex"
|
|
159
215
|
```
|
|
160
216
|
|
|
161
|
-
|
|
162
|
-
**Assignment and mode**
|
|
217
|
+
Priority and labels:
|
|
163
218
|
```yaml
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
219
|
+
priority: high
|
|
220
|
+
labels: ["feature", "api"]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Relationships:
|
|
224
|
+
```yaml
|
|
225
|
+
dependencies: []
|
|
226
|
+
blocks: []
|
|
227
|
+
related: []
|
|
167
228
|
```
|
|
168
229
|
|
|
169
|
-
|
|
230
|
+
Planning:
|
|
170
231
|
```yaml
|
|
171
|
-
|
|
172
|
-
|
|
232
|
+
planning:
|
|
233
|
+
node_type: work
|
|
234
|
+
group_ids: []
|
|
235
|
+
lane: null
|
|
236
|
+
rank: null
|
|
237
|
+
horizon: null
|
|
238
|
+
precedes: []
|
|
173
239
|
```
|
|
174
240
|
|
|
175
|
-
|
|
241
|
+
Resolution:
|
|
176
242
|
```yaml
|
|
177
|
-
|
|
178
|
-
blocks: [] # ticket IDs this ticket blocks
|
|
179
|
-
related: [] # ticket IDs related to this ticket
|
|
243
|
+
resolution: completed # completed | merged | dropped
|
|
180
244
|
```
|
|
181
245
|
|
|
182
|
-
|
|
246
|
+
Limits:
|
|
183
247
|
```yaml
|
|
184
248
|
agent_limits:
|
|
185
249
|
iteration_timebox_minutes: 20
|
|
@@ -188,7 +252,7 @@ agent_limits:
|
|
|
188
252
|
checkpoint_every_minutes: 5
|
|
189
253
|
```
|
|
190
254
|
|
|
191
|
-
|
|
255
|
+
Verification:
|
|
192
256
|
```yaml
|
|
193
257
|
verification:
|
|
194
258
|
commands:
|
|
@@ -196,254 +260,121 @@ verification:
|
|
|
196
260
|
- "npx @picoai/tickets validate"
|
|
197
261
|
```
|
|
198
262
|
|
|
199
|
-
|
|
200
|
-
- Other relationship views (parent/child rollups, duplicates, supersedes, reverse edges, etc.) are computed by tooling and MUST NOT be persisted in `ticket.md`.
|
|
201
|
-
- There is no `updated_at`. “Last updated” is derived from log timestamps (`ts`).
|
|
202
|
-
|
|
203
|
-
**Custom fields (namespaced)**
|
|
263
|
+
Custom fields:
|
|
204
264
|
```yaml
|
|
205
265
|
custom:
|
|
206
266
|
my_org_priority: "P1"
|
|
207
|
-
upstream_ref: "RFC-42"
|
|
208
267
|
```
|
|
209
268
|
|
|
210
|
-
|
|
211
|
-
|
|
269
|
+
Rules:
|
|
270
|
+
- `resolution` is only valid on terminal tickets (`done` or `canceled`)
|
|
271
|
+
- `custom` is reserved for repo-local extensions not standardized by the spec
|
|
272
|
+
- other relationship views are computed by tooling and must not be persisted in `ticket.md`
|
|
212
273
|
|
|
213
|
-
###
|
|
214
|
-
- `version` is an integer format version (current: `1`).
|
|
215
|
-
- `version_url` must point to the repo-local definition for that version.
|
|
216
|
-
- Version files live under `/.tickets/spec/version/` and end with a diff from the previous version.
|
|
217
|
-
- New tooling must read older versions. If `version` is missing, tools may assume `1` and warn.
|
|
218
|
-
- Bumps are rare and only when a change cannot be expressed additively.
|
|
219
|
-
|
|
220
|
-
### Ticket body sections (required)
|
|
221
|
-
The ticket body MUST include these sections (at least the headings):
|
|
274
|
+
### Required body sections
|
|
222
275
|
- `# Ticket`
|
|
223
276
|
- `## Description`
|
|
224
|
-
- `## Acceptance Criteria`
|
|
225
|
-
- `## Verification`
|
|
226
|
-
|
|
227
|
-
---
|
|
277
|
+
- `## Acceptance Criteria`
|
|
278
|
+
- `## Verification`
|
|
228
279
|
|
|
229
280
|
## Status model
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
- `
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
- `
|
|
257
|
-
- `ts`
|
|
258
|
-
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- `
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
- `
|
|
266
|
-
- `
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- `
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
- `
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
-
|
|
290
|
-
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
1. Ticket locator
|
|
328
|
-
- A ticket ID, which maps to the ticket definition at:
|
|
329
|
-
- `/.tickets/<ticket-id>/ticket.md`
|
|
330
|
-
|
|
331
|
-
2. Task scope
|
|
332
|
-
- A short statement of what the agent is expected to do on that ticket (for example: "implement acceptance criteria", "fix failing tests", "investigate and report").
|
|
333
|
-
|
|
334
|
-
3. Run limits
|
|
335
|
-
- The run's execution limits (timebox / max tool calls / max iterations), if the ticket defines them. Agents must treat these as hard stop conditions.
|
|
336
|
-
|
|
337
|
-
### Standard instruction template
|
|
338
|
-
When launching an agent, use the following template (adapt as needed to the agent tool, but keep the semantics):
|
|
339
|
-
|
|
340
|
-
- Ticket: `<ticket-id>`
|
|
341
|
-
- Ticket file: `/.tickets/<ticket-id>/ticket.md`
|
|
342
|
-
- Scope: `<what to do>`
|
|
343
|
-
- Limits: follow `agent_limits` in the ticket (or repo defaults if not present)
|
|
344
|
-
- Stop behavior: on limit hit, stop work and write a run log entry to:
|
|
345
|
-
- `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
|
|
346
|
-
|
|
347
|
-
### Mandatory agent procedure (vendor-agnostic)
|
|
348
|
-
Given a ticket assignment, an agent must:
|
|
349
|
-
|
|
350
|
-
1. Open the ticket file at `/.tickets/<ticket-id>/ticket.md`.
|
|
351
|
-
2. Identify acceptance criteria and verification steps from the ticket.
|
|
352
|
-
3. Validate the ticket before proceeding.
|
|
353
|
-
4. If beginning active work, set status to `doing`.
|
|
354
|
-
5. Plan minimally: determine the smallest change set that satisfies the acceptance criteria.
|
|
355
|
-
6. Implement within limits.
|
|
356
|
-
7. Verify using the ticket's verification steps (or reasonable defaults if absent).
|
|
357
|
-
8. Record progress with `tickets log`, reusing the same run metadata for the same run when appropriate.
|
|
358
|
-
- if the log is machine-written, include `context`
|
|
359
|
-
- if the ticket was created by splitting a parent, include `created_from` and the copied/adapted handoff bullets in `context`
|
|
360
|
-
9. If the run changes lifecycle state, use `tickets status` again (`blocked`, `done`, or explicit reassignment/reaffirmation):
|
|
361
|
-
- Write progress and outcomes to a per-run log file:
|
|
362
|
-
- `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
|
|
363
|
-
- Include a `context` field capturing the relevant context for this run (copied/adapted inputs, decisions carried in, and any subticket handoff details).
|
|
364
|
-
- If the agent cannot write files, it must output the log content in its final response so a human/tool can persist it.
|
|
365
|
-
|
|
366
|
-
### What to do if the ticket is missing or invalid
|
|
367
|
-
If the assigned ticket file cannot be found, or is missing required sections:
|
|
368
|
-
- The agent must not proceed with implementation.
|
|
369
|
-
- The agent must log the issue and request clarification, or propose a minimal ticket fix as its output.
|
|
370
|
-
|
|
371
|
-
### Multi-ticket assignments (rare)
|
|
372
|
-
If an agent is assigned more than one ticket in a single run:
|
|
373
|
-
- The run instructions must list ticket IDs in priority order.
|
|
374
|
-
- The agent must work on only one ticket at a time, logging separately under each ticket’s logs directory.
|
|
375
|
-
- Prefer splitting work into separate runs for clarity.
|
|
376
|
-
|
|
377
|
-
### Human responsibility
|
|
378
|
-
Humans (or an orchestrator) are responsible for:
|
|
379
|
-
- selecting which tickets are assigned to which agents
|
|
380
|
-
- ensuring two agents are not intentionally assigned the same ticket unless parallel exploration is desired
|
|
381
|
-
|
|
382
|
-
---
|
|
383
|
-
|
|
384
|
-
## Agent workflow (recommended protocol)
|
|
385
|
-
Agents MUST:
|
|
386
|
-
- Read the ticket before starting work.
|
|
387
|
-
- Respect `assignment.mode` (do not work tickets marked `human_only`).
|
|
388
|
-
- Respect hard limits in `agent_limits`; if a limit is reached, stop and write a log entry.
|
|
389
|
-
- At the end of an iteration (success or failure), write a log entry that includes the `context` for that iteration and verification results (or why verification was not run).
|
|
390
|
-
- If `max_iterations` is reached without completion, stop and log a recommendation (tighten criteria, split subtickets, or request a human decision).
|
|
391
|
-
|
|
392
|
-
Humans using agentic coding tools can follow the same protocol; use `--machine` logging with `actor_type: agent` and an `actor_id` that names the tool and the human (e.g., `cursor (human:@alice)`).
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
|
|
396
|
-
## Splitting tickets (subtickets) in parallel workflows
|
|
397
|
-
If an agent discovers a ticket is too large or should be parallelized:
|
|
398
|
-
1) Create subtickets with `npx @picoai/tickets new`.
|
|
399
|
-
2) Link with `related` (and only use `dependencies`/`blocks` when there is a real ordering constraint).
|
|
400
|
-
3) Log the split on the original ticket and include `tickets_created`.
|
|
401
|
-
4) Ensure each new ticket is executable in isolation by copying/adapting the minimum required context into the child `ticket.md`, and writing a first child log entry that includes `created_from` and `context` (the carried-over bullets).
|
|
402
|
-
|
|
403
|
-
Avoid maintaining an authoritative “subtickets list” by frequently editing the parent `ticket.md` (it’s a merge-conflict hotspot). Prefer derived views and logs.
|
|
404
|
-
|
|
405
|
-
---
|
|
406
|
-
|
|
407
|
-
## Validation, issues reports, and repair
|
|
408
|
-
- `npx @picoai/tickets validate`:
|
|
409
|
-
- exit `0`: ok
|
|
410
|
-
- exit `1`: validation errors
|
|
411
|
-
- exit `2`: tooling/IO errors
|
|
412
|
-
- Add `--all-fields` to validate optional front-matter (priority, labels, assignment.owner, verification.commands) and include corresponding repairs in `--issues` output.
|
|
413
|
-
|
|
414
|
-
- `npx @picoai/tickets validate --issues` emits a machine-readable report with:
|
|
415
|
-
- all `issues` (errors and warnings), and
|
|
416
|
-
- a `repairs` section that can be edited and consumed by `tickets repair` in `--non-interactive` mode.
|
|
417
|
-
- Use `--all-fields` with `validate` and `repair` when you want optional front-matter fields to be checked and fixed.
|
|
418
|
-
- Use `--interactive` with `repair` to step through each fix, see what’s expected, and supply values (include `--all-fields` to cover optional fields too).
|
|
419
|
-
|
|
420
|
-
Minimal shape (example):
|
|
421
|
-
```yaml
|
|
422
|
-
schema_version: 1
|
|
423
|
-
tool: "tickets"
|
|
424
|
-
generated_at: "2026-01-29T00:00:00Z"
|
|
425
|
-
issues: []
|
|
426
|
-
repairs:
|
|
427
|
-
- id: "R0001"
|
|
428
|
-
enabled: false
|
|
429
|
-
safe: true
|
|
430
|
-
action: "add_sections"
|
|
431
|
-
ticket_path: "/.tickets/<id>/ticket.md"
|
|
432
|
-
params: {}
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
- `npx @picoai/tickets repair --issues-file <path>` applies enabled repairs:
|
|
436
|
-
- Safe repairs can be non-interactive.
|
|
437
|
-
- Disruptive repairs (like changing `id`) must have explicit decisions filled in (or require interactive mode).
|
|
438
|
-
- Basic log repairs are supported for missing/invalid `event_type` and invalid or missing `context` on machine-written work logs.
|
|
439
|
-
|
|
440
|
-
---
|
|
441
|
-
|
|
442
|
-
## Safety & hygiene
|
|
443
|
-
- Do not write secrets into tickets or logs.
|
|
444
|
-
- Avoid pasting large environment dumps into logs.
|
|
445
|
-
- Prefer minimal diffs; avoid unrelated refactors.
|
|
446
|
-
- When in doubt, add a log entry with decisions and next steps, and hand off.
|
|
281
|
+
- `todo`, `doing`, `blocked`, `done`, `canceled`
|
|
282
|
+
- `done` and `canceled` are terminal unless explicitly reopened by a human
|
|
283
|
+
|
|
284
|
+
`tickets status` changes the canonical lifecycle state and appends a machine-written status entry to logs.
|
|
285
|
+
|
|
286
|
+
## Claims
|
|
287
|
+
|
|
288
|
+
Claims are optional advisory leases used to reduce duplicate swarm work.
|
|
289
|
+
|
|
290
|
+
Rules:
|
|
291
|
+
- claims live only in logs
|
|
292
|
+
- claims do not change ticket `status`
|
|
293
|
+
- a claim can be acquired, renewed, released, or force-overridden with a reason
|
|
294
|
+
- expired claims are treated as inactive
|
|
295
|
+
|
|
296
|
+
Use:
|
|
297
|
+
- `npx @picoai/tickets claim --ticket <id>`
|
|
298
|
+
- `npx @picoai/tickets claim --ticket <id> --release`
|
|
299
|
+
- `npx @picoai/tickets claim --ticket <id> --force --reason "..."` to override
|
|
300
|
+
|
|
301
|
+
## Run logs
|
|
302
|
+
|
|
303
|
+
Run logs are append-only JSONL files under `logs/`.
|
|
304
|
+
|
|
305
|
+
Required log fields:
|
|
306
|
+
- `version`
|
|
307
|
+
- `version_url`
|
|
308
|
+
- `ts`
|
|
309
|
+
- `run_started`
|
|
310
|
+
- `actor_type`
|
|
311
|
+
- `actor_id`
|
|
312
|
+
- `summary`
|
|
313
|
+
- `event_type`: `status|work|claim`
|
|
314
|
+
|
|
315
|
+
Conditional fields:
|
|
316
|
+
- `context`: required for machine-written `work` entries
|
|
317
|
+
- `claim`: required for `claim` entries
|
|
318
|
+
|
|
319
|
+
Recommended fields:
|
|
320
|
+
- `changes`
|
|
321
|
+
- `verification`
|
|
322
|
+
- `tickets_created`
|
|
323
|
+
- `created_from`
|
|
324
|
+
- `decisions`
|
|
325
|
+
- `next_steps`
|
|
326
|
+
- `blockers`
|
|
327
|
+
- `custom`
|
|
328
|
+
|
|
329
|
+
## Derived views and rollups
|
|
330
|
+
|
|
331
|
+
Rollups are always derived from ticket state and logs. Parent or group tickets do not maintain authoritative child ledgers.
|
|
332
|
+
|
|
333
|
+
Derived rollup counters:
|
|
334
|
+
- `total_leaf`
|
|
335
|
+
- `active_leaf`
|
|
336
|
+
- `todo`
|
|
337
|
+
- `doing`
|
|
338
|
+
- `blocked`
|
|
339
|
+
- `done_completed`
|
|
340
|
+
- `merged`
|
|
341
|
+
- `dropped`
|
|
342
|
+
|
|
343
|
+
Completion percentage uses only active leaf work. `merged` and `dropped` do not count against the remaining denominator.
|
|
344
|
+
|
|
345
|
+
## Commands
|
|
346
|
+
|
|
347
|
+
Primary commands:
|
|
348
|
+
- `init`
|
|
349
|
+
- `new`
|
|
350
|
+
- `validate`
|
|
351
|
+
- `repair`
|
|
352
|
+
- `status`
|
|
353
|
+
- `log`
|
|
354
|
+
- `claim`
|
|
355
|
+
- `list`
|
|
356
|
+
- `plan`
|
|
357
|
+
- `graph`
|
|
358
|
+
|
|
359
|
+
Listing and reporting:
|
|
360
|
+
- `list` can filter by planning fields, claim state, and readiness
|
|
361
|
+
- `plan` reports rollups and ready queues
|
|
362
|
+
- `graph` can render dependency, sequence, portfolio, or combined views
|
|
363
|
+
|
|
364
|
+
## Agent protocol
|
|
365
|
+
|
|
366
|
+
Agents should:
|
|
367
|
+
1. Load the repo skill if supported and present, otherwise read `TICKETS.md`
|
|
368
|
+
2. Open the assigned ticket
|
|
369
|
+
3. Validate before implementation
|
|
370
|
+
4. Respect `assignment.mode`, `agent_limits`, planning constraints, and active claims
|
|
371
|
+
5. Use `status`, `log`, `claim`, `plan`, and `graph` through the CLI
|
|
372
|
+
6. If splitting work, create child tickets with copied minimum context and log `created_from`
|
|
373
|
+
|
|
374
|
+
## Safety and hygiene
|
|
375
|
+
- Do not write secrets into tickets or logs
|
|
376
|
+
- Avoid unrelated refactors in ticket-scoped work
|
|
377
|
+
- Prefer adding logs with decisions and next steps over rewriting ticket history
|
|
447
378
|
<!-- @picoai/tickets:managed:end -->
|
|
448
379
|
|
|
449
380
|
---
|
|
@@ -458,39 +389,18 @@ This section is intended for ongoing team customization and expansion.
|
|
|
458
389
|
Use this section for reusable team preferences agents should apply by default.
|
|
459
390
|
|
|
460
391
|
Examples:
|
|
461
|
-
- decomposition preference
|
|
462
|
-
- required human checkpoints
|
|
463
|
-
-
|
|
464
|
-
-
|
|
465
|
-
-
|
|
392
|
+
- decomposition preference
|
|
393
|
+
- required human checkpoints
|
|
394
|
+
- verification evidence format
|
|
395
|
+
- claim usage policy
|
|
396
|
+
- rollout and handoff expectations
|
|
466
397
|
|
|
467
|
-
### External System Mapping
|
|
398
|
+
### External System Mapping
|
|
468
399
|
|
|
469
400
|
Document how external systems map to in-repo tickets.
|
|
470
401
|
|
|
471
|
-
|
|
472
|
-
- source systems (Jira/Linear/Notion/Figma/etc.)
|
|
473
|
-
- external state -> canonical `status` mapping
|
|
474
|
-
- assignment and ownership boundaries (human teams vs agent teams/swarms)
|
|
475
|
-
- synchronization rules and conflict resolution approach
|
|
476
|
-
|
|
477
|
-
### Local Custom Policy
|
|
478
|
-
|
|
479
|
-
Use this area for repo-specific policy that should not be overwritten.
|
|
480
|
-
|
|
481
|
-
Examples:
|
|
482
|
-
- additional review gates before moving ticket status to `done`
|
|
483
|
-
- rules for high-risk or production-impacting changes
|
|
484
|
-
- release-note and changelog policy
|
|
485
|
-
|
|
486
|
-
### Optional Team Metadata Conventions
|
|
487
|
-
|
|
488
|
-
If teams need additional metadata, prefer `custom.*` namespaced keys in ticket front matter and logs.
|
|
489
|
-
|
|
490
|
-
Examples:
|
|
491
|
-
- `custom.external.ticket_id`
|
|
492
|
-
- `custom.external.state`
|
|
493
|
-
- `custom.routing.queue`
|
|
494
|
-
- `custom.design.figma_url`
|
|
402
|
+
### Local Semantic Notes
|
|
495
403
|
|
|
404
|
+
Use this section to explain local meanings for human-facing concepts such as feature, phase, milestone, and roadmap.
|
|
405
|
+
The machine-readable source of truth for overrides should remain `.tickets/config.yml`.
|
|
496
406
|
<!-- @picoai/tickets:user:end -->
|