Skip to content

Reserved Workspace Seats — PRODUCT

Status: [CURRENT-CANONICAL] — NEW-S240. Spec destination ratified by Liam at S240 kickoff (separate doc per S240 user-decision-2, mirroring the RLS-PATTERN spec-pair pattern landed S239). Substrate from docs/plans/phase-0-investigation/architecture/04-workspace-types.md §4.2 (S240 ratification — upfront seats, columns per feature spec).

This file holds user-perspective invariants for the 5 non-procurement reserved workspace satellite tables — what the platform guarantees about each seat’s existence, shape, and behaviour at v1 apply time. Companion TECH.md carries per-seat DDL + migration draft path + validation steps.

Invariants are numbered globally (S-1, S-2, …) so TECH.md references by ID. Each carries [RATIFIED-S2XX] with source citation. The five reserved seats are: intelligence_workspaces, sales_proposal_workspaces, product_guide_workspaces, competitor_research_workspaces, training_onboarding_workspaces. The sixth baseline satellite — procurement_workspaces — is out of scope for this spec: it carries a 6-column ratified scope per OQ-Q38-E and is owned by the procurement feature spec.

  • docs/plans/phase-0-investigation/architecture/04-workspace-types.md §4.2 + §4.3 (S240 upfront-seats ratification + extensibility procedure).
  • docs/plans/phase-0-investigation/10-feedback-investigation-findings/00-synthesis-v2.md §3.4 (Q-OQR1-03 — 6 baseline application_types) + §3.9 (Shape B typed-columns over JSONB).
  • docs/plans/phase-0-investigation/0.9-decision-graph.md §11.1 ONT.3 (application_types vocabulary) + §11.3 row 4 (bid_workspaces → procurement_workspaces rename precedent).
  • docs/specs/rls-pattern/PRODUCT.md P-1 (auto-RLS event trigger) + P-2 (per-role grants helper) + P-3 (fail-loud Data API).
  • phase-b-prerequisite-1-onthology-pipeline.md §5 closure (Q-OQR1-113-A — satellite per application_type vocabulary entry).

Engineers writing the v1 reserved-seat migration; reviewers verifying seat-shape compliance; per-application feature spec authors deciding which columns their ALTER TABLE adds; CI guard authors.

S-1 — Five reserved seats exist at v1 apply time

Section titled “S-1 — Five reserved seats exist at v1 apply time”

When the v1 reserved-workspace-seats migration applies, all five satellite tables exist in the public schema with their final names: intelligence_workspaces, sales_proposal_workspaces, product_guide_workspaces, competitor_research_workspaces, training_onboarding_workspaces. No partial seat-application is permitted — either all five land or the migration fails.

[RATIFIED-S240] — per Liam S240 ratification (architecture/04-workspace-types.md §4.2 S240 framing). Names match the Q-OQR1-03 application_types vocabulary entries verbatim (<application_type_key>_workspaces per Q-OQR1-113-A).

Cross-refs: [Q-OQR1-03], [Q-OQR1-113-A], [arch 04-workspace-types §4.2].

S-2 — Primary key shape (uuid, default gen_random_uuid)

Section titled “S-2 — Primary key shape (uuid, default gen_random_uuid)”

Each seat table carries a primary key column id uuid PRIMARY KEY DEFAULT gen_random_uuid(). The PK column is named id (matching the workspaces table convention per the Shape B pattern in 00-synthesis-v2.md §3.9).

[RATIFIED-S240] — derived from S240 architecture/04-workspace-types.md §4.2 framing (“PK + FK + RLS only”) + the platform-standard uuid PK pattern already used across workspaces and procurement_workspaces.

Cross-refs: [arch 04-workspace-types §4], platform uuid PK precedent.

S-3 — Foreign key to workspaces.id (NOT NULL, UNIQUE, ON DELETE CASCADE)

Section titled “S-3 — Foreign key to workspaces.id (NOT NULL, UNIQUE, ON DELETE CASCADE)”

Each seat table carries a column workspace_id uuid NOT NULL UNIQUE REFERENCES workspaces(id) ON DELETE CASCADE. The 1:1 cardinality between a workspace and its satellite is enforced by the UNIQUE constraint per OQ-Q113-A (“each workspace bound to application_type='<key>' has exactly one row in <key>_workspaces”).

[RATIFIED-S240] — per architecture/04-workspace-types.md §4.1 (1:1 cardinality with workspaces) + S240 §4.2 (“FK to workspaces.id” load-bearing). ON DELETE CASCADE ensures workspace deletion cleans up the satellite row.

Cross-refs: [Q-OQR1-113-A], [arch 04-workspace-types §4.1].

S-4 — RLS enabled via auto-trigger (RLS-PATTERN P-1 inheritance)

Section titled “S-4 — RLS enabled via auto-trigger (RLS-PATTERN P-1 inheritance)”

Each seat table has row-level security enabled at v1 apply time. The enabling happens via the rls_auto_enable() event trigger per docs/specs/rls-pattern/PRODUCT.md P-1 — no explicit ALTER TABLE ... ENABLE ROW LEVEL SECURITY statement is required in the seat migration. If the RLS-PATTERN migration has not yet applied when the seat migration runs, the seat migration MUST emit an explicit ALTER TABLE ... ENABLE ROW LEVEL SECURITY per seat as a belt-and-braces safeguard.

