Product-Guide Workspaces — PRODUCT
Product-Guide Workspaces — PRODUCT
Section titled “Product-Guide Workspaces — PRODUCT”Status:
[CURRENT-CANONICAL]— NEW-S244 Wave 0. Reserved-seat spec for theproduct_guideapplication type satellite. Phase 1 deliverable per RATIFIED-S243 Item 15 (docs/plans/phase-0-investigation/pre-s244-project-feedback.mdline 53 +docs/specs/id-31-canonical-pipeline-implementation-plan/PLAN.md§5 row “product-guide-workspaces” line 494).
Summary
Section titled “Summary”product_guide_workspaces is the reserved Phase 1 satellite table for the product_guide application type — one of six baseline application_types per Q-OQR1-03 (docs/plans/phase-0-investigation/architecture/04-workspace-types.md §3.2 line 77). At v1 apply time the satellite ships as a reserved seat (PK + FK + RLS only per docs/specs/reserved-workspace-seats/PRODUCT.md S-1..S-8); per-app columns are added via ALTER TABLE at the product-guide feature build cycle, not in the Q-OQR1-16 combined-PR migration. This spec ratifies the seat shape and names the existing product-guide-adjacent code surfaces in the repo that the feature-build cycle will integrate against.
Behavior
Section titled “Behavior”Reserved-seat lifecycle
Section titled “Reserved-seat lifecycle”-
When the Q-OQR1-16 combined-PR migration applies (PLAN.md §4.2 T2 sub-task 7),
product_guide_workspacesexists in the public schema with only the columns required for a reserved seat perdocs/specs/reserved-workspace-seats/PRODUCT.mdS-2 + S-3 —id uuid PRIMARY KEY DEFAULT gen_random_uuid()andworkspace_id uuid NOT NULL UNIQUE REFERENCES workspaces(id) ON DELETE CASCADE. No application-specific columns exist at this point. -
Row-level security is enabled on the table at creation time via the
rls_auto_enable()event trigger perdocs/specs/rls-pattern/PRODUCT.mdP-1, and the standard 3-role grants block is applied viagrant_standard_public_table_access('public.product_guide_workspaces'::regclass)perdocs/specs/reserved-workspace-seats/PRODUCT.mdS-6 (anon SELECT; authenticated + service_role full CRUD). Both must hold immediately after the migration commits — RLS-without-grants returns42501 permission deniedfrom the Data API per RLS-PATTERN P-3. -
Each row in
product_guide_workspacesis 1:1 with a row inworkspaceswhereworkspaces.application_type_idresolves to theapplication_types.key='product_guide'row (per Q-OQR1-113-A satellite-per-application_type cardinality andarchitecture/04-workspace-types.md§4.1 line 95). TheUNIQUEconstraint onworkspace_idenforces this cardinality. -
When the parent
workspacesrow is deleted, the satellite row cascades automatically (perON DELETE CASCADE). Deleting a satellite row does not affect the parent workspace (no reverse cascade) — same shape asprocurement_workspacesand the other reserved seats. -
Row visibility is governed by inheritance through the
workspace_idFK — a tenant role can read or write aproduct_guide_workspacesrow iff it has access to the parentworkspacesrow, via a per-seat RLS policy that delegates toworkspacesvia JOIN-or-EXISTS perdocs/specs/reserved-workspace-seats/PRODUCT.mdS-5. No separatetenant_idcolumn is added to the satellite.
Feature-build deferral
Section titled “Feature-build deferral”-
Per-application-type column lists (whatever shape product-guide-specific fields take — e.g.
product_id,guide_section_set, layout config) are not added at the Phase 1 migration. They land viaALTER TABLE public.product_guide_workspaces ADD COLUMN ...migrations authored alongside the product-guide feature spec at feature-build time (perarchitecture/04-workspace-types.md§4.2 line 110 +docs/specs/reserved-workspace-seats/PRODUCT.mdS-7). -
The reserved-seat invariants in
docs/specs/reserved-workspace-seats/PRODUCT.mdS-1 through S-8 apply verbatim to this seat — this PRODUCT.md does not re-state them; the cross-reference is load-bearing. If those invariants change, this seat changes with them. -
The naming convention
product_guide_workspacesis frozen at S240 perdocs/specs/reserved-workspace-seats/PRODUCT.mdS-8 +architecture/04-workspace-types.md§3.2 line 77. Renaming requires a separate ratification cycle (precedent:bid_workspaces → procurement_workspacesper0.9-decision-graph.md§11.3 row 4).
Integration with existing product-guide-adjacent code
Section titled “Integration with existing product-guide-adjacent code”-
The repo already carries product-guide-related code and data distinct from this satellite. The existing surface is content-side, not application-type-side:
guidestable (supabase/migrations/20260416102457_pre_squash_reconciliation.sql:3804-3813) — carries aguide_typeCHECK column with'product'as one of five allowed values ('sector','product','company','research','custom'). Rows withguide_type='product'are the three live Phew product guides — Advanced Audits, LMS, Websites — perdocs/specs/p0-product-guide-section-alignment-spec.mdlines 22-26 +docs/specs/p0-product-guide-section-alignment-spec.mdline 121.guide_sectionstable (supabase/migrations/20260422174420_wire_product_guide_sections.sql,20260422174117_add_research_feed_to_product_guides.sql) — 19+1 sections wired per product guide (S189 WP4 + WP5).lib/intelligence/guide-generator.ts:50— auto-generatesguide_type='research'guides for intelligence workspaces (notproduct); shows how guides bind to workspaces today viaworkspace_idon the generator’s caller chain.lib/guide-section-mapping.ts:118-126— domain-filtered guide-section lookup; referencesguides.domain_filterandguides.is_published.lib/mcp/tools/guides.ts:52-105— MCP tools (list_guides,get_guide,create_guide,update_guide) operate on theguidestable withguide_typeas a filter parameter.docs/ontology/25-application-type.md:20-22 + 50— namesproduct_guideas a baselinecore-provenance application type with label “Product Guide”.docs/specs/p0-product-guide-section-alignment-spec.md— section-alignment spec governs the content shape ofguides/guide_sectionsrows whereguide_type='product'; orthogonal to this satellite.
-
The existing
guides.guide_type='product'rows are content records — they bind to workspaces viaguide_idon consumer tables (e.g. intelligence flow perlib/intelligence/guide-generator.ts:90-150), not via a satellite row. The newproduct_guide_workspacessatellite is the application-type seat for workspaces themselves; the two integrate at feature-build time but are independent objects today. -
No data migration is performed at Phase 1 — the satellite ships empty. Backfill (if any — e.g. populating
product_guide_workspacesrows for any existingworkspaces.application_type_id → 'product_guide'rows) is a feature-build-cycle deliverable. As of S243 no productionworkspaces.typerows carry a product-guide value (production carries only 4intelligencerows verified S234 perarchitecture/04-workspace-types.md§2.2 line 40); the feature-build cycle creates them when product-guide workspaces become a user-facing concept.
Out of scope (v1 reserved seat)
Section titled “Out of scope (v1 reserved seat)”- Per-app column shape — owned by the future product-guide feature PRODUCT/TECH spec. This spec does not constrain what columns the feature spec adds.
- Product-guide content behaviour — section taxonomy, ROI/Impact handling, IMPACT-of-If-Not-Now, FAQs, layer nesting, and the rest of
docs/specs/p0-product-guide-section-alignment-spec.mdscope. That spec covers theguides/guide_sectionscontent model; nothing about the workspace-satellite seat. guides↔product_guide_workspacesintegration shape — how a workspace withapplication_type='product_guide'references its associatedguidesrow(s), and whether that reference lives on the satellite as a typed column (e.g.primary_guide_id uuid REFERENCES guides(id)) or stays loose. Deferred to feature build.guide_typeCV alignment — the existingguides.guide_type='product'CHECK constraint vs. the newapplication_types.key='product_guide'row. Whether these collapse, alias, or coexist is a feature-build decision. Open question: at feature build, evaluate whetherguide_typeretires in favour ofapplication_types-driven discrimination (similar to theworkspaces.type→workspaces.application_type_idcollapse per Q-OQR1-01).- State machine — per-application state machines live in
lib/<application_key>/per Q-OQR1-05.lib/product_guide/does not yet exist; not in scope for the reserved-seat spec. - Admin UI — workspace-settings surface per application type is v1.1 admin-UI scope per Q-OQR1-13.
- MCP tooling for
product_guide_workspaces—lib/mcp/tools/exposure decisions are feature-build scope. The existinglib/mcp/tools/guides.tscontinues to operate onguidesrows independent of this satellite.
Sources
Section titled “Sources”- RATIFIED-S243 Item 15 — NEW Phase 1 spec ratification (
docs/plans/phase-0-investigation/pre-s244-project-feedback.mdline 53; PLAN.md §5 row 494 + Wave 0 ordering at §8 line 588). - RATIFIED-S240 — reserved seats pattern + S-1..S-8 invariants (
docs/specs/reserved-workspace-seats/PRODUCT.md). - RATIFIED-S239 — RLS pattern P-1..P-5 (
docs/specs/rls-pattern/PRODUCT.md). - RATIFIED-S235 — application_types Option (c) hybrid + 6 baseline
core-provenance rows includingproduct_guide(Q-OQR1-01 + Q-OQR1-03;architecture/04-workspace-types.md§3 line 67 + ontologydocs/ontology/25-application-type.mdline 20). - RATIFIED-S235 — satellite-per-application_type cardinality + naming pattern (Q-OQR1-113-A;
architecture/04-workspace-types.md§4.1). - Existing-code anchors (current state, not ratifications) —
lib/mcp/tools/guides.ts,lib/intelligence/guide-generator.ts,lib/guide-section-mapping.ts,supabase/migrations/20260416102457_pre_squash_reconciliation.sql:3804-3813(guidesschema),supabase/migrations/20260422174420_wire_product_guide_sections.sql,docs/specs/p0-product-guide-section-alignment-spec.md.
End of PRODUCT spec. Implementation references in ./TECH.md.