@picoai/tickets 0.2.0 → 0.4.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.
@@ -6,180 +6,247 @@ 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 (marker-scoped update).
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 (including root `TICKETS.md`).
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 only (no heading-level merge across the full document),
20
- - preserves user-owned content.
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
- **TICKETS.md ** explains the workflow, file formats, and required tool usage for both humans and agents. If there is ever a conflict between this file and other docs, follow this file.
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`: 2
35
- - `version_url`: `version/20260311-tickets-spec.md`
36
- - Local file: `/.tickets/spec/version/20260311-tickets-spec.md`
42
+ - `version`: 3
43
+ - `version_url`: `version/20260317-2-tickets-spec.md`
44
+ - Local file: `/.tickets/spec/version/20260317-2-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
- ## What this system is
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
- ## What this is trying to do
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
- This system addresses those problems with stable `ticket.md` files, merge-friendly per-run logs, and explicit acceptance + verification + bounded iteration guidance.
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
- ## Non-negotiables (for merge safety and auditability)
55
- - **Keep `ticket.md` stable and human-readable.** Put history in run logs.
56
- - **Append-only logs.** Never rewrite or delete log lines.
57
- - **Use the repo-local CLI for automation.** Don’t invent parallel formats.
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
63
+ - `/.tickets/derived/planning-index.json`: derived cache used by `list`, `plan`, and `graph`
58
64
 
59
- ---
65
+ ## What this system is
66
+ - A lightweight, Markdown-first ticket format stored under `/.tickets/`
67
+ - A merge-friendly history model: append-only JSONL run logs, one file per run, per ticket
68
+ - A repo-local CLI (`npx @picoai/tickets`) that is the only state-changing integration surface
69
+ - A generic planning model that supports features, phases, milestones, and roadmap views without hardcoding those terms into execution semantics
60
70
 
61
- ## Quickstart (humans and agents)
71
+ ## Non-negotiables
72
+ - Keep `ticket.md` stable and human-readable. Put history in run logs.
73
+ - Keep run logs append-only. Never rewrite or delete log lines.
74
+ - Use the repo-local CLI for automation. Do not invent parallel formats.
75
+ - Do not derive execution behavior from free-form labels alone. Use the planning primitives.
76
+
77
+ ## Quickstart
62
78
 
63
79
  ### Initialize
64
- Create the repo structure and templates (idempotent):
65
80
  - `npx @picoai/tickets init`
66
- - Add `--examples` to generate example tickets (7 sample tickets with required/optional fields, relationships, and logs that validate under the current spec).
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.
81
+ - `npx @picoai/tickets init --apply`
82
+
83
+ Default `init` creates, if missing:
84
+ - `TICKETS.md`
85
+ - `AGENTS_EXAMPLE.md`
86
+ - `/.tickets/config.yml`
87
+ - `/.tickets/skills/tickets/SKILL.md`
88
+ - `/.tickets/spec/version/`
92
89
 
93
- If validation fails and you want a complete report + repair plan:
94
- - `npx @picoai/tickets validate --issues --all-fields > issues.yaml`
90
+ ### Create and validate a ticket
91
+ - `npx @picoai/tickets new --title "Short title"`
92
+ - `npx @picoai/tickets validate`
93
+ - `npx @picoai/tickets validate --issues --all-fields --output issues.yaml`
95
94
  - `npx @picoai/tickets repair --issues-file issues.yaml --all-fields --non-interactive`
96
95
 
97
- Expected handling loop for a ticket:
98
- - validate the assigned ticket before changing code
99
- - use `tickets status` when the lifecycle state changes (`todo`, `doing`, `blocked`, `done`, `canceled`)
100
- - use `tickets log` for run history within a state: progress, checkpoints, blockers, decisions, verification, and handoff notes
101
- - machine-written work logs must include `--context`; for split child bootstrapping, pair `--created-from <parent-id>` with `--context ...`
102
- - reuse the same `--run-started` and `--run-id` for entries from the same run when you want a single per-run log file
96
+ ### Coordinate work
97
+ - `npx @picoai/tickets status --ticket <id> --status doing`
98
+ - `npx @picoai/tickets log --ticket <id> --summary "..." --machine --context "..."`
99
+ - `npx @picoai/tickets claim --ticket <id>`
100
+ - `npx @picoai/tickets list --ready --sort lane`
101
+ - `npx @picoai/tickets plan --format json`
102
+ - `npx @picoai/tickets graph --view portfolio`
103
103
 
