@elitedcs/ghl-mcp 3.81.1 → 3.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/emil-skills-MIT.txt +19 -0
- package/LICENSES/taste-skill-MIT.txt +19 -0
- package/NOTICE +26 -0
- package/README.md +7 -7
- package/dist/capture-helper.js +5 -1
- package/dist/index.js +33682 -28089
- package/guide/guide.html +11 -7
- package/package.json +17 -1
- package/skills/blueprint/README.md +2 -2
- package/skills/blueprint/SKILL.md +1 -1
- package/skills/blueprint/examples/medspa-build-plan.json +2 -24
- package/skills/blueprint/examples/sample-build-plan.json +1 -23
- package/skills/blueprint/presets/clinic.preset.json +2 -26
- package/skills/blueprint/presets/coach.preset.json +2 -26
- package/skills/blueprint/presets/ecommerce.preset.json +0 -22
- package/skills/blueprint/presets/generic-client.preset.json +0 -24
- package/skills/blueprint/presets/local-service.preset.json +2 -26
- package/skills/blueprint/presets/med-spa.preset.json +2 -26
- package/src/command-os/design/rules/anti-default-contract.mjs +37 -0
- package/src/command-os/design/rules/anti-default.json +1098 -0
- package/src/command-os/design/rules/check-static.mjs +238 -0
- package/src/command-os/design/rules/fixtures/claude-default.html +55 -0
- package/src/command-os/design/rules/fixtures/external-css.html +7 -0
- package/src/command-os/design/rules/fixtures/generator-run-1.html +31 -0
- package/src/command-os/design/rules/fixtures/house-clean.html +59 -0
- package/src/command-os/design/rules/web.json +222 -0
package/guide/guide.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<title>GHL Command — User Guide</title>
|
|
7
|
-
<!-- guides-hash:
|
|
7
|
+
<!-- guides-hash: c6cd1ce6e416eaff -->
|
|
8
8
|
<style>
|
|
9
9
|
/* Deliberately light in every environment, including a dark-mode OS. This is a
|
|
10
10
|
reference document people read at length, print, and save to PDF, and a page
|
|
@@ -253,7 +253,7 @@ body.app.reading #indexview{display:none}
|
|
|
253
253
|
<a class="card pub" href="#g-invoices-and-payments" data-k="invoice bill billing payment paid product price coupon promo code discount transactions orders revenue estimate"><h3>Bill a client and see what you were paid</h3><p>Products, invoices, coupons, and the money reads, without opening the billing screen.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Open guide →</span></div></a>
|
|
254
254
|
<a class="card pub" href="#g-stand-up-a-pipeline" data-k="pipeline stages create new client setup opportunity sales process deal stages"><h3>Stand up a pipeline</h3><p>Stages, fields, and tags for a new client in one conversation.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide →</span></div></a>
|
|
255
255
|
<a class="card pub" href="#g-track-and-move-opportunities" data-k="opportunities deals move stage track stuck value won lost pipeline board"><h3>Track and move opportunities</h3><p>Move deals between stages, update values, and see what is stuck.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 minute</span><span class="open">Open guide →</span></div></a></div></div>
|
|
256
|
-
<div class="catsec" id="cat-client-builds-and-pages"><h2>Client builds and pages</h2><div class="cards"><a class="card pub" href="#g-blueprint-build-a-client-account" data-k="blueprint client account build intake onboarding new client complete template from scratch"><h3>The Blueprint: build a client account</h3><p>From intake form to a complete, reviewed account build you approve before it runs.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 hour</span><span class="open">Open guide →</span></div></a>
|
|
256
|
+
<div class="catsec" id="cat-client-builds-and-pages"><h2>Client builds and pages</h2><div class="cards"><a class="card pub" href="#g-blueprint-build-a-client-account" data-k="blueprint client account build intake onboarding new client complete template from scratch"><h3>The Blueprint: build inside a client account</h3><p>From intake form to a complete, reviewed account build you approve before it runs.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 hour</span><span class="open">Open guide →</span></div></a>
|
|
257
257
|
<a class="card pub" href="#g-build-a-funnel-from-a-template" data-k="funnel template landing page website client funnel brand designed gohighlevel templates build a funnel rebrand a funnel"><h3>Build a client funnel from a real GoHighLevel template</h3><p>Search the 900+ designed funnels GoHighLevel already ships, install the one that fits your client, and have it arrive in their brand.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide →</span></div></a>
|
|
258
258
|
<a class="card pub" href="#g-clone-and-rebrand-a-site" data-k="clone site copy rebrand landing page existing url duplicate make one like this mirror"><h3>Clone and rebrand a site</h3><p>Rebuild an existing page for a new client, with a rights check and a review report.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~30 minutes</span><span class="open">Open guide →</span></div></a>
|
|
259
259
|
<a class="card pub" href="#g-page-studio-pages-and-sites" data-k="page studio compose website landing page funnel build page site sections hero"><h3>Page Studio: pages and sites</h3><p>Compose landing pages and full sites that render correctly in GHL.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~20 minutes</span><span class="open">Open guide →</span></div></a>
|
|
@@ -319,7 +319,7 @@ Do not change anything. This is a read.</p></div>
|
|
|
319
319
|
<li>The comparison is the useful one. Line a new client's account up against your template account and the setup list writes itself.</li>
|
|
320
320
|
<li>User roles matter for workflow notifications. A notification pointed at somebody who has left the business fails silently, and this is where you spot them.</li>
|
|
321
321
|
<li>Snapshots are how you carry a whole account setup to a new client. Claude can list what you have and create a share link for one.</li>
|
|
322
|
-
<li>
|
|
322
|
+
<li>Chat creation is off until you enable “Let GHL Command create sub-accounts from chat” in Your agency. This switch does not enable deletion. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key. Creation also needs an agency key with permission to create locations. Deletion requires separate confirmation and GoHighLevel authorization; its current plan gate has not been verified. Removing a saved key only disconnects an account.</li>
|
|
323
323
|
<li>Needs the full license. Reading users and numbers is free.</li>
|
|
324
324
|
<li><b>Destructive actions ask before they act.</b> Twelve of them did not until 31 August, including deleting a custom field, which erases that field on every contact, and deleting or voiding an invoice.</li>
|
|
325
325
|
<li><b>Changing a sub-account's business details is refused if Claude cannot read the account first.</b> Those are the details your text-message registration is filed against, and a check that could not run is not a check that passed. Timezone and other settings are unaffected.</li>
|
|
@@ -378,6 +378,10 @@ Do not change anything. This is a read.</p></div>
|
|
|
378
378
|
<li>switch-between-client-accounts</li>
|
|
379
379
|
<li>audit-your-workflows</li>
|
|
380
380
|
</ul>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="gsec"><h2>Create or register a sub-account</h2>
|
|
383
|
+
<p class="gpara">For chat creation, open Your agency in the cockpit and enable “Let GHL Command create sub-accounts from chat”. Save the setting. It takes effect the next time Claude starts and allows creation only. Confirm the target agency and new client details before asking GHL Command to create the account.</p>
|
|
384
|
+
<p class="gpara">You can also use the “Register an existing sub-account” card on New client. Create the account in GoHighLevel first, then register its own Private Integration key. This path stays available whether or not chat creation is enabled.</p>
|
|
381
385
|
</div>
|
|
382
386
|
<p class="gfoot">Works in Claude Desktop and Claude Code. Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
383
387
|
</main></div>
|
|
@@ -651,7 +655,7 @@ Then tell me which ones you can fix safely and which ones need a decision from m
|
|
|
651
655
|
<section class="gpage" id="g-blueprint-build-a-client-account">
|
|
652
656
|
<div class="hero"><div class="hero-in">
|
|
653
657
|
<p class="eyebrow">GHL Command User Guide</p>
|
|
654
|
-
<h1>The Blueprint: build a client account</h1>
|
|
658
|
+
<h1>The Blueprint: build inside a client account</h1>
|
|
655
659
|
<p class="sub">From intake form to a complete, reviewed account build you approve before it runs.</p>
|
|
656
660
|
<div class="badges"><span class="badge on">Full license</span><span class="badge">~1 hour</span><span class="badge">Client builds and pages</span></div>
|
|
657
661
|
</div></div>
|
|
@@ -691,7 +695,7 @@ Build nothing until I say approved.</p></div>
|
|
|
691
695
|
<li>If a workflow step moves a deal to a new stage, the plan makes it find the deal first. That pairing is checked before the build runs, because a stage move on its own saves cleanly and then does nothing at all.</li>
|
|
692
696
|
<li>The manual list is short but real: connecting a payment provider, phone and A2P registration, connecting social accounts, and domain settings. Those need a human with account access, and no tool can honestly do them for you.</li>
|
|
693
697
|
<li><b>If you are told there are no submissions, the answers are not lost.</b> GoHighLevel does not report submissions for forms created outside its own editor, which is every intake form this installs, so the tool that reads submissions will say there are none even after your client has filled it in. The answers are on the contact tagged <code>blueprint-intake</code>. Say "read the intake from the contact" and Claude will pull it from there with the ordinary contact tools and carry on into the plan.</li>
|
|
694
|
-
<li>
|
|
698
|
+
<li>Blueprint builds assets inside a registered sub-account. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key. Confirm that account before building. On an account that has been built before, it refuses to quietly compose a second, different plan. That refusal is deliberate: it is what stops you ending up with duplicate pipelines and duplicate workflows.</li>
|
|
695
699
|
<li>The build plan is worth keeping. It is the document you walk your client through on the kickoff call.</li>
|
|
696
700
|
<li>Budget an hour end to end, most of it your review time. The building itself is minutes.</li>
|
|
697
701
|
<li>Needs the full license.</li>
|
|
@@ -2197,7 +2201,7 @@ This is a read. Do not apply anything.</p></div>
|
|
|
2197
2201
|
<li>Check whether workflows arrive published. A snapshot that lands live starts messaging real contacts the moment the account has any, which is rarely what you want on day one.</li>
|
|
2198
2202
|
<li>Name your snapshots with versions and dates. "Client Launch Template v4.6" tells you something; "Client Template Final" does not.</li>
|
|
2199
2203
|
<li>Imported snapshots are somebody else's work and can change out from under you. If a template matters to your business, build your own from an account you control.</li>
|
|
2200
|
-
<li>
|
|
2204
|
+
<li>Reading snapshots and making share links use your agency key. Apply a snapshot in the GoHighLevel agency view, or select one during API creation on Agency Pro. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key.</li>
|
|
2201
2205
|
<li>Needs the full license.</li>
|
|
2202
2206
|
<li><b>A cloned automation is checked after it is copied.</b> You are told how many steps and triggers actually landed, and whether anything in the copy still points back at the original.</li>
|
|
2203
2207
|
<li><b>This mattered:</b> until 31 August a cloned automation could still enrol people into the workflow it was copied from. Clone a nurture sequence for a new client and their leads went into the previous client's automation, while the copy reported itself perfect.</li>
|
|
@@ -2445,7 +2449,7 @@ Do not add any contacts or deals to it yet.</p></div>
|
|
|
2445
2449
|
<div class="gsec"><h2>What it looks like</h2>
|
|
2446
2450
|
<div class="chat"><span class="chat-cap">Your Claude conversation</span>
|
|
2447
2451
|
<div class="msg user">Which account am I in?</div>
|
|
2448
|
-
<div class="msg claude">You are in <b>
|
|
2452
|
+
<div class="msg claude">You are in <b>your practice account</b>. Want me to list the other sub-accounts you can reach?</div>
|
|
2449
2453
|
<div class="msg user">Switch to Radiance Med Spa.</div>
|
|
2450
2454
|
<div class="msg claude">Done. Active account is now <b>Radiance Med Spa</b>. Everything from here runs against that account until you switch again.</div>
|
|
2451
2455
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elitedcs/ghl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.83.0",
|
|
4
4
|
"mcpName": "io.github.drjerryrelth/ghl-command",
|
|
5
5
|
"description": "GoHighLevel MCP Server for Claude. 250 tools — full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -8,6 +8,18 @@
|
|
|
8
8
|
"ghl-mcp": "dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
+
"LICENSES/Apache-2.0.txt",
|
|
12
|
+
"LICENSES/taste-skill-MIT.txt",
|
|
13
|
+
"LICENSES/emil-skills-MIT.txt",
|
|
14
|
+
"NOTICE",
|
|
15
|
+
"src/command-os/design/rules/anti-default.json",
|
|
16
|
+
"src/command-os/design/rules/web.json",
|
|
17
|
+
"src/command-os/design/rules/anti-default-contract.mjs",
|
|
18
|
+
"src/command-os/design/rules/check-static.mjs",
|
|
19
|
+
"src/command-os/design/rules/fixtures/claude-default.html",
|
|
20
|
+
"src/command-os/design/rules/fixtures/house-clean.html",
|
|
21
|
+
"src/command-os/design/rules/fixtures/generator-run-1.html",
|
|
22
|
+
"src/command-os/design/rules/fixtures/external-css.html",
|
|
11
23
|
"dist/index.js",
|
|
12
24
|
"dist/capture-helper.js",
|
|
13
25
|
"templates/action-schemas.json",
|
|
@@ -33,6 +45,9 @@
|
|
|
33
45
|
"test": "vitest run",
|
|
34
46
|
"test:watch": "vitest",
|
|
35
47
|
"prepublishOnly": "npm run build",
|
|
48
|
+
"prepack": "node scripts/check-design-licenses.mjs",
|
|
49
|
+
"guard:design-packaging": "node scripts/check-design-licenses.mjs",
|
|
50
|
+
"test:anti-default": "node scripts/test-anti-default.mjs",
|
|
36
51
|
"build:assessment": "node src/command-os/assessment/build-app.mjs"
|
|
37
52
|
},
|
|
38
53
|
"keywords": [
|
|
@@ -78,6 +93,7 @@
|
|
|
78
93
|
"@clack/prompts": "^1.1.0",
|
|
79
94
|
"@types/node": "^26.2.0",
|
|
80
95
|
"esbuild": "^0.28.1",
|
|
96
|
+
"happy-dom": "^20.14.0",
|
|
81
97
|
"open": "^11.0.0",
|
|
82
98
|
"typescript": "^7.0.2",
|
|
83
99
|
"vitest": "^4.1.6"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GHL Command Blueprint
|
|
2
2
|
|
|
3
|
-
Blueprint turns a
|
|
3
|
+
Blueprint turns a client's intake into a reviewable plan for assets inside an already registered sub-account, with separate automatic and manual checklists. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key. It plans. You approve. Nothing is built until you say so.
|
|
4
4
|
|
|
5
5
|
The skill produces the reviewable build plan and the two-part checklist, and stops at the approval gate. On your approval it builds the automatic list for you through `apply_build_plan`: a dry run first, which writes nothing and reports exactly what it would create, then the live build on your go.
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ The skill produces the reviewable build plan and the two-part checklist, and sto
|
|
|
12
12
|
|
|
13
13
|
## Before you run it
|
|
14
14
|
|
|
15
|
-
- **Be in the right account.**
|
|
15
|
+
- **Be in the right account.** Register the client sub-account with its own Private Integration key, then select and confirm it before running Blueprint. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key.
|
|
16
16
|
- **You need GHL Command** connected to your GoHighLevel.
|
|
17
17
|
|
|
18
18
|
## What you get back
|
|
@@ -8,7 +8,7 @@ compatibility: Claude Code, Claude Cowork, Claude.ai
|
|
|
8
8
|
|
|
9
9
|
You are a **senior GoHighLevel solutions architect**. You turn a client's intake into a complete, build-ready account plan — clean, minimal, every automation wired to fire, in the order it must be built so nothing references a dead ID. You have one professional obsession: the GHL silent-failure bug, where an action points at a pipeline, stage, field, or workflow whose ID no longer exists and GHL skips it and everything beneath it with no error and a workflow that still shows green. You design so that can never happen.
|
|
10
10
|
|
|
11
|
-
This skill produces a **build plan** (the contract in `references/brief-schema.md` and `references/build-plan-schema.md`) and renders it for human review. It
|
|
11
|
+
This skill produces a **build plan** (the contract in `references/brief-schema.md` and `references/build-plan-schema.md`) and renders it for human review. It plans assets inside an already registered account; confirm the account returned by `get_current_location` before proceeding. GHL Command creates sub-accounts on GoHighLevel's Agency Pro plan; on other plans you create it in GoHighLevel and register it in GHL Command with its key. The member creates and copies that key in the sub-account; do not promise agency-key token minting or build a marketplace/OAuth app. `apply_build_plan` does not create the location itself. **This skill itself never writes to the account** — it stops at the approval gate. Building is done by the MCP's `apply_build_plan`, which is live: after approval you run it `mode:"dry_run"` first, show the report, and only on the operator's go run `mode:"execute"` (STEP 9 below).
|
|
12
12
|
|
|
13
13
|
> Account-agnostic, always. No hardcoded IDs, no dependency on any specific agency's stack. The plan carries symbolic **refs** (`pipeline.main`, `stage.new_lead`), never real GHL IDs. The executor resolves ref → id at build time, after each object is created and verified. That is what kills the silent-failure class.
|
|
14
14
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"planId": "plan_medspa_demo",
|
|
4
4
|
"briefId": "sub_medspa_demo",
|
|
5
5
|
"preset": "med_spa",
|
|
6
|
-
"summary": "Generated by the GHL Command Blueprint plan-gen skill from preset med_spa v2.0.0 (brief source: intake_form). Builds Glow Aesthetics a Tier 1 v2 account: 2 plan user(s) from the staff answers, a pipeline from the client's own stages, custom fields, a source / lifecycle / interest tag system, custom values every message reads from, a booking calendar assigned to real staff, an A2P-compliant intake form
|
|
6
|
+
"summary": "Generated by the GHL Command Blueprint plan-gen skill from preset med_spa v2.0.0 (brief source: intake_form). Builds Glow Aesthetics a Tier 1 v2 account: 2 plan user(s) from the staff answers, a pipeline from the client's own stages, custom fields, a source / lifecycle / interest tag system, custom values every message reads from, a booking calendar assigned to real staff, an A2P-compliant intake form, 15 email + 17 SMS send-ready templates in the client's voice, and 8 workflows: Speed to Lead (5 touches in 24 hours, a call task and an alert to a real person, an opportunity card, then the nurture-start hand-off as its last action), Missed Call Text-Back (call_status trigger), Lead Nurture (11 touches across 31 days of waits, stops on reply, hands off to Win-back), Replied - Stop & Route, Win-back (5 touches across 31 days), and the three appointment workflows (confirm & move, reminders at 24 h and 2 h, no-show rescue). SMS-bearing workflows are held DRAFT behind the A2P handoff. Nothing is built until you approve.",
|
|
7
7
|
"users": [
|
|
8
8
|
{
|
|
9
9
|
"ref": "user.dana_reyes",
|
|
@@ -313,27 +313,6 @@
|
|
|
313
313
|
]
|
|
314
314
|
}
|
|
315
315
|
],
|
|
316
|
-
"funnels": [
|
|
317
|
-
{
|
|
318
|
-
"ref": "funnel.main",
|
|
319
|
-
"name": "Glow Aesthetics Lead Funnel || Lead Funnel",
|
|
320
|
-
"target": "ghl",
|
|
321
|
-
"pages": [
|
|
322
|
-
{
|
|
323
|
-
"ref": "page.optin",
|
|
324
|
-
"name": "Free skin assessment || Free Skin Assessment",
|
|
325
|
-
"role": "optin",
|
|
326
|
-
"formRef": "form.intake"
|
|
327
|
-
},
|
|
328
|
-
{
|
|
329
|
-
"ref": "page.thankyou",
|
|
330
|
-
"name": "Thank You",
|
|
331
|
-
"role": "confirmation",
|
|
332
|
-
"calendarRef": "calendar.consult"
|
|
333
|
-
}
|
|
334
|
-
]
|
|
335
|
-
}
|
|
336
|
-
],
|
|
337
316
|
"templates": {
|
|
338
317
|
"emails": [
|
|
339
318
|
{
|
|
@@ -1552,7 +1531,7 @@
|
|
|
1552
1531
|
"owner": "OPERATOR-EXT",
|
|
1553
1532
|
"title": "Connect Stripe (to take payment)",
|
|
1554
1533
|
"trigger": "channels.payment != 'Stripe connected'",
|
|
1555
|
-
"instruction": "Connect Stripe under Payments > Integrations and create your consult-deposit and membership products.
|
|
1534
|
+
"instruction": "Connect Stripe under Payments > Integrations and create your consult-deposit and membership products. Authorize the payment connection in GoHighLevel.",
|
|
1556
1535
|
"produces": null,
|
|
1557
1536
|
"successCheck": "Stripe shows connected and products exist",
|
|
1558
1537
|
"blocks": []
|
|
@@ -1566,7 +1545,6 @@
|
|
|
1566
1545
|
"pipeline.*",
|
|
1567
1546
|
"calendar.*",
|
|
1568
1547
|
"form.*",
|
|
1569
|
-
"funnel.*",
|
|
1570
1548
|
"email.*",
|
|
1571
1549
|
"sms.*",
|
|
1572
1550
|
"email_template.*",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"planId": "plan_abc123",
|
|
4
4
|
"briefId": "sub_abc123",
|
|
5
5
|
"preset": "generic",
|
|
6
|
-
"summary": "Generated by the GHL Command Blueprint plan-gen skill from preset generic v2.0.0 (brief source: agency_os). Builds Glow Aesthetics a Tier 1 v2 account: 1 plan user(s) from the staff answers, a pipeline from the client's own stages, custom fields, a source / lifecycle / interest tag system, custom values every message reads from, a booking calendar assigned to real staff, an A2P-compliant intake form
|
|
6
|
+
"summary": "Generated by the GHL Command Blueprint plan-gen skill from preset generic v2.0.0 (brief source: agency_os). Builds Glow Aesthetics a Tier 1 v2 account: 1 plan user(s) from the staff answers, a pipeline from the client's own stages, custom fields, a source / lifecycle / interest tag system, custom values every message reads from, a booking calendar assigned to real staff, an A2P-compliant intake form, 15 email + 17 SMS send-ready templates in the client's voice, and 8 workflows: Speed to Lead (5 touches in 24 hours, a call task and an alert to a real person, an opportunity card, then the nurture-start hand-off as its last action), Missed Call Text-Back (call_status trigger), Lead Nurture (11 touches across 31 days of waits, stops on reply, hands off to Win-back), Replied - Stop & Route, Win-back (5 touches across 31 days), and the three appointment workflows (confirm & move, reminders at 24 h and 2 h, no-show rescue). SMS-bearing workflows are held DRAFT behind the A2P handoff. Nothing is built until you approve.",
|
|
7
7
|
"users": [
|
|
8
8
|
{
|
|
9
9
|
"ref": "user.dana_reyes",
|
|
@@ -280,27 +280,6 @@
|
|
|
280
280
|
]
|
|
281
281
|
}
|
|
282
282
|
],
|
|
283
|
-
"funnels": [
|
|
284
|
-
{
|
|
285
|
-
"ref": "funnel.main",
|
|
286
|
-
"name": "Glow Aesthetics Funnel || Lead Funnel",
|
|
287
|
-
"target": "ghl",
|
|
288
|
-
"pages": [
|
|
289
|
-
{
|
|
290
|
-
"ref": "page.landing",
|
|
291
|
-
"name": "Landing",
|
|
292
|
-
"role": "optin",
|
|
293
|
-
"formRef": "form.intake"
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
"ref": "page.thankyou",
|
|
297
|
-
"name": "Thank You",
|
|
298
|
-
"role": "confirmation",
|
|
299
|
-
"calendarRef": "calendar.consult"
|
|
300
|
-
}
|
|
301
|
-
]
|
|
302
|
-
}
|
|
303
|
-
],
|
|
304
283
|
"templates": {
|
|
305
284
|
"emails": [
|
|
306
285
|
{
|
|
@@ -1545,7 +1524,6 @@
|
|
|
1545
1524
|
"pipeline.*",
|
|
1546
1525
|
"calendar.*",
|
|
1547
1526
|
"form.*",
|
|
1548
|
-
"funnel.*",
|
|
1549
1527
|
"email.*",
|
|
1550
1528
|
"sms.*",
|
|
1551
1529
|
"email_template.*",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"presetVersion": "2.0.0",
|
|
4
4
|
"schemaVersion": "0.1",
|
|
5
5
|
"title": "Clinic / Practice",
|
|
6
|
-
"description": "A clinic / practice new-patient system at v2 depth (chiropractic, physical therapy, dental, functional medicine, primary care and similar). Patient pipeline, lead-source / interest / insurance fields, source + lifecycle + interest tags, a round-robin New Patient Visit calendar, an A2P-compliant new-patient form
|
|
6
|
+
"description": "A clinic / practice new-patient system at v2 depth (chiropractic, physical therapy, dental, functional medicine, primary care and similar). Patient pipeline, lead-source / interest / insurance fields, source + lifecycle + interest tags, a round-robin New Patient Visit calendar, an A2P-compliant new-patient form, 15 email + 17 SMS send-ready templates written to be compliance-safe (no condition, diagnosis or treatment is ever named in a message), and 8 workflows: Speed to Lead (15 actions, 5 touches in 24 h, then a hand-off), Missed Call Text-Back, Lead Nurture (31 days, 11 touches), Replied - Stop & Route, Win-back (31 days, 5 touches), Visit Booked - Confirm & Move, Visit Reminders, No-Show Rescue.",
|
|
7
7
|
"default": false,
|
|
8
8
|
"selectors": {
|
|
9
9
|
"businessTypes": [
|
|
@@ -359,30 +359,6 @@
|
|
|
359
359
|
]
|
|
360
360
|
}
|
|
361
361
|
],
|
|
362
|
-
"funnels": [
|
|
363
|
-
{
|
|
364
|
-
"ref": "funnel.main",
|
|
365
|
-
"name": "{{business.name}} New Patient Funnel || New Patient Funnel",
|
|
366
|
-
"target": "ghl",
|
|
367
|
-
"pages": [
|
|
368
|
-
{
|
|
369
|
-
"ref": "page.optin",
|
|
370
|
-
"name": "{{offer.leadMagnet}} || New Patient Visit",
|
|
371
|
-
"role": "optin",
|
|
372
|
-
"formRef": "form.intake",
|
|
373
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (H1 = the new-patient promise, e.g. \"A first visit that is mostly listening\") + GEO quotable summary + 3-5 outcome-led points + insurance / cash-pay clarity + the A2P-compliant capture form with a NOT-pre-checked SMS consent checkbox, legal name + address, Privacy/Terms links + a 4-8 Q FAQ with FAQPage JSON-LD + NAP footer. Honor compliance_notes; no outcome claims."
|
|
374
|
-
},
|
|
375
|
-
{
|
|
376
|
-
"ref": "page.thankyou",
|
|
377
|
-
"name": "Thank You",
|
|
378
|
-
"role": "confirmation",
|
|
379
|
-
"calendarRef": "calendar.new_patient",
|
|
380
|
-
"conditionalOn": "goal.bookingNeeded == true",
|
|
381
|
-
"copyDirection": "CONFIRMATION page: \"Your request is in\", what happens next (a text and an email), and the booking widget via cv.booking_link so they self-schedule now."
|
|
382
|
-
}
|
|
383
|
-
]
|
|
384
|
-
}
|
|
385
|
-
],
|
|
386
362
|
"templates": {
|
|
387
363
|
"emails": [
|
|
388
364
|
{
|
|
@@ -1700,7 +1676,7 @@
|
|
|
1700
1676
|
"owner": "OPERATOR-EXT",
|
|
1701
1677
|
"title": "Connect Stripe (for cash-pay deposits and plans)",
|
|
1702
1678
|
"trigger": "channels.payment != 'Stripe connected'",
|
|
1703
|
-
"instruction": "Connect Stripe under Payments > Integrations and create the new-patient offer and care-plan products.
|
|
1679
|
+
"instruction": "Connect Stripe under Payments > Integrations and create the new-patient offer and care-plan products. Authorize the payment connection in GoHighLevel.",
|
|
1704
1680
|
"produces": null,
|
|
1705
1681
|
"successCheck": "Stripe shows connected and products exist",
|
|
1706
1682
|
"blocks": []
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"presetVersion": "2.0.0",
|
|
4
4
|
"schemaVersion": "0.1",
|
|
5
5
|
"title": "Coach / Consultant",
|
|
6
|
-
"description": "A coach / consultant client-acquisition system at v2 depth (1:1, group, course or hybrid programs sold from a discovery call or an application). Client Journey pipeline, program-interest / challenge / timeline fields, source + lifecycle + interest tags, a round-robin Discovery Call calendar, an A2P-compliant application form
|
|
6
|
+
"description": "A coach / consultant client-acquisition system at v2 depth (1:1, group, course or hybrid programs sold from a discovery call or an application). Client Journey pipeline, program-interest / challenge / timeline fields, source + lifecycle + interest tags, a round-robin Discovery Call calendar, an A2P-compliant application form, 15 email + 17 SMS send-ready templates built on belief shifts rather than hype, and 8 workflows: Speed to Lead (15 actions, 5 touches in 24 h, then a hand-off), Missed Call Text-Back, Lead Nurture (31 days, 11 touches), Replied - Stop & Route, Win-back (31 days, 5 touches), Call Booked - Confirm & Move, Call Reminders, No-Show Rescue. No income or result claims unless the brief supplies real ones.",
|
|
7
7
|
"default": false,
|
|
8
8
|
"selectors": {
|
|
9
9
|
"businessTypes": [
|
|
@@ -360,30 +360,6 @@
|
|
|
360
360
|
]
|
|
361
361
|
}
|
|
362
362
|
],
|
|
363
|
-
"funnels": [
|
|
364
|
-
{
|
|
365
|
-
"ref": "funnel.main",
|
|
366
|
-
"name": "{{business.name}} Application Funnel || Application Funnel",
|
|
367
|
-
"target": "ghl",
|
|
368
|
-
"pages": [
|
|
369
|
-
{
|
|
370
|
-
"ref": "page.optin",
|
|
371
|
-
"name": "{{offer.leadMagnet}} || Apply for a Discovery Call",
|
|
372
|
-
"role": "optin",
|
|
373
|
-
"formRef": "form.intake",
|
|
374
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (H1 = the promise in the client's words, no income claims) + who this is for / not for + GEO quotable summary + how the program works (delivery_format) + what the call is and is not + the A2P-compliant application form with a NOT-pre-checked SMS consent checkbox, legal name + address, Privacy/Terms links + a 4-8 Q FAQ with FAQPage JSON-LD. Real client results only if the brief supplies them with consent."
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"ref": "page.thankyou",
|
|
378
|
-
"name": "Thank You",
|
|
379
|
-
"role": "confirmation",
|
|
380
|
-
"calendarRef": "calendar.discovery",
|
|
381
|
-
"conditionalOn": "goal.bookingNeeded == true",
|
|
382
|
-
"copyDirection": "CONFIRMATION page: \"Application received\", what happens next (a text in a minute), and the call booking widget via cv.booking_link so they self-schedule now."
|
|
383
|
-
}
|
|
384
|
-
]
|
|
385
|
-
}
|
|
386
|
-
],
|
|
387
363
|
"templates": {
|
|
388
364
|
"emails": [
|
|
389
365
|
{
|
|
@@ -1686,7 +1662,7 @@
|
|
|
1686
1662
|
"owner": "OPERATOR-EXT",
|
|
1687
1663
|
"title": "Connect Stripe (to enroll clients)",
|
|
1688
1664
|
"trigger": "channels.payment != 'Stripe connected'",
|
|
1689
|
-
"instruction": "Connect Stripe under Payments > Integrations and create your program products and payment plans so enrollment can happen on the call.
|
|
1665
|
+
"instruction": "Connect Stripe under Payments > Integrations and create your program products and payment plans so enrollment can happen on the call. Authorize the payment connection in GoHighLevel.",
|
|
1690
1666
|
"produces": null,
|
|
1691
1667
|
"successCheck": "Stripe shows connected and program products exist",
|
|
1692
1668
|
"blocks": []
|
|
@@ -296,28 +296,6 @@
|
|
|
296
296
|
]
|
|
297
297
|
}
|
|
298
298
|
],
|
|
299
|
-
"funnels": [
|
|
300
|
-
{
|
|
301
|
-
"ref": "funnel.main",
|
|
302
|
-
"name": "{{business.name}} VIP Funnel || VIP List Funnel",
|
|
303
|
-
"target": "ghl",
|
|
304
|
-
"pages": [
|
|
305
|
-
{
|
|
306
|
-
"ref": "page.optin",
|
|
307
|
-
"name": "{{offer.leadMagnet}} || Join the VIP List",
|
|
308
|
-
"role": "optin",
|
|
309
|
-
"formRef": "form.vip_signup",
|
|
310
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (H1 = the welcome offer, e.g. \"Your first order, {{custom_values.welcome_code}}\") + what the list gets (first look, real restock alerts, no daily blasts) + GEO quotable summary + 3 outcome-led points about the products + the A2P-compliant capture form with a NOT-pre-checked SMS consent checkbox, legal name + address, Privacy/Terms links + a 4-8 Q FAQ (shipping, returns, code rules) with FAQPage JSON-LD. Reviews only if real."
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
"ref": "page.thankyou",
|
|
314
|
-
"name": "Thank You",
|
|
315
|
-
"role": "confirmation",
|
|
316
|
-
"copyDirection": "CONFIRMATION page: show the welcome code big, say it is also on its way by text and email, one button to the store (cv.store_link), the expiry in plain words."
|
|
317
|
-
}
|
|
318
|
-
]
|
|
319
|
-
}
|
|
320
|
-
],
|
|
321
299
|
"templates": {
|
|
322
300
|
"emails": [
|
|
323
301
|
{
|
|
@@ -321,30 +321,6 @@
|
|
|
321
321
|
]
|
|
322
322
|
}
|
|
323
323
|
],
|
|
324
|
-
"funnels": [
|
|
325
|
-
{
|
|
326
|
-
"ref": "funnel.main",
|
|
327
|
-
"name": "{{business.name}} Funnel || Lead Funnel",
|
|
328
|
-
"target": "ghl",
|
|
329
|
-
"pages": [
|
|
330
|
-
{
|
|
331
|
-
"ref": "page.landing",
|
|
332
|
-
"name": "Landing",
|
|
333
|
-
"role": "optin",
|
|
334
|
-
"formRef": "form.intake",
|
|
335
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (one H1 = the offer promise in the customer's words) + GEO quotable summary + 3 outcome-led points grounded in offer + audience + the A2P-compliant capture form (form.intake) with a NOT-pre-checked SMS consent checkbox, visible business legal name + address, Privacy/Terms links + a 4-8 Q FAQ with FAQPage JSON-LD. Tone matched to business.type. A2P block is MANDATORY."
|
|
336
|
-
},
|
|
337
|
-
{
|
|
338
|
-
"ref": "page.thankyou",
|
|
339
|
-
"name": "Thank You",
|
|
340
|
-
"role": "confirmation",
|
|
341
|
-
"calendarRef": "calendar.consult",
|
|
342
|
-
"conditionalOn": "goal.bookingNeeded == true",
|
|
343
|
-
"copyDirection": "CONFIRMATION page: \"Got it\", what happens in the next few minutes (a text and an email), and the booking widget via cv.booking_link so they self-schedule now."
|
|
344
|
-
}
|
|
345
|
-
]
|
|
346
|
-
}
|
|
347
|
-
],
|
|
348
324
|
"templates": {
|
|
349
325
|
"emails": [
|
|
350
326
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"presetVersion": "2.0.0",
|
|
4
4
|
"schemaVersion": "0.1",
|
|
5
5
|
"title": "Local Service",
|
|
6
|
-
"description": "A local service business system at v2 depth (roofing, HVAC, plumbing, electrical, landscaping, cleaning, pest, restoration and similar). Jobs pipeline, service / urgency / address / quote fields, source + lifecycle + interest tags, a round-robin Estimate Visit calendar, an A2P-compliant quote-request form
|
|
6
|
+
"description": "A local service business system at v2 depth (roofing, HVAC, plumbing, electrical, landscaping, cleaning, pest, restoration and similar). Jobs pipeline, service / urgency / address / quote fields, source + lifecycle + interest tags, a round-robin Estimate Visit calendar, an A2P-compliant quote-request form, 15 email + 17 SMS send-ready templates, and 8 workflows: Speed to Lead (15 actions, 5 touches in 24 h with an \"is this urgent?\" fork by reply, then a hand-off), Missed Call Text-Back (the single highest-value automation for a trade), Lead Nurture (31 days, 11 touches), Replied - Stop & Route, Win-back (31 days, 5 touches; seasonal), Estimate Booked - Confirm & Move, Estimate Reminders, No-Show Rescue.",
|
|
7
7
|
"default": false,
|
|
8
8
|
"selectors": {
|
|
9
9
|
"businessTypes": [
|
|
@@ -369,30 +369,6 @@
|
|
|
369
369
|
]
|
|
370
370
|
}
|
|
371
371
|
],
|
|
372
|
-
"funnels": [
|
|
373
|
-
{
|
|
374
|
-
"ref": "funnel.main",
|
|
375
|
-
"name": "{{business.name}} Quote Funnel || Quote Funnel",
|
|
376
|
-
"target": "ghl",
|
|
377
|
-
"pages": [
|
|
378
|
-
{
|
|
379
|
-
"ref": "page.optin",
|
|
380
|
-
"name": "{{offer.leadMagnet}} || Get a Quote",
|
|
381
|
-
"role": "optin",
|
|
382
|
-
"formRef": "form.intake",
|
|
383
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (H1 = the promise, e.g. \"A written quote, same week, no surprises\") + service area (business.location / service_area) + GEO quotable summary + 3-5 outcome-led points (licensed/insured only if true, response time, written quotes) + the A2P-compliant capture form with a NOT-pre-checked SMS consent checkbox, legal name + address, Privacy/Terms links + a 4-8 Q FAQ with FAQPage JSON-LD + NAP footer."
|
|
384
|
-
},
|
|
385
|
-
{
|
|
386
|
-
"ref": "page.thankyou",
|
|
387
|
-
"name": "Thank You",
|
|
388
|
-
"role": "confirmation",
|
|
389
|
-
"calendarRef": "calendar.estimate",
|
|
390
|
-
"conditionalOn": "goal.bookingNeeded == true",
|
|
391
|
-
"copyDirection": "CONFIRMATION page: \"Got it\", what happens next (a text in a minute; if urgent, reply URGENT), and the estimate booking widget via cv.booking_link."
|
|
392
|
-
}
|
|
393
|
-
]
|
|
394
|
-
}
|
|
395
|
-
],
|
|
396
372
|
"templates": {
|
|
397
373
|
"emails": [
|
|
398
374
|
{
|
|
@@ -1696,7 +1672,7 @@
|
|
|
1696
1672
|
"owner": "OPERATOR-EXT",
|
|
1697
1673
|
"title": "Connect Stripe (deposits and invoices)",
|
|
1698
1674
|
"trigger": "channels.payment != 'Stripe connected'",
|
|
1699
|
-
"instruction": "Connect Stripe under Payments > Integrations so deposits and invoices can be taken from the quote.
|
|
1675
|
+
"instruction": "Connect Stripe under Payments > Integrations so deposits and invoices can be taken from the quote. Authorize the payment connection in GoHighLevel.",
|
|
1700
1676
|
"produces": null,
|
|
1701
1677
|
"successCheck": "Stripe shows connected",
|
|
1702
1678
|
"blocks": []
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"presetVersion": "2.0.0",
|
|
4
4
|
"schemaVersion": "0.1",
|
|
5
5
|
"title": "Med Spa",
|
|
6
|
-
"description": "The default GHL Command Blueprint reference preset, v2 depth. A med-spa lead-to-member system: Patient Journey pipeline, lead-source / service-interest / appointment fields, source + lifecycle + interest tags, a round-robin consult calendar, an A2P-compliant intake form
|
|
6
|
+
"description": "The default GHL Command Blueprint reference preset, v2 depth. A med-spa lead-to-member system: Patient Journey pipeline, lead-source / service-interest / appointment fields, source + lifecycle + interest tags, a round-robin consult calendar, an A2P-compliant intake form, 15 email + 17 SMS send-ready templates, and 8 workflows: Speed to Lead (15 actions, 5 touches in 24 h, then a hand-off), Missed Call Text-Back, Lead Nurture (31 days, 11 touches), Replied - Stop & Route, Win-back (31 days, 5 touches), Consult Booked - Confirm & Move, Consult Reminders, No-Show Rescue. Staff alerts and call tasks on every workflow that needs a human. SMS-bearing workflows stay DRAFT behind the A2P handoff.",
|
|
7
7
|
"default": true,
|
|
8
8
|
"selectors": {
|
|
9
9
|
"businessTypes": [
|
|
@@ -346,30 +346,6 @@
|
|
|
346
346
|
]
|
|
347
347
|
}
|
|
348
348
|
],
|
|
349
|
-
"funnels": [
|
|
350
|
-
{
|
|
351
|
-
"ref": "funnel.main",
|
|
352
|
-
"name": "{{business.name}} Lead Funnel || Lead Funnel",
|
|
353
|
-
"target": "ghl",
|
|
354
|
-
"pages": [
|
|
355
|
-
{
|
|
356
|
-
"ref": "page.optin",
|
|
357
|
-
"name": "{{offer.leadMagnet}} || Free Skin Assessment",
|
|
358
|
-
"role": "optin",
|
|
359
|
-
"formRef": "form.intake",
|
|
360
|
-
"copyDirection": "OPTIN page per templates/funnel-page-content-template.md: Hero (one H1 = the offer promise, e.g. \"Look rested, not done\") + GEO quotable summary + 3-5 outcome-led benefits grounded in offer + audience + the A2P-compliant capture form (form.intake) with a NOT-pre-checked SMS consent checkbox carrying the four disclosures, visible business legal name + mailing address, Privacy/Terms links + a 4-8 Q FAQ with FAQPage JSON-LD + NAP/legal footer. A2P block is MANDATORY."
|
|
361
|
-
},
|
|
362
|
-
{
|
|
363
|
-
"ref": "page.thankyou",
|
|
364
|
-
"name": "Thank You",
|
|
365
|
-
"role": "confirmation",
|
|
366
|
-
"calendarRef": "calendar.consult",
|
|
367
|
-
"conditionalOn": "goal.bookingNeeded == true",
|
|
368
|
-
"copyDirection": "CONFIRMATION page: \"Your assessment request is in\", the next-step expectation (a text and email are on the way), and the booking widget via cv.booking_link so they self-schedule now. NAP + Privacy/Terms in the footer."
|
|
369
|
-
}
|
|
370
|
-
]
|
|
371
|
-
}
|
|
372
|
-
],
|
|
373
349
|
"templates": {
|
|
374
350
|
"emails": [
|
|
375
351
|
{
|
|
@@ -1673,7 +1649,7 @@
|
|
|
1673
1649
|
"owner": "OPERATOR-EXT",
|
|
1674
1650
|
"title": "Connect Stripe (to take payment)",
|
|
1675
1651
|
"trigger": "channels.payment != 'Stripe connected'",
|
|
1676
|
-
"instruction": "Connect Stripe under Payments > Integrations and create your consult-deposit and membership products.
|
|
1652
|
+
"instruction": "Connect Stripe under Payments > Integrations and create your consult-deposit and membership products. Authorize the payment connection in GoHighLevel.",
|
|
1677
1653
|
"produces": null,
|
|
1678
1654
|
"successCheck": "Stripe shows connected and products exist",
|
|
1679
1655
|
"blocks": []
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// These pins are deliberately separate from the refreshable upstream catalogue.
|
|
2
|
+
export const HOUSE_RULE_PINS = Object.freeze({
|
|
3
|
+
AD02: Object.freeze({ source: 'house', check: 'measured', threshold: 18, unit: 'px', medium: 'web' }),
|
|
4
|
+
AD03: Object.freeze({ source: 'house', check: 'measured', threshold: 7, unit: 'contrast ratio', medium: 'web' }),
|
|
5
|
+
AD74: Object.freeze({ source: 'house', check: 'measured', threshold: 0, unit: 'characters', medium: 'both' }),
|
|
6
|
+
});
|
|
7
|
+
export const JUDGED_RULE_IDS = Object.freeze(['AD38', 'AD73', 'AD82', 'AD83']);
|
|
8
|
+
export const DUPLICATE_RULE_PINS = Object.freeze({ AD19: 'W11', AD20: 'W11', AD32: 'W6', AD69: 'W13' });
|
|
9
|
+
|
|
10
|
+
export function assertAntiDefaultContract(catalogue, webRules) {
|
|
11
|
+
const rules = catalogue?.rules;
|
|
12
|
+
if (!Array.isArray(rules) || rules.length !== 83) throw new Error('The anti-default catalogue must contain 83 rules.');
|
|
13
|
+
const byId = new Map(rules.map(rule => [rule.id, rule]));
|
|
14
|
+
for (let i = 1; i <= 83; i++) {
|
|
15
|
+
const id = `AD${String(i).padStart(2, '0')}`;
|
|
16
|
+
if (!byId.has(id)) throw new Error(`The anti-default catalogue is missing ${id}.`);
|
|
17
|
+
}
|
|
18
|
+
for (const [id, pin] of Object.entries(HOUSE_RULE_PINS)) {
|
|
19
|
+
for (const [key, value] of Object.entries(pin)) {
|
|
20
|
+
if (byId.get(id)?.[key] !== value) throw new Error(`House rule ${id} must retain ${key}: ${value}.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const judged = rules.filter(rule => rule.check === 'judged').map(rule => rule.id).sort();
|
|
24
|
+
if (JSON.stringify(judged) !== JSON.stringify(JUDGED_RULE_IDS)) throw new Error('The four judged rules must remain listed and unscored.');
|
|
25
|
+
for (const [id, canonical] of Object.entries(DUPLICATE_RULE_PINS)) {
|
|
26
|
+
if (byId.get(id)?.duplicateOf !== canonical || !webRules.some(rule => rule.id === canonical)) {
|
|
27
|
+
throw new Error(`${id} must reference the existing web rule ${canonical}.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const rule of rules) {
|
|
31
|
+
if (rule.duplicateOf && DUPLICATE_RULE_PINS[rule.id] !== rule.duplicateOf) throw new Error(`Unreviewed duplicate mapping for ${rule.id}.`);
|
|
32
|
+
if (!rule.group || !rule.rewrite || !rule.howMeasured) throw new Error(`${rule.id} must retain its measurement and rewrite instructions.`);
|
|
33
|
+
}
|
|
34
|
+
if (!catalogue.howToRead?.independence || !catalogue.boundary?.deliberateOverlap || !catalogue.provenance?.sources?.length) {
|
|
35
|
+
throw new Error('The catalogue must retain its independence, boundary and provenance metadata.');
|
|
36
|
+
}
|
|
37
|
+
}
|