@primitive.ai/prim 0.1.0-alpha.52 → 0.1.0-alpha.54

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
@@ -31,8 +31,8 @@ npx @primitive.ai/prim
31
31
  In commands such as `npx --yes @primitive.ai/prim@latest ...`, the first `--yes`
32
32
  belongs to **npm**: it skips npm's package-install confirmation. It does not approve a
33
33
  Primitive action. Prim's own global `--yes` comes after the package name, for example
34
- `npx --yes @primitive.ai/prim@latest --yes decisions create ...`, and applies only to
35
- that Prim invocation.
34
+ `npx --yes @primitive.ai/prim@latest --yes decisions create ... --attribution user`,
35
+ and applies only to that Prim invocation.
36
36
 
37
37
  ## Quick Start
38
38
 
@@ -215,7 +215,7 @@ prim decisions show <id> # Drill into one decision
215
215
  prim decisions cascade <id> # Blast radius of a decision
216
216
  prim decisions check --files <…> # Active decisions referencing files (warn-only)
217
217
  prim decisions confirm <id> # Answer a rationale-confirmation prompt
218
- prim decisions create --intent <…> # Author a decision directly (flags-only)
218
+ prim decisions create --intent <…> --attribution <user|agent> # Record with explicit origin
219
219
  prim decisions link <child> --on <parent> # Relate: <child> depends on <parent>
220
220
  prim decisions unlink <child> --on <parent> # Remove that dependency
221
221
  ```
@@ -226,12 +226,19 @@ JSON; human-readable status goes to STDERR.
226
226
  When passive capture is inactive in the current repo, an approved one-time create is:
227
227
 
228
228
  ```bash
