Presales with Docs
Guide a client conversation from desired outcome to a reviewable, non-binding ballpark. The presales operator owns the meeting and every commercial approval.
Start
Read references/live-discovery.md. Ingest supplied requirements before asking anything. Ask the operator whether the conversation is client-visible or private, then create
<client-slug>-presales/discovery-record.mdfrom the reference template. State that this is discovery for an indicative ROM. Complete when: visibility is known and the record contains every fact already available from supplied material.Ask: “What outcome would make this project successful for you?” Ask exactly one client-facing question, then wait. Honor operator controls:
park,skip,revisit,summarize,private checkpoint, andend discovery. Complete when: the client has answered or the item is explicitly parked.
Discovery loop
Update
discovery-record.mdafter every answer: confirmed facts, client decisions, assumptions, exclusions, unresolved items, and conflicts remain distinct. Choose the next question by this order: conflict, readiness blocker, largest estimate swing, then output detail. Ask one question and wait. Offer a recommended answer only when the operator or client needs options; label it as a recommendation. Complete when: every readiness-gate field is confirmed, assumed with a stated basis, or recorded as non-blocking, and no blocking conflict remains.Present one scope checkpoint: outcomes, scope in/out, work breakdown, assumptions, unresolved items, and proposed effort ranges. Ask the operator for one confirmation. Revise through the discovery loop when they reject it. Complete when: the operator explicitly approves the estimate basis.
Ballpark
Read references/estimate-input.md. Build the JSON input from the approved basis and controlled sources. For a Notion-backed rate card, also read references/notion-rate-card.md, load an approved/effective card into a private snapshot, and map every estimate role to one composite rate key. Use the inline rate card only as the documented fallback. Keep tokens, private rates, snapshots, and role math out of client-visible conversation. Complete when: every service line has role, day range, rate-card match, and basis; snapshot provenance verifies when used; every external cost has source and as-of date; timeline has a stated basis.
Run the deterministic calculator in draft mode:
python3 "<this skill dir>/scripts/calculate_ballpark.py" estimate.json \ --output-dir ./ballpark-outputWhen step 5 produced a Notion snapshot, add
--rate-card-snapshot ./private/rate-card-snapshot.json. Never run the loader in a client-visible terminal.Validation errors return to the discovery loop. Review
internal-estimate.mdprivately; the client artifact contains totals but no day rates. Complete when: every total traces to an input line and the operator accepts the range, confidence, assumptions, exclusions, contingency, and validity period.Ask one approval question: “Do you approve this ROM for client discussion?” After explicit approval, record the human reviewer:
python3 "<this skill dir>/scripts/calculate_ballpark.py" estimate.json \ --output-dir ./ballpark-output --approved-by "Reviewer name"Present
client-ballpark.md. If approval is withheld, present the discovery summary and missing decisions instead. Complete when: approved output names its reviewer, or the session ends without a commercially usable estimate.
Hard gates
- A ballpark is a range. The client artifact states ROM status, confidence, basis, assumptions, exclusions, contingency, validity, unresolved items, and non-binding use.
- Critical unknowns stay in
blocking_unknowns; the calculator refuses an estimate. - Services, one-time infrastructure, and recurring cloud/BAU remain separate totals.
- Keep private rates, margins, discounts, and role-level math in internal artifacts.
- Fetch Notion rates through the read-only deterministic loader, not through model context.
- Reject changed snapshots, ambiguous active versions, mixed currency, and missing mappings.
- The calculator performs arithmetic; the model performs discovery and decomposition.
For a complete synthetic run, read examples/sample-session.md and use examples/sample-estimate.json.