Build with Estii

Reuse and curate scope

Fill a deal from work you have already priced, and keep the library catalogue right.

Reuse scope you have already priced

Your library holds the work you sell, named, with a low/typical/high estimate range behind each line drawn from deals you have already won. Reach for it before writing scope from scratch.

estii library find "take card payments"
estii library inspect lib_blk_stripe
estii deal fill nd_abc123 lib_blk_stripe --into "Integrations" --dry-run
estii deal fill nd_abc123 lib_blk_stripe --into "Integrations" --level high --yes

find matches your phrase against the catalogue and reports how strong each match is and what caused it, so you can tell a name hit from a loose topical one. It matches on words, including a word your query only starts (auth reaches authentication), and a nothing-found result says what to try instead. Every row also carries what the item is worth at your rates, as a low-to-high range, and a grade from A+ to C for how well attested and how current it is: a B or a C is work you have sold before but not lately.

inspect opens one item: its tasks in order, each with its own price and grade, and for each estimate line the low, typical, and high amounts with the number of deals behind them and what that line costs. A line marked manual was typed by someone rather than observed.

fill creates the line item, its tasks, and an estimate per line, taking the --level end of each range. Leave --into off and it lands where the item's own placement hints point, reporting that it derived the destination; when nothing points anywhere it stops and asks you to name one.

An estimate line names a resource, and a deal holds its own copy of your resources, so a line can name one this deal does not have. When that happens the fill writes nothing and reports each unresolved line with the deal resources it could map to. Say which:

estii deal fill nd_abc123 lib_blk_hosting --into "Platform" --map "Cloud Engineer=Specialist" --yes

Or pass --drop-unresolved to fill without those lines, which names every one it dropped. Unresolved lines are always reported, never dropped silently.

Keep the library right

The catalogue drifts: a name stops matching how people ask for the work, an estimate someone typed by hand is out of date, an item is filed where nobody looks. Correcting it is the same shape as every other write here, so a diff comes first and nothing lands until you say so.

estii library list --updates
estii library set lib_blk_hosting keywords="Infrastructure, Hosting, Environments" --dry-run
estii library set lib_blk_hosting keywords="Infrastructure, Hosting, Environments" --yes
estii library set lib_tsk_host_provision estimate."Specialist"=3-5d --yes
estii library move lib_blk_hosting --to "Support & run" --yes

Curating needs the manager role, the same one a rate change needs. estii space members lists who holds which role here, so a refusal names someone to ask. It reports email addresses to owners and admins only, the same way the app gates its members page.

An estimate amount names its unit — 4d, 3-5d, 10±2d — and a bare number is refused with the units that line accepts. The same write marks the line as typed by hand, so the next deal you win does not average your correction away.

estii library add item name="Managed backup" group="Support & run" --yes
estii library add task item="Managed backup" name="Restore drill" estimate."Specialist"=2d --yes
estii library export --out library.json

add puts new work in the catalogue directly, active and ready to fill from. export writes the whole tree — collections, groups, items, tasks and their lines — which is the read worth doing before a round of edits.

If whatever is reading the catalogue is not running the binary, the same two reads are plain HTTP: GET /v1/space/:id/library for the rows and GET /v1/space/:id/library/export for the tree. Both answer what an item is worth at your rates and how well attested it is. Neither carries your cost, your margin, or the matcher guidance a curator wrote.

Add at scale

Adding at scale is a different safety class, so it has its own verb.

estii library propose name="Managed backup" group="Support & run" tasks="Restore drill" --yes
estii library propose --into "Managed hosting" tasks="Patch window" --yes
estii library propose --data @library.json --yes
estii library list --status proposed
estii library open

propose puts items up for review instead of into the catalogue. Until someone accepts one, it is excluded from find, from matching and from estii deal fill, so proposing is safe to run against a library people are already using where a run of add is not. --data takes the same document export writes, which is what turns twenty items into one call. A group= the space holds is recorded on the proposal; one it does not hold is carried as a hint and the group is created only if the review accepts it. A proposal whose name matches something you already have is marked as a likely duplicate, so the review opens on a merge.

Three things are done in the app

An item leaves the catalogue by archival (estii library set <ref> status=archived) rather than deletion, because the evidence behind it outlives the item. A waiting review — new evidence that would move a line, or a suggested match — is accepted or declined in the app: estii library list --updates names the items with one, and estii library open <ref> opens the item on the page where you action it: the catalogue scrolls to it and marks it briefly, and the item's own menu in the app copies that same link back. And a proposal is accepted, merged or discarded there too: estii library open opens the page, where the Proposals control carries the count.