Demo Bootstrap & Client Onboarding Tooling Specification
Demo Bootstrap & Client Onboarding Tooling Specification
Section titled “Demo Bootstrap & Client Onboarding Tooling Specification”ARCHIVED / SUPERSEDED (15/06/2026, ID-95.16 — PI-17). This spec (31/03/2026) pre-dates the ID-95 per-client topology, the
tenant_configbranding model, and thesignup_policyconfig-table sign-up design. Its bootstrap/onboarding flow (manual SQL snippets, GUC-era assumptions, single-instance seed model) is NOT the current process and MUST NOT be followed. It is retained here as a historical record only — for demo-seed mining of the platform dev/demo instance, mine from THIS archived copy. Current model:specs/id-95-per-client-topology/(PRODUCT.md + TECH.md) and the operational runbookrunbooks/client-app-deploy.md.This file lives under
specs/_archive/, which is excluded from the rendered docs (underscore-prefixed path; seesrc/content.config.tsglob). A pointer stub remains at the former live pathspecs/demo-bootstrap-spec.md.
Status: ARCHIVED — superseded by ID-95 (was: Draft) Created: 31/03/2026 Author: Liam + Claude Code
Summary
Section titled “Summary”Knowledge Hub needs repeatable tooling to stand up new instances from scratch. Two use cases:
- Demo instance — pre-populated with seed data for demonstrations (prospect meetings, trade shows, internal training)
- Fresh client onboarding — empty DB populated with client-specific content
Today, standing up a new instance requires manually following
docs/operations/production-setup-guide.md, running SQL snippets by hand, and
executing multiple scripts in the correct order. This spec defines five phases
of work to automate the entire flow into two scripts: bootstrap-instance.sh
(demo) and onboard-client.sh (client).
Motivation
Section titled “Motivation”-
Repeatable demos — The first client is live. Prospect demos currently run against production data, which is unprofessional and risks exposing client information. A dedicated demo instance with curated seed data is needed.
-
Client onboarding friction — Setting up the first client took multiple sessions of manual work. The second client should take under an hour, not days.
-
Confidence in schema reproducibility — The migration chain (1 squashed baseline + 20 incremental, 21 total recorded in
schema_migrations, plus 1 new migration forentity_aliases) has never been replayed against a fresh Supabase project. This spec forces that validation. -
Prerequisite data is undocumented — Taxonomy (15 domains, 57 subtopics), layer vocabulary (4 rows), entity aliases (22 rows), and guide definitions (8 guides) must all be seeded before the application is functional. This knowledge is scattered across migration files, seed scripts, and the production DB.
Prerequisites
Section titled “Prerequisites”- Supabase Pro plan — Per-org pricing model at ~$25/month base + ~$10/month per additional project. A second project is required for demo/client instances.
- Supabase CLI installed (
/opt/homebrew/bin/supabase) - API keys — Anthropic (classification/summaries), OpenAI (embeddings)
- Python 3 with
requirements.txtdependencies installed (requirements.txtexists at project root) - bun package manager with
node_modulesinstalled
Current State Analysis
Section titled “Current State Analysis”What exists today
Section titled “What exists today”| Asset | Location | Notes |
|---|---|---|
| Production setup guide | docs/operations/production-setup-guide.md | Manual, step-by-step. Some counts outdated (says 92 migrations, actually 21). |
| Bid test data seed | scripts/seed-bid-test-data.ts | Creates 1 bid workspace, 10 questions, 3 responses. Idempotent, supports --dry-run and --clean. |
| Guide definitions seed | scripts/seed-phew-guides.ts | Creates 8 guides (4 sector, 3 product, 1 company) with sections. Idempotent, supports --apply and --clear. |
| Migration files | supabase/migrations/ (21 files, will become 22) | 1 squashed baseline (S118) + 20 incremental. Never replayed on a fresh project. Missing entity_aliases table (BLOCKER). |
| Client documentation | docs/client-documentation/ | 9 .docx files (7 Q&A library + 2 non-Q&A: Product_KB_Dev_Brief.docx, Sector-Intelligence-Brief-Liam-Final.docx), 12 .md files (9 in markdown/ subdir + 3 at root: Knowledge Hub -- Claude Integration Guide.md, Knowledge Hub -- Platform Overview.md, sector-intelligence-analysis.md), 1 PDF. Covers audits, LMS, security, FAQs. |
| Python ingestion scripts | scripts/ingest.py, scripts/ingest_markdown.py, scripts/import_bid_library.py | Three entry points for different content types. |
| Entity aliases (DB) | entity_aliases table | 22 rows: 14 generic (ISO, WordPress, etc.) + 8 client-specific (Phew products). BLOCKER: This table is NOT present in any of the 21 migration files — it exists only in production. A prerequisite migration is required before seed.sql can work. |
| Taxonomy (DB) | taxonomy_domains + taxonomy_subtopics | 15 domains, 57 subtopics. 10 domains have key signals (security, compliance, implementation, support, corporate, product-feature, methodology, legislation-policy, market-intelligence, sector-news), 5 are sector intelligence domains without key signals (safeguarding-child-protection, safeguarding-adults, multi-academy-trusts, education, products-services). |
| Layer vocabulary (DB) | layer_vocabulary table | 4 rows: sales_brief, bid_detail, company_reference, research. Note: production setup guide says 5 (fact/evidence/method/policy/narrative) but the actual DB has 4 different values. |
| Coverage targets | coverage_targets table | Empty — no defaults exist. |
| Content templates | content_templates table | Empty — no defaults exist. |
| Governance config | governance_config table | Empty — no defaults exist. Schema: per-domain rows with posture/reviewer_id/timeout_days/thresholds, NOT key/value. |
What is missing
Section titled “What is missing”- No
supabase/seed.sql— All reference data lives only in the production DB or hardcoded in seed scripts - No orchestration script — Each step must be run manually in the correct order
- No demo data pack — No curated content set designed to showcase all features
- No post-setup validation — No automated check that a new instance is functional
- No client onboarding script — No way to set up a new client without deep platform knowledge
Phase 1: Seed SQL
Section titled “Phase 1: Seed SQL”Goal: Create supabase/seed.sql containing all reference data needed for a
functional Knowledge Hub instance.
Implementation
Section titled “Implementation”PREREQUISITE: Before seed.sql can be applied, the entity_aliases table
must exist. This table is NOT present in any of the 21 migration files — it
exists only in production (likely created via MCP execute_sql during S118 or
earlier). A new migration must be created first:
-- Migration: create_entity_aliases_tableCREATE TABLE IF NOT EXISTS public.entity_aliases ( id uuid DEFAULT gen_random_uuid() PRIMARY KEY, alias text NOT NULL, canonical text NOT NULL, is_active boolean DEFAULT true, created_at timestamptz DEFAULT now());
CREATE INDEX IF NOT EXISTS idx_entity_aliases_alias ON public.entity_aliases (alias);CREATE UNIQUE INDEX IF NOT EXISTS idx_entity_aliases_alias_canonical ON public.entity_aliases (alias, canonical);
ALTER TABLE public.entity_aliases ENABLE ROW LEVEL SECURITY;
-- RLS: same pattern as other reference tablesCREATE POLICY entity_aliases_select ON public.entity_aliases FOR SELECT TO authenticated USING (true);CREATE POLICY entity_aliases_insert ON public.entity_aliases FOR INSERT TO authenticated WITH CHECK (public.get_user_role() = 'admin');CREATE POLICY entity_aliases_update ON public.entity_aliases FOR UPDATE TO authenticated USING (public.get_user_role() = 'admin');CREATE POLICY entity_aliases_delete ON public.entity_aliases FOR DELETE TO authenticated USING (public.get_user_role() = 'admin');This migration must be created via
supabase migration new create_entity_aliases and pushed via supabase db push
BEFORE Phase 2 bootstrap can succeed.
Create a single idempotent SQL file that seeds all prerequisite data. Each
section uses INSERT ... ON CONFLICT DO NOTHING or equivalent guards.
1.1 Taxonomy Domains (15 rows)
Section titled “1.1 Taxonomy Domains (15 rows)”Extracted from production DB. All values must be seeded:
INSERT INTO taxonomy_domains (id, name, description, colour, display_order, key_signal)VALUES ('17d9f23f-1c4f-4d6d-b9c3-f37c178a547e', 'security', 'Information security, data protection, cyber security, and access control policies and practices.', 'security', 1, '**Key signal:** Content about protecting information, systems, and data — controls, policies, and security practices.'), ('8d6c0b63-f77c-4021-a54b-15c07fa04420', 'compliance', 'Regulatory compliance, industry standards, certifications, and audit processes.', 'compliance', 2, '**Key signal:** Content about proving adherence to external requirements — standards bodies, regulators, auditors.'), ('7ea9e1ca-0a99-48e4-8a38-0aff9b910e7b', 'implementation', 'Solution deployment, system migration, client onboarding, and third-party integration.', 'implementation', 3, '**Key signal:** Content about concrete delivery activities — what happens, when it happens, and how the transition is managed.'), ('d234988f-f548-4ea6-afbd-3aa7969674bd', 'support', 'Service level agreements, helpdesk operations, maintenance, and incident management.', 'support', 4, '**Key signal:** Content about keeping a live service running — BAU operations, response commitments, and what happens when things go wrong.'), ('2cf9db4f-fa8d-4c7b-97ce-c3ce6f966f1b', 'corporate', 'Company information, financial standing, insurance, references, and staffing.', 'corporate', 5, '**Key signal:** Content about the organisation itself — who you are, your track record, your people, and your financial health.'), ('609bbcc4-ea14-4d74-b53d-d074ddce19a4', 'product-feature', 'Product functionality, technical capabilities, reporting, and usability.', 'product', 6, '**Key signal:** Content about what the product or platform CAN do — its capabilities, architecture, and user experience.'), ('047b2b0f-59a1-4242-bbc8-b912c57d29aa', 'methodology', 'Project delivery approach, project management, quality assurance, and delivery frameworks.', 'methodology', 7, '**Key signal:** Content about HOW you work — your processes, governance, and quality practices.'), ('52eb10ea-eaa6-433d-9c56-d573240b5cf8', 'safeguarding-child-protection', 'Safeguarding children and young people — KCSIE, DBS, SCR, DSL roles, safer recruitment, and child protection policies.', 'security', 8, NULL), ('7ced99c1-cc93-4074-a4fb-d3c6f30b817b', 'safeguarding-adults', 'Adult safeguarding — SAB statutory duties, Making Safeguarding Personal, Care Act compliance, and vulnerable adult protection.', 'compliance', 9, NULL), ('9da13d3a-5ccb-4363-adc0-ce32dc442423', 'multi-academy-trusts', 'MAT governance, central services, school improvement, trust-wide compliance, and multi-site safeguarding.', 'implementation', 10, NULL), ('e6be270b-5ee4-4b5a-ab51-3627fbed2372', 'education', 'Education sector — schools, colleges, universities, Ofsted, DfE requirements, and education technology.', 'methodology', 11, NULL), ('406054e3-8e00-46e2-9bff-038b9daff1b9', 'products-services', 'Phew Design product portfolio — LMS, Websites, Advanced Audits, and associated services.', 'product', 12, NULL), ('5e792735-8ce9-4b45-901b-44aaeb79bd9e', 'legislation-policy', NULL, NULL, 13, '**Key signal:** Content about laws, statutory guidance, regulatory policy updates, and legislative instruments.'), ('dee601a0-7c43-4470-acea-da0cbfc1601c', 'market-intelligence', NULL, NULL, 14, '**Key signal:** Content about competitors, market trends, procurement activity, and commercial landscape.'), ('43326cbe-bbe3-47f5-a70e-df314bfa966d', 'sector-news', NULL, NULL, 15, '**Key signal:** Content about sector events, leadership changes, inspections, audits, and organisational restructuring in target sectors.')ON CONFLICT (id) DO NOTHING;1.2 Taxonomy Subtopics (57 rows)
Section titled “1.2 Taxonomy Subtopics (57 rows)”All 57 subtopics extracted from production, grouped by parent domain. The seed SQL will reference parent domain IDs using the hardcoded UUIDs above. Full list grouped by domain:
- security (5): data-protection, cyber-security, encryption, access-control, iso-27001
- compliance (9): standards, regulatory, audit, certification, health-and-safety, environmental, modern-slavery, equalities, safeguarding
- implementation (4): deployment, migration, onboarding, integration
- support (4): sla, helpdesk, maintenance, incident
- corporate (8): company-info, financial, insurance, references, staffing, supply-chain, financial-standing, methodology
- product-feature (4): functionality, technical, reporting, usability
- methodology (4): approach, project-management, quality, delivery
- legislation-policy (7): kcsie, education-act-dfe, health-social-care-legislation, gdpr-data-protection, funding-policy, safeguarding-guidance, cpd-requirements
- market-intelligence (5): competitor-products, competitor-market-activity, competitor-leadership, market-trends, procurement-activity
- sector-news (7): mat-leadership, mat-restructuring, mat-audits-ofsted, education-sector-audits, health-sector-audits, local-authority-inspections, safeguarding-practice
Each row includes the production UUID, name, description, display_order, and domain_id FK.
1.3 Layer Vocabulary (4 rows)
Section titled “1.3 Layer Vocabulary (4 rows)”INSERT INTO layer_vocabulary (id, key, label, description, display_order, is_active)VALUES ('d9fbcd98-f865-4229-8497-f82fae611973', 'sales_brief', 'Sales Brief', 'Positioning and messaging for internal sales', 10, true), ('01fe4de1-4f3c-433e-8f08-191f10ce54dd', 'bid_detail', 'Bid Detail', 'Factual content for tender responses', 20, true), ('3c2ce19c-e8f1-40a5-8c60-8912737b4572', 'company_reference', 'Company Reference', 'Controlled corporate documents', 30, true), ('4509e22e-defc-4dde-9a71-ee8e24e32f89', 'research', 'Research', 'Background material and market intelligence', 40, true)ON CONFLICT (id) DO NOTHING;Note: The production setup guide documents 5 layer vocabulary rows (fact, evidence, method, policy, narrative) but the actual production DB has 4 different rows (sales_brief, bid_detail, company_reference, research). The seed SQL must match production reality.
1.4 Entity Aliases (22 rows)
Section titled “1.4 Entity Aliases (22 rows)”Two categories:
Generic aliases (14 rows) — technology/standard names, client-independent:
- ISO Certification -> ISO 27001, Iso Certifications -> ISO 27001, ISO 27001 2013 -> ISO 27001, ISO 27000 -> ISO 27001
- ISO 9001 2015 -> ISO 9001
- wordpress -> WordPress, Wordpress -> WordPress
- Csharp -> C#, csharp -> C#
- Asp Net -> ASP.NET, Asp.net -> ASP.NET
- Hcaptcha -> hCaptcha, Wcag 2 1 Aa -> WCAG 2.1 AA, agile -> Agile
Client-specific aliases (8 rows) — Phew Design product/company names:
- Phew -> Phew Design Limited, Phew Design Ltd -> Phew Design Limited
- Learning Management System -> Phew LMS, Phew Lms -> Phew LMS
- Phew Audit -> Phew Audit System, Phew Audit Platform -> Phew Audit System
- Phew Pdms -> Phew PDMS
Note: The exact split between generic and client-specific aliases should be
verified by querying production:
SELECT * FROM entity_aliases ORDER BY canonical;. The 22-row total is
confirmed, but some aliases may have been recategorised since the last manual
count.
The seed SQL will include all 22 with ON CONFLICT DO NOTHING. For client
onboarding, a separate step will replace client-specific aliases with the new
client’s product names.
1.5 Governance Config
Section titled “1.5 Governance Config”Currently empty in production. The actual table schema (from baseline migration) is per-domain, not key/value:
-- governance_config schema (from migration):-- id uuid PK-- domain text NOT NULL UNIQUE-- posture text NOT NULL DEFAULT 'open' CHECK (posture IN ('open', 'review_on_change'))-- reviewer_id uuid FK -> auth.users-- timeout_days integer DEFAULT 7-- quality_score_threshold integer DEFAULT 40-- auto_flag_on_quality_drop boolean DEFAULT true-- auto_flag_on_freshness_transition boolean DEFAULT true-- auto_flag_cooldown_days integer DEFAULT 7-- created_by uuid FK -> auth.users-- updated_by uuid FK -> auth.users-- created_at timestamptz DEFAULT now()-- updated_at timestamptz DEFAULT now()Recommendation: Leave governance_config empty in seed.sql (matching
production state). Governance posture should be configured per-client via the
admin UI after setup, because reviewer_id requires a valid auth.users UUID
which does not exist until after user creation. Add a comment in seed.sql:
-- governance_config: intentionally empty.-- Configure per-domain governance posture via Admin > Settings after creating users.-- Table columns: domain, posture (open|review_on_change), reviewer_id, timeout_days,-- quality_score_threshold, auto_flag_on_quality_drop, auto_flag_on_freshness_transition,-- auto_flag_cooldown_days.File Inventory
Section titled “File Inventory”| File | Action |
|---|---|
supabase/migrations/YYYYMMDDHHMMSS_create_entity_aliases.sql | Create — prerequisite migration for entity_aliases table (BLOCKER) |
supabase/seed.sql | Create — all reference data in one idempotent SQL file |
Acceptance Criteria
Section titled “Acceptance Criteria”-
seed.sqlcan be applied to a fresh post-migration DB without errors - All 15 taxonomy domains present with correct key signals
- All 57 taxonomy subtopics present with correct parent domain references
- All 4 layer vocabulary rows present
- All 22 entity aliases present
- Re-running
seed.sqlon an already-seeded DB produces no errors (idempotent) - UUIDs in seed match production values (enables consistent cross-environment references)
Effort Estimate
Section titled “Effort Estimate”3-4 hours — Primarily data extraction and SQL authoring. The taxonomy and subtopic data is the bulk of the work (57 individual INSERT statements with UUIDs and FKs).
Phase 2: Bootstrap Script
Section titled “Phase 2: Bootstrap Script”Goal: Create scripts/bootstrap-instance.sh — a single script that takes a
fresh Supabase project from empty to fully functional demo instance.
Implementation
Section titled “Implementation”2.1 Script Structure
Section titled “2.1 Script Structure”#!/usr/bin/env bashset -euo pipefail
# Usage:# ./scripts/bootstrap-instance.sh # interactive# ./scripts/bootstrap-instance.sh --env .env.demo # use env file# ./scripts/bootstrap-instance.sh --dry-run # preview only2.2 Input
Section titled “2.2 Input”The script accepts:
--env <path>— path to.envfile with target Supabase credentials--dry-run— print what would happen without executing--skip-migrations— skip migration push (if already applied)--skip-seed— skip seed.sql (if already applied)--skip-guides— skip guide seeding--skip-bid-data— skip bid test data seeding--demo— include demo data pack (Phase 4)
Required env vars (from file or environment):
SUPABASE_URL/NEXT_PUBLIC_SUPABASE_URLSUPABASE_ANON_KEY/NEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SECRET_KEYSUPABASE_PROJECT_REF— project ID for CLI commandsSUPABASE_DB_PASSWORD— required forsupabase db pushANTHROPIC_API_KEY— for classification during content ingestionOPENAI_API_KEY— for embedding generation
2.3 Execution Steps
Section titled “2.3 Execution Steps”- Verify connection — Query
SELECT 1via Supabase JS client to confirm credentials work - Check DB state — Count tables in
publicschema. If > 0, warn and require--forceto proceed - Link project —
supabase link --project-ref $SUPABASE_PROJECT_REF - Push migrations —
supabase db push(applies all 22 migration files: 21 existing + 1 newentity_aliases) - Verify migrations —
supabase migration listand confirm count matches local files - Apply seed.sql — Execute via
psqlor Supabase REST API - Verify seed — Count taxonomy_domains (expect 15), taxonomy_subtopics (expect 57), layer_vocabulary (expect 4), entity_aliases (expect 22)
- Seed guides —
bun run scripts/seed-phew-guides.ts --apply - Verify guides — Count guides (expect 8) and guide_sections (expect >= 70)
- Seed bid test data —
bun run scripts/seed-bid-test-data.ts - Verify bid data — Count workspaces (expect 1), bid_questions (expect 10), bid_responses (expect 3)
- Print summary — Table of all verification results
2.4 Idempotency
Section titled “2.4 Idempotency”Each step checks whether it has already been completed:
- Migrations:
supabase migration listshows applied count - Seed data: Count queries before inserting (seed.sql uses
ON CONFLICT DO NOTHING) - Guides:
seed-phew-guides.tsalready has idempotent slug-check - Bid data:
seed-bid-test-data.tsalready checks for existing test bid
2.5 Error Handling
Section titled “2.5 Error Handling”- Each step exits with a clear error message on failure
--dry-runprints each step without executing- Failed steps do not prevent subsequent steps from being attempted (with
--continue-on-errorflag) - Final summary marks each step as PASS/FAIL/SKIP
File Inventory
Section titled “File Inventory”| File | Action |
|---|---|
scripts/bootstrap-instance.sh | Create — orchestration script |
scripts/lib/bootstrap-utils.sh | Create — shared functions (verify_connection, count_rows, print_summary) |
Acceptance Criteria
Section titled “Acceptance Criteria”- Script runs end-to-end against a fresh Supabase project without manual intervention
-
--dry-runmode prints all steps without executing any - Idempotent — safe to re-run on an already-bootstrapped instance
- Each step has a verification check that confirms success
- Script exits with non-zero code if any critical step fails
- Works with both
.envfile and environment variables
Effort Estimate
Section titled “Effort Estimate”4-5 hours — Shell scripting, Supabase CLI integration, verification logic.
Phase 3: Client Onboarding Script
Section titled “Phase 3: Client Onboarding Script”Goal: Create scripts/onboard-client.sh — automates setting up a new client
instance with their specific content.
Implementation
Section titled “Implementation”3.1 Script Structure
Section titled “3.1 Script Structure”#!/usr/bin/env bashset -euo pipefail
# Usage:# ./scripts/onboard-client.sh \# --client "Acme Corp" \# --env .env.acme \# --docs ./acme-documents/ \# --taxonomy ./acme-taxonomy.json # optional3.2 Input
Section titled “3.2 Input”Required:
--client <name>— client name (used in logging and metadata)--env <path>— path to.envfile for the client’s Supabase project--docs <dir>— directory containing client documents for ingestion
Optional:
--taxonomy <path>— JSON file with client-specific taxonomy overrides--aliases <path>— JSON file with client-specific entity aliases--urls <path>— text file with URLs to ingest (one per line)--skip-bootstrap— skip migrations and seed (if already done)--dry-run— preview mode--batch-tag <tag>— tag for the import batch (defaults toinitial-import-{date})
3.3 Execution Steps
Section titled “3.3 Execution Steps”- Bootstrap — Run
bootstrap-instance.sh --env $ENV --skip-bid-data(clients don’t need test bid data) - Customise taxonomy — If
--taxonomyprovided, apply overrides:- Add client-specific domains
- Modify descriptions or key signals
- Remove irrelevant domains (mark inactive, don’t delete)
- Seed client aliases — If
--aliasesprovided, insert client-specific entity aliases - Create admin user — Print instructions for manual user creation (cannot be automated — Supabase Auth requires email verification)
- Ingest .docx files — Scan
--docsdir for.docxfiles, runpython3 scripts/import_bid_library.py <dir> --batch-tag $TAG - Ingest .md files — Scan
--docsdir for.mdfiles/subdirs, runpython3 scripts/ingest_markdown.py <dir> --tag $TAG --author "$CLIENT" - Ingest URLs — If
--urlsprovided, runpython3 scripts/ingest.py --file $URLS - Generate summaries —
bun run scripts/batch-generate-summaries.tsfor items missing AI summaries - Seed guides — Run
scripts/seed-phew-guides.ts --apply(or client-specific guide definitions if provided) - Post-onboarding verification:
- Count content_items by content_type
- Count content_items by primary_domain
- Count items with embeddings vs without
- Count items with classifications vs without
- Count Q&A library entries
- Verify semantic search returns results
- Print summary report
3.4 Taxonomy Override Format
Section titled “3.4 Taxonomy Override Format”{ "add_domains": [ { "name": "client-specific-domain", "description": "Description of the domain", "colour": "security", "display_order": 20, "key_signal": "Key signal text" } ], "modify_domains": [ { "name": "corporate", "description": "Updated description for this client" } ], "deactivate_domains": ["sector-news", "market-intelligence"]}3.5 Client Alias Override Format
Section titled “3.5 Client Alias Override Format”{ "aliases": [ { "alias": "Acme", "canonical": "Acme Corporation Ltd", "category": "client" }, { "alias": "Acme Corp", "canonical": "Acme Corporation Ltd", "category": "client" }, { "alias": "Widget Pro", "canonical": "Acme Widget Pro Platform", "category": "client" } ], "remove_aliases": ["Phew", "Phew Design Ltd", "Phew Lms"]}3.6 Progress Reporting
Section titled “3.6 Progress Reporting”The script provides progress output at each stage:
[1/10] Bootstrap: applying migrations... DONE (21 migrations)[2/10] Bootstrap: applying seed data... DONE (15 domains, 57 subtopics)[3/10] Customising taxonomy... SKIP (no --taxonomy provided)[4/10] Seeding client aliases... DONE (12 aliases)[5/10] Admin user setup... MANUAL (see instructions below)[6/10] Ingesting .docx files... DONE (7 Q&A files, 142 Q&A pairs + 2 narrative docs)[7/10] Ingesting .md files... DONE (12 files, 12 content items)[8/10] Ingesting URLs... SKIP (no --urls provided)[9/10] Generating AI summaries... DONE (16 summaries)[10/10] Verification... PASS
=== Onboarding Summary ===Client: Acme CorpContent items: 151 - Q&A pairs: 142 - Articles: 9Classified: 151/151 (100%)Embedded: 151/151 (100%)Domains covered: 7/15File Inventory
Section titled “File Inventory”| File | Action |
|---|---|
scripts/onboard-client.sh | Create — client onboarding orchestration |
scripts/lib/onboard-utils.sh | Create — shared functions for onboarding |
docs/templates/client-taxonomy.example.json | Create — taxonomy override template |
docs/templates/client-aliases.example.json | Create — alias override template |
Acceptance Criteria
Section titled “Acceptance Criteria”- Script sets up a functional client instance from scratch with one command (plus manual admin user step)
- Supports mixed content types (.docx, .md, URLs)
- Taxonomy customisation works for adding, modifying, and deactivating domains
- Client-specific aliases replace Phew-specific ones
- Post-onboarding verification catches missing classifications or embeddings
-
--dry-runshows what would happen without writing data - Progress reporting is clear and informative
Effort Estimate
Section titled “Effort Estimate”6-8 hours — More complex than bootstrap due to taxonomy customisation, multi-format ingestion, and verification logic.
Phase 4: Demo Data Pack
Section titled “Phase 4: Demo Data Pack”Goal: Define and implement a curated demo dataset that showcases all Knowledge Hub features.
Implementation
Section titled “Implementation”4.1 Demo Requirements
Section titled “4.1 Demo Requirements”A compelling demo must cover these features:
| Feature | Minimum data needed |
|---|---|
| Browse page | 15+ content items across 4+ domains, mix of content types (article, blog, guidance, Q&A) |
| Search | Sufficient content density for meaningful semantic search results (at least 3 results per common query) |
| Bid workspace | 1 active bid with 10 questions, 3 draft responses, KB matches visible |
| Q&A Library | 20+ Q&A pairs across multiple domains for copy-to-bid demonstration |
| Coverage matrix | Items in at least 5 domains, visible gaps in 2-3 domains |
| Dashboard | Mix of fresh/ageing content, quality scores distributed across range, recent activity |
| Review queue | 3-5 items pending review (low quality score or governance flags) |
| Guides | 8 guides with some sections populated, some empty (shows value of filling gaps) |
| Change reports | At least 1 digest covering recent content changes |
| Entity graph | Multiple entities with relationships (e.g. ISO 27001 mentioned across 5+ items) |
4.2 Content Sources
Section titled “4.2 Content Sources”The demo data pack ingests from three sources:
-
Client documentation (markdown) — 12 .md files total:
docs/client-documentation/markdown/— 9 .md files (converted from .docx Q&A templates)docs/client-documentation/(root) — 3 .md files:Knowledge Hub -- Claude Integration Guide.md,Knowledge Hub -- Platform Overview.md,sector-intelligence-analysis.mdThese get classified and embedded automatically viaingest_markdown.py.
-
Client .docx Q&A files (
docs/client-documentation/*.docx) — 9 .docx files total, but requiring different ingestion paths:- Q&A library files (7): The “Tender and Bid Library Template” and
“DRAFT” .docx files. Ingest via
import_bid_library.py. - Non-Q&A .docx files (2):
Product_KB_Dev_Brief.docxandSector-Intelligence-Brief-Liam-Final.docx. These are narrative documents, not Q&A pairs. Ingest viaingest_markdown.pyafter converting to markdown (mammoth or manual), or viaingest.pyif a URL-based approach is preferred.
- Q&A library files (7): The “Tender and Bid Library Template” and
“DRAFT” .docx files. Ingest via
-
Synthetic demo content — A small set of purpose-built content items that fill specific demo gaps (e.g. items in domains not covered by real client docs, items with varying quality scores, items with known expiry dates for freshness demonstration).
4.3 Synthetic Demo Content
Section titled “4.3 Synthetic Demo Content”Create scripts/demo-content.json containing 10-15 synthetic content items
designed to:
- Fill domain coverage gaps (ensure at least 5 domains have content)
- Provide varying quality scores (some high, some low for review queue)
- Include items with expiry dates (for freshness demonstration)
- Include items with different content types (article, blog, guidance, policy)
- Include items created at different dates (for dashboard time distribution)
4.4 Demo Bootstrap Extension
Section titled “4.4 Demo Bootstrap Extension”The bootstrap-instance.sh --demo flag triggers additional steps after base
bootstrap:
- Ingest
docs/client-documentation/markdown/viaingest_markdown.py(9 files) - Ingest
docs/client-documentation/*.md(3 root-level .md files) viaingest_markdown.py - Import Q&A .docx files (7) via
import_bid_library.py - Ingest non-Q&A .docx files (2:
Product_KB_Dev_Brief.docx,Sector-Intelligence-Brief-Liam-Final.docx) viaingest_markdown.pyafter mammoth conversion - Insert synthetic demo content from
scripts/demo-content.json - Run
batch-generate-summaries.tsfor AI summaries - Backfill reader HTML via
backfill-reader-html.ts - Verify demo coverage:
- Content spans 5+ domains
- Browse page shows 15+ items
- Q&A library has 20+ entries
- At least 1 bid workspace exists with matched content
- Coverage matrix shows both coverage and gaps
File Inventory
Section titled “File Inventory”| File | Action |
|---|---|
scripts/demo-content.json | Create — synthetic demo content definitions |
scripts/seed-demo-content.ts | Create — inserts synthetic demo items with classification + embedding |
scripts/bootstrap-instance.sh | Modify — add --demo flag handling |
Acceptance Criteria
Section titled “Acceptance Criteria”-
bootstrap-instance.sh --demoproduces a fully populated demo instance - Browse page shows 15+ items across multiple domains and content types
- Semantic search returns relevant results for common bid queries (e.g. “data protection”, “quality management”, “case studies”)
- Bid workspace shows matched KB content for test questions
- Coverage matrix shows meaningful coverage with visible gaps
- Dashboard displays distributed quality scores and freshness states
- Demo can be reset and rebuilt from scratch in under 30 minutes (including AI processing)
Effort Estimate
Section titled “Effort Estimate”5-6 hours — Synthetic content authoring, ingestion script, verification checks.
Phase 5: Documentation
Section titled “Phase 5: Documentation”Goal: Update operational documentation to reference new tooling and create guides for demo and client onboarding flows.
Implementation
Section titled “Implementation”5.1 Update Production Setup Guide
Section titled “5.1 Update Production Setup Guide”Modify docs/operations/production-setup-guide.md:
- Fix outdated migration count (says 92, should say 21)
- Fix outdated table count (says 30, should say 39 tables + 1 view:
quality_issues_pending) - Fix layer vocabulary description (says 5 rows with fact/evidence/method/policy/narrative, should say 4 rows with sales_brief/bid_detail/company_reference/research)
- Add reference to
supabase/seed.sqlfor step 4 (Configure Taxonomy) - Add reference to
bootstrap-instance.shas alternative to manual setup - Add reference to
onboard-client.shfor client setup
5.2 Create Demo Setup Guide
Section titled “5.2 Create Demo Setup Guide”Create docs/operations/demo-setup-guide.md:
- Prerequisites (Supabase project, API keys, local environment)
- Quick start:
./scripts/bootstrap-instance.sh --env .env.demo --demo - What the demo includes (content, bids, guides)
- How to reset the demo (delete project, recreate, re-run)
- Demo walkthrough script (suggested flow for prospect meetings)
- Troubleshooting common issues
5.3 Create Client Onboarding Guide
Section titled “5.3 Create Client Onboarding Guide”Create docs/operations/client-onboarding-guide.md:
- Prerequisites checklist
- Preparing client documents (accepted formats, directory structure)
- Creating the Supabase project
- Running the onboarding script
- Post-onboarding manual steps (create admin user, invite team)
- Customising taxonomy for the client
- Verifying the setup
- Ongoing maintenance (cron jobs, monitoring)
File Inventory
Section titled “File Inventory”| File | Action |
|---|---|
docs/operations/production-setup-guide.md | Modify — fix counts, add tooling references |
docs/operations/demo-setup-guide.md | Create — demo-specific instructions |
docs/operations/client-onboarding-guide.md | Create — client onboarding flow |
Acceptance Criteria
Section titled “Acceptance Criteria”- Production setup guide has accurate counts and references new tooling
- Demo setup guide enables a new team member to stand up a demo instance without prior knowledge
- Client onboarding guide covers the full flow from project creation to verification
- All guides use UK English, DD/MM/YYYY date format
Effort Estimate
Section titled “Effort Estimate”2-3 hours — Documentation writing and cross-referencing.
Verification Steps
Section titled “Verification Steps”After all phases are complete, the following end-to-end verification must pass:
- Fresh project test — Create a new Supabase project, run
bootstrap-instance.sh --demo, verify all acceptance criteria from Phases 1-4 - Idempotency test — Re-run
bootstrap-instance.shon the same project, verify no errors and no duplicate data - Client onboarding test — Create another new project, run
onboard-client.shwith the existing client documentation, verify content is ingested and classified - Migration replay validation — Confirm all 22 migrations (21 existing + 1
new
entity_aliases) apply cleanly to a fresh project (this is the first time the squashed baseline has been replayed)
Effort Summary
Section titled “Effort Summary”| Phase | Description | Effort | Dependencies |
|---|---|---|---|
| 1 | Seed SQL (supabase/seed.sql) + entity_aliases migration | 3-4h | None (migration is a blocker for seed) |
| 2 | Bootstrap Script (scripts/bootstrap-instance.sh) | 4-5h | Phase 1 |
| 3 | Client Onboarding Script (scripts/onboard-client.sh) | 6-8h | Phase 2 |
| 4 | Demo Data Pack | 5-6h | Phase 2 |
| 5 | Documentation | 2-3h | Phases 1-4 |
| Total | 20-26h |
Phases 3 and 4 can run in parallel after Phase 2 is complete. With two agents, the total wall-clock time could be reduced to 15-19 hours.
Dependencies
Section titled “Dependencies”| Dependency | Type | Notes |
|---|---|---|
| Supabase Pro plan | Infrastructure | Second project needed. ~$10/month additional. |
| Supabase CLI | Tooling | Must be installed at /opt/homebrew/bin/supabase |
| Migration chain integrity | Technical | The 21-migration chain (+ 1 new entity_aliases migration) has never been replayed. Phase 2 is the first validation. |
| Python environment | Tooling | requirements.txt exists at project root. Install via pip install -r requirements.txt. |
| API keys | Infrastructure | Anthropic + OpenAI keys needed for classification and embedding during content ingestion |
Jina Reader (r.jina.ai) | External service | Used by ingest.py for URL content extraction. Requires network access to r.jina.ai. |
| Sentry | External service (optional) | Error tracking. Not required for bootstrap but recommended for production instances. |
docs/client-documentation/ | Data | Must remain in repo for demo data pack |
entity_aliases migration | Technical (BLOCKER) | Must be created and pushed before seed.sql can be applied. See Phase 1 prerequisite. |
| Risk | Severity | Mitigation |
|---|---|---|
| Migration replay fails on fresh project | High | Phase 2 validates this explicitly. If it fails, fix migrations before proceeding. |
entity_aliases table missing from migrations | High (BLOCKER) | Must create migration before Phase 1 seed can work. See Phase 1 prerequisite section. |
| Seed SQL UUIDs conflict with auto-generated IDs | Medium | Use explicit UUIDs from production to avoid collisions. Test on fresh project. |
| Demo content insufficient for compelling demo | Medium | Phase 4 includes verification criteria. Iterate on synthetic content if coverage is thin. |
| Supabase CLI TLS errors during migration push | Low | Documented in production setup guide. Fallback: use MCP apply_migration tool. |
| Python ingestion scripts fail on client documents | Medium | Test with existing client docs in Phase 4. Document supported formats in Phase 5. |
| Layer vocabulary values outdated in docs | Low | Phase 1 establishes canonical values from production DB. Phase 5 fixes documentation. |
| Key signal text abbreviated in seed SQL | Medium | Seed SQL should use full production text from the taxonomy migration, not hand-abbreviated versions. Script extraction from production DB recommended over manual enumeration. |
| Subtopic count fragility | Medium | The 57-subtopic list is fragile if manually maintained. Seed extraction should be scripted from production DB (SELECT * FROM taxonomy_subtopics ORDER BY domain_id, display_order;) rather than manually enumerated, to avoid counts drifting. |
Open Questions
Section titled “Open Questions”-
Should the seed SQL include Phew-specific entity aliases? For a generic demo, yes. For a new client, the Phew aliases should be replaced. The current design includes all 22 in seed.sql and the client onboarding script removes/replaces client-specific ones.
-
Should guide definitions be in seed.sql or remain in the TypeScript seed script? The current design keeps them in
seed-phew-guides.tsbecause they contain complex nested section definitions that are cleaner in TypeScript. The bootstrap script calls the TS script after applying seed.sql. -
Should the bootstrap script handle Vercel deployment? No — deployment is a separate concern. The bootstrap script handles DB setup only. Vercel deployment follows the existing production setup guide.
-
Coverage targets and content templates — should we seed defaults? Both tables are currently empty in production. If sensible defaults emerge during implementation, they should be added to seed.sql. Otherwise, they remain empty and are configured per-client after onboarding.