104
- ### Log your work (human or agent)
105
- Use the CLI to write logs whenever possible (merge-friendly, structured, and tooling-validated).
104
+ ## Repository layout
105
+ - Canonical workflow guide: `TICKETS.md`
106
+ - Machine-readable overrides: `/.tickets/config.yml`
107
+ - Repo skill projection: `/.tickets/skills/tickets/SKILL.md`
108
+ - Ticket storage root: `/.tickets/<ticket-id>/`
109
+ - Ticket definition: `ticket.md`
110
+ - Run logs: `logs/<run_started>-<run_id>.jsonl`
111
+
112
+ ## Core planning model
113
+
114
+ The planning model is intentionally generic. Agents, validators, and rollups operate on these primitives, not on human aliases.
115
+
116
+ Primitives:
117
+ - `planning.node_type`: `work`, `group`, `checkpoint`
118
+ - `planning.group_ids`: membership edges pointing from a child to one or more containing groups
119
+ - `planning.precedes`: sequencing edges
120
+ - `planning.lane`: coarse ordering bucket
121
+ - `planning.rank`: fine ordering within a lane or peer set
122
+ - `planning.horizon`: roadmap scope such as `current`, `next`, `later`
123
+ - `status`: execution lifecycle state
124
+ - `resolution`: terminal work outcome: `completed`, `merged`, `dropped`
125
+ - advisory `claim`: optional coordination state, stored in logs only
126
+
127
+ Interpretation:
128
+ - `dependencies` and `blocks` are hard execution constraints
129
+ - `planning.precedes` is sequence/order, not a hard dependency
130
+ - `group_ids` is the only persisted grouping edge; reverse membership and rollups are derived
131
+ - `lane`, `rank`, and `horizon` are generic ordering dimensions, not hardcoded PM vocabulary
132
+ - claims do not change `status`
133
+
134
+ ### Default human semantic mapping
135
+
136
+ By default:
137
+ - `feature` -> `planning.node_type = group`
138
+ - `phase` -> `planning.lane`
139
+ - `milestone` -> `planning.node_type = checkpoint`
140
+ - `roadmap` -> `planning.horizon`
141
+
142
+ Repos may override these mappings in `.tickets/config.yml` without changing the core CLI or validation invariants.
143
+ Treat the list above as defaults. Agents should consult `.tickets/config.yml` before interpreting repo-specific planning language or creating tickets.
144
+
145
+ ### Worked example
106
146
 
107
- Actor defaults for both `tickets status` and `tickets log`:
108
- - `actor_id`: `--actor-id`, else `TICKETS_ACTOR_ID`, else `@${USER|USERNAME}`, else `"unknown"`
109
- - `actor_type`: `--actor-type`, else `TICKETS_ACTOR_TYPE`, else infer `agent` from `actor_id` prefix `agent:`, infer `human` from prefix `@`, else default to `human`
147
+ ```yaml
148
+ ---
149
+ id: 0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d
150
+ version: 3
151
+ version_url: "version/20260317-2-tickets-spec.md"
152
+ title: "Feature Alpha"
153
+ status: doing
154
+ created_at: 2026-03-17T17:00:00Z
155
+ planning:
156
+ node_type: group
157
+ lane: build
158
+ rank: 1
159
+ horizon: current
160
+ ---
161
+ ```
110
162
 
111
- Agentic tools (including human-invoked tools like Cursor/Windsurf/Codex CLI/Claude Code) SHOULD log with `--machine`:
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"`
163
+ Child work ticket:
113
164
 
114
- Humans can log without machine marker:
115
- - `npx @picoai/tickets log --ticket <id> --summary "Investigated failing test; will retry tomorrow."`
165
+ ```yaml
166
+ planning:
167
+ node_type: work
168
+ group_ids: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d"]
169
+ lane: build
170
+ rank: 2
171
+ horizon: current
172
+ precedes: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6e"]
173
+ ```
116
174
 
