From 33983451099b86268ea056053be6aa7de348b6ce Mon Sep 17 00:00:00 2001 From: karti Date: Wed, 12 Aug 2026 21:33:38 -0700 Subject: [PATCH] Plan: add RBAC, capacity tiers, imports, admin settings; expand contracts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Six additions, and one promoted to foundation. RBAC becomes a Wave 0 task rather than something absorbed into each CRUD track. Authorization today stops at "is a member", and eight parallel write tracks plus a bulk-import feature are about to land. Import especially: one bad column mapping can rewrite thousands of records, so it must not ship before there is a real answer to who may run it. Suggested default is team leads and platform admins only — easy to loosen later, unpleasant to tighten. A government/sovereign capacity tier joins secure and community. It is a schema change, so it is cheaper before the tables carry real data. Matching must never satisfy a government requirement with community capacity, and the tier interacts with the export-control predicate already modelled in compliance.ts. Imports are split so the work is reusable: a CSV/Excel framework carrying the upload, mapping, dry-run preview and idempotent commit, with Notion and Google Sheets as thin OAuth front-ends onto the same mapping step. Notion databases are tables with typed properties, so treating them as a separate importer would duplicate the hard part. Admin settings gains Piggy's model selection, defaulting to a Nemotron model on Prime Intellect inference, with the endpoint configurable so an on-prem install can point at the customer's own. Contracts is expanded from "surface the schema" to the full field set — the hierarchy with order-form-beats-MSA precedence, negotiated SLA terms including fee abatement and its trigger, spare-pool scope, maintenance classes and the reasonable-endeavours carve-out, plus take-or-pay and termination tier. Written as a first draft to be corrected by someone who negotiates these for a living. Also records three open questions, including that the Prime Intellect API token could not be found on cloud-1 — searched ~/.prime, ~/.config/prime, /opt and /etc. Co-Authored-By: Claude Opus 5 (1M context) --- docs/build-plan.md | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/docs/build-plan.md b/docs/build-plan.md index 55ad0b6..52f7a53 100644 --- a/docs/build-plan.md +++ b/docs/build-plan.md @@ -68,14 +68,17 @@ provenance, agent chat) as ideas, and credit in NOTICE as already done. ## Waves -### Wave 0 — Foundation (must finish before Wave 1 UI work) +### Wave 0 — Foundation (must finish before Wave 1) -Two tracks, independent of each other, so both can run at once. +Three tracks. F1 and F3 are independent of each other; F2 should follow F3, or +the two should be built together, because the write path needs the permission +model to call into. | | Task | Why it blocks | |---|---|---| | **F1** | Install the shadcn primitive set: dialog, sheet, drawer, select, dropdown-menu, table, tabs, tooltip, popover, command, form, switch, textarea, label, separator, sonner, avatar, checkbox, radio-group | Every form and table below needs these. Building them ad hoc in parallel guarantees five inconsistent buttons. | -| **F2** | A shared write-path convention in the API: zod schemas derived from the ontology, a mutation helper, consistent error shapes, and activity logging on every mutation | Eight CRUD tasks land at once in Wave 1. Without a settled pattern they will each invent one. | +| **F3** | **RBAC.** A real permission model: capability checks (`deal:write`, `commitment:write`, `contract:sign`, `data:import`, `settings:admin`) resolved from team membership and role, enforced in one place, and used to disable the UI control as well as reject the request — so the button and the 403 cannot disagree. | Today authorization stops at "is a member". Eight CRUD tracks and a bulk-import feature are about to land; without this each invents its own check, and import in particular is a bulk write that must not be available to everyone. | +| **F2** | A shared write-path convention in the API: zod schemas derived from the ontology, a mutation helper, consistent error shapes, automatic activity logging, and capability checks from F3 | Eight CRUD tasks land at once in Wave 1. Without a settled pattern they will each invent one. | ### Wave 1 — Parallel build (up to ~10 tracks) @@ -93,14 +96,20 @@ Backend tracks need only **F2**. Frontend tracks need **F1**. | **A6** | Buzz adapter behind the same notifier interface as Slack | A5 | | **A7** | `pig` CLI with `--json` output, for prime-agent's kernel and for scripts | A2 | +| **A12** | **Capacity tiers.** Add a `government` (sovereign) tier alongside `secure_cloud` and `community_cloud`. A schema change with a migration, plus matching rules: a government requirement must never be satisfied by community capacity, and the tier interacts with the export-control predicate already in `compliance.ts`. | — | +| **A14** | **Import framework.** CSV and Excel first, since both are just tabular: upload, column mapping, a dry-run preview showing what would be created or updated, per-row validation and error reporting, and an idempotent commit keyed on a chosen column. Gated on `data:import`. | F2, F3 | +| **A15** | **Notion import.** Notion databases are tables with typed properties, so this maps onto A14's mapping step rather than being a separate importer. OAuth, database picker, property→field mapping. | A14 | +| **A16** | **Google Sheets import.** Same shape as A15: OAuth, sheet and range picker, then A14's mapping. | A14 | + **Frontend** | | Task | Depends on | |---|---|---| | **A8** | Data table (sort, filter, paginate, column visibility) + ⌘K command palette | F1 | | **A9** | `SourcedValue` / provenance display, wired to `facts`; fact review queue (approve/dismiss proposals) | F1 | -| **A10** | Contracts UI — the schema is rich and nothing surfaces it | F1 | +| **A10** | **Contracts UI.** The schema is the richest part of PIG and nothing surfaces it. Build it out fully and plausibly: MSA / DPA / SLA / order form / capacity commitment, the parent-child hierarchy with order-form-beats-MSA precedence, negotiated SLA terms (uptime target, measurement unit and window, remedy type including fee abatement with its trigger duration, credit tiers and cap, claim deadline, credit expiry, spare-pool scope, maintenance classes, reasonable-endeavours carve-out, RCA hours), obligations with renewal alarms, and take-or-pay / prepay / termination-tier fields that make a backlog figure meaningful. Treat the field set as a first draft to be corrected by anyone who negotiates these for a living. | F1, F2 | | **A11** | Record create/edit sheets for accounts, contacts, demand deals, supply deals | F1, F2 | +| **A13** | **Admin settings.** Platform-admin-only page: Piggy's model (defaulting to a Nemotron model on Prime Intellect inference), the inference endpoint, invite management, team and role administration, Prime Intellect API key, and sync toggles. | F1, F3 | ### Wave 2 — Integration (needs Wave 1) @@ -127,3 +136,24 @@ Wave 0; it touches no UI and no shared API conventions. **A3 (auth seam) should land before any second deployment exists.** It is cheap now and expensive once an on-prem install has to keep working. + +**F3 (RBAC) gates the import work.** Bulk import is the single most dangerous +write in the product — one bad mapping can rewrite thousands of records — so it +must not ship before there is a real answer to who may run it. + +**A12 (capacity tiers) is a schema change**, so it is cheaper before the tables +carry real data than after. + +--- + +## Open questions + +- **Where is the Prime Intellect API token?** Searched cloud-1's `~/.prime`, + `~/.config/prime`, `/opt` and `/etc` and found nothing. Needed for A13 (model + selection against PI inference) and to switch inventory sync on. Scope it to + `Availability → Read` for sync; model access needs its own key. +- **Which Nemotron model** should Piggy default to, and is it served from PI + inference or from your own spark-1 box? The adapter should treat the endpoint + as configuration either way. +- **Who may import?** Suggested default: team leads and platform admins only, + never a plain member. Easy to loosen, unpleasant to tighten after the fact.