[RATIFIED-S240] — combined ratification: S240 Liam ratification (architecture §4.2 framing) + RLS-PATTERN P-1 (auto-trigger). The belt-and-braces clause prevents a “what if migration order changes” failure mode at apply time.

Cross-refs: [RLS-PATTERN P-1], [arch 04-workspace-types §4.2].

S-5 — Per-tenant RLS policy inherited from workspaces

Section titled “S-5 — Per-tenant RLS policy inherited from workspaces”

Each seat table’s row-level access is governed by inheritance through the workspace_id FK — the seat row is readable / writable to the same tenant role that has access to the parent workspaces row. The seat migration installs per-seat RLS policies that delegate to the parent workspace’s tenant scope via a JOIN-or-EXISTS pattern; no separate tenant_id column is added to the seat table.

[RATIFIED-S240] — derived from architecture/04-workspace-types.md §4.2 framing (“per-tenant policies”) + Q-OQR1-04 KISS single-discriminator ratification (no per-satellite tenant duplication). Implementation pattern lands in companion TECH.md T-5.

Cross-refs: [Q-OQR1-04], [arch 04-workspace-types §4.2], [RLS-PATTERN P-1].

S-6 — Per-role grants applied via RLS-PATTERN T-2 helper

Section titled “S-6 — Per-role grants applied via RLS-PATTERN T-2 helper”

Each seat table receives the standard 3-role grants block per docs/specs/rls-pattern/PRODUCT.md P-2 (anon SELECT, authenticated full CRUD, service_role full CRUD) via the grant_standard_public_table_access(target_table regclass) helper from RLS-PATTERN T-2. The seat migration calls the helper for each of the 5 seats immediately after CREATE TABLE.

[RATIFIED-S240] — combined ratification: S240 (architecture §4.2) + RLS-PATTERN P-2 (per-role grants requirement) + Supabase platform-deadline 30/05/2026 (grants-default-deny).

Cross-refs: [RLS-PATTERN P-2], [RLS-PATTERN T-2], [arch 04-workspace-types §4.2].

S-7 — No per-app columns at v1 (feature-spec ALTER discipline)

Section titled “S-7 — No per-app columns at v1 (feature-spec ALTER discipline)”

At v1 apply time, each reserved seat carries only the columns specified in S-2 + S-3 (id PK + workspace_id FK). No application-type-specific columns (buyer, deadline, outcome etc.) are added in the seat migration. When an application’s feature spec ships, the feature-spec migration adds columns via ALTER TABLE ... ADD COLUMN against the seat table — never re-creates the table.

[RATIFIED-S240] — per Liam S240 ratification (architecture §4.2 framing — “per-app column lists specced per-application-type when that application reaches build”). The discipline is load-bearing: it preserves the seat as a stable FK target while column lists evolve per-application.

Cross-refs: [arch 04-workspace-types §4.2], feature-spec authoring convention.

Seat table names match the S240 architecture record verbatim and must not be renamed without a separate ratification cycle. The 5 names: intelligence_workspaces, sales_proposal_workspaces, product_guide_workspaces, competitor_research_workspaces, training_onboarding_workspaces. Singular noun matching the application_types.key value per Q-OQR1-113-A.

[RATIFIED-S240] — per architecture/04-workspace-types.md §3 Q-OQR1-03 vocabulary table + Q-OQR1-113-A naming pattern. Precedent: bid_workspaces → procurement_workspaces rename per 0.9-decision-graph.md §11.3 row 4 required a ratification cycle.

Cross-refs: [Q-OQR1-03], [Q-OQR1-113-A], [0.9-decision-graph §11.3].

  • procurement_workspaces seat shape — owned by the procurement feature spec (docs/specs/procurement-workspaces/{PRODUCT,TECH}.md or equivalent) with the 6-column scope ratified per OQ-Q38-E. Procurement is not a “reserved seat awaiting columns” — it has columns at v1.
  • Per-application admin UI — workspace settings surfaces per application type are v1.1 admin-UI scope per Q-OQR1-13 (00-synthesis-v2.md §3.13).
  • Client-extended application types beyond the 6 baseline — covered by architecture/04-workspace-types.md §4.3 extensibility procedure; seat tables for net-new application_types are feature-spec creations, not part of the v1 reserved-seats migration.
  • State-machine wiring — per-application state machines live in lib/<application_key>/ per Q-OQR1-05; not v1 scope for the reserved seats.
  • Per-app column lists — see S-7. Feature specs own these.

v1.1 candidates (DEFERRED — not blocking)

Section titled “v1.1 candidates (DEFERRED — not blocking)”
  • Application-type admin UI section — per Q-OQR1-13 v1.1 admin-UI scope; outside reserved-seats spec but binds at the seat level if column editing surfaces ship.
  • Cross-seat aggregation views — read-side views joining workspaces + satellites for cross-application reporting; deferred until at least 2 non-procurement applications ship.

End of PRODUCT spec. Implementation references in ./TECH.md.