@freetesh/zeno 0.9.1 → 0.10.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "zeno",
4
- "version": "0.9.1",
4
+ "version": "0.10.0",
5
5
  "description": "Keeps your domain knowledge and AI rules local and enforces them, so Claude hallucinates less.",
6
6
  "author": {
7
7
  "name": "Ritesh Firodiya",
package/README.md CHANGED
@@ -36,7 +36,8 @@ It has two halves that read the same config:
36
36
  constitution, your wiki and decision records, existing features and tasks,
37
37
  cost vs value, and the write-less ladder, then answers **DO IT**, **DO IT
38
38
  DIFFERENTLY** or **PUSH BACK** with citations. Push back stops work until you
39
- give a reason; overrides are logged and feed `zeno learn`.
39
+ give a reason. Every verdict is logged; `zeno learn` shows how often the gate
40
+ stops you and turns repeated overrides into proposals.
40
41
  - **No assumptions.** A request is not a fact. Each claim in it ("users want
41
42
  this", "it is slow") is checked against the repo and its data sources and
42
43
  marked backed or not. Work that rests on an assumption stops until you agree
@@ -202,7 +203,7 @@ hooks/ session start: constitution titles, qmd refresh
202
203
  standards/ default standards
203
204
  packs/ vendor doc packs
204
205
  templates/ files init writes: dependency-cruiser base (synced) and starters
205
- scripts/ log-verdict.mjs — append-only override log
206
+ scripts/ log-verdict.mjs — append-only verdict log
206
207
  cli/ the zeno CLI (TypeScript, vitest; built to cli/dist for npm)
207
208
  evals/ plugin evals and the fixture product
208
209
  ```
@@ -1,11 +1,11 @@
1
- import { proposals, readDecisions, readVerdicts, recordDecision } from "../learn.js";
1
+ import { proposals, readDecisions, readVerdicts, recordDecision, summarise } from "../learn.js";
2
2
  import { findProducts } from "../run.js";
3
3
  import { requireEstate } from "./env.js";
4
4
  const DEFAULT_THRESHOLD = 3;
5
5
  export function registerLearn(program, env) {
6
6
  program
7
7
  .command("learn")
8
- .description("turn overridden verdicts across products into proposals to change the rules")
8
+ .description("show how often the gate stops work, and turn overrides across products into proposals to change the rules")
9
9
  .option("--threshold <n>", "overrides of one principle before it is proposed", String(DEFAULT_THRESHOLD))
10
10
  .option("--approve <id>", "mark a proposal approved (then edit the standard)")
11
11
  .option("--reject <id>", "mark a proposal rejected; it returns only with new evidence")
@@ -23,7 +23,8 @@ export function registerLearn(program, env) {
23
23
  console.log(`${options.approve ? "approved" : "rejected"} ${target}`);
24
24
  return;
25
25
  }
26
- console.log(`${entries.length} overridden verdict(s) logged across the estate`);
26
+ const s = summarise(entries);
27
+ console.log(`${s.total} verdict(s) logged: ${s.proceeded} went ahead, ${s.stopped} stopped, ${s.overridden} overridden, ${s.dropped} dropped`);
27
28
  if (found.length === 0)
28
29
  console.log("no proposals");
29
30
  for (const proposal of found) {
package/cli/dist/learn.js CHANGED
@@ -1,5 +1,14 @@
1
1
  import { appendFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
2
2
  import { basename, join } from "node:path";
3
+ export const OUTCOMES = ["proceeded", "stopped", "overridden", "dropped"];
4
+ const outcomeOf = (entry) => entry.outcome ?? "overridden";
5
+ /** How often the gate let work through, stopped it, or was overridden. */
6
+ export function summarise(entries) {
7
+ const counts = Object.fromEntries(OUTCOMES.map((o) => [o, 0]));
8
+ for (const entry of entries)
9
+ counts[outcomeOf(entry)] += 1;
10
+ return { total: entries.length, ...counts };
11
+ }
3
12
  const LOG = join(".context", "raw", "zeno", "verdicts.jsonl");
4
13
  const MAX_REASONS = 5;
5
14
  function readJsonLines(path) {
@@ -41,7 +50,9 @@ function toProposal(id, summary, entries) {
41
50
  * times, or one reason given in two or more products. A decided proposal comes
42
51
  * back only when its count has grown past what it was when decided.
43
52
  */
44
- export function proposals(entries, options) {
53
+ export function proposals(all, options) {
54
+ // Only an override says a rule may be wrong; a verdict the user followed says nothing about it.
55
+ const entries = all.filter((entry) => outcomeOf(entry) === "overridden");
45
56
  const found = [];
46
57
  for (const [principle, group_] of group(entries, (e) => e.principles)) {
47
58
  if (group_.length >= options.threshold) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freetesh/zeno",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "zeno CLI: keep your domain knowledge and AI rules in your repo, and enforce them.",
5
5
  "license": "MIT",
6
6
  "author": "Ritesh Firodiya",
@@ -134,17 +134,27 @@ Proceed only after the user agrees in writing ("agree", or "agree to 1–4").
134
134
  "Go ahead" to a verdict is not agreement to terms that were never shown. Work
135
135
  covers only the terms agreed to.
136
136
 
137
- ## Logging (push back and overrides)
137
+ ## Logging (every verdict)
138
138
 
139
- When the user overrides a PUSH BACK, rejects a DO IT DIFFERENTLY or agrees to
140
- terms, append one line to the product's log so zeno can learn from it later.
141
- Pass each agreed term with its own `--term`:
139
+ Log every verdict once, when you know what happened next. A trivial request
140
+ that skipped the gate is not logged. `--outcome` is one of:
141
+
142
+ - `proceeded` — work went ahead as the verdict said (DO IT, or an accepted
143
+ *Instead*).
144
+ - `stopped` — you stopped and asked, and the user has not answered yet. Log it
145
+ when you stop; if the user later overrides, log a second line.
146
+ - `overridden` — the user went on against a PUSH BACK, rejected a DO IT
147
+ DIFFERENTLY, or agreed to terms. `--reason` is required: the user's reason,
148
+ verbatim. Pass each agreed term with its own `--term`.
149
+ - `dropped` — the user chose to drop the request.
142
150
 
143
151
  ```bash
144
- node ../../scripts/log-verdict.mjs --verdict push-back --principles C-04,C-14 \
145
- --request "<one line>" --reason "<the user's reason, verbatim>" \
146
- --term "<term 1>" --term "<term 2>"
152
+ node ../../scripts/log-verdict.mjs --verdict push-back --outcome overridden \
153
+ --principles C-04,C-14 --request "<one line>" \
154
+ --reason "<the user's reason, verbatim>" --term "<term 1>" --term "<term 2>"
147
155
  ```
148
156
 
149
157
  (path relative to this skill). It writes to `.context/raw/zeno/verdicts.jsonl`
150
- in the current repo. Never edit or delete existing lines.
158
+ in the current repo. Never edit or delete existing lines. `zeno learn` reads
159
+ the log across products: how often the gate stops work, and which rules keep
160
+ being overridden.