pi-canon 0.2.0 → 0.2.1

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
@@ -16,7 +16,7 @@ Or clone this repo into `~/.pi/agent/extensions/`. Node 22.18 or later, Pi 0.83
16
16
 
17
17
  ## The first article
18
18
 
19
- Every session opens with one orientation line saying how many articles govern the project, or inviting the first one when the store is empty. From there it takes one tool call:
19
+ A session is not greeted: through 0.2.0 every session opened with an orientation line, and a 2x2 experiment with an inert implementation priced that line at more first-pass correctness than the whole tool schema, so 0.2.1 deleted it. The tool description carries the doctrine instead. The first article takes one tool call:
20
20
 
21
21
  ```json
22
22
  { "action": "write",
@@ -80,7 +80,7 @@ pi-canon is an increment on the pattern rather than a replacement for it, and it
80
80
 
81
81
  **A journal**, append-only, one file per event. Agents log whether you want them to or not, and that impulse has to land somewhere that is not the reference page. The instruction on the way in is to record the source as it arrived, names and exact numbers included, because articles distill and only the journal keeps the original.
82
82
 
83
- **A spine**, the addressing convention. An article's address is computed from the asset instead of searched for, and nothing has to be configured for that mapping to hold, which makes the spine a convention rather than a mode. It is also why no part of the package searches: there is nothing to find when the path already decided the address.
83
+ **A spine**, the addressing convention. An article's address is computed from the asset instead of searched for, and nothing has to be configured for that mapping to hold, which makes the spine a convention rather than a mode. It is also why nothing in the RECALL path searches: when a touch already decided the address, there is nothing to find. The `search` action exists for the opposite direction, the agent that wants to ask, and it never runs unasked.
84
84
 
85
85
  **Surfacing**, push rather than pull. When a tool call is detected touching a governed asset, that article's capsule is staged for the session, at most once per article, so nobody has to think to ask. Detection of a path inside a tool call is best effort. Resolution, once a path is in hand, is not.
86
86
 
@@ -100,7 +100,7 @@ Such an article may say so, with `scope: rule` on the write. Nothing filters on
100
100
 
101
101
  ## The tool
102
102
 
103
- One tool, `pi_canon`, four actions.
103
+ One tool, `pi_canon`, five actions: `read`, `write`, `journal`, `map`, and `search`.
104
104
 
105
105
  | action | parameters | does |
106
106
  |---|---|---|
@@ -145,7 +145,7 @@ export default function (pi) {
145
145
  Six keys, and any other throws at registration by name, because everything else is a constant on purpose.
146
146
 
147
147
  - **`root`** places the store. Absolute is used as given, relative joins the project cwd. Default `<project>/.canon`.
148
- - **`surface: false`** silences the orientation line, the per-turn flush, and the settle reminder. The `pi_canon` tool and `/pi-canon` stay registered and working.
148
+ - **`surface: false`** silences the per-turn flush and the settle reminder. The `pi_canon` tool and `/pi-canon` stay registered and working.
149
149
  - **`resurface: false`** returns an article to surfacing at most once per session however long ago it left the window. The default is `true`: an article counts as seen only while it is still in the context the provider receives, so one folded or compacted away surfaces again the next time its asset is touched. A fresh touch is what brings it back, so nothing re-surfaces on its own.
150
150
  - **`retrieval`** ranks the articles that govern no asset, the one category the address spine can never reach, against what the agent is doing. The default is `"none"`, which ranks nothing and surfaces nothing unaddressed: the spine alone, exactly as 1.0. `"lexical"` is BM25 over the standard library, no dependency and no model. Anything that needs a model is supplied here as `{ name, score, index? }`, so this package never carries one and never decides which you run. With a retriever configured the tool's filing rule changes with it, because the advice costs knowledge in either direction. On the default it says knowledge filed off the asset path never surfaces, which is true and is why you should not file it there. With a retriever it says the opposite: a constraint governing many assets and owning none belongs at its own address naming the rule, because the only parent unrelated packages share is the root and a root article surfaces on every touch of anything.
151
151
 
@@ -184,7 +184,7 @@ Nothing in the package can compel an agent to keep a line it has decided to cut.
184
184
 
185
185
  What the package does not do, stated so nothing above reads as more than it is:
186
186
 
187
- - No search the agent can call. There is no query action and no grep. `map` is the only listing, and an asset resolves to its article by exact address or by the ancestor walk, never by ranking.
187
+ - No search that runs unasked. `search` is an action the agent calls; touches resolve to articles by exact address or the ancestor walk, never by ranking, and no query ever fires on the agent's behalf.
188
188
  - No embeddings and no model. `retrieval: "lexical"` builds a BM25 index over the articles that govern no asset, and nothing else is ranked ever; any other ranker is a function the caller supplies.
189
189
  - No filesystem watching, and no staleness detection: `updated` is the date of the last write and is never compared against the asset.
190
190
  - No delete and no rename. Removing or moving an article is a file operation you perform.
@@ -245,4 +245,4 @@ That is development evidence over two arms of one run and it carries no confirma
245
245
  - The narrative version: [My agents' wiki was written faster than it was read](https://medium.com/@shane.conner/my-agents-wiki-was-written-faster-than-it-was-read-and-what-was-read-sold-me-back-debt-i-had-a8085319c68b).
246
246
  - [pi-fold](https://github.com/shaneconner/pi-fold), a separate optional package serving the working tier. pi-canon ships the two persistent tiers of the same four-tier stack: the journal is the episodic tier, the canon the semantic tier. The two compose, neither requires the other, and neither knows what the other has spent.
247
247
 
248
- MIT. In a clone of this repo, `node tests/verify.mjs` runs the gate suite: it prints 67 named invariants and ends with `all 67 gates green`.
248
+ MIT. In a clone of this repo, `node tests/verify.mjs` runs the gate suite: every invariant prints by name and the run must end `all N gates green`, 142 of them at this release.
@@ -111,22 +111,14 @@ export function registerPiCanon(pi: any, options: CanonOptions = {}): void {
111
111
 
112
112
  pi.registerTool(buildCanonTool(ready, retriever.name));
113
113
 
114
- /* One orientation line per session, riding the first turn: without it a fresh
115
- or headless session never hears the doctrine, and the write-after reminder
116
- (nextTurn at settle) cannot reach a session that ends when the agent does. */
114
+ /* session_start only resets per-session state. Through 0.2.0 it also delivered an
115
+ orientation line; a 2x2 with an inert implementation priced that line at more
116
+ first-pass correctness than the whole tool schema, and the study that removed it
117
+ found nothing the benefit side could see. The doctrine rides the tool
118
+ description, which every session carries anyway. */
117
119
  pi.on("session_start", (_event: unknown, ctx: any) => {
118
120
  runtime = undefined;
119
- const { store } = ready(ctx);
120
- if (!surface) return;
121
- const count = store.list().length;
122
- const text = count
123
- ? `[pi-canon] ${count} ${count === 1 ? "article governs" : "articles govern"} this project. Read the governing ` +
124
- "article before working on an asset; after real changes update it and journal the " +
125
- "source: names, exact numbers, who said what. Articles distill; the journal keeps the original."
126
- : "[pi-canon] No articles yet in .canon/. When work teaches you something durable about an " +
127
- "asset, write its article with pi_canon and journal the source as it happened: names, " +
128
- "exact numbers, who said what. Articles distill; the journal keeps the original.";
129
- deliver(pi, text, "nextTurn");
121
+ ready(ctx);
130
122
  });
131
123
 
132
124
  /* The window the provider is about to receive, which is the only definition of what
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-canon",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Canonical project memory for the Pi coding agent: one article per asset at a knowable address, an append-only journal beneath it.",
5
5
  "type": "module",
6
6
  "exports": {