Feature Workflow

For Claude Code: Read this entire document when invoked via /project:feature. You are the enforcer of this workflow. Do not skip steps. Do not proceed to the next step until the current one is complete. Ask the developer for the required information at each gate — do not assume or infer it.

Purpose

A repeatable runbook for planning and shipping new features in the jjk-workspace monorepo. The defining characteristic of this workflow versus bug fix: you write before you code. A brief exists before a branch exists.


The Workflow

Step 1 — Write the Brief

Gate: One paragraph. Three questions answered.

Before anything else — no branch, no file, no grepping — write a brief. It lives in your head or a scratch note; it does not need to be committed. But it must exist and must answer:

  1. What problem does this solve? (For whom, in what situation.)
  2. What does done look like? (Specific, observable behavior — not “it works.”)
  3. What are you explicitly NOT doing? (Scope boundary. Name it or it will grow.)

If you can’t answer all three, you don’t have a feature yet — you have an idea. Think longer.

Claude Code: Ask the developer for their brief. If they give you something vague, push back with these three questions explicitly. Do not proceed until all three are answered cleanly.


Step 2 — Check the Pre-Code Checklist

Before designing anything, run the standard checks from the Claude Code Guide:

  1. Does anything in shared/ already solve part of this?
  2. Grep for related implementations — don’t rebuild what exists.
  3. Do the Design Principles govern any part of this?
  4. Does the Project Spec constrain the approach?
  5. Do any ADRs apply?

Claude Code: Run these checks actively — don’t ask the developer to do it. Read the relevant files. Surface any conflicts or prior decisions before Step 3.


Step 3 — ADR Check

Does this feature warrant a new ADR?

A new ADR is warranted if the feature:

  • Introduces a new external vendor or service
  • Creates a new data flow pattern or boundary rule
  • Changes how packages depend on each other
  • Adopts a new framework or major library
  • Contradicts or amends a prior ADR

If yes: scaffold the ADR now with npm run adr:new "Title" and write it to Proposed status before proceeding. The ADR does not need to be Accepted yet, but it must exist.

If no: proceed.

Claude Code: Make this determination based on the brief. State your reasoning. If an ADR is needed, scaffold it and draft the context + decision sections before moving on.


Step 4 — Acceptance Criteria

Gate: Bullet points. What does done actually look like?

Translate the brief into testable criteria. These are not test cases — they are the plain-language definition of done:

  • “Scheduled LinkedIn posts with status: queued and a scheduledFor in the past are dispatched within one scheduler cycle.”
  • “The admin UI shows an error state when the post fails to dispatch, not a silent failure.”
  • “No existing post rating behavior is affected.”

Three to five bullets is typical. More than seven means scope is too large — split the feature.

Claude Code: Draft the acceptance criteria from the brief and ask the developer to confirm or amend them. Do not proceed until both parties agree on what done looks like.


Step 5 — Branch

Branch from main using the established convention:

feat/<short-slug>

Examples:

feat/linkedin-dispatch-error-state
feat/post-rating-anonymous-auth
feat/admin-draft-preview

No ticket numbers. No dates. Readable slug only.

Claude Code: Confirm the branch name with the developer before creating it.


Step 6 — Build

Build the minimal thing that satisfies the acceptance criteria. Refer to the pre-code checklist constantly. Do not:

  • Gold-plate the implementation
  • Add adjacent improvements opportunistically
  • Expand scope beyond the acceptance criteria

If you discover the feature is larger than anticipated, stop and discuss. Either trim scope or split into multiple features. Do not silently expand.

IaC/config components (new Firestore indexes, Terraform resources, new Cloud Scheduler jobs, Firebase rules changes) are part of the feature — not follow-up work. They ship in the same branch.


Step 7 — Verify Against Acceptance Criteria

Gate: Check each criterion explicitly.

Go through the acceptance criteria from Step 4 one by one:

  • Does the feature satisfy it?
  • Run the relevant test suite.
  • If a criterion is testable with an automated test and one doesn’t exist, add it.

Do not mark done until every criterion is met. If a criterion turns out to be wrong or irrelevant, that’s a conversation — not a silent skip.

Claude Code: Walk through each acceptance criterion with the developer. Confirm pass/fail on each one before proceeding.


Step 8 — Docs Update

Features always touch docs. Before closing the branch, update:

  • Project Spec (engineering/project-spec.md) if the feature adds a new pattern, constraint, or behavioral rule CC should know about.
  • Relevant ADR if one was created in Step 3 — update status to Accepted and fill in the consequences section.
  • Infrastructure docs (infrastructure/) if new GCP resources, Firebase config, or Terraform was added.
  • Claude Code Guide (operations/claude-code.qmd) if new commands or workflows are introduced.

This is not optional cleanup. Docs ship in the same branch as the feature.

Claude Code: Identify which docs need updating based on what was built. Draft the updates. Do not proceed to deploy until docs are committed.


Step 9 — Commit

Follow the established convention:

feat: <plain description of what was added>

If the feature includes multiple logical changes, use multiple commits on the branch — one per logical unit. The final merge to main should tell a readable story.

Examples:

feat: dispatch error state for failed LinkedIn posts
feat: add anonymous auth gate to post rating flow
feat: admin draft preview with live markdown render

Step 10 — Deploy

# Functions only
npx firebase deploy --only functions

# If Firestore rules or indexes changed
npx firebase deploy --only firestore

# If frontend changed
npx ng build frontend && npx firebase deploy --only hosting:blog

# If infra changed
cd infra && terraform apply

# Full deploy
npm run build && firebase deploy

Verify the feature is live and behaves as specified by the acceptance criteria in production.


Quick Reference

Step Action Gate
1 Brief Three questions answered
2 Pre-code checklist Shared/, grep, principles, spec, ADRs checked
3 ADR check New ADR scaffolded if warranted
4 Acceptance criteria Both parties agree on done
5 Branch feat/<slug> created
6 Build Minimal; IaC in same branch
7 Verify Every criterion confirmed
8 Docs Spec, ADR, infra, CC guide updated as needed
9 Commit Conventional commits, readable story
10 Deploy Live in production, verified