From 8ea297e8bf4569c19aa253763a332b59fe6ee0b6 Mon Sep 17 00:00:00 2001 From: glenn Date: Fri, 31 Jul 2026 10:54:12 +0200 Subject: [PATCH] Reseam as callista-odoo-demo: source-agnostic discovery, parallel build, follow-through MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Callista consumes this pipeline for both plain Odoo implementations and vertical demos, and is not a maintainer upstream — so the generic demo craft that had accumulated in the buildease-demo vertical skill lands here instead, where every engagement can reach it. Moved in from buildease-demo (they were never construction-specific): - Phase A: discovery brief from a transcript, notes, email, Knowcap, or a batched interview. Replaces the Knowcap-bound step 1. Infers before it asks. - Fork the slow half: instance prep and client research as two parallel subagents, then join. - Purge test residue: ordering, traps, read-back-the-counts evidence. - Phase C: objection sheet, scoped quote, implementation timeline, SOW. New here: - Extension points — a vertical supplies module routing, solution precedence, purge chain, demo-data policy and follow-through framing, and nothing else. Anything it needs beyond those is a gap to fix here, not to work around. - Named steps instead of numbered ones. Numbering meant an upstream renumber silently misrouted an extending skill with nothing to detect it. Renamed the skill to callista-odoo-demo: skills resolve by directory name, so a same-named fork shadows upstream depending on install order, and two people would build different demos from the same brief. MIT retained; SMEtools copyright kept, Callista added for modifications. Fork point and divergence recorded in UPSTREAM.md. Co-Authored-By: Claude Opus 5 --- LICENSE | 1 + README.md | 84 +++++++------- SKILL.md | 325 ++++++++++++++++++++++++++++++++++++++++++++-------- UPSTREAM.md | 44 +++++++ 4 files changed, 368 insertions(+), 86 deletions(-) create mode 100644 UPSTREAM.md diff --git a/LICENSE b/LICENSE index 35f1fa4..29edef3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2026 SMEtools +Copyright (c) 2026 Callista BV (modifications) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 5062050..c6d7f79 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,79 @@ -# Odoo Demo Architect +# Callista Odoo Demo -**Turn a discovery call into a complete, working Odoo demo — and the documents to sell it — with an AI agent doing the build.** +**Turn a discovery call into a complete, working Odoo demo — and the documents to sell it, before and after the meeting — with an AI agent doing the build.** -> Powered by **[Claude Code](https://claude.com/claude-code)** (the agent) + **[Knowcap](https://knowcap.ai)** (the memory). Claude does the research, build, code, and testing; Knowcap — queried over its MCP — feeds the agent the *truth of what the client actually said* in the discovery call. The agent is only as good as its memory: Knowcap is the memory. +> Fork of **[Smetools/odoo-demo-architect](https://github.com/Smetools/odoo-demo-architect)** (MIT). See [`UPSTREAM.md`](UPSTREAM.md) for the fork point and what diverges. -A Claude Code skill. Point it at a discovery call (in Knowcap) and a reachable Odoo instance; it mines the client's pains, researches what Odoo does natively vs. what needs building, stands up a **live database** (modules + realistic data + the 1–2 "hero" features that win the deal), **tests** that those features actually fire, and generates three sales documents: a **run-of-show**, a **one-pager** for the decision-maker, and a **one-page step-by-step demo script**. +A Claude Code skill. Point it at whatever discovery material exists — a transcript, meeting notes, an email thread, Knowcap, or nothing at all — and a reachable Odoo instance. It writes the discovery brief, researches what Odoo does natively vs. what needs building, stands up a **live database** (modules + realistic data + the 1–2 "hero" features that win the deal), **tests** that those features actually fire, and generates the sales documents. After the demo it writes the follow-through set. -Built from a real engagement where this produced a full Odoo 19 Enterprise demo — credit-limit hard-block with manager override, weight-based fleet load-building, localized data, three sales docs — ready for a CEO meeting, with the founder barely touching the keyboard. +## Three phases ---- +| Phase | Produces | +|---|---| +| **A — Discovery brief** | `discovery_brief.md` in a fixed six-section shape, from any source. Infers first, asks the gaps in one batch | +| **B — Build** | A live Odoo DB with working heroes, a verification log with real numbers, and three sales docs: run-of-show, decision-maker one-pager, 1-page demo script | +| **C — Follow-through** | Objection sheet, scoped quote, implementation timeline, statement of work | -## The stack -- **Claude Code** — the agent that reads the call, researches native-vs-custom, builds the database, writes + ships the custom code, and tests every hero feature. -- **Knowcap** — the meeting-intelligence layer. The agent calls the **Knowcap MCP** (`get_source_transcriptions`, `search_memories`) to pull the discovery transcript and the client's pains in their own words. No transcript hunting, no "remind me what they said." → [knowcap.ai](https://knowcap.ai) +Each phase is usable alone. Phase C runs days after the demo. -## What you get -- A **live Odoo demo DB** tailored to the client (any Odoo: Online, self-hosted, or Odoo.sh). -- **Working hero features**, no-code where possible, custom module only when necessary. -- A **verification log** proving each hero fired (real numbers). -- Three **self-contained HTML docs** (brand-themed): run-of-show, one-pager, 1-page script. +## Verticals extend this + +Vertical skills (e.g. `buildease-demo` for construction) wrap this one and supply only +their own module routing, solution precedence, purge chain, demo-data policy, and +follow-through framing. They do not restate the pipeline. See +[Extension points](SKILL.md#extension-points). ## Install + ```bash -# clone into your Claude Code skills folder -git clone https://github.com/Smetools/odoo-demo-architect ~/.claude/skills/odoo-demo-architect +git clone ~/.claude/skills/callista-odoo-demo ``` -Or drop the folder anywhere Claude Code loads skills. Then just ask Claude: *"build an Odoo demo for from our discovery call."* + +Then ask Claude: *"build an Odoo demo for <client> from these notes."* + +**Do not** install this as `odoo-demo-architect` — skills resolve by directory name, and a +same-named fork silently shadows upstream depending on install order. ## Prerequisites + - **Claude Code.** -- **Knowcap** (recommended) with its **MCP** connected — so the agent can pull the discovery transcript + extracted pains directly. → [knowcap.ai](https://knowcap.ai). (No Knowcap? Paste a transcript or notes instead.) - A reachable **Odoo instance + API key** (Settings → My Profile → Account Security → New API Key). - On **Odoo.sh**: create the project + enter any partner trial code first (web-only), then come back with the DB URL + API key. +- Optional: **Knowcap** with its MCP connected, as one possible discovery source → [knowcap.ai](https://knowcap.ai). - Optional: the **Perplexity MCP** for the native-vs-custom research step (web search works too). ## Quickstart + 1. Put your Odoo creds in env vars (or `scripts/creds.json`): `ODOO_URL`, `ODOO_DB`, `ODOO_LOGIN`, `ODOO_KEY`. 2. Verify the connection: `python scripts/odoo_connect.py` → prints `server_version`. -3. Copy `demo_config.example.json` → `scripts/demo_config.json`, fill it from the discovery call. -4. Ask Claude to run the pipeline (see `SKILL.md`). +3. Copy `demo_config.example.json` → `scripts/demo_config.json`, fill it from the brief. +4. Ask Claude to run the pipeline (see [`SKILL.md`](SKILL.md)). -## How it works (pipeline) -1. **Mine the discovery — via Knowcap.** Pull the meeting transcript over the Knowcap MCP; extract pains in the client's words + the 1–2 heroes. -2. **Research native-vs-custom** for each hero, for the client's exact Odoo version. -3. **Connect** to Odoo over XML-RPC; confirm the version. -4. **Install** the scope's modules. -5. **Load realistic data** (idempotent; currency before invoices; pre-stage so heroes fire live). -6. **Build heroes** — no-code first, custom module as fallback. -7. **Test every hero** on a throwaway record; keep demo objects pristine. -8. **Generate the docs** from the brand templates. -9. **Hand off** — login, cheat-sheet, verification log, doc links. - -Full procedure in [`SKILL.md`](SKILL.md). +`scripts/creds.json` and `scripts/demo_config.json` are gitignored — they hold client API keys. Keep it that way. ## Read this before touching Odoo 19 + Several core fields were renamed in v19 (`res.users.group_ids`, `res.groups` lost `category_id`, etc.), credit limit is **warning-only** natively, and fleet load-by-weight needs `stock_fleet`. All the footguns are in [`reference/odoo19-field-gotchas.md`](reference/odoo19-field-gotchas.md) so you don't relearn them the hard way. ## Files + ``` -SKILL.md the procedure (what the agent follows) -scripts/odoo_connect.py XML-RPC connector + helpers -scripts/build_demo.py config-driven data + hero builder (template) -demo_config.example.json per-client config shape +SKILL.md the procedure (what the agent follows) +UPSTREAM.md fork point + divergence from upstream +scripts/odoo_connect.py XML-RPC connector + helpers +scripts/build_demo.py config-driven data + hero builder (template) +demo_config.example.json per-client config shape reference/odoo19-field-gotchas.md version-specific fields + footguns -templates/ brand.css + the three doc templates +templates/ brand.css + the doc templates ``` ## License -MIT. Use it, fork it, sell with it. + +MIT — see [`LICENSE`](LICENSE). Original copyright SMEtools; modifications Callista BV. ## Credit -Built by **[SMEtools](https://www.smetools.io)** — Odoo implementation + AI automation. -Runs on **[Claude Code](https://claude.com/claude-code)** + **[Knowcap](https://knowcap.ai)**. + +Original by **[SMEtools](https://www.smetools.io)** — Odoo implementation + AI automation. +Fork maintained by **[Callista BV](https://www.callista.be)**. +Runs on **[Claude Code](https://claude.com/claude-code)**. diff --git a/SKILL.md b/SKILL.md index 30ea28f..9259fb5 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,77 +1,310 @@ --- -name: odoo-demo-architect -description: Build a complete, client-tailored Odoo demo from a discovery call. Mines the client's pains, researches native-vs-custom for each hero feature, stands up a LIVE Odoo database (modules + realistic data + working hero features) over XML-RPC, tests it, and generates the sales docs (run-of-show, one-pager, step-by-step script). Use when prepping an Odoo sales demo, POC, or proof-of-value before a client meeting. Triggers: "build an Odoo demo", "demo DB for ", "Odoo proof of concept", "stand up a demo before the meeting". +name: callista-odoo-demo +description: Build a complete, client-tailored Odoo demo end to end — assembles the discovery brief from any source (transcript, notes, email, Knowcap, or a live interview), researches native-vs-custom per hero feature, stands up a LIVE Odoo database over XML-RPC (modules + realistic data + working heroes), tests it, and generates the sales docs and the post-demo follow-through set (objection sheet, scoped quote, timeline, SOW). Use when prepping an Odoo sales demo, POC, or proof-of-value, or when writing the follow-up after one. Triggers: "build an Odoo demo", "demo DB for ", "Odoo proof of concept", "stand up a demo before the meeting", "write the follow-up after the demo". --- -# Odoo Demo Architect +# Callista Odoo Demo -Turn a discovery call into a polished, working Odoo demo + the documents to sell it — end to end, with minimal human steering. Built from a real engagement that won on first showing. +Turn a discovery call into a working Odoo demo, then into the documents that sell it. -> **Powered by Claude Code (the agent) + Knowcap (the memory).** The agent pulls the discovery call from **Knowcap** over its MCP — the client's pains in their own words — then researches, builds, writes + ships the custom code, and tests. The agent is only as good as its memory; Knowcap is the memory. → knowcap.ai +Three phases. **Discovery brief** → **Build** → **Follow-through**. Each is usable alone: +a brief without a build is still a brief, and Follow-through runs days after the demo. -## What it produces -1. A **live Odoo database** with the client's modules installed, realistic industry data, and the 1–2 "hero" features that map to their pain — actually working, not slideware. -2. Three **sales documents** (brand-themed, self-contained HTML): a **run-of-show**, a **one-pager** for the decision-maker, and a **1-page step-by-step demo script**. -3. A **verification log** proving each hero feature fired (e.g. "credit block raised at 56,379 > 50,000; override confirmed"). +> Fork of [Smetools/odoo-demo-architect](https://github.com/Smetools/odoo-demo-architect) +> (MIT). Diverges in three ways: discovery is source-agnostic rather than Knowcap-bound, +> the build forks two parallel agents, and Follow-through is new. See `UPSTREAM.md`. -## Inputs you need before starting -- **Discovery material** — pull the meeting transcript from **Knowcap** via its MCP (`get_source_transcriptions`; locate it with `list_sources` / `search_memories`). This is the agent's memory of what the client actually said. (No Knowcap? A transcript or notes works too.) -- **Agreed scope** — which Odoo areas are in Phase 1 (Sales, Inventory, Accounting, Fleet, etc.). -- **A reachable Odoo instance + credentials** — `URL`, `DB`, `login`, and an **API key** (Settings → My Profile → Account Security → New API Key). Works on Odoo Online, self-hosted, or Odoo.sh. - - *Odoo.sh note:* create the project + enter any partner trial code FIRST (web UI only — no API for project creation). Then proceed here once the DB is up and you have an API key. +**Vertical skills extend this one** — see [Extension points](#extension-points). If a +vertical skill invoked you, apply its overlays; do not make it restate the pipeline. -## The pipeline (run in order) +--- -### 1. Mine the discovery — via Knowcap -Pull the meeting transcript from **Knowcap** over the MCP (`get_source_transcriptions`, after locating the source with `list_sources` / `search_memories`). From it, extract and write down: -- The **business shape** (entities, what they sell, who they sell to). Watch for "it's a group" that is really ONE company in Odoo — confirm chart-of-accounts/P&L/warehouse are shared. -- The **top 3–5 pains in the client's own words** (quote them). These become the demo beats. -- The **1–2 hero features** — the differentiators that justify the spend. Everything else is supporting flow. +## Phase A — Discovery brief -### 2. Research native-vs-custom (don't assume) -For EACH hero feature, verify whether Odoo does it natively, no-code, or needs custom code — for the client's **exact Odoo version**. Use the Perplexity MCP (`perplexity_ask`) or web search. Ask precisely, e.g. *"In Odoo , is there a native hard-block (not warning) on SO confirmation over credit limit?"* Capture the verdict + citations. This step repeatedly overturns assumptions (e.g. credit limit is **warning-only** natively; v19 fleet dispatch IS native but only via `stock_fleet`). +Goal: `discovery_brief.md` in the six-section shape the rest of the pipeline consumes. -### 3. Connect (XML-RPC) -Use `scripts/odoo_connect.py`. Authenticate, print `server_version` to confirm the major version (field names differ across versions — see `reference/odoo19-field-gotchas.md`). All build steps go through the `x(model, method, *args, **kwargs)` helper. +**Source, in order of preference:** +1. A transcript, meeting notes, or email thread — read it. +2. Knowcap over MCP, if available and the user wants it (`get_source_transcriptions`, + after locating the source with `list_sources` / `search_memories`). +3. Nothing written down → interview the user. -### 4. Install modules for the scope -`button_immediate_install` on the `ir.module.module` ids. Common set: `sale_management`, `stock`, `account_accountant`, `stock_delivery`, `stock_picking_batch`, `fleet`, `web_studio`, `base_automation`, `contacts`. For fleet load-by-weight on v19 also install `stock_fleet` (Stock Transport — adds vehicle capacity + batch dispatch). Module installs are heavy; allow several minutes. +### Intake — infer first, ask only the gaps + +Before asking anything, **look**: glob the working directory for a transcript, notes, +brief, or `.md`/`.txt`/`.docx` that plausibly is the source, and read it. Then answer +each item below from what you read. Only the items you genuinely cannot answer go to +the user, in **one** `AskUserQuestion` batch — never a serial interrogation, never a +question whose answer is sitting in the file you just read. + +| Item | Infer from | Ask only if | +|---|---|---| +| **Source brief location** | A single obvious candidate file in the working directory | Zero or several candidates — ask which, or paste | +| **Odoo UI language** | Language the brief is written in; client country; `l10n_*` in scope | Brief is English but the client clearly isn't anglophone — ask (nl_BE / fr_BE / en_US / other) | +| **Client website / company info** | URL or company name in the brief — fetch the site, mine it for what they build or sell, size, regions, branding | No name or URL anywhere in the source | +| **Odoo instance** | `demo_config.json`, prior session, the brief | Not found — always ask, never guess a URL or API key | +| **Demo audience** | Attendee list in a transcript header or email thread | Source is notes with no names | +| **Rate card** | A rates file in the project | Only needed at Phase C — don't ask now | + +Anything still missing after that batch: write it into the brief as `(unknown)` and +carry on. One unknown does not block building the demo. + +If nothing written down exists at all, the interview replaces the table — still one +batch: who the client is, what they sell or build, how they quote today, how they +invoice, the top 3 complaints they voiced, who is in the room. + +**Write `discovery_brief.md` with these six sections and no others:** + +```markdown +## Business shape +Entities, product/customer types, volumes, shared financials. +Company name, website, country, what they actually do — from the site if you fetched it. +Watch for "it's a group" that is really ONE company in Odoo — confirm whether +chart-of-accounts, P&L and warehouse are shared. + +## Top pains +3–5 items. Direct client quotes where you have them. Mark anything you inferred as (inferred). + +## Hero features +1–2. Each names the pain it kills and the decision-maker it lands on. +Everything else is supporting flow. + +## Phase 1 scope +Odoo apps in scope, plus any vertical modules routed by an extending skill. + +## Odoo instance +URL, database, login, API key. Ask if absent — do not guess. +UI language + `l10n_*` localisation to install. + +## Demo audience +Who is in the room and what each one needs to hear. +``` + +Never invent a pain quote. An inferred pain marked `(inferred)` is fine; a fabricated +quote read back to the client in the demo is not. + +Show the brief to the user and get a yes before Phase B. + +--- + +## Phase B — Build + +Steps are **named, not numbered** — reference them by name, and never rename a step +casually, because extending skills point at these names. + +### Fork the slow half + +*Instance prep* and *client research* are independent: the install list comes from the +brief (plus any routing overlay), while research feeds hero *building*, which happens +after both. Installing over XML-RPC is minutes of waiting that produces log spew nobody +needs in context. Run them as two parallel subagents launched in **one** message: + +**Agent 1 — instance prep.** Give it the Odoo credentials and the module list. It sets +company, currency, UoM and UI language, installs the localisation, then the modules, +then walks Settings for behaviours that default off. It loads **no data** — that is the +join step's job. Returns: what installed, what failed, the settings it changed. + +**Agent 2 — client research.** Give it the brief. It fetches the client's website and +researches each hero feature (see *Research native-vs-custom*). Returns: per hero, the +verdict and the click-path if the capability already exists. + +**Join.** Both done → install anything research turned up that prep didn't know about +(incremental, cheap) → *Load demo data* → *Build heroes* → *Test heroes*. + +Two agents, not five. Do not fan out further — hero building is sequential against one +database, and parallel writes will fight. + +### Research native-vs-custom + +For EACH hero feature, verify whether Odoo does it natively, no-code, or needs custom +code — for the client's **exact Odoo version**. Use the Perplexity MCP (`perplexity_ask`) +or web search. Ask precisely, e.g. *"In Odoo , is there a native hard-block (not +warning) on SO confirmation over credit limit?"* Capture the verdict + citations. + +This step repeatedly overturns assumptions — credit limit is **warning-only** natively; +v19 fleet dispatch IS native but only via `stock_fleet`. Version assumptions are the #1 +source of wasted effort. + +An extending skill may insert its own tier ahead of native — see [Extension points](#extension-points). + +### Connect + +Use `scripts/odoo_connect.py`. Authenticate, print `server_version` to confirm the major +version (field names differ across versions — see `reference/odoo19-field-gotchas.md`). +All build steps go through the `x(model, method, *args, **kwargs)` helper. + +### Install modules + +`button_immediate_install` on the `ir.module.module` ids. Common set: `sale_management`, +`stock`, `account_accountant`, `stock_delivery`, `stock_picking_batch`, `fleet`, +`web_studio`, `base_automation`, `contacts`. For fleet load-by-weight on v19 also install +`stock_fleet` (Stock Transport — adds vehicle capacity + batch dispatch). Module installs +are heavy; allow several minutes. + +### Load demo data + +Industry-appropriate, minimal but believable, generated from the brief — the client's own +partners, products, projects and orders, staged so each hero has a record to fire on. +Drive it from a `demo_config.json` (see `demo_config.example.json`) and +`scripts/build_demo.py`. Rules: -### 5. Generate + load realistic demo data -Industry-appropriate, minimal but believable. Drive it from a `demo_config.json` (see `demo_config.example.json`) and `scripts/build_demo.py`. Rules: - **Get-or-create by name** so re-runs are idempotent. -- Set the right **currency** first (activate it with `context={'active_test': False}`, set on `res.company`) — BEFORE posting any invoices (currency can't change once journal entries exist). -- Give products a **weight** if fleet is in scope. Give customers **credit limits** (`use_partner_credit_limit=True`, `credit_limit=...`) if credit is in scope. -- **Pre-stage state** to make heroes fire live: e.g. post an unpaid invoice to put a customer's receivable JUST under their limit, so a live order tips them over. Keep one demo quotation in **draft** for the live click. +- Set the right **currency** first (activate it with `context={'active_test': False}`, set + on `res.company`) — BEFORE posting any invoices. Currency can't change once journal + entries exist. +- Give products a **weight** if fleet is in scope. Give customers **credit limits** + (`use_partner_credit_limit=True`, `credit_limit=...`) if credit is in scope. +- **Pre-stage state** so heroes fire live: e.g. post an unpaid invoice putting a + customer's receivable JUST under their limit, so a live order tips them over. Keep one + demo quotation in **draft** for the live click. - Seed stock with `inventory_mode` context so deliveries can reserve (go Ready). -### 6. Build the hero features — no-code first, module as fallback -- **Prefer no-code:** server actions / automated rules (`base.automation`) / Studio. Portable to any Odoo, no deploy. -- **Custom module only if needed:** generate a minimal module, push to the instance's git (Odoo.sh) or hand it to the user to deploy, then install + test. Keep modules tiny and version-correct. -- Example hero (credit hard-block + manager override): override `sale.order.action_confirm` to raise `UserError` when `partner.credit + amount_total > credit_limit` unless the user is in an approver group; add an "Override" button gated to that group. (No-code equivalent: a Studio approval rule on the Confirm button + a stored "over limit" flag.) +### Build heroes -### 7. Test every hero over XML-RPC -On a THROWAWAY record: trigger the action, assert the block fires, assert the override path works, then delete the throwaway. Leave the real demo objects pristine. Print a verification log with the actual numbers. +- **Prefer no-code:** server actions / automated rules (`base.automation`) / Studio. + Portable to any Odoo, no deploy. +- **Custom module only if needed:** generate a minimal module, push to the instance's git + (Odoo.sh) or hand it to the user to deploy, then install + test. Keep modules tiny and + version-correct. +- Example hero (credit hard-block + manager override): override `sale.order.action_confirm` + to raise `UserError` when `partner.credit + amount_total > credit_limit` unless the user + is in an approver group; add an "Override" button gated to that group. + +### Test heroes + +**Mandatory.** A demo hero that fails live loses the deal. Trigger each hero, assert the +block fires, assert the override path works. Print a verification log with actual numbers +(e.g. "credit block raised at 56,379 > 50,000; override confirmed"). + +Test against a **throwaway** partner named `ZZ Test…`, never the client's own records — a +hero you tested is a hero you consumed, and the demo needs its first click to be the first +click. + +### Purge test residue + +**A demo environment ships with zero test residue.** Debugging a chain takes several runs, +each leaving a full trail; "it's cancelled and the partner is archived" is not clean — +those records still list on screen. Write the purge as a function in the test script and +run it until the counts are zero, not as a one-off you improvise at the end. + +Odoo blocks most deletion unless you go in dependency order, leaves last. An extending +skill supplies the exact chain for its own models; the generic order is: + +``` +transient wizard rows → downstream documents (cancelled only, newest first) +→ invoices → time entries → tasks → projects → sale orders → the partner +``` + +The traps, each of which costs a debugging round: + +- `search` will not find the partner once archived — pass `context={"active_test": False}` + or the purge silently no-ops and reports success. +- Invoices must go to draft before cancel; period-sequenced documents cancel newest-first only. +- **Delete the partner last, and only once nothing references it.** Deleting it first nulls + `partner_id` on whatever survived, so a `partner_id`-based purge can no longer see those + records and a `partner_id`-based assertion reports clean over an environment that isn't. + Sweep by name as well, and assert on both. +- Anything the tests **copy** inherits the source record's customer, not the throwaway one. + Repoint copies at the throwaway partner or they escape the purge. +- Make every step best-effort with its own `try`, and **print what it kept** — a silent + purge that skipped nine records reads exactly like one that worked. + +Finish by reading back the counts of every model you touched into the verification log. +"No test residue" is a claim; the counts are the evidence. + +### Sanity-check the staged numbers + +A chain that passes every assertion can still look broken on screen. Check the staged data +reads plausibly: quantities consumed well under quantities ordered (over 100% makes any +progress or delivery view look wrong), costs under selling prices, dates in the past. +Derive staged quantities from the ordered quantity rather than hard-coding them, so they +cannot drift when a formula changes. + +### Sales docs + +From `templates/` (brand-themed, `{{placeholder}}`-driven), produce three self-contained +HTML files filled with the client's data: -### 8. Generate the sales docs -From `templates/` (genericized, brand-themed), produce three self-contained HTML files, filling in the client's data: - **run-of-show** — beats with exact click-paths + what to say. -- **one-pager** — before/after, what's automated, investment, the path to go-live; branded for the *selling* company; decision-maker audience. +- **one-pager** — before/after, what's automated, investment, path to go-live; branded for + the *selling* company; decision-maker audience. - **demo-script-1pager** — 7-ish numbered steps (Do + Say), prints on one A4. -### 9. Hand off -Output: the login, the pre-loaded data cheat-sheet, the verification log, and links to the three docs. Remind the user to rehearse once and keep the demo quotation in draft. +### Hand off + +Output: the login, the pre-loaded data cheat-sheet, the verification log, and links to the +three docs. Remind the user to rehearse once and keep the demo quotation in draft. + +--- + +## Phase C — Follow-through + +Runs after the demo happened. Needs: the built demo, the verification log, and what +actually came up in the room. Ask the user for the room notes — objections raised, who +pushed back, what they asked for that wasn't there. + +Generate four documents, reusing `templates/` branding and its self-contained-HTML rule +(no external assets, single file, prints to A4). + +| Document | Contents | +|---|---| +| **Objection sheet** | Every objection raised → the honest answer. Where the product already covers it, name the module and the screen. Where it doesn't, say so and give the workaround or the build estimate. | +| **Scoped quote** | Line items from the Phase 1 scope: modules, configuration, data migration, custom work, training. Days and rate per line. Flag assumptions separately from committed lines. | +| **Implementation timeline** | Phased, with the client's own dependencies on it (data extraction, sign-offs, who from their side). Weeks, not dates, unless a start date is agreed. | +| **Statement of work** | Deliverables, acceptance criteria, out-of-scope list, change-request process. The out-of-scope list is the point — write it properly. | + +Rules: +- Every number traces to something. No invented day-rates, no invented licence costs — ask + the user for the rate card. +- Anything the demo *didn't* prove goes in the quote as build work, not as "included". + Cross-check against the verification log from *Test heroes*. +- The out-of-scope list is where the follow-through earns its keep. Anything discussed and + not quoted goes in it explicitly. + +Show all four to the user before anything leaves the machine. + +--- + +## Extension points + +A vertical skill (construction, retail, …) wraps this one rather than restating it. It may +override exactly these, and nothing else: + +| Extension point | What the vertical supplies | Applied at | +|---|---|---| +| **Module routing** | A pain → module table keyed on the client's own words | *Install modules*, and Phase A's `## Phase 1 scope` | +| **Solution precedence** | An extra tier ahead of native, e.g. ` → native Odoo → custom` | *Research native-vs-custom* | +| **Purge chain** | The exact model teardown order for its own models, replacing the generic chain | *Purge test residue* | +| **Demo data policy** | An override of what dataset gets loaded, or an instruction not to install a stock one | *Load demo data* | +| **Follow-through framing** | Vertical-specific objections and scope lines | Phase C | + +Rules for the boundary: +- The vertical does **not** reimplement `scripts/`, `templates/`, or `demo_config.json` handling. +- It references steps by **name** (*Test heroes*, *Purge test residue*), never by number. +- Anything a vertical needs that isn't in the table above is a gap in *this* skill — fix it + here, so the next vertical gets it free. + +--- ## Guardrails -- **Never invent that a feature works — test it.** Step 7 is mandatory; a demo hero that fails live loses the deal. -- **Research before building** (step 2). Version assumptions are the #1 source of wasted effort. + +- **Never invent that a feature works — test it.** *Test heroes* is mandatory. +- **Research before building.** Version assumptions are the #1 source of wasted effort. - **Don't hard-code the client.** Everything client-specific lives in `demo_config.json`. - **Currency before invoices. Weight before fleet. Pre-stage before the live click.** Order matters. -- Read `reference/odoo19-field-gotchas.md` before touching Odoo 19 — several core fields were renamed. +- Never hand over an environment holding test records. Purge them and read back the counts; + do not settle for "cancelled and archived" and do not write leftovers off as a note. +- Never send anything client-facing without the user reading it first. +- Read `reference/odoo19-field-gotchas.md` before touching Odoo 19 — several core fields + were renamed. +- `discovery_brief.md`, `demo_config.json` and the follow-through docs hold client data and + API keys — keep them in the project directory, never in a scratchpad you'd forget. ## Files + - `scripts/odoo_connect.py` — XML-RPC connector + `x()` helper (correct context-kwarg passing). - `scripts/build_demo.py` — config-driven data + hero builder (template to adapt per engagement). - `demo_config.example.json` — the shape of a per-client config. - `reference/odoo19-field-gotchas.md` — version-specific field names + footguns learned the hard way. -- `templates/` — the three doc templates (brand-themed, `{{placeholder}}` driven). +- `templates/` — doc templates (brand-themed, `{{placeholder}}` driven). +- `UPSTREAM.md` — fork point and divergence from Smetools/odoo-demo-architect. diff --git a/UPSTREAM.md b/UPSTREAM.md new file mode 100644 index 0000000..6ba099a --- /dev/null +++ b/UPSTREAM.md @@ -0,0 +1,44 @@ +# Upstream + +Fork of **[Smetools/odoo-demo-architect](https://github.com/Smetools/odoo-demo-architect)** (MIT). + +| | | +|---|---| +| Fork point | `ada2751` — *docs: credit Claude Code (agent) + Knowcap (memory via MCP) throughout* | +| Forked on | 2026-07-31 | +| Upstream state at fork | 2 commits, no tags, no releases | + +Callista is not a maintainer upstream, so changes land here rather than as PRs. Upstream +is effectively inert; pull from it deliberately rather than tracking it. + +```bash +git remote add upstream https://github.com/Smetools/odoo-demo-architect +git fetch upstream && git log --oneline HEAD..upstream/main +``` + +## Why the fork exists + +Callista runs this pipeline for both plain Odoo implementations and vertical demos +(BuildEase/construction via the `buildease-demo` skill). Three things it needed are not +upstream's problem to solve: + +| Divergence | Upstream | Here | +|---|---|---| +| **Discovery source** | Step 1 pulls the transcript from Knowcap over MCP; everything else is a fallback mentioned in passing | Phase A takes a transcript, notes, an email thread, Knowcap, or a batched interview, and infers before it asks. Knowcap is one source among several | +| **Build parallelism** | Linear steps 3–7 | *Fork the slow half* — instance prep and client research run as two parallel subagents, then join | +| **After the demo** | Ends at hand-off | Phase C — objection sheet, scoped quote, implementation timeline, SOW | +| **Extensibility** | None; a vertical would fork the whole pipeline | [Extension points](SKILL.md#extension-points) — a vertical supplies routing, precedence, purge chain, demo-data policy, and nothing else | +| **Step references** | Numbered `### 1.`–`### 9.` | Named steps. Numbers meant a renumbering upstream silently misrouted an extending skill | +| **Purge** | One line inside step 7 ("delete the throwaway") | *Purge test residue* — ordering, traps, and read-back-the-counts evidence | + +## Renamed + +The skill is `callista-odoo-demo`, **not** `odoo-demo-architect`. Skills resolve by +directory name under `~/.claude/skills/`, so a same-named fork would silently shadow +upstream depending on install order — and two people would build measurably different +demos from the same brief. Keep the names distinct. + +## Attribution + +MIT. `LICENSE` retains the SMEtools copyright as required and adds Callista's for the +changes. Keep both.