Purpose
You claimed a CDX Caldova tenant and it arrives with licences but no Dynamics 365 apps installed. This skill takes it from empty to demo-ready.
It is written from a real end-to-end build (Aug 2026). Everything here was executed and verified, including the things that did not work — those are called out explicitly so you do not repeat the same dead ends.
Caldova is Microsoft's fictional pharmaceutical / life-sciences enterprise. The packaged
demo narrative is supplier sourcing, procurement, RFP management, supplier risk and contract
manufacturing (partner org in the scenarios: Allerveo). You can keep that narrative or
reskin it to your own industry — see reference/04-demo-data-reskin.md.
🚀 START HERE — run the guided start
When a user invokes this skill, do not start executing and do not dump a questionnaire. Open
reference/00-guided-start.md and follow it. It is the choreography for the first ten minutes:
- Detect before you ask.
pac auth list,pac env list, a record-count sweep, and a check for an existing~/.caldova-demo-profile.json. Then tell the user what you found and branch:
| Found | Branch |
|---|---|
| No auth profile, no tenant | A — claim a tenant (00-claim-tenant.md) |
| Auth profile, empty org | B — fresh build → intake |
| Org already has records | C — resume; summarise, then ask what is next |
| Decision record exists | D — reuse it; confirm, do not re-interview |
-
Interview in six themed batches, not one wall of thirteen questions — who you sell to, workloads, data depth, the gated decisions, operating preferences, sign-ins. Content and rationale for each question live in
reference/00-operator-profile.md. -
Confirm the whole plan once, then run unattended.
-
Write
~/.caldova-demo-profile.jsonbefore the first build step, so a crash or a new session never re-interviews the user. Never write a password into it.
No tenant yet? Branch A covers claiming plus the MCAPS BYOT Azure subscription request. Those two are sequential, not parallel — the tenant must exist before the request has anything to attach to. And the launcher is not a progress bar: it can spin for 15–30 minutes after the tenant already exists. Verify in My Dashboard. Run the intake while it provisions.
Read this before you touch anything
First: confirm which identity you are operating as
Ask the operator for the Caldova admin UPN and sign in as that account before running anything.
| Identity | Example | Use for |
|---|---|---|
| Their corporate account | {{USER_EMAIL}} |
The CDX portal only |
| Caldova tenant admin | admin@caldova<NNNNNNNN>.onmicrosoft.com |
Everything else in this playbook |
Get the UPN from CDX → My Dashboard → the tenant row → Credentials. Then:
pac auth create --name caldova # interactive browser sign-in as the Caldova admin
pac auth list # confirm the * is on the caldova profile
…and sign the browser in to the M365 admin portal and PPAC as that same account. Later, once the
BYOT subscription lands, az login --tenant <caldova-tenant-id> too.
🔒 Ask for the UPN, never the password. All sign-ins are interactive browser prompts — the operator types their password into the Microsoft sign-in page. Do not request, store, echo or write a tenant password anywhere.
Why this is first: wrong-identity failures do not announce themselves. pac returns an empty
environment list (looks like nothing was created), portals load with nothing in them, and file
uploads land in the wrong OneDrive. If something is inexplicably empty, check identity before
debugging anything else. Full detail in reference/00-claim-tenant.md § Step 2.5.
Phase 0.5 is mandatory: one intake, then run unattended
This skill is exportable. Whoever is running it is probably not the person who wrote it.
Design contract: ask everything at the start, then work alone. A full build contains four
multi-hour waits and dozens of small decisions. Asking each one when you reach it pins the operator
to the session for a day. reference/00-operator-profile.md collects all thirteen decisions in
a single exchange — industry and accounts, which workloads, data depth, Sales Premium
authorisation, live-send policy, journey shape, recovery policy, notifications, and the batched
sign-ins.
Every worked example in this skill (the CPG brand families, the retail/grocery archetypes, the
gen-ci-data.py product list) comes from one seller's territory. They are illustrations, not
defaults. Inheriting them silently produces a demo that resonates with nobody.
State the privacy rule out loud: recommend fictional company names, because a demo tenant carrying real account names shows Customer B's pipeline to Customer A the moment it is demoed.
After intake, only three things justify interrupting the operator
- An interactive password prompt — cannot be automated. Batch every sign-in at intake so this happens once, at a time of their choosing, rather than four hours in.
- A destructive or commercial action not pre-authorised — deleting an environment, sending real email, accepting licensing terms.
- A genuine dead end, after diagnosis, with every unblocked task already finished.
Everything else has a rule instead of a question:
| Situation | Do this, don't ask |
|---|---|
| Long wait | Switch to independent work — seed data while CI installs, configure Service while F&O provisions |
| Failure | Retry once, apply the intake recovery policy, else record it and continue with everything not blocked by it |
Masked error ({1}{0}) |
Diagnose with a raw fetch first — most of these were solved without the operator |
| Ambiguous choice | Take the reversible option and note it (non-semantic over semantic, Draft over Live) |
If you catch yourself about to ask a mid-build question, it belongs in the intake. Add it to
reference/00-operator-profile.md so the next operator is never asked it at that point again.
The single most important lesson: progress indicators lie
This recurs at every layer of the build. Tooling and portals report state confidently and wrongly, in both directions — claiming success that has not happened, and claiming in-progress long after work has finished.
Five separate pac commands returned confidently wrong answers:
| Command | What it claimed | Reality |
|---|---|---|
pac application list |
33 apps in BOTH Installed and NotInstalled | Broken filter |
pac solution list |
3 solutions | Full Sales + CS + Field Service + Project Ops deployed |
pac copilot list |
All 43 agents "Published / Provisioned" | 37 were Draft |
pac admin list |
Environment Type = Sandbox | Already converted to Production |
pac admin list |
1 environment in the tenant | 3 — it silently omits every environment without a Dataverse DB, including F&O envs mid-provision |
And three UI surfaces do the same:
| Surface | What it showed | Reality |
|---|---|---|
| CDX tenant launcher | Still working, 15–30 min | Tenant already created — visible in My Dashboard |
| CI provisioning portal | Installing |
App module already existed in the org |
| PPAC direct URLs (licensing/apps/dataflows) | 404 / error page | Pages exist; reachable via the tab strip |
bots table |
All 45 agents statecode=0 status=1 |
Says nothing about publish state — check Copilot Studio |
msdyn_aiconfiguration |
50 rows, looks configured | They are Copilot prompts, not predictive scoring models |
F&O Create — Succeeded |
Environment deployed fine | Demo data may be entirely absent — verify by legal entity |
| CI admin provisioning grid | Not Installed for CI – Data / Journeys |
Fully entitled — needed only a self-service region pick at home.ci.ai.dynamics.com |
| Per-user licence check | No Customer Insights licence on the user | CI is an ORG-level service plan — it can never appear per user, on any tenant |
| Billing → Your products | 1 product in the tenant | 17 licences under Billing → Licenses, incl. the multi-app demo SKU |
| Predictive scoring form | Valid, Get started enabled | Default BPF filter matched 0 of 421 leads — API-seeded records have no BPF instance. Set BPF = None. |
| CI activity relationship dialog | Apply enabled on an email→CustomerId join |
Joins against the target's primary key; produces zero matches |
| CI – Journeys email | Compliance profile bound, real address present | msdynmkt_placeholders tokens declared but unbound — Ready to send silently does nothing |
| Entitlement PATCH | Succeeded on create, so edits look safe | Editable only while Draft — every PATCH after activation fails |
| Journey analytics | Sent 40 · Delivered 40 · 0 failed, but the demo folder was empty |
Delivered fine — Exchange Junk-filtered it, and junk runs before inbox rules |
| Email open rate 97.5% | Outstanding engagement | Defender scanning the tracking pixel — 44 opens, all client "Unknown", mail never read |
| CI prediction data picker | "There are no available tables for the selected activity type" | Data is fine — the activity's semantic type was Purchase; OOB models only accept SalesOrder / SalesOrderLine / Subscription |
| CI measure template picker | Offers no monetary column, only ActivityTime / Title / EventDate… |
Templates read the projected UnifiedActivity, not your source table. Unmapped semantic fields simply do not exist downstream |
| Prediction review page | Customer transaction history: In progress, Run greyed |
Stale/misleading. The left-rail tab is the truth — it read "Step is empty" because the Add-data selection never persisted through Save draft |
F&O Allowed MCP clients grid |
Renders empty for ~10s, and virtualized cells read as "" even when visible |
7 first-party clients were already registered. Verify via /data/McpAllowedClients, never the DOM |
| F&O "company which does not exist" | Account/permissions problem, or a broken environment | Usually self-inflicted — an unknown ?cmp= value persists to your session and breaks every later page load. Recover with ?cmp=DAT |
| CI segment "Estimated segment size" | The member count you'll get | An estimate — previewed 79, resolved to 50 |
CI segment-suggestions Run greyed, no error |
Config incomplete somewhere unknown | The Activity step's "Confirm the applicable activity source table" checkbox only renders after you pick the type; skip it and the review page shows a blank source table |
| CI differentiator attribute picker | Every listed attribute is usable | Date measures are offered but rejected on Save — 'Lastpurchasedate' ... isn't allowed |
| CI differentiator "No item found. Could not find any segments." | No segments exist | They do — the other one was still Refreshing. Needs 2 segments with completed refreshes |
F&O account structure Draft after Activate |
Activation failed | It's a batch job; it stays Draft until the batch service runs it — and that service can be idle on a fresh environment |
| A reskinned tenant | The rebrand is complete | The reskin covers records, not config — queues, case subjects and price lists keep their Contoso names and are visible in every dropdown |
| A timed-out OData batch | The work failed, re-run it | The browser kept going. Quotes read 38 at timeout and 56 minutes later. Re-query counts and resume by diff, or you will duplicate |
Sales agent stuck on Draft after Start |
The start silently failed — retry it | There is a second Start agent confirmation prompt below the fold. Two identically-named buttons; click the last one. (This corrects an earlier, wrong note in the skill) |
| F&O MCP server reachable | Transport is healthy, so the agent "works" | Says nothing about data — Caldova's ERP has 1 legal entity and 0 customers |
| 118 knowledge articles in the org | The knowledge base is well stocked | Only 6 were Published. 41 good articles sat in Draft — invisible to knowledge search and agent assist. Filter on statecode eq 3 and islatestversion eq true, never on row count |
| F&O "nothing can post" | The batch service is idle/stuck | ❌ Wrong diagnosis. FiscalPeriods = 0 — the fiscal years exist as headers with no periods inside, because creating a year over OData never generates them. Fix on the mi=FiscalCalendars form, not in batch |
| F&O required-field error on insert | Fill those fields and it will work | If the retry returns a TargetInvocationException, the entity refuses standalone inserts entirely. Stop guessing payloads — go to the form |
| A rejected Dataverse POST naming only the entity | The whole payload shape is wrong | Often one field is poisoning it — description alone breaks contracts. Bisect the payload; the message will not name the field |
| Repeating Windows sign-in prompt for the demo tenant | Your session expired — sign in again | Signing in never fixes it. The Dataverse CLI has no auth profile for that org, so it falls back to your corporate WAM identity and hits AADSTS90072. dsregcmd /listaccounts shows one account, in corp. Filter the AAD log on your demo tenant GUID (not on AADSTS, which is full of unrelated noise) |
| Cross-tenant Dataverse MCP | Can't work — the demo tenant is foreign to your device | It works fine with a profile. A sibling server pointed at a different tenant worked because dataverse auth list had a matching row. auth create first, register second — the reverse order is what causes the prompts |
| A Dataverse MCP server that is registered and enabled | It is working | Verify at the tool list, not the settings screen. It can spawn, fail auth, exit, and still read as enabled. m-diagnostics.jsonl logs failed to connect; a row in auth list with a still-failing server means the token expired (re-run auth create), while no row means it never authenticated at all |
MCP server set to enabled: false |
It is off and cannot prompt any more | ⚠️ It still spawns. enabled gates tool exposure, not process spawning — the host relaunches it every session, it retries the cross-tenant token, and the prompt keeps coming. m-diagnostics.jsonl logs MCP server "…" failed to connect at the exact moment of the dialog. You must delete the entry from m-mcp-servers.json |
| Omnichannel / Contact Center "provisioned" | Config record + all msdyn_oc* tables + 14 workstreams + telephony solutions all present |
Those ship with the solutions. The runtime is separate and the five channel toggles ship OFF (admin center → Channels → Manage channels). Tick Chat → Save and the runtime provisions in ~90s |
| Enabling a channel — the Save "fails" | The toggle reverted on reload, so it did not save | ⚠️ It did save. The checkbox reverts while provisioning is in flight, with no error and no toast. Poll CCaaS_GetContactCenterState() — State=2/Status=2001 → State=1/Status=2002 — instead of re-toggling in a loop |
CCaaS_GetContactCenterState() returns 404 |
The API is unsupported in this org | Transient. It 404s during provisioning, alongside remote name could not be resolved: e-<orgid>…. Both clear once the runtime lands |
| A chat widget with a real app ID and embed snippet | The widget is live | The snippet is generated locally by a Dataverse plugin and works fine against an unprovisioned runtime. It bootstraps, builds its iframe, then dies on ERR_NAME_NOT_RESOLVED. The page just looks empty — only the console names the cause. Working looks like a bubble saying "We're online" and zero console errors |
F&O Allowed MCP clients grid |
Renders empty for ~10s, and virtualized cells read as "" even when visible |
7 first-party clients were already registered. Verify via /data/McpAllowedClients, never the DOM |
| Close Agent picker "has no options" | The field is broken or the data is missing | Its options are role="menuitemcheckbox" inside .fui-Combobox__listbox, not role="option" — and it is search-as-you-type, so nothing renders until you fill() a term |
Close Agent Products having errors |
Your product selection is wrong | The products are fine — it validates that the fields hold data. Click Add missing info; in Caldova the real gap was an empty Product page URL on every product |
Close Agent Email delivery = is filled |
Delivery is configured and understood | It self-satisfies with zero input — and there is no autonomy switch. A started Close Agent runs a fixed five-touch outbound sequence (2/3/4/5-day, plus 7-day) |
| Close Agent target "Contact → Email → Contains data" | A narrow, safe test set | It is every open opportunity with a contact email. Query the domains before starting — one real address makes it an outbound campaign |
Close Agent Knowledge sources = is not filled |
Optional. Save succeeds and returns "Changes saved" |
⚠️ Optional for Save, FATAL for Start. The aria text is the loading state — the section spins forever with no error and permanently greys Start agent. Ticking prerequisites, confirming Copilot Studio consent, uploading a file source, and publishing the bot all fail to clear it. Screenshot the tab — the spinner is invisible in innerText |
Only trust these verification methods:
| To check… | Look here |
|---|---|
| Tenant claimed / created | CDX My Dashboard → Overview, not the launcher window |
| Apps installed | https://<org>.crm.dynamics.com/main.aspx?forceUCI=1&pagetype=apps |
| Environment type, and whether an environment exists at all | Power Platform admin center environment hub |
| Agent publish state | Copilot Studio Agents list |
| CI – Data / Journeys availability | home.ci.ai.dynamics.com — and complete the first-run region form, which is the install |
| CI licence entitlement | admin.cloud.microsoft/#/licenses → the SKU → Manage apps & services. Never a per-user check; never "Your products" |
| CI – Data progress | The Getting started checklist on the CI home page |
| Agent publish state | Copilot Studio Agents list — never the bots table |
| Predictive scoring | Sales Hub → App Settings, and a record count by statecode |
| CI prediction / measure readiness | The activity's semantic field map (Configure activities → step 2 → Map field types = Yes). If Sales amount is unmapped, nothing downstream can see money |
| A prediction wizard step's real state | The left-rail tab tooltip (Step is valid / Step is empty) — not the Review page summary |
| F&O demo data | /data/LegalEntities?$top=50 — expect more than one row; dat alone means empty. Also check /data/MainAccounts?$top=1&$count=true ≠ 0. Don't look for USMF — it ships only with the Contoso dataset |
| F&O MCP server live? | GET /mcp → 401 + WWW-Authenticate (a 404 means not enabled), and /.well-known/oauth-protected-resource → 200 |
| F&O allowed MCP clients | GET /data/McpAllowedClients?$top=20 — check before adding, Microsoft seeds 7 first-party entries |
| F&O MCP server live? | GET /mcp should return 401 + WWW-Authenticate (404 = not enabled), and /.well-known/oauth-protected-resource should return 200 |
| Anything in Dataverse | Xrm.WebApi from a browser console (see below) |
The general rule for this whole playbook: a spinner is not evidence. Go look at the management surface.
Corollary — a form is not a spinner. If a portal is asking you something, answering it is the work, not a delay to wait out. This skill once told an operator CI – Data was not installed when it only needed a region selected. Never report a product unavailable until you have opened its own portal and completed whatever it asks for.
Never call an install failed before 60 minutes
Observed landing times: Sales Premium ~5.5 min, CS Demo Data ~20 min, Project Operations
~35 min, Field Service ~50+ min. pac application install frequently never returns even
after the app has fully deployed, and hard-errors at exactly 60 minutes. I wrongly killed
Field Service at 48 minutes; it had actually landed.
The Xrm.WebApi technique — use this constantly
Any open model-driven app page exposes Xrm in the top frame. Direct Dataverse reads/writes
from there are dramatically more reliable than the admin UI widgets, which are hosted in
cross-origin island-cluster iframes that intermittently fail with ERR_CONNECTION_CLOSED.
const base = Xrm.Utility.getGlobalContext().getClientUrl();
const r = await Xrm.WebApi.retrieveMultipleRecords('account','?$select=name&$top=50');
await Xrm.WebApi.updateRecord('account', id, { name: 'New Name' });
Use it for bulk edits, verification sweeps and anything the UI makes tedious.
⚠️ Batch your loops at 50–60 records. Every
Xrm.WebApicall is a separate HTTP round trip, and creating a record in a terminal state costs two (create, then updatestatecode). A 300-record loop runs for minutes and will hit the automation tool's execution timeout mid-loop, leaving a partial write you may not notice. Verify the tally after every batch, and never schedule a whole class of record last — if that batch is the one that dies, the gap is invisible until something downstream fails.
Phase order
Run these in order. Later phases depend on earlier ones.
| # | Phase | Reference | Rough time |
|---|---|---|---|
| 0 | Claim the tenant, then request the Azure subscription (serial) | reference/00-claim-tenant.md |
~15 min claim + procurement lead time |
| 0.2 | Get the admin UPN and sign in as the Caldova admin | reference/00-claim-tenant.md § 2.5 |
5 min, mandatory |
| 0.5 | Single intake — all 13 decisions + batched sign-ins | reference/00-operator-profile.md |
10 min, mandatory, do it FIRST |
| 1 | Create environment with D365 apps enabled | reference/01-environment-provisioning.md |
10 min + install time |
| 2 | Install the CE app portfolio | reference/01-environment-provisioning.md |
1–3 hrs mostly waiting |
| 3 | Create connections + bind connection references | reference/02-connections-and-agents.md |
20 min |
| 4 | Configure first-party agents | reference/02-connections-and-agents.md |
30 min |
| 5 | Convert to Production + branding | reference/03-branding-and-polish.md |
15 min |
| 5.5 | First-party agents + predictive scoring (needs seeded data) | reference/08-agents-and-sales-insights.md |
45 min + async training |
| 6 | Reskin demo data to your industry | reference/04-demo-data-reskin.md |
30–45 min |
| 7 | Customer Insights (Journeys + Data) — optional | reference/06-customer-insights.md |
2-3 hrs per product |
| 8 | Chapters 2 & 3 add-ons — optional, needs Azure sub | see "Chapters 2 & 3" below | procurement lead time + deploy |
| 9 | Finance & Operations apps — optional, separate env | reference/07-finance-and-operations.md |
hours |
| Phase 0 is the longest pole in the tent, and it is serial. Claim the tenant → wait for | |||
Completed in My Dashboard (the launcher is unreliable and may spin 15–30 min after the tenant |
|||
| exists) → only then request the NET NEW Azure subscription, which needs an existing tenant to | |||
| attach to and carries procurement lead time. Two back-to-back waits, neither startable early. Two | |||
things there will bite you if you skip the file: CDX tenant slots are capped (a full 3 of 3 |
|||
| blocks the claim silently), and **changing any tenant password permanently breaks the add-on | |||
| experiences**. |
Phase 0.5 costs ten minutes and needs no tenant, which makes it the right way to spend a Phase 0 wait — and running it early is what buys the operator an unattended build. Its answers feed Phases 5.5, 6, 7 and 9, so collecting them late means asking questions those phases have already stalled on.
Ordering note: although numbered 0.5, treat the intake as the actual first action whenever the tenant already exists. Everything downstream reads from its decision record.
Phase 3 is the one everyone misses. A fresh environment has zero connections and every connection reference unbound, which silently blocks every first-party agent. Their admin pages just spin on "Loading" forever with no error. Do this before touching agents.
Phase 7 is irreversible. Customer Insights installs cannot be cancelled mid-cycle and may
consume production licensing. Read reference/06-customer-insights.md before starting it.
Quick start
# 1. Authenticate AS THE CALDOVA TENANT ADMIN (interactive browser sign-in)
# Ask the operator for the admin UPN: admin@caldova<NNNNNNNN>.onmicrosoft.com
# Get it from CDX > My Dashboard > tenant row > Credentials
pac auth create --name caldova
# 2. Confirm the caldova profile is the ACTIVE one (look for the *)
pac auth list
# 3. Confirm which app templates the tenant licences
pac admin list-app-templates
Step 2 is not optional. If a previous profile is still active, every subsequent command silently targets the wrong tenant.
Then follow reference/01-environment-provisioning.md.
Do not create the environment with
pac admin create --templates. It does not reliably set the "Enable Dynamics 365 apps" flag, and that flag is irreversible. Use the PPAC wizard. Details in the reference file.
Known-good outcome
A finished environment from this playbook has:
- ~18–22 published apps (count varies with which optional packages you install) — Sales Hub, Sales Team Member, Copilot Service workspace, Copilot Service admin center, Field Service (+ Mobile, + Connected), Project, Project Operations (+ Team Member), Resource Scheduling, Channel Integration Framework, D365 App for Outlook, Agentic Simulations, Power Pages Management, Power Platform Environment Settings, Solution Health Hub
- 8 connections, all Connected, with all connection references bound
- Customer Service agents configured (Case Management, Customer Intent, Knowledge)
- Environment Type = Production (no SANDBOX badge)
- Custom branded app header
- Demo data matching your industry
Run scripts/verify-environment.js to confirm all of the above in one call.
Honest limitations
One thing this playbook could not solve:
- Publishing the first-party agents. 38 of 44 Copilot Studio agents ship as Draft and
would not publish.
PvaPublishAPI →409 Conflict / ExternalServiceException,pac copilot publish→OrganizationServiceFault, Copilot Service admin center Publish → "Unable to publish Copilot Studio agents", and the Copilot Studio Publish button is disabled with agent status stuck on "Setting up…". Three independent paths failing identically = server-side provisioning state. Waiting 25+ minutes did not clear it. If you hit this, raise support referencing thePvaPublish409. Agents still function for demo purposes where the admin surface enables them directly (Case Management, Customer Intent and Knowledge agents were all configured successfully).
That is the only unsolved item. Chapters 2 & 3 are no longer a dead end — see below.
Chapters 2 & 3: the Azure subscription gate
Full request procedure, states to wait for, and the tenant-scoping caveat live in
reference/00-claim-tenant.md§ Step 3. Summary below.
The Caldova CDX page (https://cdx.transform.microsoft.com/caldova) carries two Add-On
experience cards, both fronted by * * * PRE-REQ: MUST ADD NEW AZURE SUB VIA MCAPS BYOT * * *:
| Add-on | Solution area | Deploys |
|---|---|---|
| Chapter 2: Build, Observe, and Tune | Cloud and AI Platforms | Caldova's invoice-assurance solution, proof of concept → scaled and governed |
| Chapter 3: Security + Agent 365 Scenarios | AI Business Solutions, Security | XDR base infra, Entra Connect, MDE, Agent 365 |
This is not a permanent block — it is a procurement step:
- Request a NET NEW Azure subscription via the MCAPS BYOT process → https://aka.ms/MCAPSBYOT. It must be net new; an existing subscription attached to another tenant will not do.
- Wait for it to reach Status
Completed/ stepAzTsPreReqsCompletedin the CDX tenant detail page, under Subscriptions. It appears there automatically once provisioned — you do not attach it by hand. - Only then do the Get Add-On buttons on the two cards actually work.
Verified Aug 2026: subscription ME-Caldova<NNNNNNNN>-{{USER_ALIAS}}-1 landed on the CDX tenant page
with AzTsPreReqsCompleted / Completed, releasing both add-ons.
Do not change any tenant passwords. The CDX page states in caps that passwords must remain exactly as issued or the add-on experiences will not work. This is easy to trip over if you have been hardening the tenant.
Note the add-on subscription lives in the Caldova tenant, not your corporate tenant, so
az login --tenant cadd283e-... as the Caldova admin is required before any az work against it.
Supporting documentation on that page
Seller FAQ - Caldova TenantSTEP 1 - Caldova Demo Experience One-Time Setup GuideSTEP 2 - Caldova Demo Experience Chapter Narrative
Reference files
| File | Contents |
|---|---|
reference/00-guided-start.md |
🚀 START HERE — detect-before-you-ask, the four branches, six-batch interview, plan confirmation, decision record |
reference/00-claim-tenant.md |
Phase 0 — claiming the CDX experience, tenant slot limits, credentials, the MCAPS BYOT Azure subscription |
reference/00-operator-profile.md |
Phase 0.5 — intake content: the 13 decisions and why each matters, archetype starters by industry |
reference/01-environment-provisioning.md |
Environment creation, solo-only apps, app install strategy, timings |
reference/02-connections-and-agents.md |
The connection-reference blocker, agent prerequisite chains, Entra app user |
reference/03-branding-and-polish.md |
Production conversion, modern theming, the undocumented master switch |
reference/04-demo-data-reskin.md |
Reskin methodology, entity checklist, the fields everyone forgets |
reference/05-troubleshooting.md |
Every failure hit during the build and how it was diagnosed |
reference/06-customer-insights.md |
CI Journeys + CI Data: install surface, CDP demo data, the semantic activity map that gates measures/predictions, measures, segments, suggestions, insights, churn + CLV models |
reference/07-finance-and-operations.md |
F&O: ask Murray Fife for templates first; licence checks, the Sandbox-only demo-data template, wizard traps, the MCP server, and the full build-from-scratch-over-OData recipe (legal entities → GL → posting profiles) |
reference/08-agents-and-sales-insights.md |
First-party agent inventory, predictive lead/opportunity scoring, and how to seed a trainable corpus |
reference/09-reference-build-state.md |
Snapshot of one real completed build — what "done" looks like, and what was left outstanding |
assets/caldova-demo-setup-overview.pptx |
8-slide overview deck — what the skill does, how to install it, how to use it. Hand this to someone instead of explaining it |
assets/build-overview-deck.js |
pptxgenjs generator for that deck — edit and re-run node build-overview-deck.js to restyle or re-word it |
scripts/bind-connection-references.js |
Bind all connection references to connections in one pass |
scripts/reskin-demo-data.js |
Template for bulk demo-data rewriting |
scripts/verify-environment.js |
Health check: apps, connections, refs, agents, data cleanliness |
scripts/gen-ci-data.py |
Generate an 11-source CPG CDP dataset with built-in identity-resolution difficulty |
JavaScript scripts are browser-console code. Paste into DevTools on any open model-driven app page, or run through Playwright. The Python script runs standalone.
⚠️
gen-ci-data.pyships with a CPG product portfolio and company list. Those are worked examples from the original build. Replace them with the operator's brand architecture from Phase 0 — a CDP dataset that disagrees with the CRM reskin breaks the exact cross-system unification demo it exists to prove.