Skip to content
Back to skills

Build Estimate

ASecurity

Project a build's remaining effort onto the calendar from MEASURED rates, not guesses. Reads a calibration ledger of past builds (tasks landed per hour under a named process profile), scales by task kind and status, walks the calendar past weekends and holidays, and returns low/mid/high finish dates with a fit verdict against a target date. Two modes — `project` (before or during a build) and `calibrate` (after a build, append the actuals so the next estimate is better). Use when a plan needs...

  • 6 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 5, 2026
ai-agentspythongogit

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned October 5, 2026

npx -y skills add shawnclybor/clybor-claude-tooling --skill build-estimate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Build Estimate?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Build Estimate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/shawnclybor-build-estimate/badge)](https://www.skillsdirectory.com/skills/shawnclybor-build-estimate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: build-estimate
description: Project a build's remaining effort onto the calendar from MEASURED rates, not guesses. Reads a calibration ledger of past builds (tasks landed per hour under a named process profile), scales by task kind and status, walks the calendar past weekends and holidays, and returns low/mid/high finish dates with a fit verdict against a target date. Two modes — `project` (before or during a build) and `calibrate` (after a build, append the actuals so the next estimate is better). Use when a plan needs its "Estimated effort" section, when someone asks "will this fit by <date>", when the calendar needs reassessing mid-build, or when a build finishes and its actuals should be recorded. Triggers — "estimate the build", "how long will this take", "will we make the date", "reassess the calendar", "record the actuals", "calibrate the estimate".
---

# build-estimate

**The rule: an effort estimate is a calculation from the ledger, not a number typed into a table.**
`plan.md`'s *Estimated effort* section is produced by this tool and cites the rate it used. A
hand-written "3–4 days" has no basis anyone can check, and on the settlement-verifier build it was
wrong by a factor of two within four days (written Aug 23 for 61 tasks; 21 of them then landed in
15.5 hours).

Tool: `estimate.py` beside this file. Ledger: `calibration.json` beside it. Stdlib Python only.

## When

| Moment | Mode | Who calls it |
|---|---|---|
| `build-plan` Phase 5, writing *Estimated effort* | `project` | build-plan — the section is this tool's output pasted in |
| Mid-build, "are we still on track" / a scope or date question | `project` | you, on request; re-run whenever tasks land or the target moves |
| `build-evaluate` PASS, before closing the slug | `calibrate` | build-evaluate — the actuals go into the ledger or the next build estimates blind |

## `project` — from a spec to a calendar

1. **Write the spec** at `.claude/PRPs/<slug>/estimate/estimate-<YYYY-MM-DD>.json` (the
   `estimate/` directory is opaque to the PRP naming hook; the JSON is data, not an artifact).
   Fields, all named in `estimate.py --help`:
   - `process` — which profile the build runs under. `intensive` = build-execute with mandatory
     per-iteration adversarial review and a mutation harness (the only MEASURED profile today).
     `standard` and `light` are ASSUMED multipliers and the output says so.
   - `tasks` — the open tasks, each with a `kind` from the ledger's `task_kinds` and a `status`
     (`not-started` / `staged` / `in-review`). **Read the task text and the staging area before
     assigning these** — a task whose code is staged and green is 40% of a task, not 100%.
   - `fixed` — gate steps with a known clock (build-evaluate, quality-review) in minutes.
   - `optional` — a second scenario (e.g. the tasks a real-matter demo adds). Reported separately
     so the human sees what fits without them and what it costs to add them.
   - `start`, `start_hours_left`, `hours_per_day`, `holidays`, `target`. Look the holidays up
     and compute them — US Labor Day is the *first Monday* of September, and the first estimate
     on the settlement-verifier build put it a week early from memory.
2. **Run** `python3 .claude/skills/build-estimate/estimate.py project <spec>`.
3. **Paste the output** into `plan.md` § *Estimated effort*, replacing whatever was there, with
   the date and the spec path. Keep the *assumptions carried* block — it is what a later reader
   uses to see why the number was what it was.
4. **State the verdict in one line to the human**: fits / marginal / does not fit, at which
   estimate, and which optional items would push it over. The decision to cut or move the date
   is theirs; the tool's job is to make the arithmetic un-arguable.

Do not add a "review" or "contingency" line on top: a task unit already contains its review
rounds and repairs, because that is how the ledger measured it. If the build is not running the
measured process, change `process`, not the task list.

## `calibrate` — closing the loop

After `build-evaluate` returns PASS (or the build is abandoned with tasks landed — those count too):

1. Count from evidence, not memory: iteration-report mtimes or timestamps, tasks flipped in
   `state.json` / the plan checklist, hours actually at the keyboard with overnight and meeting
   gaps excluded.
2. Write a record JSON (`estimate.py --help` shows the shape) with a `note` saying what made the
   run typical or atypical — single operator, task mix, anything that would make the rate not
   transfer.
3. `python3 .claude/skills/build-estimate/estimate.py calibrate <record.json>`; it appends and
   prints the profile's new resolved rate.
4. **Promote** — `~/gits/clybor-claude-tooling/scripts/promote.sh .claude/skills/build-estimate`
   — and commit there. The ledger's value is cumulative across projects; a record left in one
   project's copy calibrates nothing else, and the drift gate will block the next commit anyway.

If a build ran under a profile that has no measured record, calibrating it is what turns that
profile's ASSUMED multiplier into data. Add the profile to `calibration.json` first if it is a
genuinely different process; do not stretch an existing profile to cover it.

## Adding a task kind

A kind is a *shape of work with a measured cost*, not a topic. Add one only when a finished build
shows a class of task that consistently ran at a different multiple of the median, and write the
observation into its `basis`. Kinds with no basis are guesses wearing a label.

## Anti-patterns

- **Typing the estimate.** If the section in `plan.md` has no `rate per task unit` line, it was
  not produced by this tool.
- **Re-using a stale projection.** The Aug 23 figure was still governing on Aug 28 after half the
  tasks had landed. Re-run on every "will we make it" question; it costs seconds.
- **Counting calendar days as working days.** Weekends and holidays are in the spec for a reason.
- **Estimating optional scope as required.** Put it under `optional` so the human sees the split.
- **Calibrating from memory.** "It felt like two days" is not a record.

Files in this skill

  • SKILL.md6.1 KB
  • calibration.json9.7 KB
  • estimate.py10.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.