flightpack/delivery: a whole tracker in a package
Eighty-seven commits since 14 October turned the projects package into a delivery tracker: one write path, an append-only event log, sprints, sources, webhooks and agent seats.
Of all the packages, flightpack/delivery is the one that grew fastest. Its history has 87 commits since 14 October 2026, and 20 of them landed on the first day. It sits on top of the projects package and turns a project into a delivery workspace: a ticket prefix, areas, phases, a calendar, tickets, sprints and milestones with exit criteria. It came out of the Sprintly work. I read the history as an analyst, so this post is about the decisions that hold the rest up, not the screens.
Decision one: every change goes through one door
The README states it in its second sentence: every change goes through one write path, the TrackerWriter. A caller does not update a ticket row. It builds an operation and asks the writer to apply it. Each operation carries an actor, and the actor is one of four kinds: a person, an agent, the system or an import. The writer holds the rules engine and refuses an operation that breaks an error rule, so a caller cannot skip a rule by forgetting to ask.
caller -> Operation + actor (human | agent | system | import) -> rules engine -> one transaction -> ticket row changed + event appended -> hooks after commit, queued with retry
The consequence I like is the event log. Ticket events are append only, and a database trigger guards them. A tracker that can rewrite its own history is a spreadsheet with a login page.
Decision two: edit with a version, claim with a lease
A ticket is edited with its version, so two people saving at the same time cannot overwrite each other without being told. Work is claimed with a lease. The claimant sends a heartbeat, can release the claim, and a sweep that runs every five minutes frees claims that went quiet. Without a lease, a claim made by someone who left for the day blocks the ticket until someone notices. This matters more once the claimant can be an agent, which is the subject of the post on a seat for AI agents.
Seven versions, one fortnight
| Version | What arrived |
|---|---|
| 0.1 | Foundation: schema, the writer, workspace set-up, delivery roles, permissions, dashboard and settings cards, "my work" |
| 0.2 | Tickets end to end: create, edit, split, status with lifecycle rules, claims, checklist, links, comments, search, saved views, bulk change, board and list |
| 0.3 | Sprints: state machine, close checks, carry-over that keeps the home sprint, backlog, burn-down, planning screen |
| 0.4 | Roadmap: milestone delivery fields, exit criteria, the rules engine with dependencies and evidence, health check |
| 0.5 | Sources: connect another tracker, preview, import, sync with a rule for who owns each field, a scheduler that backs off when a source fails |
| 0.6 | Outbound webhooks on milestone delivered and ticket closed, with retries and a log that keeps only the result and duration |
| 0.7 | Agent seats: tokens with scopes and a project list. The review and revert queue followed on 22 October |
The order is the one I trust: foundation first, then the write path's first real customer (tickets), then planning on top, then connections to the outside.
After the versions
- 22 October: progress reports with a snapshot, a narrative, a publish gate and immutability once published; export as Markdown, JSON or PDF, with the PDF stored in the library package.
- 22 October: a file tracker exporter and an import that joins a milestone the project already has instead of adding a duplicate. The parser has its own post.
- 23 October: a capacity-levelled schedule that gives each person one ticket at a time at their capacity, and a workload view. The Gantt page is covered here.
- 25 October: an integration health endpoint, and an import tuned so that, by its own commit message, 5,000 tickets load in under a minute. I have not measured that myself.
What it needs, and how it leaves
It requires the projects package. It uses api-credentials for tracker scopes and agent tokens, and clients so that a client's users become stakeholders, but both are optional. Install is delivery:install, which runs migrations, seeds permissions and creates three roles. Uninstall keeps the data by default, and --purge drops every delivery table. Both are written in the contract every package follows.
What I would tell another small team
If a tracker will ever be written to by more than one kind of actor, build the single write path first and the screens second. Everything I listed above, from the lease to the import to the agent seat, was cheap because there was one door to put the rule behind.