cf3117e458
CI / verify (push) Successful in 1m33s
The token was found on cloud-1 after all, in a Claude memory note. Verifying its claims against the live API turned up a defect in code already shipped. **prices.onDemand is the total for the whole node, not per-GPU.** Confirmed: datacrunch lists 1x A100 at 1.79 and 2x A100 at 3.58, and gpuMemory scales the same way (640 for 8x 80GB). packages/prime/src/map.ts stores both as if they were per-GPU, so an 8-GPU node reads eight times too expensive. It would have silently poisoned inventory search, the max-price filter and every margin comparison against bought capacity — and nobody would have noticed, because the numbers still look plausible. Logged rather than fixed, per the instruction to hold; it needs a regression test built from the real 1x/2x pair. **Inference is a different host.** api.primeintellect.ai is compute and pods; inference is api.pinference.ai/api/v1, OpenAI-compatible. PIG's config knows only the first, so A4 and A13 need both. **Piggy's default model** is nvidia/nemotron-3-nano-30b-a3b, and the important detail is that it is a hybrid reasoning model which thinks aloud by default and truncates under a tight max_tokens. `reasoning_effort: "none"` gives ~1s terse output for tool use and extraction, which is what Piggy does nearly all of the time. One claim did NOT reproduce: the note warns of Cloudflare 403ing non-browser user-agents, but PIG's own UA and curl's both returned 200. Recorded as history in case a 403 ever appears. Also logged: the key is a broad, never-expiring credential sitting in plaintext in a memory markdown file. PIG's sync should hold a separate narrower key scoped to availability reads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
189 lines
11 KiB
Markdown
189 lines
11 KiB
Markdown
# Build plan
|
||
|
||
Where PIG stands, what remains, and what can be built in parallel.
|
||
|
||
Written so that work can be handed to several people (or several agents) at
|
||
once without them colliding. The dependency edges are real — the waves are not
|
||
decoration.
|
||
|
||
---
|
||
|
||
## What already works
|
||
|
||
Live at primeintellectgrowth.com. ~10.7k lines, 39 tests, green CI.
|
||
|
||
- The ontology and margin engine, with the `allocations` join at the centre
|
||
- Both pipelines, capacity availability / matching / idle alerts
|
||
- Auth: sign in, register with an invite code, profile creation, sign out
|
||
- Theming (7 accents, light/dark, server-persisted), responsive to 393px
|
||
- MCP server (9 tools), Prime Intellect API client, demo dataset
|
||
- Docker + compose + Caddy, deploy script, CI on Gitea Actions
|
||
|
||
## The two gaps that block a demo
|
||
|
||
1. **No write path for allocations or commitments.** The core table can only be
|
||
populated by seed. A visitor can look at the demo book but cannot enter a
|
||
deal of their own.
|
||
2. **No way to mint an API key**, so the MCP server is unreachable in
|
||
production despite being the headline feature.
|
||
|
||
Everything else is additive. These two are load-bearing.
|
||
|
||
---
|
||
|
||
## On borrowing from Comp AI CRM
|
||
|
||
Their repo (MIT) was cloned and inventoried. Findings that shaped this plan:
|
||
|
||
**Their component library is far deeper — 68 primitives to our 9.** Notably
|
||
`data-table`, `command`, `sheet`, `drawer`, `combobox`, `chart`,
|
||
`sortable-list`, and a set of agent-chat components (`message`, `reasoning`,
|
||
`thinking-indicator`, `thread-message`, `suggestion`) that map almost exactly
|
||
onto what Piggy will need.
|
||
|
||
**`SourcedValue` / `Provenance` is worth adopting outright.** A dotted underline
|
||
on any agent-derived value, with a tooltip carrying the claim, the reasons, when
|
||
it was observed, and the source URL. PIG already has that data — `facts` holds
|
||
score, band, evidence and `sourceUrl` — and nothing currently surfaces it.
|
||
|
||
**But we are ahead of them on mobile, not behind.** Measured across both repos:
|
||
|
||
| | Comp AI | PIG |
|
||
|---|---|---|
|
||
| tsx files | 329 | 16 |
|
||
| Responsive utilities | 211 (0.6/file) | 58 (3.6/file) |
|
||
| Safe-area handling | 0 | 5 |
|
||
| Mobile nav | none found | bottom tab bar |
|
||
|
||
They have no drawer or sheet used for navigation, no `viewport-fit`, and no
|
||
safe-area insets anywhere. Their app is effectively desktop-only. So the plan
|
||
below adds *depth* from them, not mobile behaviour.
|
||
|
||
**Do not copy their component files.** Most are shadcn/ui originals, which are
|
||
MIT and designed to be installed from upstream — take them from source, where
|
||
they are canonical and current. Borrow their *compositions* (data-table,
|
||
provenance, agent chat) as ideas, and credit in NOTICE as already done.
|
||
|
||
---
|
||
|
||
## Waves
|
||
|
||
### Wave 0 — Foundation (must finish before Wave 1)
|
||
|
||
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. |
|
||
| **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)
|
||
|
||
Backend tracks need only **F2**. Frontend tracks need **F1**.
|
||
|
||
**Backend**
|
||
|
||
| | Task | Depends on |
|
||
|---|---|---|
|
||
| **A1** | Allocations + capacity commitments write API, with the availability invariant enforced server-side (cannot allocate beyond the shape) | F2 |
|
||
| **A2** | API keys: generate, list, revoke. Show the plaintext once. | F2 |
|
||
| **A3** | Auth-provider seam — extract Supabase behind an interface so OIDC is a second implementation | — |
|
||
| **A4** | **Piggy**: worker draining `agent_tasks`, `AgentProvider` interface, prime-agent adapter using `defineTool` with PIG tools only (no bash, no filesystem), writing to `facts` | — |
|
||
| **A5** | Slack adapter: link channels to accounts, post stage changes and idle alerts, slash command for capacity match | F2 |
|
||
| **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 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)
|
||
|
||
| | Task | Depends on |
|
||
|---|---|---|
|
||
| **B1** | Allocation UI: allocate capacity to a deal from the matcher, place and release holds | A1, A8, A11 |
|
||
| **B2** | Piggy chat UI: streaming, reasoning, tool calls, in-record ask | A4, F1 |
|
||
| **B3** | Settings for Slack/Buzz connections and channel links | A5, A6, F1 |
|
||
| **B4** | End-to-end tests over the critical paths: register → create a commitment → allocate → see margin move | B1 |
|
||
|
||
---
|
||
|
||
## Sequencing advice
|
||
|
||
Build **F1 and F2 first and alone.** They are small and they are the interface
|
||
every other track codes against. Starting Wave 1 before they settle is how
|
||
parallel work turns into merge conflict.
|
||
|
||
**A1 and A2 are the highest value in Wave 1** — they close the two gaps that
|
||
block a demo. If only two things get done, do those.
|
||
|
||
**A4 (Piggy) is fully independent** and can start immediately alongside
|
||
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.
|
||
|
||
---
|
||
|
||
## Prime Intellect API — verified facts
|
||
|
||
Confirmed against the live API, not assumed. These change how A4, A13 and the
|
||
inventory sync must be built.
|
||
|
||
**Two different hosts.** `api.primeintellect.ai` is the compute/pods API
|
||
(availability, pods, billing). Inference is `api.pinference.ai/api/v1`, which
|
||
is OpenAI-compatible (`/chat/completions`, `/models`, and an Anthropic-style
|
||
`/messages`). PIG's config needs both, separately — `PRIME_API_BASE` today
|
||
points only at the first.
|
||
|
||
**⚠️ `prices.onDemand` is the TOTAL FOR THE NODE, not per-GPU.** Verified:
|
||
datacrunch lists 1× A100 at 1.79 and 2× A100 at 3.58. `gpuMemory` is likewise
|
||
a node total (640 for 8× 80GB). The current mapper stores both as if per-GPU,
|
||
so an 8-GPU node reads eight times too expensive — see the logged bug. Divide
|
||
by `gpuCount` at the boundary and keep the node total alongside it.
|
||
|
||
**Piggy's default model:** `nvidia/nemotron-3-nano-30b-a3b` ($0.05/$0.20 per
|
||
Mtok). It is a *hybrid reasoning* model that thinks aloud by default and will
|
||
ramble or truncate under a tight `max_tokens`. Pass **`reasoning_effort:
|
||
"none"`** for tool use, routing, extraction and classification — roughly one
|
||
second, terse output. Leave reasoning on only for genuine math or logic, where
|
||
it arrives in a separate `reasoning_content` field while `content` stays clean.
|
||
|
||
**Billing** is pay-as-you-go against a shared balance, not a per-model
|
||
whitelist. Check with `GET /api/v1/billing/wallet`.
|
||
|
||
**The user-agent concern did not reproduce** — both a browser UA and PIG's own
|
||
returned 200. Worth remembering it was once an issue if a 403 ever appears.
|
||
|
||
## Open questions
|
||
|
||
- **Which inference host for on-prem?** Piggy's endpoint must be configuration,
|
||
since a customer deployment should reach their own inference rather than
|
||
Prime Intellect's. The model *name* should be admin-selectable (A13); the
|
||
*host* belongs in environment configuration.
|
||
- **Who may import?** Suggested default: team leads and platform admins only,
|
||
never a plain member. Easy to loosen, unpleasant to tighten after the fact.
|
||
- **Which key does PIG get?** The existing key is broad and never expires. PIG's
|
||
sync should hold a separate, narrower one — see the logged task.
|