117
- ---
175
+ Checkpoint ticket:
118
176
 
119
- ## Repository layout
120
- - Canonical workflow guide: `TICKETS.md`
121
- - Ticket storage root: `/.tickets/`
122
- - One ticket per directory: `/.tickets/<ticket-id>/`
123
- - Ticket definition: `/.tickets/<ticket-id>/ticket.md`
124
- - Run logs: `/.tickets/<ticket-id>/logs/<run_started>-<run_id>.jsonl`
177
+ ```yaml
178
+ planning:
179
+ node_type: checkpoint
180
+ group_ids: ["0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d"]
181
+ lane: launch
182
+ rank: 1
183
+ horizon: current
184
+ ```
125
185
 
126
- Notes:
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).
186
+ Dropped child:
129
187
 
130
- ---
188
+ ```yaml
189
+ status: canceled
190
+ resolution: dropped
191
+ ```
192
+
193
+ Claim log example:
194
+
195
+ ```json
196
+ {"version":3,"version_url":"version/20260317-2-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":""}}
197
+ ```
131
198
 
132
199
  ## Ticket definition (`ticket.md`)
133
- Ticket files are Markdown documents with YAML front matter and a Markdown body.
134
200
 
135
- ### YAML front matter
136
- Front matter MUST start at the first line and be enclosed by `---`.
201
+ Ticket files are Markdown documents with YAML front matter and a Markdown body.
137
202
 
138
- #### Required fields
203
+ ### Required front matter
139
204
  - `id`: lowercase UUIDv7 string
140
- - `version`: format version (integer)
141
- - `version_url`: path to the definition for this version (repo-local, relative to `.tickets/spec/`)
205
+ - `version`: integer format version
206
+ - `version_url`: repo-local path to the spec
142
207
  - `title`: string
143
208
  - `status`: `todo|doing|blocked|done|canceled`
144
- - `created_at`: ISO 8601 timestamp in UTC (use `Z`)
209
+ - `created_at`: ISO 8601 UTC timestamp
145
210
 
146
- Example:
211
+ ### Optional front matter
147
212
 
148
- ```md
149
- ---
150
- id: 0191c2d3-4e5f-7a8b-9c0d-1e2f3a4b5c6d
151
- version: 2
152
- version_url: "version/20260311-tickets-spec.md"
153
- title: "Add tickets validate --issues"
154
- status: todo
155
- created_at: 2026-01-29T18:42:10Z
156
- ---
157
- # Ticket
158
- ...
213
+ Assignment:
214
+ ```yaml
215
+ assignment:
216
+ mode: mixed
217
+ owner: "agent:codex"
159
218
  ```
160
219
 
161
- #### Optional fields
162
- **Assignment and mode**
220
+ Priority and labels:
163
221
  ```yaml
164
- assignment:
165
- mode: mixed # human_only | agent_only | mixed
166
- owner: null # "@alice", "team:core", "agent:codex"
222
+ priority: high
223
+ labels: ["feature", "api"]
224
+ ```
225
+
226
+ Relationships:
227
+ ```yaml
228
+ dependencies: []
229
+ blocks: []
230
+ related: []
167
231
  ```
168
232
 
169
- **Priority and labels**
233
+ Planning:
170
234
  ```yaml
171
- priority: medium # low | medium | high | critical
172
- labels: ["bug", "docs"]
235
+ planning:
236
+ node_type: work
237
+ group_ids: []
238
+ lane: null
239
+ rank: null
240
+ horizon: null
241
+ precedes: []
173
242
  ```
174
243
 
175
- **Relationships (the only ones written in v1)**
244
+ Resolution:
176
245
  ```yaml
177
- dependencies: [] # ticket IDs this ticket depends on
178
- blocks: [] # ticket IDs this ticket blocks
179
- related: [] # ticket IDs related to this ticket
246
+ resolution: completed # completed | merged | dropped
180
247
  ```
181
248
 
182
- **Agent limits (hard limits for agents)**
249
+ Limits:
183
250
  ```yaml
184
251
  agent_limits:
185
252
  iteration_timebox_minutes: 20