229
- npx --yes @primitive.ai/prim@latest --yes decisions create --intent "…"
229
+ npx --yes @primitive.ai/prim@latest --yes decisions create --intent "…" --attribution user
230
230
  ```
231
231
 
232
232
  Here npm's first `--yes` only permits package resolution; Prim's second `--yes`
233
233
  confirms this create. It does not enable the repo or authorize a later create.
234
234
 
235
+ Every create requires `--attribution user|agent`. Use `user` only when the person
236
+ directly stated, selected, or confirmed the exact recorded choice. Use `agent` when
237
+ the agent introduced that exact choice while pursuing a broader request. A broad task
238
+ prompt or permission to implement does not make the resulting agent choice a user
239
+ Decision. If the origin is ambiguous, confirm the exact choice with the person before
240
+ creating it; do not guess.
241
+
235
242
  `link` / `unlink` curate the dependency edges the automatic linker would otherwise
236
243
  own — `<child>` depends on `<parent>`. Both are idempotent and refuse any link that
237
244
  would create a cycle (exit 2); an unresolved id exits 4.
package/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: prim
3
- description: Use the prim CLI for Primitive’s decision graph. MUST INVOKE before finishing any coding, planning, specification, or review task where the user or agent chose between plausible approaches or established or changed a lasting goal, priority, constraint, invariant, default, commitment, tradeoff, exception, or shared instruction—even when Primitive was not mentioned. Also invoke for Primitive setup, reading decisions, conflict gates, reconcile, rationale confirmations, linking, and team presence. SKIP routine implementation that merely follows an existing decision, temporary tactics, and unrelated uses of “decision.”
3
+ description: Use the prim CLI for Primitive’s decision graph. MUST INVOKE before finishing any coding, planning, specification, or review task where the user or agent chose between plausible approaches or established or changed a lasting goal, priority, constraint, invariant, default, commitment, tradeoff, exception, or shared instruction—even when Primitive was not mentioned. Also invoke for Primitive setup, reading decisions, conflict gates, reconcile, rationale confirmations, linking, and team presence. SKIP — do not invoke even to check — when the task shows no fork that should guide future work, for example temporary tactics (a change that is explicitly temporary or to-be-reverted); routine implementation that merely follows an existing decision or a convention already visible in the code or repo instructions; or the word “decision” merely naming code, data, or UI. Such signals need no graph lookup to rule out.
4
4
  ---
5
5
 
6
6
  # Working with the prim CLI
@@ -80,7 +80,7 @@ Confirmations are author-targeted and rare by design; answering keeps the graph'
80
80
 
81
81
  Capture is automatic for low-level choices made while coding in an active repo. Use the deliberate CLI path for higher-order decisions that emerge in conversation: goals, priorities, principles, invariants, constraints, defaults, commitments, durable tradeoffs, and exceptions.
82
82
 
83
- A decision worth deliberately recording is a genuine **fork in the road**: the user or agent encountered multiple plausible paths, selected one, and that selection should inform future work. Record the chosen behavior, direction, constraint, or tradeoff—not routine implementation needed to finish the task or follow an existing convention. A teammate working elsewhere should benefit from knowing it.
83
+ A decision worth deliberately recording is a genuine **fork in the road**: the user or agent encountered multiple plausible paths, selected one, and that selection should inform future work. Record the chosen behavior, direction, constraint, or tradeoff—not routine implementation needed to finish the task or follow an existing convention. Small design choices made in-flight while implementing—such as edge-case handling, parameter defaults, retry or timeout values, log levels, naming, or the shape of an internal data structure—are implementation details even when you chose between alternatives: never deliberately record them or spend a rationale question on them; passive capture already covers coding activity. A teammate working elsewhere should benefit from knowing it.
84
84
 
85
85
  ### Ground the rationale in real sources
86
86
 
@@ -91,8 +91,10 @@ Record only rationale supported by those sources. Do not mistake the implementat
91
91
  For proactively identified decisions in an active repo, let confidence in the rationale determine the interaction:
92
92
 
93
93
  - **Clear and well-supported** — record the decision and rationale silently at the natural task boundary.
94
- - **Plausible but uncertain** — at the task boundary, state the proposed rationale and ask for lightweight confirmation: “I understand the reason for choosing X to be Y. Is that right?” Record after confirmation or correction.
95
- - **No supported rationale** — at the task boundary, ask one focused question: “What made you choose X over the other path?” Record after the answer.
94
+ - **Plausible but uncertain** — at the task boundary, state the proposed rationale and ask for lightweight confirmation: “I understand the reason for choosing X to be Y. Is that right?” Record in the same turn with the rationale omitted; add it once confirmed or corrected.
95
+ - **No supported rationale** — at the task boundary, ask one focused question: “What made you choose X over the other path?” Record in the same turn with the rationale omitted; add it when the answer arrives.
96
+
97
+ In both cases the question is a courtesy, not a gate: never make the record wait on an answer, and never fabricate a rationale to fill the gap. An unanswered question with no record is the only wrong outcome.
96
98
 
97
99
  These questions share the interruption budget below; never ask separate questions for the decision and its rationale. If both are uncertain, combine them into one concise prompt. An explicit request to “add this decision to Primitive” still records immediately with the information supplied—do not delay it to demand rationale.
98
100
 
@@ -109,8 +111,10 @@ an explicit local `prim.active=false` is always inactive. Every
109
111
  rationale, then wait for approval before creating it. A previous approval never
110
112
  carries forward to another Decision.
111
113
  - After approval, pass Prim's global `--yes` for that invocation:
112
- `npx --yes @primitive.ai/prim --yes decisions create ...`. The first `--yes` is
113
- npm's package-install flag; the second is Prim's one-time confirmation.
114
+ `npx --yes @primitive.ai/prim --yes decisions create ... --attribution user`.
115
+ The person's approval of the exact proposed choice is user ratification. The
116
+ first `--yes` is npm's package-install flag; the second is Prim's one-time
117
+ confirmation.
114
118
  - Do not run `prim enable` merely to bypass this boundary or infer permission to
115
119
  activate the repo. Activation requires a separate user request (a requested
116
120
  `prim setup` counts because setup explicitly activates its current repo). A
@@ -124,7 +128,7 @@ When the user asks to record a decision—for example, “add this decision to P
124
128
 
125
129
  ### Clear decisions: record without interrupting
126
130
 
127
- When the user clearly makes a durable fork-in-the-road decision without explicitly asking to record it, record it at the next natural task boundary without asking a redundant confirmation question **when passive capture is active**. In an inactive repo, present it and obtain the per-create approval above. Preserve the user's meaning and stated rationale; do not strengthen, broaden, or embellish it. Prefer the governing position over the implementation activity that revealed it.
131
+ When the user clearly makes a durable fork-in-the-road decision without explicitly asking to record it, record it at the next natural task boundary without asking a redundant confirmation question **when passive capture is active**. An explicit ratification of a direction—“agreed,” “ship it that way,” or any equivalent affirmation—is such a decision even when the ratified option was your own proposal: the ratification is the approval, so record it and do not ask whether to record. That rule is general: in an active repository, never ask permission to record — the only question the budget permits is the single rationale question, and only when no rationale was stated. In an inactive repo, present it and obtain the per-create approval above. Preserve the user's meaning and stated rationale; do not strengthen, broaden, or embellish it. Prefer the governing position over the implementation activity that revealed it.
128
132
 
129
133
  Examples that qualify:
130
134
 
@@ -166,16 +170,18 @@ npx --yes @primitive.ai/prim decisions recent --limit 20
166
170
  If an equivalent decision is already present, do not create or suggest it again. After this duplicate check—or after the user confirms an onboarding proposal—author the decision directly. If the repo is inactive, that confirmation authorizes Prim's `--yes` only for the approved create:
167
171
 
168
172
  ```
169
- npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
173
+ npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --attribution user --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
170
174
  ```
171
175
 
172
176
  Inactive-repo form after approval:
173
177
 
174
178
  ```
