Agent Engineering
Module 06 · Shipping/Lesson 6.2/3 min

Tickets

One session of work, stated so completely that a cold agent needs nothing else.

A ticket is a handoff artifact scoping exactly one session. Where a spec answers "what are we building", a ticket answers "what happens in the next forty minutes".

The discipline: a ticket must be executable by an agent with no memory of any previous session. That is not a stylistic preference — it is the property that makes multi-session work survivable, because every session starts cold whether you like it or not.

The shape

specs/scheduled-exports/t3-due-scheduler.md
# T3 — Find and enqueue due schedules

Spec: specs/scheduled-exports.md (read it first)
Depends on: T1 (schedules table), T2 (schedule CRUD) — both merged.

## Context you need
- Schedules are in db/schema/export_schedules.ts (added in T1).
- The queue API is src/queue/index.ts. See enqueue() and its test.
- Accounts carry a timezone: accounts.timezone, IANA string.

## Task
Add a function findDueSchedules(now: Date) in src/export/scheduler.ts that
returns schedules whose next run time has passed, evaluated in each account's
timezone. Add a worker entry that calls it every 5 minutes and enqueues an
export job per due schedule.

## Do not
- Do not implement the export itself. T4 does that. Enqueue only.
- Do not add a new scheduling library.
- Do not change the schema.

## Done when
- Unit tests cover: DST transition, month-end for monthly schedules,
  a schedule whose account was deleted, and two schedules due at once.
- npm run check passes.
- git diff touches only src/export/ and its tests.

Why each section exists

  • Context you need replaces the previous sessions’ memory with three pointers. Pointers, not contents — the agent reads the primaries itself (Lesson 5.3).
  • Do not is where you stop the neighbouring ticket from being done twice.
  • Done when includes the diff scope. That single line prevents most of the sprawl.
  • The test list is you doing the part agents do badly (Lesson 4.6) — deciding what must be true.

Sizing

A ticket is correctly sized when it passes the Lesson 4.4 test: one intent, one reviewable commit, checkable done, nameable files. If writing "done when" is hard, the ticket is too big or too vague — split it before you start, not halfway through.

Watch out

Do not carry a chain of tickets in one long session to "save setup time". The setup is thirty seconds of reading a ticket; the cost of carrying is the entire second half of the work done in the dumb zone. One ticket, one session, one commit.

Try it

Take your spec and write the first three tickets. Then hand ticket 1 to a fresh agent with no other context and watch what it asks. Anything it has to ask is something you will have to write in every future ticket too.

Takeaways

  • A ticket must stand alone — assume zero memory of previous sessions.
  • Give pointers to primaries, not copied content.
  • Include the expected diff scope in the definition of done.
  • One ticket, one session, one commit.
What does it mean if you cannot write the "done when" section?

The ticket is not yet one task. Either the outcome is not observable — in which case you need an acceptance criterion, not a ticket — or it contains several outcomes and needs splitting. Writing this section is the sizing test, not paperwork after the fact.

A course by Pieter Zandbergen