Skip to content

Doing your first ticket

End-to-end: pick an issue, do the work, ship it. Walk this once and the rest is muscle memory.

This guide assumes a code ticket (writes code + tests). If your ticket has the foundation label, jump to § Research / foundation tickets — the workflow shape differs.

1. Pick

Open the project board. Filter by Status = Todo. Look for:

  • Something scoped — a single concern, not a sprawling feature
  • Something unblocked — no blocks arrows pointing in
  • Something the labels suggest matches your skills (backend if you're comfortable with Prisma, frontend if you're more at home in JSX, etc.)

Good first picks for someone new:

  • #1 — fix the AIB GPU matcher (small, isolated, has tests)
  • #5 — UC-5 filter by stock state (touches one page, well-scoped)

2. Read context

Before writing code, skim:

If a non-trivial design decision is implied by the ticket, write an ADR before the implementation. ADRs after the fact rationalise; ADRs before the fact decide.

3. Branch + claim

git checkout master && git pull
git checkout -b feat/issue-N-slug

Move the issue to In Progress on the project board. From the CLI:

bash scripts/set-issue-status.sh <issue-number> "In Progress"

(See Contributing → Project board status updates for what the script does.)

4. Write the code

Conventions:

  • Test-first when feasible. Vitest specs in tests/ mirror src/. A bug fix should have a regression test that fails before the fix.
  • One concern per commit. "feat: add stock filter" is one commit; "refactor BuildHeader" is a separate commit.
  • Conventional commit messages. feat:, fix:, chore:, docs:, refactor:, test:. Scope optional: feat(matching): ....
  • Update docs in the same PR as the code. If the architecture changes, update the relevant architecture page. If a runbook needs a new step, update it.

5. Run the gates

Before pushing:

npx vitest run         # all tests pass
npx tsc --noEmit       # type-check
npm run lint           # eslint
mkdocs build --strict  # if you touched docs/, this catches broken refs

6. Push + PR

git push -u origin feat/issue-N-slug
~/bin/gh.exe pr create --fill --base master

The --fill flag uses your commit messages for the PR title and body. Edit the body to add Closes #N (so merging the PR closes the issue) plus a Test plan checklist.

7. Wait for CI

CI runs:

  • Vitest (43/43)
  • Type-check
  • Lint
  • Docs build (if you touched docs/)

If anything's red, fix locally and push again. Force-push the branch if you need to amend; --force-with-lease is safer than --force.

8. Self-review

Before merging:

  • Read the diff yourself. Look for accidental console.logs, stray comments, unused imports.
  • Visit the affected pages locally and click through the flow.
  • Verify any documentation is rendering as intended in mkdocs serve.

9. Merge

Squash-merge via gh:

~/bin/gh.exe pr merge --squash --delete-branch

The squash keeps master history clean — one commit per ticket.

10. Close the loop

  • Issue auto-closes via the Closes #N line in your PR body
  • Project board auto-moves the issue to Done
  • If the work surfaced follow-ups, file them as new issues immediately
  • If you wrote an ADR, mention it in the PR body so future you can find it

What to do when blocked

  • Blocked on a decision? Write the decision options as an RFC, tag MASTER for review.
  • Blocked on missing infrastructure? File the missing piece as its own issue and link it as a dependency.
  • Blocked on understanding? Write what you understand into the issue's comments. Half the time, articulating the confusion solves it.

Don'ts

  • Don't merge to master without a PR. Even for trivial doc fixes — the PR is the record.
  • Don't open issues without project + assignee. --project "961tech" --assignee "@me" are required (or use the web UI which auto-adds via the project workflow).
  • Don't --no-verify git hooks unless the hook itself is broken (and then file an issue to fix the hook).
  • Don't taskkill /f /im node.exe on Windows. It kills your editor session too.

For all conventions in one place, see Contributing.

Research / foundation tickets

If your ticket has the foundation label, the middle of the workflow is different — you're producing docs, not code. Adjust steps 4-7:

What changes

Step Code ticket Foundation ticket
Branch feat/issue-N-slug docs/issue-N-slug
Body Write code + tests Write the artifact(s) listed in the ticket body (RFC, ADR, reference, etc.)
Gates vitest + tsc + lint mkdocs build --strict
Self-review Click through affected pages Preview docs locally with mkdocs serve and read every new/changed page

Pattern for research

Foundation tickets are usually research-then-decide. The shape:

  1. Read the ticket body — it lists what to evaluate, what to compare, what to produce
  2. Research — for "compare options X, Y, Z" tickets, dispatch parallel subagents to research each option in isolation. Use superpowers:dispatching-parallel-agents for this — much faster than sequential
  3. Synthesise — pull subagent findings into a single RFC at docs/rfc/NNNN-slug.md (use the template)
  4. Decide — once the RFC is reviewed and a path picked, the decision becomes one or more ADRs at docs/adr/NNNN-slug.md
  5. Update affected reference / architecture docs to match the decision
  6. Apply the what-needs-updating checklist — even though there's no code change, schema changes, env vars, glossary terms often emerge from the research

What stays the same

  • Same branch convention (just docs/ prefix instead of feat/)
  • Same PR + Closes-N + auto-close flow
  • Same project board status updates
  • Same self-review discipline

When in doubt

If you're unsure whether to start with an RFC or jump straight to an ADR: write the RFC. Even a thin RFC ("here are 3 options, here's the recommendation, here's why") gives MASTER something concrete to react to before you commit to a direction.