# Estimation method

The estimate is engineering hours for the story's scope as written. It excludes buffer: the Story Risk Level is what communicates uncertainty buffer, per the dev review SOP. Never conflate the two, a large story can be LOW risk (lots of pattern following work) and a small story can be MEDIUM or HIGH (novel modeling in few files).

## The method, in order

1. Build the Code paths and intended updates table first. The estimate is derived from it, never invented independently of it.
2. Assign hours per row or per cluster of rows using the anchor table below, at 0.25 hour granularity. Include test files in the rows they verify.
3. Sum and round up to the nearest 0.5 hour.
4. Sanity check the total against the nearest anchor story below. If the total differs from the anchor by more than about a third, either the scope read is wrong or the anchor does not fit, figure out which and say so in the Estimate subsection.
5. Apply the bands:
   - Bugs and small tasks default to 2 hours, 1 hour when genuinely trivial.
   - Stories normally land between 2 and 8 hours. 8 hours is the practical upper bound for a single ticket.
   - A total above 8 hours is a solid argument the ticket should be more than one ticket: the review must say so and sketch the split.
   - 10 hours is a hard cap. The skill never sets an Original Estimate above 10 hours, ever. A story that computes above 10 gets no estimate set until the split question is resolved with the user.
6. Show the work: the review's Estimate subsection carries the breakdown table (work item, hours) and ends with "Recommended Jira original estimate: N engineering hours."
7. Calibrate down, not up (Gib, 2026-08-14). The estimates assume Gib develops with agent assistance, so pattern following surfaces, cards, column definitions, copy sweeps, and test files go faster than a solo dev baseline. Lean toward the low end of every band. Across an epic the distribution matters: most stories should land 2 to 6 hours, and a wall of 8 plus estimates reads like gaming the system to the people approving them. Reserve 8 and above for genuinely large compositions, and when a total creeps high, first re-check the scope read for anything that actually belongs to a neighboring story.

## Anchor table, calibrated from real Command Center estimates

From 100 estimated KACP issues on the Ksense Command Center account (53 bugs median 2h, 24 tasks median 2h, 23 stories median 5h), with named anchors:

| Work shape | Hours | Anchors |
| --- | --- | --- |
| Trivial fix, styling pass, config change | 1 to 2 | KACP-22843 styling 1h, KACP-22868 tutorials fix 2h |
| Bug fix on an existing surface | 2 | The overwhelming KCC default, 2h across dozens of bugs |
| Small workflow or logic tuneup | 3 | KACP-22201 interest holder workflow tuneup 3h |
| Notification or email story on existing plumbing | 3.5 | KACP-22194, KACP-22195 notifications 3.5h each |
| Modal or single form on existing patterns | 4 to 5 | KACP-22197 logs modal 4.5h |
| Additive schema plus seed, no backfill | 3.5 to 5 | KACP-22200 cron sync tables 5h |
| Grid rework or tuneup on the existing DataGrid | 5 | KACP-22196 epic grid tuneup 5h |
| New grid page on existing patterns | 6 to 8 | Portal grid reviews ran 6h (KACP-23136) to 10h (KACP-22814), KCC side stays in band |
| Detail page with cards or tabs on existing patterns | 5 to 7 | KACP-22882 signature logging and data model 7h |
| New end to end surface, UI plus API plus side effects | 6.5 to 8 | KACP-22888 e-sign email 6.5h, KACP-22885 certificate 7.5h |
| Schema with production backfill or migration review queue | Add 2 to 3 to the schema base | This is the most common reason a story crosses 8 and should split |

Historical over the line examples for the split argument: KACP-22881 at 9.5h, KACP-23006 at 14h, KACP-20762 at 17h. Under the current rule each of those gets a split recommendation in its review instead of a large estimate.

## Per row guidance

- A focused test file rides with its surface at 0.5 to 1 hour, not as a separate large line.
- LaunchDarkly flag plumbing on a surface is 0.5.
- Seed catalog entries are 0.5 to 1.
- Route or page shell with nav and guard is 1 to 2 on its own, and folds into the page's line when the story includes the page.