@@ -188,7 +255,7 @@ agent_limits:
188
255
  checkpoint_every_minutes: 5
189
256
  ```
190
257
 
191
- **Verification commands**
258
+ Verification:
192
259
  ```yaml
193
260
  verification:
194
261
  commands:
@@ -196,254 +263,127 @@ verification:
196
263
  - "npx @picoai/tickets validate"
197
264
  ```
198
265
 
199
- Important:
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)**
266
+ Custom fields:
204
267
  ```yaml
205
268
  custom:
206
269
  my_org_priority: "P1"
207
- upstream_ref: "RFC-42"
208
270
  ```
209
271
 
210
- Custom fields MUST live under `custom` to avoid collisions. Tooling should ignore unknown keys under `custom`.
211
- Extensions are repo-local; use a clear prefix for keys and avoid introducing new top-level extension fields.
272
+ Rules:
273
+ - `resolution` is only valid on terminal tickets (`done` or `canceled`)
274
+ - `custom` is reserved for repo-local extensions not standardized by the spec
275
+ - other relationship views are computed by tooling and must not be persisted in `ticket.md`
212
276
 
213
- ### Versioning
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):
277
+ ### Required body sections
222
278
  - `# Ticket`
223
279
  - `## Description`
224
- - `## Acceptance Criteria` (checkable list)
225
- - `## Verification` (commands or steps)
226
-
227
- ---
280
+ - `## Acceptance Criteria`
281
+ - `## Verification`
228
282
 
229
283
  ## Status model