175
- npx --yes @primitive.ai/prim --yes decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
179
+ npx --yes @primitive.ai/prim --yes decisions create --intent "Adopt prosemirror-collab over Yjs" --attribution user --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
176
180
  ```
177
181
 
178
- 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). Omit `--files` for broad directions that should not immediately participate in file-based Conflict Gates. STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`.
182
+ Both `--intent` and `--attribution` are required. Set `--attribution user` only when the person directly stated, selected, or confirmed the exact recorded choice. Set `--attribution agent` when you introduced that exact choice while pursuing a broader request. A broad task prompt, implementation permission, or assignment of responsibility does not turn your implementation choice into a user Decision. If the origin is ambiguous, ask the person to confirm the exact choice before creating it; after confirmation, use `user`. Never guess attribution.
183
+
184
+ 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). Omit `--files` for broad directions that should not immediately participate in file-based Conflict Gates. STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` — pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`.
179
185
 
180
186
  ### Inferred decisions: finish first, then optionally ask once
181
187
 
package/dist/index.js CHANGED
@@ -2309,6 +2309,9 @@ function registerDaemonCommands(program2) {
2309
2309
  });
2310
2310
  }
2311
2311
 
2312
+ // src/commands/decisions.ts
2313
+ import { Option } from "commander";
2314
+
2312
2315
  // src/decisions/cascade-renderer.ts
2313
2316
  var DEPENDENTS_INLINE_LIMIT = 5;
2314
2317
  var KNOWLEDGE_INLINE_LIMIT = 4;
@@ -2764,6 +2767,7 @@ var defaultDeps4 = { getClient };
2764
2767
  function toRequestBody(request) {
2765
2768
  const candidate = {
2766
2769
  intent: request.intent,
2770
+ attribution: request.attribution,
2767
2771
  kind: request.kind,
2768
2772
  rationale: request.rationale,
2769
2773
  area: request.area,
@@ -3103,7 +3107,12 @@ function registerDecisionsCommands(program2) {
3103
3107
  throw err;
3104
3108
  }
3105
3109
  });
3106
- decisions.command("create").description("Author a decision directly \u2014 the deliberate manual path around automatic capture").requiredOption("--intent <text>", "What was decided (required)").option("--kind <kind>", "change | exploration | task_execution | unclear (default change)").option("--rationale <text>", "Why the decision was made").option(
3110
+ decisions.command("create").description("Record a decision directly with its explicit user or agent origin").requiredOption("--intent <text>", "What was decided (required)").addOption(
3111
+ new Option(
3112
+ "--attribution <origin>",
3113
+ "Who originated the exact choice: user | agent (required)"
3114
+ ).choices(["user", "agent"]).makeOptionMandatory()
3115
+ ).option("--kind <kind>", "change | exploration | task_execution | unclear (default change)").option("--rationale <text>", "Why the decision was made").option(
3107
3116
  "--area <area>",
3108
3117
  "Functional area (auth, data, infra, ui, api, billing, mobile, docs, testing)"
3109
3118
  ).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(
@@ -3124,6 +3133,7 @@ function registerDecisionsCommands(program2) {
3124
3133
  }
3125
3134
  const request = {
3126
3135
  intent: opts.intent,
3136
+ attribution: opts.attribution,
3127
3137
  kind: opts.kind,
3128
3138
  rationale: opts.rationale,
3129
3139
  area: opts.area,
@@ -3874,7 +3884,7 @@ import { execFileSync } from "child_process";
3874
3884
  import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
3875
3885
  import { homedir as homedir6 } from "os";
3876
3886
  import { dirname as dirname4, join as join6, resolve as resolve2 } from "path";
3877
- import { Option } from "commander";
3887
+ import { Option as Option2 } from "commander";
3878
3888
  var PRE_COMMIT = { hookName: "pre-commit", binName: "prim-pre-commit" };
3879
3889
  var POST_COMMIT = { hookName: "post-commit", binName: "prim-post-commit" };
3880
3890
  var HOOKS = [PRE_COMMIT, POST_COMMIT];
@@ -4167,12 +4177,12 @@ function registerHooksCommands(program2) {
4167
4177
  hooks.command("install").description(
4168
4178
  "Install the prim git hooks \u2014 pre-commit + post-commit (auto-detects Husky; use --target to override)"
4169
4179
  ).addOption(
4170
- new Option("--target <where>", "install destination; bypasses Husky detection").choices([
4180
+ new Option2("--target <where>", "install destination; bypasses Husky detection").choices([
4171
4181
  "husky",
4172
4182
  "git-hooks"
4173
4183
  ])
4174
4184
  ).addOption(
4175
- new Option(
4185
+ new Option2(
4176
4186
  "--scope <scope>",
4177
4187
  "project (default, this repo) or user (a global core.hooksPath capturing every repo)"
4178
4188
  ).choices(["project", "user"])
@@ -4212,7 +4222,7 @@ function registerHooksCommands(program2) {
4212
4222
  hooks.command("uninstall").description(
4213
4223
  "Remove the prim git hooks (.git/hooks, or the global core.hooksPath with --scope user)"
4214
4224
  ).addOption(
4215
- new Option(
4225
+ new Option2(
4216
4226
  "--scope <scope>",
4217
4227
  "project (default, this repo) or user (global core.hooksPath)"
4218
4228
  ).choices(["project", "user"])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.52",
3
+ "version": "0.1.0-alpha.54",
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",