pi-canon 0.2.1 → 0.2.2

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
@@ -108,6 +108,7 @@ One tool, `pi_canon`, five actions: `read`, `write`, `journal`, `map`, and `sear
108
108
  | `write` | `path`, `capsule`, `body`, `scope` | Creates or updates the article, then returns `Wrote <address>.` and any advisory lint. Never refuses. An empty string means untouched, not erase. |
109
109
  | `journal` | `body`, `subject`, `slug` | Appends a dated entry as its own file, `<date>-<slug>[-n].md`. pi_canon can never rewrite one. An empty body gets a sentence back asking what happened. |
110
110
  | `map` | `path` (optional prefix) | One line per article as `address: capsule`, or a sentence when the store or the filter is empty. Output is unbounded. |
111
+ | `search` | `query` | Ranks articles and journal entries against the words in one pass, ten results, each carrying what scopes it: an article its address and capsule, a journal entry its instant and subjects. Says how many matches the cap dropped. The one action that reaches the journal's content. |
111
112
 
112
113
  `subject` is an array of addresses. A subject passed as a bare string is ignored and the entry lands with none at all.
113
114
 
@@ -149,7 +150,7 @@ Six keys, and any other throws at registration by name, because everything else
149
150
  - **`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
151
  - **`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
152
 
152
- - **`standout`** is how far the best-ranked article must beat the best one that will not ride anyway, meaning the fourth, the one the three-per-message cap was already going to leave behind. A multiple, not a score: `standout: 1.5` asks for the best to score half again what the first held-back rival scored. Default `1.4`, an operating point priced by a 120-cell benchmark rather than picked: it kept every rule fact the uncut channel delivered while cutting suggestions from 26 a session to 3, raised the rate at which the agent acted on one from 0.17 to 0.82, and never fired at all on a store with nothing relevant to say, 0 rankings of 139. Precision is the side to protect: an unsolicited line that is usually noise teaches the agent to skip the next one, and suggestion fatigue costs more than the tokens do. The other side has a price too, and the same benchmark paid it: a cutoff set past what a decisive ranking reaches silences the channel, and at 2.0 it delivered nothing and gave back everything the channel had won. `standout: 1` is no cutoff, the measurement setting for reading your own store's trace. Below `1` throws at registration, because it asks for the best article to be worse than its rival and is what a caller writes who is still thinking in scores.
153
+ - **`standout`** is how far the best-ranked article must beat the best one that will not ride anyway, meaning the fourth, the one the three-per-message cap was already going to leave behind. A multiple, not a score: `standout: 1.5` asks for the best to score half again what the first held-back rival scored. Default `1.4`, an operating point priced by a 120-cell benchmark rather than picked: it matched the uncut channel's delivery to within that benchmark's own noise floor while cutting suggestions from 26 a session to 3, raised the rate at which the agent acted on one from 0.17 to 0.82, and never fired at all on a store with nothing relevant to say, 0 rankings of 139. Precision is the side to protect, though the measured argument is tokens rather than attention: the same benchmark found good suggestions opened at the same rate buried among twenty-seven as one of four, so what the cutoff saves is the context it declines to spend on lines that were never going to be read. The other side has a price too, and the same benchmark paid it: a cutoff set past what a decisive ranking reaches silences the channel, and at 2.0 it delivered nothing and gave back everything the channel had won. `standout: 1` is no cutoff, the measurement setting for reading your own store's trace. Below `1` throws at registration, because it asks for the best article to be worse than its rival and is what a caller writes who is still thinking in scores.
153
154
 
154
155
  **It is a ratio because a score is not the same quantity twice.** `lexical` normalizes against a saturation ceiling computed from the query, so a score is a fraction of the best match POSSIBLE for that query rather than of the best match available in your store, and it falls as the agent says more. On a 380-article store the same article at the same relevance scored 0.68 against a short question and 0.16 with a hundred words of tool output around it. Across two benchmark runs it was worse than unstable, it inverted: keeping the answers on one corpus needed a cutoff below 0.11, and silencing the other needed one above 0.73. Dividing by another score from the same query cancels both.
155
156
 
@@ -30,9 +30,9 @@ export interface CanonOptions {
30
30
  /* How far the best-ranked article must stand out from the rest of what this same
31
31
  query touched before it may ride a message. A multiple, not a score: 2 means the
32
32
  best must score twice the best article that will not ride, the one just past the
33
- per-turn cap. Default 1.4, the operating point a 120-cell study priced: it kept
34
- every fact the uncut channel delivered at a ninth of the suggestion volume. 1 is
35
- no cutoff and is the 1.0 behavior exactly.
33
+ per-turn cap. Default 1.4, the operating point a 120-cell study priced: it
34
+ matched the uncut channel's delivery to within that study's own noise floor at a
35
+ ninth of the suggestion volume. 1 is no cutoff and is the 1.0 behavior exactly.
36
36
 
37
37
  Relative rather than absolute because an absolute cutoff is not the same quantity
38
38
  twice. A lexical score is a fraction of the query's whole idf mass, so it falls as
@@ -43,9 +43,11 @@ export interface CanonOptions {
43
43
  Dividing by another score from the same query cancels both, which is why this ports
44
44
  and a number never did.
45
45
 
46
- Raising it trades recall for precision, and precision is the side that matters: an
47
- unsolicited line that is usually noise teaches the agent to skip the next one, and
48
- that costs more than the tokens do. Ignored when retrieval is "none". */
46
+ Raising it trades recall for precision, and precision is the side to protect,
47
+ though the measured argument is tokens rather than attention: the same study
48
+ found good suggestions opened at the same rate buried among twenty-seven as one
49
+ of four, so what the cutoff declines to spend is context on lines that were
50
+ never going to be read. Ignored when retrieval is "none". */
49
51
  standout?: number;
50
52
  }
51
53
 
@@ -141,10 +141,11 @@ function filingTail(retrieval: string): string {
141
141
  though it has no address at all.
142
142
 
143
143
  Every result carries what SCOPES it, which is the one thing a result cannot be useful
144
- without. A study of a 259 KB flat memory found sessions receiving every fact they needed
145
- and still answering wrong, because a grep returned 201 answers to one question with nothing
146
- saying which situation each applied to. For an article the scope is its address; for a
147
- journal entry it is the instant and the subjects it named. Neither is decoration.
144
+ without. A study of a 259 KB flat memory found grep returning 201 occurrences of one
145
+ answer with nothing saying which subsystem each applied to; the sessions almost never
146
+ received the governing fact under its own scope, and scored accordingly. For an article
147
+ the scope is its address; for a journal entry it is the instant and the subjects it
148
+ named. Neither is decoration.
148
149
 
149
150
  Ranking reuses LexicalRetriever rather than growing a second notion of relevance, so search
150
151
  and recommendation cannot drift apart. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-canon",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
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": {