@primitive.ai/prim 0.1.0-alpha.35 → 0.1.0-alpha.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,13 +1,19 @@
1
1
  # @primitive.ai/prim
2
2
 
3
3
  The official CLI for [Primitive](https://getprimitive.ai)'s **decision graph**. It
4
- passively captures the decisions your team makes while coding, gates edits that
5
- conflict with prior team decisions, and reports team presence from the command
6
- line and via session + git hooks.
4
+ passively captures the decisions your team makes while coding and reports team
5
+ presence from the command line and via session + git hooks.
7
6
 
8
7
  > [!WARNING]
9
8
  > This project is in **alpha**. Commands and APIs may change between releases.
10
9
 
10
+ > [!NOTE]
11
+ > **Conflict Gates** check each edit against the decision graph and surface any
12
+ > load-bearing decision it conflicts with; their **Enforcement** tier blocks or pauses
13
+ > a conflicting edit until you reconcile and retry. Conflict Gates are **not currently
14
+ > enabled** — automatic decision capture runs regardless. To enable them for your team,
15
+ > contact **support@getprimitive.ai**.
16
+
11
17
  ## Installation
12
18
 
13
19
  Requires Node.js 20+.
@@ -37,7 +43,7 @@ Or run the steps individually:
37
43
  # 1. Authenticate via browser (WorkOS OAuth)
38
44
  prim auth login
39
45
 
40
- # 2. Wire the session hooks (decision capture + conflict gate + presence)
46
+ # 2. Wire the session hooks (decision capture + presence)
41
47
  prim claude install # or: prim codex install / prim hermes install
42
48
 
43
49
  # 3. Start the companion daemon (latency + team presence)
@@ -94,7 +100,7 @@ prim auth status # Check authentication status
94
100
  ### Session integration
95
101
 
96
102
  Wires the agent's session hooks so the decisions you make are captured into the
97
- graph, conflicting edits are gated, and presence is reported. Each hook
103
+ graph, and presence is reported. Each hook
98
104
  self-resolves the CLI at run time (PATH, then a local install, then
99
105
  `npx --yes @latest`), so it keeps working with no global install.
100
106
 
@@ -147,9 +153,12 @@ would create a cycle (exit 2); an unresolved id exits 4.
147
153
  ### Reconcile
148
154
 
149
155
  ```bash
150
- prim reconcile <id> # Mint a single-use bypass for a decision a gate flagged
156
+ prim reconcile <id> # Mint a single-use bypass for a decision Conflict Gates flagged
151
157
  ```
152
158
 
159
+ Part of Conflict Gates **Enforcement**, which is not currently enabled (see the note
160
+ at the top). Contact support@getprimitive.ai to enable it.
161
+
153
162
  ### Hooks
154
163
 
155
164
  ```bash
package/SKILL.md CHANGED
@@ -9,9 +9,9 @@ description: Use the prim CLI for Primitive's decision graph — passive decisio
9
9
 
10
10
  ## Mental model
11
11
 
12
- As your team codes, prim passively captures the **decisions** you make -- which library, which pattern, which config value -- into a queryable graph, and links them: a decision can depend on earlier decisions (auto-linked from shared files, or related by hand — see *Relate decisions*) and reference the files it touched. When a later change conflicts with a load-bearing prior decision, prim **gates** the edit and surfaces the decision for review.
12
+ As your team codes, prim passively captures the **decisions** you make -- which library, which pattern, which config value -- into a queryable graph, and links them: a decision can depend on earlier decisions (auto-linked from shared files, or related by hand — see *Relate decisions*) and reference the files it touched. **Conflict Gates** can check a later change against that graph and surface any load-bearing decision it conflicts with; with **Enforcement**, prim blocks the edit until you reconcile the decision and retry. Conflict Gates are **not currently enabled** — capture runs regardless. To enable them for your team, contact support@getprimitive.ai.
13
13
 
14
- You never invoke capture. It runs automatically through the session hooks installed by `npx --yes @primitive.ai/prim claude install` (Claude Code), `npx --yes @primitive.ai/prim codex install` (Codex), or `npx --yes @primitive.ai/prim hermes install` (Hermes). Your job is to **respond** to the gate, **read** the graph before load-bearing edits, and **answer** the occasional rationale confirmation.
14
+ You never invoke capture. It runs automatically through the session hooks installed by `npx --yes @primitive.ai/prim claude install` (Claude Code), `npx --yes @primitive.ai/prim codex install` (Codex), or `npx --yes @primitive.ai/prim hermes install` (Hermes). Your job is to **read** the graph before load-bearing edits and **answer** the occasional rationale confirmation. (Responding to Conflict Gates applies only once Enforcement is enabled — see below.)
15
15
 
16
16
  ## Auth
17
17
 
@@ -29,17 +29,19 @@ The CLI auto-refreshes a still-valid session from the stored refresh token (proa
29
29
 
30
30
  1. Every command accepts `--help`. When unsure of flags, run `npx --yes @primitive.ai/prim <cmd> --help` rather than guessing.
31
31
  2. The CLI prints API errors as one-liners to stderr and exits non-zero. Treat any non-zero exit as actionable. If auth-related, re-check `auth status`.
32
- 3. `<idOrShortId>` arguments accept either a full decision ID or the short ID shown in feeds and gate reasons.
32
+ 3. `<idOrShortId>` arguments accept either a full decision ID or the short ID shown in feeds (and gate reasons, when Conflict Gates are enabled).
33
33
 
34
- ## Heed the conflict gate
34
+ ## Conflict Gates & Enforcement (not currently enabled)
35
35
 
36
- Before an edit (Claude Code: Edit/Write/MultiEdit; Codex: apply_patch; Hermes: write_file/patch) a PreToolUse hook scores the target file against the graph:
36
+ **Conflict Gates** check each edit against the decision graph before it lands and surface any load-bearing decision it conflicts with. Their **Enforcement** tier goes further -- a conflicting edit is blocked (or paused for confirmation) until you reconcile the decision and retry. **Conflict Gates are not currently enabled** — automatic decision capture (above) runs regardless. To enable Conflict Gates and Enforcement for your team, contact support@getprimitive.ai.
37
+
38
+ When Enforcement is enabled, before an edit (Claude Code: Edit/Write/MultiEdit; Codex: apply_patch; Hermes: write_file/patch) a PreToolUse hook scores the target file against the graph:
37
39
 
38
40
  - **deny** -- the edit is blocked: it conflicts with a load-bearing prior decision. Don't fight it. Read the reason line; it names the decision id. If you genuinely intend to override that decision, run `npx --yes @primitive.ai/prim reconcile dec_<shortId>`, then retry the edit once. Otherwise choose an approach that respects the decision.
39
41
  - **warn / additional context** -- the edit proceeds, but a relevant prior decision is surfaced. Read it. On Codex a would-be `ask` is delivered as allow-plus-context (Codex can't pause mid-tool), so that context is your only signal -- read it before continuing. Hermes has no soft-confirm tier, so a would-be `ask` arrives as a **deny** carrying the same reconcile directive: reconcile and retry, or set `PRIM_HOOK_MODE=warn` to downgrade it to context-only.
40
42
  - **"decision check skipped / not verified" or "... partial / truncated"** -- the check could not fully run. Treat constraints as UNKNOWN, not clear; never read silence as approval.
41
43
 
42
- The gate fail-opens on its *own* infrastructure errors (no daemon, network blip, org-unbound token) -- a setup problem never blocks your edit. That is exactly why an "unavailable" note matters: it is the honest signal that the check, not your edit, is what failed.
44
+ When enabled, the gate fail-opens on its *own* infrastructure errors (no daemon, network blip, org-unbound token) -- a setup problem would not block your edit. That is why an "unavailable" note would matter: it is the honest signal that the check, not your edit, is what failed.
43
45
 
44
46
  ## Read the graph before large or load-bearing edits
45
47
 
@@ -49,6 +51,8 @@ The gate fail-opens on its *own* infrastructure errors (no daemon, network blip,
49
51
 
50
52
  ## Reconcile and the verdict footer
51
53
 
54
+ Reconcile and the verdict footer are part of Conflict Gates **Enforcement**, which is **not currently enabled** (contact support@getprimitive.ai to turn it on); the `reconcile` command stays available regardless. When Enforcement is on:
55
+
52
56
  `npx --yes @primitive.ai/prim reconcile <idOrShortId>` mints a single-use bypass for the named decision -- it prints `[prim] reconcile bypass issued for dec_<short> (expires in ...)` to STDERR, with the bypass JSON on STDOUT. Your *next* edit to the governed file then goes through, and on that edit prim prints a verdict footer to STDERR -- confirmation the override was recorded, not silently dropped:
53
57
 
54
58
  ```
@@ -75,7 +79,7 @@ Capture is automatic for the decisions you *make while coding*. When the user in
75
79
  npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
76
80
  ```
77
81
 
78
- Only `--intent` is required. Optional: `--kind` (change|exploration|task_execution|unclear, default change), `--rationale`, `--area`, `--decided`, `--alternatives` (comma-separated), `--confidence` (high|medium|low, default high), `--reversibility` (high|low, default high), and `--files` (comma-separated repo-relative paths the decision governs — pass these to make the conflict gate fire on later edits to those files, same path form as `decisions check`). STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` — pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`. Author on the user's behalf only when they ask for a decision to be recorded; don't narrate your own routine edits into the graph (the hooks already do that).
82
+ Only `--intent` is required. Optional: `--kind` (change|exploration|task_execution|unclear, default change), `--rationale`, `--area`, `--decided`, `--alternatives` (comma-separated), `--confidence` (high|medium|low, default high), `--reversibility` (high|low, default high), and `--files` (comma-separated repo-relative paths the decision governs — these are the files Conflict Gates would check on later edits, same path form as `decisions check`; Conflict Gates are not currently enabled). STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` — pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`. Author on the user's behalf only when they ask for a decision to be recorded; don't narrate your own routine edits into the graph (the hooks already do that).
79
83
 
80
84
  ## Relate decisions (link / unlink)
81
85
 
@@ -116,14 +120,14 @@ npx --yes @primitive.ai/prim hooks uninstall
116
120
 
117
121
  Under `CI=1` (or with `--non-interactive`), `hooks install` fails fast in a Husky repo unless `--yes` or `--target` is set; the error names both escapes. `hooks uninstall` only removes the `.git/hooks` copies — if a hook was installed into `.husky/`, remove the prim block from that file manually. To suppress the hooks for one commit, use `git commit --no-verify`.
118
122
 
119
- These git hooks are separate from the **session hooks** (`claude install` / `codex install` / `hermes install`) that drive in-session capture and the conflict gate.
123
+ These git hooks are separate from the **session hooks** (`claude install` / `codex install` / `hermes install`) that drive in-session capture (and Conflict Gates, when enabled).
120
124
 
121
125
  ## Output formats
122
126
 
123
127
  The CLI keeps STDOUT machine-readable and STDERR human-readable. The `decisions` and `reconcile` commands **always** emit a single JSON document on STDOUT — no flag needed; pipe straight to `jq`. The `decisions` commands have **no** `--json` flag and reject one; `reconcile` accepts a reserved no-op `--json`. `auth status` and `skill status` default to human-readable STDOUT and take `--json` to switch to JSON.
124
128
 
125
129
  - **STDOUT is machine-readable** — JSON (one document per invocation). `decisions` reads project lean shapes, not raw rows.
126
- - **STDERR is human-readable** — a verdict-first line, plus the gate/verdict-footer/presence notes.
130
+ - **STDERR is human-readable** — a verdict-first line, plus presence notes (and, when Conflict Gates are enabled, the gate/verdict-footer notes).
127
131
  - **Exit code is authoritative** where it carries meaning — `auth status` exits 0 when authenticated; `decisions show`/`cascade`/`confirm` exit non-zero (e.g. 4 not-found) on a missing or unauthorized id.
128
132
 
129
133
  Examples:
@@ -135,12 +139,12 @@ Examples:
135
139
 
136
140
  ## Pitfalls
137
141
 
138
- - **An "unavailable" / "not verified" gate or check is not an all-clear.** Treat constraints as UNKNOWN and proceed deliberately; never read the silence as approval.
139
- - **A `deny` means a real prior decision conflicts.** Reconcile only when you genuinely intend to override it; otherwise pick an approach that respects it.
142
+ - **An "unavailable" / "not verified" decision check is not an all-clear.** Treat constraints as UNKNOWN and proceed deliberately; never read the silence as approval — the same holds for Conflict Gates once enabled.
143
+ - **When Enforcement is enabled, a `deny` means a real prior decision conflicts.** Reconcile only when you genuinely intend to override it; otherwise pick an approach that respects it.
140
144
  - **Reconcile bypasses are single-use and short-lived.** One bypass clears your *next* edit to the governed file; it is not a standing override.
141
145
  - **Capture of your coding activity is automatic, never manual.** If decisions aren't showing up, check that the session hooks are installed (`claude status` / `codex status` / `hermes status`) and the daemon is running — don't try to inject moves by hand. (Deliberately *authoring* a decision the user asks you to record is a separate, supported path — `decisions create`, above.)
142
146
  - **Don't fabricate rationale on a confirmation.** If you don't know why a decision was made, say so rather than guessing.
143
147
 
144
148
  ## After each task
145
149
 
146
- If the conflict gate denied or warned you, report which decision(s) it named and whether you reconciled. If you read the graph before a load-bearing change, note what you found so the user can verify in the dashboard.
150
+ If Conflict Gates are enabled and one denied or warned you, report which decision(s) it named and whether you reconciled. If you read the graph before a load-bearing change, note what you found so the user can verify in the dashboard.
package/dist/index.js CHANGED
@@ -2105,7 +2105,7 @@ function registerDecisionsCommands(program2) {
2105
2105
  "Functional area (auth, data, infra, ui, api, billing, mobile, docs, testing)"
2106
2106
  ).option("--decided <items>", "Comma-separated option(s) chosen").option("--alternatives <items>", "Comma-separated options considered but rejected").option("--confidence <level>", "high | medium | low (default high)").option("--reversibility <level>", "high | low (default high)").option(
2107
2107
  "--files <paths>",
2108
- "Comma-separated repo-relative paths this decision governs (gates edits to them)"
2108
+ "Comma-separated repo-relative paths this decision governs (the files Conflict Gates would check \u2014 not currently enabled)"
2109
2109
  ).action(async (opts) => {
2110
2110
  const request = {
2111
2111
  intent: opts.intent,
@@ -3265,7 +3265,7 @@ async function performReconcile(idOrShortId, opts = {}) {
3265
3265
  }
3266
3266
  function registerReconcileCommands(program2) {
3267
3267
  program2.command("reconcile <idOrShortId>").description(
3268
- "Issue a single-use bypass for a flagged decision (used by the cooperative reconcile loop)"
3268
+ "Issue a single-use bypass for a decision flagged by Conflict Gates Enforcement (not currently enabled)"
3269
3269
  ).option(
3270
3270
  "--flag <conflictFlagId>",
3271
3271
  "Specific flag id to bind the bypass to (default: the decision's latest unack'd flag)"
@@ -3925,14 +3925,13 @@ function formatWelcome(state) {
3925
3925
  bold(color("Welcome to Primitive", "green")),
3926
3926
  "",
3927
3927
  "Primitive captures the decisions your team makes while coding into a",
3928
- "shared graph \u2014 and flags edits that conflict with earlier ones before",
3929
- "they land.",
3928
+ "shared graph \u2014 automatically, as you work.",
3930
3929
  "",
3931
3930
  bold("How it works"),
3932
3931
  bullet("Capture is automatic \u2014 keep coding; your decisions are recorded for you."),
3933
- bullet("The conflict gate has your back: when an edit conflicts with a"),
3934
- " load-bearing decision, prim surfaces it. Run `prim reconcile dec_<id>` to clear",
3935
- " that decision and retry.",
3932
+ bullet("Conflict Gates (with Enforcement) flag or block edits that conflict"),
3933
+ " with a load-bearing decision \u2014 not currently enabled. Contact",
3934
+ " support@getprimitive.ai to turn them on for your team.",
3936
3935
  bullet('Occasional yes/no prompts confirm the "why" behind a decision \u2014'),
3937
3936
  " answering keeps the graph trustworthy.",
3938
3937
  ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.35",
3
+ "version": "0.1.0-alpha.36",
4
4
  "description": "CLI for Primitive's decision graph — passive decision capture, conflict gate, and team presence",
5
5
  "type": "module",
6
6
  "license": "MIT",