AI Integration — User Journeys
AI Integration — User Journeys
Section titled “AI Integration — User Journeys”Last verified: Session 210 (29 April 2026). Refresh covers S195-S209 + production-readiness S10-S13. Tool, resource, and prompt counts are auto-generated — see
docs/generated/mcp-inventory.md.
Overview
Section titled “Overview”The AI Integration area has two distinct user populations:
- Web app users (viewer / editor / admin) interact with AI as invisible
infrastructure. Classification, summaries, embeddings, and quality scores
appear as platform features — never branded as “AI”. The only AI surface a
non-admin will ever see is the
classification_confidencepercentage in the Source Information accordion (editor+) and the optional “Continue in Claude”ClaudePromptButtonbridge. - Claude users (Claude Desktop, Claude.ai, Cowork, Claude Code) interact
with Canonical through the MCP server — an outcome-grouped tool set
plus resources, prompts, and 4 MCP Apps (counts auto-generated; see
docs/generated/mcp-inventory.md). They search, classify, create, and visualise KB data inside Claude. The surface is organised so callers reach for an outcome, not a tool name:findfor retrieval,where_are_we_exposedfor gaps/freshness,whats_in_my_queuefor review work,getfor fetching one or many items.
Admins also have access to the Provenance route (/provenance), the only
surface where AI mechanism data — model names, token counts, costs,
classification reasoning — is exposed (per the AI-Visibility Policy admin
carve-out).
Entry Points
Section titled “Entry Points”| Entry Point | Route / Surface | Accessible By |
|---|---|---|
| Item detail — Source Information | /item/[id] accordion | Editor, Admin |
| Provenance route | /provenance (5 tabs) | Admin only |
| MCP server | /api/mcp/mcp (Streamable HTTP transport) | Authenticated MCP clients |
| Settings — Connections | /settings connector setup | All roles |
| ClaudePromptButton bridge | Inline buttons across browse / item / certification UI | All roles |
| Manual classify | POST /api/items/[id]/classify | Editor, Admin |
| Manual summarise | POST /api/summaries/generate | Editor, Admin |
| MCP Apps (inside Claude) | show_* tools | Authenticated MCP clients |
User Journeys
Section titled “User Journeys”Journey 1: Editor Creates Content via the MCP Connector
Section titled “Journey 1: Editor Creates Content via the MCP Connector”Actor: Editor or admin using Claude Desktop / Claude.ai with the Knowledge Hub connector enabled. Goal: Add a new policy document to the KB and have it indexed for retrieval. Preconditions: OAuth bearer token in place (connector configured via Settings → Connections).
- User asks Claude to create the item.
- The user pastes the policy markdown into the Claude conversation and requests “Add this to the KB as a policy in domain X.”
- Claude calls
create_content_itemwith the appropriatecontent_type,primary_domain, optionalprimary_subtopic, and one of the typed provenance fields (source_url,source_file, orsource_document_id— S205 WP-A1 §1.21).
- Server runs the full ingest pipeline.
- Tool:
lib/mcp/tools/content.tscreate_content_itemhandler - Validates input (Zod schemas), resolves dedup, then calls
classifyContent()(Pass 1),generateSummary(),generateEmbedding(),regenerateChunks(), andrecordPipelineRun()in a single request. - Writes the row with
ingest_source = 'mcp_create'(S207 WP-A4) so theensure_v1_history_at_commit()trigger emitschange_reason = 'initial_ingest'.
- Tool:
- Claude reports back.
- Markdown response confirms creation, surfaces the suggested title, domain/subtopic, primary entities, and chunk count.
- Structured content payload mirrors the data for programmatic chaining.
- Item is searchable immediately.
- The new row is reachable through the
findtool (across itstype/scope/granularitybranches) and the web app’s browse view.
- The new row is reachable through the
Variations
Section titled “Variations”- Draft mode: Editor sets
publication_status: "draft". Embedding and chunk generation are skipped; the row is excluded from search and visible only in the review queue’s Drafts filter. - Auth failure (viewer caller):
pipeline_runsrow written with status'failed', error message'Permission denied', via lazy-imported service-role client (S206 WP4 / S207 OPS-38). - Insert failure (DB constraint): Pre-success failed-insert path also
emits a
pipeline_runsrow withstatus='failed'andphase='pre_success'in the result payload (S207 OPS-39).
Edge Cases
Section titled “Edge Cases”- Suspected duplicate: Soft-block; row inserted with
dedup_status='suspected_duplicate',metadata.suspected_duplicate_ofpointing to the existing item (S184 WP1 D1). - Admin override:
skip_dedup=truebypasses the check (admin only; silently ignored for non-admin callers). - Missing typed provenance: If the caller passes the legacy
source_documentfield, the request fails with a Zod error advertising the three typed replacements. Zod 4 strip mode is bypassed via.refine()so the error is enforced (not silently dropped).
Journey 2: Completing a Form Response with Cited Sources
Section titled “Journey 2: Completing a Form Response with Cited Sources”Actor: A user completing a form (e.g. a UK public-procurement tender
response) via the /kb:draft-response plugin command in Cowork or Claude.ai.
Goal: Draft a form response with citations back to the KB. Preconditions:
Plugin installed, MCP connector configured, the form question text is to hand.
- User invokes
/kb:draft-response "{question text}".- Command file:
.claude/plugins/knowledge-hub/1.0.0/commands/draft-response.md
- Command file:
- Plugin orchestrates skills + tools.
- The
search-strategyskill decomposes the question and calls thefindtool, choosing the appropriatetype/scope/granularitybranch (the single retrieval entry that replaced the former search trio). - The
completing-formsskill enforces UK procurement conventions and word limits (generalised from the former bid-writing skill — procurement is the first form type). - The
knowledge-synthesisskill deduplicates results and assesses confidence.
- The
- Claude returns a draft with citations.
- Each citation references a content item ID + title.
- Confidence postures:
confident(multiple high-similarity matches),cautious(single source or stale data),unmatched(no KB content — prompts the user to flag a content gap).
- User accepts → Claude calls
cite_content.- Each cited content item gets a
citationsrow linking the form response to the source item, enablingget_content_effectivenessreporting later.
- Each cited content item gets a
Variations
Section titled “Variations”- Without the connector: The plugin command works in standalone mode — the user pastes content into Claude and the same skills apply, but no live KB search.
- Via web app
/procurement/[id]/responses: AI-driven drafting also runs throughrunDraftingPipeline()server-side (/api/procurement/[id]/responses/draft). The user never sees model names — the draft simply appears in the editor.
Edge Cases
Section titled “Edge Cases”- No matching KB content: Claude reports
unmatched, suggests the user invoke thecontent-creationskill, and pre-fills a draft skeleton. - Stale citations: Synthesis skill warns the user if cited items have
freshness ∈ {stale, expired}or below-threshold quality scores.
Journey 3: Admin Audits Per-Item Provenance
Section titled “Journey 3: Admin Audits Per-Item Provenance”Actor: Admin investigating “why did this item get classified as X?” Goal: Inspect classification confidence, model used, token cost, and reasoning for a specific item. Preconditions: Admin role; item ID known.
- Admin navigates to
/provenance.- Route:
app/provenance/provenance-content.tsx - Role gate:
useUserRole()client-side +getAuthorisedClient(['admin'])on the API. Non-admins see theAccessDeniedcomponent.
- Route:
- Admin opens the Per-item tab.
- Tab:
components/provenance/per-item-tab.tsx - Pastes a UUID; route
GET /api/provenance/item/[id]returns:- Classification block: confidence (decimal + percentage),
domain/subtopic slugs + names, full
classification_reasoningtext. - Processing block: model name, input/output tokens, cost (via
lib/provenance/pricing.ts), processed timestamp. - Drafting block: if any AI form responses cite this item, lists
attribution with
PIPELINE_SYSTEM_USER_IDpromoted to “Knowledge Hub”. - Review Schedule block (S207 §5.5 Phase 3 T4): next review date,
review cadence (
Every {N} days ({N/30} months)), last reviewed (verified_at).
- Classification block: confidence (decimal + percentage),
domain/subtopic slugs + names, full
- Tab:
- Admin cross-references with Pipeline Health.
- Tab:
components/provenance/pipeline-health-tab.tsx - Keyset-paginated list of
pipeline_runsrows with time-range + kind filters and a 20K truncation guard. Failure drawer shows the full error message for any failed run.
- Tab:
- Admin downloads PDF audit.
GET /api/admin/provenance/export/verification-historyproduces an A4 PDF (via@react-pdf/renderer) of day-grouped verification events. The export call itself is logged viarecordPipelineRun().
Variations
Section titled “Variations”- Audit tab: 1:1 lift of
ActivitySectionfrom/settings; sameActivityFeedcomponent. Hosts the PDF export trigger. - Cost tab: Stub showing aggregate
pipeline_runs.cost. Labelled “Interim — Wave B”. - Disputes tab: Stub showing
classification_disputesrows. Labelled “Interim — Wave C”.
Edge Cases
Section titled “Edge Cases”- Item never classified: Per-item tab returns
classified_at: null; classification block shows “Not classified” rather than empty values. - Pipeline run truncation: When more than 20K runs match filters, the Pipeline Health tab returns the most recent 20K with a banner indicating truncation.
Journey 4: Editor Reviews Content Quality with Cadence Awareness
Section titled “Journey 4: Editor Reviews Content Quality with Cadence Awareness”Actor: Editor processing the review queue. Goal: Verify items whose
review cadence has elapsed. Preconditions: next_review_date and
review_cadence_days configured on items (set via the Review Cadence Editor
on item detail).
- Editor opens
/review.-
Page:
app/review/page.tsx -
The
ReviewCadenceCard(S206 §5.5 Phase 3 T1) shows count pills for overdue / due-soon items per the four-band matrix:Band Badge governance_review_status='review_overdue'”Review overdue” (red) next_review_date ≤ 14 days inclusive”Review due {DD/MM/YYYY}” (amber) > 14 ≤ 30 days inclusiveMuted text-only badge > 30or NULLNo badge
-
- Editor toggles “Overdue reviews” filter.
- Component:
components/review/review-filters.tsx(S205 §5.5 Phase 3 T2). Toggle changes the route’s filter fromverified_at IS NULLtoverified_at.is.null,governance_review_status.eq.review_overdueso verified-but-overdue rows surface.
- Component:
- Editor verifies an item.
POST /api/review/actionwithaction: "verify". Setsverified_atandverified_by; resolves any openreview_neededflags.- §5.5 Phase 2 T2 cadence-driven auto-renewal: if
review_cadence_daysis set,next_review_dateadvances toGREATEST(current, today) + cadence(symmetric with the governanceapprovepath).
- Editor edits the cadence directly on item detail.
- Component:
components/content/review-cadence-editor.tsx(S206 §5.5 Phase 3 T3). Provides a date picker plus 5-preset Select (No recurring review / Every 3 months / Every 6 months / Every 12 months / Custom…). Custom range [1, 1095] days; client-side validation rejects out-of-range before POST. - Self-contained TanStack
useMutationPATCHes/api/items/:idwithfield='next_review_date'or'review_cadence_days'.
- Component:
Variations
Section titled “Variations”- Read-only view: Reader view hides the Cadence Editor via
{!readOnly && ...}guard inmetadata-sidebar.tsx. - MCP-driven:
whats_in_my_queue(the single faceted queue) acceptsfacet: "governance"plusinclude_overdue+status_filter(pending/review_overdue/all) so MCP callers triage the same queue. Thefindtool acceptsoverdue_review+review_due_within_daysfilters on its chunk-granularity branch for retrieval scoped to cadence-elapsed items.
Edge Cases
Section titled “Edge Cases”- Quality drop on verify: S208 §5.5 Phase 5 cadence-compliance scorer
applies a penalty to the freshness sub-score when
next_review_dateis populated. Scoring is preserved exactly for items WITHOUT cadence tracking.
Journey 5: Claude User Visualises Coverage via MCP Apps
Section titled “Journey 5: Claude User Visualises Coverage via MCP Apps”Actor: Knowledge worker using Claude Desktop / Claude.ai. Goal: Spot domain coverage gaps without leaving Claude. Preconditions: MCP connector configured.
- User asks Claude “where are our biggest coverage gaps?”
- Claude calls
show_coverage_matrix(read-only MCP App trigger).
- Claude calls
- Server returns the Coverage Matrix App.
- Tool:
lib/mcp/tools/apps.ts(registerAppToolwrapper) - Resource:
ui://coverage-matrix/app.html— Vite single-file build inlined fromlib/mcp/app-bundles.ts.
- Tool:
- App renders inline in Claude’s conversation.
- The HTML card calls
where_are_we_exposed(the consolidated five-layer exposure tool that absorbed the former freshness / quality / coverage-gap reads) to populate the heatmap. - Colour-coded cells (Warm Meridian semantic tokens) show domain × freshness intersection counts. Drill-down opens gap cards.
- The HTML card calls
- User clicks a gap card → Claude offers to create content.
- Plugin command
/kb:coverageor skillcontent-creationis invoked via natural-language follow-up.
- Plugin command
Variations
Section titled “Variations”- Procurement Dashboard App:
show_procurement_dashboardtriggers the same lifecycle withui://form-dashboard/app.html. Drill-down to form sections + KB retrieval (viafind) with confidence badges. - Reorient Me App:
show_reorient_meproduces a personal briefing card with urgent items, active forms, recent work, team changes. - Intelligence Feed App:
show_intelligence_feed(workspace-scoped) shows sector intelligence digest cards filtered by period.
Edge Cases
Section titled “Edge Cases”- Empty staging DB: All four apps degrade gracefully — the contract test
mcp-app-contracts.test.tsenforces type parity between formatter interfaces and app types so an empty array doesn’t break rendering.
Journey 6: Admin Configures the Claude Connector
Section titled “Journey 6: Admin Configures the Claude Connector”Actor: First-time admin onboarding to the MCP integration. Goal: Connect Claude Desktop to Canonical. Preconditions: Admin role on a deployed environment.
- Admin opens
/settings→ Connections.- Page:
app/settings/page.tsx
- Page:
- Admin follows the connector setup.
- Public OAuth metadata endpoints discoverable via
app/.well-known/oauth-protected-resource/route.ts(RFC 9728). - Consent UI:
app/oauth/consent/page.tsx. - Decision handler:
app/api/oauth/decision/route.ts.
- Public OAuth metadata endpoints discoverable via
- Claude Desktop polls
/api/mcp/mcp.- First request returns 401 with a
WWW-Authenticateheader pointing to the Protected Resource Metadata. - OAuth flow completes, bearer token cached in Claude Desktop.
- First request returns 401 with a
- Admin verifies via
/kb:briefing.- Plugin command returns the reorientation briefing — confirms tools and resources are reachable.
Variations
Section titled “Variations”- Cowork: Same flow; Cowork is an MCP-compatible client.
- Claude Code (development): Plugin marketplace handles install. After
pushing plugins to remote,
git pullin~/.claude/plugins/marketplaces/{name}/to refresh.
Edge Cases
Section titled “Edge Cases”- Plugin uninstall asymmetry:
/plugin uninstallmay leave stale disable overrides insettings.local.json. Run uninstall on each scope (user, project) explicitly.
Role Permissions Summary
Section titled “Role Permissions Summary”| Action | Viewer | Editor | Admin |
|---|---|---|---|
| Search KB via MCP | Yes | Yes | Yes |
| Read-only MCP tools (get/find/list/audit/show) | Yes | Yes | Yes |
classify_content MCP tool | No | Yes | Yes |
generate_summary MCP tool | No | Yes | Yes |
create_content_item / update_content_item | No | Yes | Yes |
delete_content_item MCP tool | No | No | Yes |
supersede_content_item MCP tool | No | No | Yes |
assign (owner, one or many) / update_publication_status | No | Yes | Yes |
Provenance route (/provenance all tabs) | No | No | Yes |
classification_confidence text in Source Information | No | Yes | Yes |
| ClaudePromptButton bridge (open Claude) | Yes | Yes | Yes |
| Settings → Connections (configure connector) | Yes (read) | Yes (read) | Yes (write) |
Current Limitations
Section titled “Current Limitations”- No in-app chat sidebar. All AI-assisted interactions either run as
invisible background processing or route the user to Claude via the
ClaudePromptButtonbridge. The CopilotKit sidebar that previously implemented an in-app chat experience was fully removed in S109. - Provenance is admin-only. Editors can see
classification_confidenceas plain text on/item/[id], but cannot access model names, token counts, costs, or classification reasoning. - MCP Apps are read-mostly. All four shipped apps invoke read-only tools. Write actions remain in the web app or via direct MCP write tools.
- Plugin commands assume the connector is configured. Standalone mode (paste content into Claude) works but lacks live KB search.
Related Documentation
Section titled “Related Documentation”- Technical reference:
docs/product-functionality/ai-integration/technical.md - Workflows:
docs/product-functionality/ai-integration/workflows.md - AI integration layers:
docs/reference/ai-integration-layers.md - AI integration strategy:
docs/reference/ai-integration-strategy.md - AI visibility policy:
docs/reference/ai-visibility-policy.md - Classification prompt:
docs/reference/classification-prompt.md - Data entry points:
docs/reference/data-entry-points.md