230
- Status values: `todo`, `doing`, `blocked`, `done`, `canceled`.
231
-
232
- Recommended transitions:
233
- - `todo` -> `doing` | `canceled`
234
- - `doing` -> `blocked` | `done` | `canceled`
235
- - `blocked` -> `doing` | `canceled`
236
- - `done` and `canceled` are immutable unless explicitly reopened by a human (set to `doing` and log why).
237
-
238
- Status updates:
239
- - `npx @picoai/tickets status --ticket <id> --status doing --actor-type agent --actor-id "agent:codex"`
240
- - `tickets status` always appends a machine-written status-change log entry.
241
-
242
- ---
243
-
244
- ## Run logs (append-only JSONL)
245
- Every ticket directory has `logs/`. Logs are where history lives; they are designed to be merge-friendly under parallel work.
246
-
247
- ### File naming: `<run_started>-<run_id>.jsonl`
248
- - `run_started` is the run start time (UTC). It is a *hint* for processing order (tools may process newer runs first by sorting filenames).
249
- - Tools SHOULD emit `run_started` in ISO 8601 **basic** form for filenames, e.g. `20260129T184210.123Z`.
250
- - `run_id` is an identifier for the run (tool-generated unless provided).
251
-
252
- Example filename:
253
- - `/.tickets/<id>/logs/20260129T184210.123Z-0191c2d3-....jsonl`
254
-
255
- ### `ts` vs `run_started`
256
- - `run_started` is constant for a given run file (and appears on every line so each JSON object is self-contained).
257
- - `ts` is per entry (the moment that particular log entry was written).
258
- - “Last updated” is derived from the newest `ts` across all logs, not from filenames.
259
-
260
- ### Log entry schema (one JSON object per line)
261
- Required fields:
262
- - `version`: format version (integer)
263
- - `version_url`: path to the definition for this version (repo-local, relative to `.tickets/spec/`)
264
- - `ts`: ISO 8601 UTC timestamp for the entry
265
- - `run_started`: ISO 8601 UTC timestamp (same for all entries in the file)
266
- - `actor_type`: `human|agent`
267
- - `actor_id`: string identifier (freeform)
268
- - `summary`: short summary string
269
- - `event_type`: `status|work`
270
-
271
- Conditional field:
272
- - `context`: `[...]` (bullets capturing the context relevant to this run; when splitting, include copied/adapted inputs from the parent)
273
- - required for machine-written `work` entries
274
- - optional for `status` entries and human-written logs
275
-
276
- Optional structured fields (recommended):
277
- - `changes`: `{files: [...], commits: [...], prs: [...]}`
278
- - `verification`: `{commands: [...], results: "pass|fail|explain why not run"}`
279
- - `tickets_created`: `[...]` (ticket IDs created during this run)
280
- - `created_from`: string (parent ticket ID when created by splitting)
281
- - `decisions`, `next_steps`, `blockers`: lists of strings
282
- - `custom`: `{...}` (namespaced custom data)
283
-
284
- Machine marker:
285
- - If a log entry is written by the `tickets` CLI with `--machine`, it MUST include a machine marker:
286
- - `written_by: "tickets"` or `machine: true`
287
-
288
- Validation strictness:
289
- - Machine-marked entries are validated strictly.
290
- - Non-machine entries are validated best-effort (warnings by default), so humans can jot notes without breaking the system.
291
-
292
- Example machine-written entry:
293
- ```json
294
- {"version":2,"version_url":"version/20260311-tickets-spec.md","ts":"2026-01-29T18:50:00Z","run_started":"20260129T184210.123Z","actor_type":"agent","actor_id":"agent:codex-cli (human:@alice)","summary":"Implemented tickets validate --issues.","event_type":"work","context":["Acceptance criteria from ticket","API schema v2"],"verification":{"commands":["npx @picoai/tickets validate"],"results":"pass"},"written_by":"tickets"}
295
- ```
296
-
297
- Merge conflict rule (rare):
298
- - If a `.jsonl` file conflicts, keep all lines from both sides; do not “clean up” history.
299
-
300
- ---
301
-
302
- ## Required tool usage (agents and automation)
303
- To keep state consistent and merge-friendly, agents and agentic tools SHOULD use the CLI for ticket operations:
304
- - Create tickets: `npx @picoai/tickets new`
305
- - Validate: `npx @picoai/tickets validate` (or `--issues` for a full report)
306
- - Repair: `npx @picoai/tickets repair --issues-file ...`
307
- - Status changes: `npx @picoai/tickets status`
308
- - Work logs: `npx @picoai/tickets log` (use `--machine` when the entry is tooling-written)
309
- - Listing/triage: `npx @picoai/tickets list` (use `--json` for automation)
310
-
311
- Humans may edit `ticket.md` directly (it is designed for that), but logs should be appended via the CLI whenever feasible.
312
- Expected command roles:
313
- - `tickets status` changes canonical lifecycle state and always records that state transition in logs
314
- - `tickets log` records run details without changing lifecycle state
315
- - first child handoff after a split should be a `tickets log` entry with both `created_from` and `context`
316
-
317
- ---
318
-
319
- ## Agent task assignment at launch time
320
-
321
- ### Principle
322
- Agents SHOULD NOT choose tickets autonomously by default. In this system, a human or orchestrator assigns a specific ticket (or a small set of tickets) to each agent run. This avoids duplicate work when multiple agents operate from the same repo snapshot and cannot coordinate live.
323
-
324
- ### Required inputs for any agent run
325
- Every agent run MUST be given, in its initial instructions (prompt, task description, CLI args, PR comment, IDE task, etc.):
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.
284
+ - `todo`, `doing`, `blocked`, `done`, `canceled`
285
+ - `done` and `canceled` are terminal unless explicitly reopened by a human
286
+
287
+ `tickets status` changes the canonical lifecycle state and appends a machine-written status entry to logs.
288
+
289
+ ## Claims
290
+
291
+ Claims are optional advisory leases used to reduce duplicate swarm work.
292
+
293
+ Rules:
294
+ - claims live only in logs
295
+ - claims do not change ticket `status`
296
+ - a claim can be acquired, renewed, released, or force-overridden with a reason
297
+ - expired claims are treated as inactive
298
+
299
+ Use:
300
+ - `npx @picoai/tickets claim --ticket <id>`
301
+ - `npx @picoai/tickets claim --ticket <id> --release`
302
+ - `npx @picoai/tickets claim --ticket <id> --force --reason "..."` to override
303
+
304
+ ## Run logs
305
+
306
+ Run logs are append-only JSONL files under `logs/`.
307
+
308
+ Required log fields:
309
+ - `version`
310
+ - `version_url`
311
+ - `ts`
312
+ - `run_started`
313
+ - `actor_type`
314
+ - `actor_id`
315
+ - `summary`
316
+ - `event_type`: `status|work|claim`
317
+
318
+ Conditional fields:
319
+ - `context`: required for machine-written `work` entries
320
+ - `claim`: required for `claim` entries
321
+
322
+ Recommended fields:
323
+ - `changes`
324
+ - `verification`
325
+ - `tickets_created`
326
+ - `created_from`
327
+ - `decisions`
328
+ - `next_steps`
329
+ - `blockers`
330
+ - `custom`
331
+
332
+ ## Derived views and rollups
333
+
334
+ Rollups are always derived from ticket state and logs. Parent or group tickets do not maintain authoritative child ledgers.
335
+
336
+ Derived rollup counters:
337
+ - `total_leaf`
338
+ - `active_leaf`
339
+ - `todo`
340
+ - `doing`
341
+ - `blocked`
342
+ - `done_completed`
343
+ - `merged`
344
+ - `dropped`
345
+
346
+ Completion percentage uses only active leaf work. `merged` and `dropped` do not count against the remaining denominator.
347
+
348
+ ## Commands
349
+
350
+ Primary commands:
351
+ - `init`
352
+ - `new`
353
+ - `validate`
354
+ - `repair`
355
+ - `status`
356
+ - `log`
357
+ - `claim`
358
+ - `list`
359
+ - `plan`
360
+ - `graph`
361
+
362
+ Listing and reporting:
363
+ - `list` is the broad queue/report view. Use it to filter and sort work across the repo.
364
+ - `plan` is the operational board. Use it for ready work, in-progress work, blocked work, and group/checkpoint rollups.
365
+ - `graph` is the structural map. Use it to inspect dependency, sequence, and containment relationships.
366
+
367
+ Derived index:
368
+ - `list`, `plan`, and `graph` maintain a derived planning index at `/.tickets/derived/planning-index.json`
369
+ - the index is disposable cache state
370
+ - the CLI rebuilds it automatically when ticket, log, config, or tool metadata changes
371
+
372
+ ## Agent protocol
373
+
374
+ Agents should:
375
+ 1. Load the repo skill if supported and present, otherwise read `TICKETS.md`
376
+ 2. Open the assigned ticket
377
+ 3. Consult `.tickets/config.yml` for repo-local defaults and semantic overrides before interpreting planning terms or creating tickets
378
+ 4. Validate before implementation
379
+ 5. Respect `assignment.mode`, `agent_limits`, planning constraints, and active claims
380
+ 6. Use `status`, `log`, `claim`, `list`, `plan`, and `graph` through the CLI
381
+ 7. If splitting work, create child tickets with copied minimum context and log `created_from`
382
+
383
+ ## Safety and hygiene
384
+ - Do not write secrets into tickets or logs
385
+ - Avoid unrelated refactors in ticket-scoped work
386
+ - Prefer adding logs with decisions and next steps over rewriting ticket history
447
387
  <!-- @picoai/tickets:managed:end -->
448
388
 
449
389
  ---
@@ -458,39 +398,18 @@ This section is intended for ongoing team customization and expansion.
458
398
  Use this section for reusable team preferences agents should apply by default.
459
399
 
460
400
  Examples:
461
- - decomposition preference (smaller tickets vs milestone-oriented tickets)
462
- - required human checkpoints for risky changes
463
- - default verification evidence format
464
- - branch/PR naming conventions
465
- - handoff expectations for agent-to-human and agent-to-agent transitions
401
+ - decomposition preference
402
+ - required human checkpoints
403
+ - verification evidence format
404
+ - claim usage policy
405
+ - rollout and handoff expectations
466
406
 
467
- ### External System Mapping (Product/Design/Engineering + Agent Teams)
407
+ ### External System Mapping
468
408
 
469
409
  Document how external systems map to in-repo tickets.
470
410
 
471
- Recommended fields to document:
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`
411
+ ### Local Semantic Notes
495
412
 
413
+ Use this section to explain local meanings for human-facing concepts such as feature, phase, milestone, and roadmap.
414
+ The machine-readable source of truth for overrides should remain `.tickets/config.yml`.
496
415
  <!-- @picoai/tickets:user:end -->