@picoai/tickets 0.1.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 +295 -358
- package/.tickets/spec/profile/defaults.yml +29 -0
- package/.tickets/spec/version/20260311-tickets-spec.md +38 -0
- package/.tickets/spec/version/20260317-tickets-spec.md +82 -0
- package/README.md +122 -147
- package/package.json +4 -1
- package/release-history.json +19 -0
- package/src/cli.js +462 -137
- 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 +75 -1
- package/src/lib/util.js +5 -1
- package/src/lib/validation.js +216 -0
- package/src/release-status.js +141 -0
package/.tickets/spec/TICKETS.md
CHANGED
|
@@ -6,169 +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
|
|
69
|
+
|
|
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.
|
|
60
75
|
|
|
61
|
-
## Quickstart
|
|
76
|
+
## Quickstart
|
|
62
77
|
|
|
63
78
|
### Initialize
|
|
64
|
-
Create the repo structure and templates (idempotent):
|
|
65
79
|
- `npx @picoai/tickets init`
|
|
66
|
-
-
|
|
67
|
-
- Add `--apply` to upsert/create the managed `## Ticketing Workflow` block in `AGENTS.md` from `AGENTS_EXAMPLE.md` (without creating `AGENTS_EXAMPLE.md` in the target repo).
|
|
68
|
-
- With `--apply`, `TICKETS.md` updates are marker-scoped: the managed block is replaced and metadata refreshed, while user-owned sections remain unchanged.
|
|
69
|
-
|
|
70
|
-
Default `init` creates (if missing): `/.tickets/`, `TICKETS.md`, `AGENTS_EXAMPLE.md`, and `/.tickets/spec/version/`.
|
|
71
|
-
|
|
72
|
-
### Create a ticket
|
|
73
|
-
- `npx @picoai/tickets new --title "Short title"` (defaults: `status: todo`, `created_at: now`)
|
|
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`
|
|
92
81
|
|
|
93
|
-
|
|
94
|
-
- `
|
|
95
|
-
- `
|
|
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/`
|
|
96
88
|
|
|
97
|
-
###
|
|
98
|
-
|
|
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`
|
|
93
|
+
- `npx @picoai/tickets repair --issues-file issues.yaml --all-fields --non-interactive`
|
|
99
94
|
|
|
100
|
-
|
|
101
|
-
- `npx @picoai/tickets
|
|
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`
|
|
102
101
|
|
|
103
|
-
|
|
104
|
-
-
|
|
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
|
|
105
143
|
|
|
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
|
|
106
157
|
---
|
|
158
|
+
```
|
|
107
159
|
|
|
108
|
-
|
|
109
|
-
- Canonical workflow guide: `TICKETS.md`
|
|
110
|
-
- Ticket storage root: `/.tickets/`
|
|
111
|
-
- One ticket per directory: `/.tickets/<ticket-id>/`
|
|
112
|
-
- Ticket definition: `/.tickets/<ticket-id>/ticket.md`
|
|
113
|
-
- Run logs: `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
|
|
160
|
+
Child work ticket:
|
|
114
161
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
+
```
|
|
118
171
|
|
|
119
|
-
|
|
172
|
+
Checkpoint ticket:
|
|
173
|
+
|
|
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
|
+
```
|
|
182
|
+
|
|
183
|
+
Dropped child:
|
|
184
|
+
|
|
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
|
+
```
|
|
120
195
|
|
|
121
196
|
## Ticket definition (`ticket.md`)
|
|
122
|
-
Ticket files are Markdown documents with YAML front matter and a Markdown body.
|
|
123
197
|
|
|
124
|
-
|
|
125
|
-
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.
|
|
126
199
|
|
|
127
|
-
|
|
200
|
+
### Required front matter
|
|
128
201
|
- `id`: lowercase UUIDv7 string
|
|
129
|
-
- `version`: format version
|
|
130
|
-
- `version_url`:
|
|
202
|
+
- `version`: integer format version
|
|
203
|
+
- `version_url`: repo-local path to the spec
|
|
131
204
|
- `title`: string
|
|
132
205
|
- `status`: `todo|doing|blocked|done|canceled`
|
|
133
|
-
- `created_at`: ISO 8601
|
|
206
|
+
- `created_at`: ISO 8601 UTC timestamp
|
|
134
207
|
|
|
135
|
-
|
|
208
|
+
### Optional front matter
|
|
136
209
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
title: "Add tickets validate --issues"
|
|
143
|
-
status: todo
|
|
144
|
-
created_at: 2026-01-29T18:42:10Z
|
|
145
|
-
---
|
|
146
|
-
# Ticket
|
|
147
|
-
...
|
|
210
|
+
Assignment:
|
|
211
|
+
```yaml
|
|
212
|
+
assignment:
|
|
213
|
+
mode: mixed
|
|
214
|
+
owner: "agent:codex"
|
|
148
215
|
```
|
|
149
216
|
|
|
150
|
-
|
|
151
|
-
**Assignment and mode**
|
|
217
|
+
Priority and labels:
|
|
152
218
|
```yaml
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
owner: null # "@alice", "team:core", "agent:codex"
|
|
219
|
+
priority: high
|
|
220
|
+
labels: ["feature", "api"]
|
|
156
221
|
```
|
|
157
222
|
|
|
158
|
-
|
|
223
|
+
Relationships:
|
|
159
224
|
```yaml
|
|
160
|
-
|
|
161
|
-
|
|
225
|
+
dependencies: []
|
|
226
|
+
blocks: []
|
|
227
|
+
related: []
|
|
162
228
|
```
|
|
163
229
|
|
|
164
|
-
|
|
230
|
+
Planning:
|
|
165
231
|
```yaml
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
232
|
+
planning:
|
|
233
|
+
node_type: work
|
|
234
|
+
group_ids: []
|
|
235
|
+
lane: null
|
|
236
|
+
rank: null
|
|
237
|
+
horizon: null
|
|
238
|
+
precedes: []
|
|
169
239
|
```
|
|
170
240
|
|
|
171
|
-
|
|
241
|
+
Resolution:
|
|
242
|
+
```yaml
|
|
243
|
+
resolution: completed # completed | merged | dropped
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Limits:
|
|
172
247
|
```yaml
|
|
173
248
|
agent_limits:
|
|
174
249
|
iteration_timebox_minutes: 20
|
|
@@ -177,7 +252,7 @@ agent_limits:
|
|
|
177
252
|
checkpoint_every_minutes: 5
|
|
178
253
|
```
|
|
179
254
|
|
|
180
|
-
|
|
255
|
+
Verification:
|
|
181
256
|
```yaml
|
|
182
257
|
verification:
|
|
183
258
|
commands:
|
|
@@ -185,238 +260,121 @@ verification:
|
|
|
185
260
|
- "npx @picoai/tickets validate"
|
|
186
261
|
```
|
|
187
262
|
|
|
188
|
-
|
|
189
|
-
- Other relationship views (parent/child rollups, duplicates, supersedes, reverse edges, etc.) are computed by tooling and MUST NOT be persisted in `ticket.md`.
|
|
190
|
-
- There is no `updated_at`. “Last updated” is derived from log timestamps (`ts`).
|
|
191
|
-
|
|
192
|
-
**Custom fields (namespaced)**
|
|
263
|
+
Custom fields:
|
|
193
264
|
```yaml
|
|
194
265
|
custom:
|
|
195
266
|
my_org_priority: "P1"
|
|
196
|
-
upstream_ref: "RFC-42"
|
|
197
267
|
```
|
|
198
268
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- `version` is an integer format version (current: `1`).
|
|
204
|
-
- `version_url` must point to the repo-local definition for that version.
|
|
205
|
-
- Version files live under `/.tickets/spec/version/` and end with a diff from the previous version.
|
|
206
|
-
- New tooling must read older versions. If `version` is missing, tools may assume `1` and warn.
|
|
207
|
-
- Bumps are rare and only when a change cannot be expressed additively.
|
|
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`
|
|
208
273
|
|
|
209
|
-
###
|
|
210
|
-
The ticket body MUST include these sections (at least the headings):
|
|
274
|
+
### Required body sections
|
|
211
275
|
- `# Ticket`
|
|
212
276
|
- `## Description`
|
|
213
|
-
- `## Acceptance Criteria`
|
|
214
|
-
- `## Verification`
|
|
215
|
-
|
|
216
|
-
---
|
|
277
|
+
- `## Acceptance Criteria`
|
|
278
|
+
- `## Verification`
|
|
217
279
|
|
|
218
280
|
## Status model
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
- `
|
|
261
|
-
- `
|
|
262
|
-
- `
|
|
263
|
-
- `
|
|
264
|
-
- `
|
|
265
|
-
- `custom
|
|
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
|
-
### Standard instruction template
|
|
317
|
-
When launching an agent, use the following template (adapt as needed to the agent tool, but keep the semantics):
|
|
318
|
-
|
|
319
|
-
- Ticket: `<ticket-id>`
|
|
320
|
-
- Ticket file: `/.tickets/<ticket-id>/ticket.md`
|
|
321
|
-
- Scope: `<what to do>`
|
|
322
|
-
- Limits: follow `agent_limits` in the ticket (or repo defaults if not present)
|
|
323
|
-
- Stop behavior: on limit hit, stop work and write a run log entry to:
|
|
324
|
-
- `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
|
|
325
|
-
|
|
326
|
-
### Mandatory agent procedure (vendor-agnostic)
|
|
327
|
-
Given a ticket assignment, an agent must:
|
|
328
|
-
|
|
329
|
-
1. Open the ticket file at `/.tickets/<ticket-id>/ticket.md`.
|
|
330
|
-
2. Identify acceptance criteria and verification steps from the ticket.
|
|
331
|
-
3. Plan minimally: determine the smallest change set that satisfies the acceptance criteria.
|
|
332
|
-
4. Implement within limits.
|
|
333
|
-
5. Verify using the ticket's verification steps (or reasonable defaults if absent).
|
|
334
|
-
6. Log the run:
|
|
335
|
-
- Write progress and outcomes to a per-run log file:
|
|
336
|
-
- `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
|
|
337
|
-
- Include a `context` field capturing the relevant context for this run (copied/adapted inputs, decisions carried in, and any subticket handoff details).
|
|
338
|
-
- If the agent cannot write files, it must output the log content in its final response so a human/tool can persist it.
|
|
339
|
-
|
|
340
|
-
### What to do if the ticket is missing or invalid
|
|
341
|
-
If the assigned ticket file cannot be found, or is missing required sections:
|
|
342
|
-
- The agent must not proceed with implementation.
|
|
343
|
-
- The agent must log the issue and request clarification, or propose a minimal ticket fix as its output.
|
|
344
|
-
|
|
345
|
-
### Multi-ticket assignments (rare)
|
|
346
|
-
If an agent is assigned more than one ticket in a single run:
|
|
347
|
-
- The run instructions must list ticket IDs in priority order.
|
|
348
|
-
- The agent must work on only one ticket at a time, logging separately under each ticket’s logs directory.
|
|
349
|
-
- Prefer splitting work into separate runs for clarity.
|
|
350
|
-
|
|
351
|
-
### Human responsibility
|
|
352
|
-
Humans (or an orchestrator) are responsible for:
|
|
353
|
-
- selecting which tickets are assigned to which agents
|
|
354
|
-
- ensuring two agents are not intentionally assigned the same ticket unless parallel exploration is desired
|
|
355
|
-
|
|
356
|
-
---
|
|
357
|
-
|
|
358
|
-
## Agent workflow (recommended protocol)
|
|
359
|
-
Agents MUST:
|
|
360
|
-
- Read the ticket before starting work.
|
|
361
|
-
- Respect `assignment.mode` (do not work tickets marked `human_only`).
|
|
362
|
-
- Respect hard limits in `agent_limits`; if a limit is reached, stop and write a log entry.
|
|
363
|
-
- 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).
|
|
364
|
-
- If `max_iterations` is reached without completion, stop and log a recommendation (tighten criteria, split subtickets, or request a human decision).
|
|
365
|
-
|
|
366
|
-
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)`).
|
|
367
|
-
|
|
368
|
-
---
|
|
369
|
-
|
|
370
|
-
## Splitting tickets (subtickets) in parallel workflows
|
|
371
|
-
If an agent discovers a ticket is too large or should be parallelized:
|
|
372
|
-
1) Create subtickets with `npx @picoai/tickets new`.
|
|
373
|
-
2) Link with `related` (and only use `dependencies`/`blocks` when there is a real ordering constraint).
|
|
374
|
-
3) Log the split on the original ticket and include `tickets_created`.
|
|
375
|
-
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).
|
|
376
|
-
|
|
377
|
-
Avoid maintaining an authoritative “subtickets list” by frequently editing the parent `ticket.md` (it’s a merge-conflict hotspot). Prefer derived views and logs.
|
|
378
|
-
|
|
379
|
-
---
|
|
380
|
-
|
|
381
|
-
## Validation, issues reports, and repair
|
|
382
|
-
- `npx @picoai/tickets validate`:
|
|
383
|
-
- exit `0`: ok
|
|
384
|
-
- exit `1`: validation errors
|
|
385
|
-
- exit `2`: tooling/IO errors
|
|
386
|
-
- Add `--all-fields` to validate optional front-matter (priority, labels, assignment.owner, verification.commands) and include corresponding repairs in `--issues` output.
|
|
387
|
-
|
|
388
|
-
- `npx @picoai/tickets validate --issues` emits a machine-readable report with:
|
|
389
|
-
- all `issues` (errors and warnings), and
|
|
390
|
-
- a `repairs` section that can be edited and consumed by `tickets repair` in `--non-interactive` mode.
|
|
391
|
-
- Use `--all-fields` with `validate` and `repair` when you want optional front-matter fields to be checked and fixed.
|
|
392
|
-
- Use `--interactive` with `repair` to step through each fix, see what’s expected, and supply values (include `--all-fields` to cover optional fields too).
|
|
393
|
-
|
|
394
|
-
Minimal shape (example):
|
|
395
|
-
```yaml
|
|
396
|
-
schema_version: 1
|
|
397
|
-
tool: "tickets"
|
|
398
|
-
generated_at: "2026-01-29T00:00:00Z"
|
|
399
|
-
issues: []
|
|
400
|
-
repairs:
|
|
401
|
-
- id: "R0001"
|
|
402
|
-
enabled: false
|
|
403
|
-
safe: true
|
|
404
|
-
action: "add_sections"
|
|
405
|
-
ticket_path: "/.tickets/<id>/ticket.md"
|
|
406
|
-
params: {}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
- `npx @picoai/tickets repair --issues-file <path>` applies enabled repairs:
|
|
410
|
-
- Safe repairs can be non-interactive.
|
|
411
|
-
- Disruptive repairs (like changing `id`) must have explicit decisions filled in (or require interactive mode).
|
|
412
|
-
|
|
413
|
-
---
|
|
414
|
-
|
|
415
|
-
## Safety & hygiene
|
|
416
|
-
- Do not write secrets into tickets or logs.
|
|
417
|
-
- Avoid pasting large environment dumps into logs.
|
|
418
|
-
- Prefer minimal diffs; avoid unrelated refactors.
|
|
419
|
-
- 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
|
|
420
378
|
<!-- @picoai/tickets:managed:end -->
|
|
421
379
|
|
|
422
380
|
---
|
|
@@ -431,39 +389,18 @@ This section is intended for ongoing team customization and expansion.
|
|
|
431
389
|
Use this section for reusable team preferences agents should apply by default.
|
|
432
390
|
|
|
433
391
|
Examples:
|
|
434
|
-
- decomposition preference
|
|
435
|
-
- required human checkpoints
|
|
436
|
-
-
|
|
437
|
-
-
|
|
438
|
-
-
|
|
392
|
+
- decomposition preference
|
|
393
|
+
- required human checkpoints
|
|
394
|
+
- verification evidence format
|
|
395
|
+
- claim usage policy
|
|
396
|
+
- rollout and handoff expectations
|
|
439
397
|
|
|
440
|
-
### External System Mapping
|
|
398
|
+
### External System Mapping
|
|
441
399
|
|
|
442
400
|
Document how external systems map to in-repo tickets.
|
|
443
401
|
|
|
444
|
-
|
|
445
|
-
- source systems (Jira/Linear/Notion/Figma/etc.)
|
|
446
|
-
- external state -> canonical `status` mapping
|
|
447
|
-
- assignment and ownership boundaries (human teams vs agent teams/swarms)
|
|
448
|
-
- synchronization rules and conflict resolution approach
|
|
449
|
-
|
|
450
|
-
### Local Custom Policy
|
|
451
|
-
|
|
452
|
-
Use this area for repo-specific policy that should not be overwritten.
|
|
453
|
-
|
|
454
|
-
Examples:
|
|
455
|
-
- additional review gates before moving ticket status to `done`
|
|
456
|
-
- rules for high-risk or production-impacting changes
|
|
457
|
-
- release-note and changelog policy
|
|
458
|
-
|
|
459
|
-
### Optional Team Metadata Conventions
|
|
460
|
-
|
|
461
|
-
If teams need additional metadata, prefer `custom.*` namespaced keys in ticket front matter and logs.
|
|
462
|
-
|
|
463
|
-
Examples:
|
|
464
|
-
- `custom.external.ticket_id`
|
|
465
|
-
- `custom.external.state`
|
|
466
|
-
- `custom.routing.queue`
|
|
467
|
-
- `custom.design.figma_url`
|
|
402
|
+
### Local Semantic Notes
|
|
468
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`.
|
|
469
406
|
<!-- @picoai/tickets:user:end -->
|