avouch 0.1.22 → 0.1.23
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 +21 -9
- package/dist/cli/avouch.js +35 -10
- package/dist/cli/init.d.ts +3 -3
- package/dist/cli/init.js +45 -32
- package/package.json +13 -1
- package/templates/agents-block.md +1 -1
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ Read in this order:
|
|
|
32
32
|
|
|
33
33
|
Start with step 0, then do the two steps, in this order.
|
|
34
34
|
|
|
35
|
-
0. At the top level of the git repository, run `npx -y avouch init`. It installs the Claude Code
|
|
35
|
+
0. At the top level of the git repository, run `npx -y avouch init`. It installs the plugin for Claude Code and for Codex (see "Claude Code and Codex plugin") and adds the Avouch instructions for coding agents. The instructions tell an agent to read the rules with `avouch query`, not with a text tool, and to run `avouch check` and `avouch gate docs` after a change. There are two modes: `--append` adds the instructions to `AGENTS.md` and `CLAUDE.md`, if they exist; `--print` writes them to the terminal, and you add them yourself. Without a flag, `init` asks in a terminal and prints otherwise. `--dry-run` shows what would change and writes nothing. Then run `/avouch:scan` in Claude Code (`$avouch:scan` in Codex), which drafts `avouch.config.json`, a first ontology and the document review ledger. See "init" in "Command line".
|
|
36
36
|
1. Every project: keep a document review ledger, and run `avouch gate docs` in CI. See "Document review ledger (gate docs)". The gate works with any Markdown style. It guarantees that each changed section of a design document has a recorded review decision. It does not guarantee that the decision is complete: it does not check that a person read the section, that `claims` lists every claim, or that the claimed places say what the section says.
|
|
37
37
|
2. For the structured checks, choose one path. The checks are: the field lists and catalogs of R2, and R3, R5, R6, R8, R9 and R10 (SPEC section 5). Each needs a fact from the project's documents (SPEC section 6). R7 needs execution evidence, which the built-in adapter does not read.
|
|
38
38
|
- (a) Write the documents to the Markdown convention, `docs/markdown-convention.md`, and use the built-in adapter. `avouch facts` checks the documents without an ontology.
|
|
@@ -86,7 +86,7 @@ A project supplies an adapter and a profile. The adapter reads the project's sou
|
|
|
86
86
|
|
|
87
87
|
## Command line
|
|
88
88
|
|
|
89
|
-
Build with `npm run build`, then run it. `avouch --help` (or `-h`) prints the
|
|
89
|
+
Build with `npm run build`, then run it. `avouch --help` (or `-h`) prints an overview: the commands, each with a short description, and the options `-h` and `-v`. `avouch <command> --help` prints the usage of one command. `avouch --version` (or `-v`) prints the version. All three exit with 0 and need no files, configuration or git. `avouch` with no arguments prints the overview on stderr and exits with 2; an unknown command prints an error and exits with 2. For example:
|
|
90
90
|
|
|
91
91
|
```sh
|
|
92
92
|
avouch check [-f <ontology.yaml>] [--config <avouch.config.json>] [--adapter <module|config.json>]
|
|
@@ -107,7 +107,7 @@ An `--adapter` path that ends in `.json` is not loaded as a module: it is the co
|
|
|
107
107
|
avouch init [--append | --print] [--plugin | --no-plugin] [--dry-run]
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
`avouch init` prepares a project for Avouch. Run it inside a git repository; it works on the git top level. Step 1 is the Claude Code
|
|
110
|
+
`avouch init` prepares a project for Avouch. Run it inside a git repository; it works on the git top level. Step 1 is the plugin, for Claude Code and then for Codex. With `--plugin`, it runs `claude plugin marketplace add githonllc/avouch` and `claude plugin install avouch@avouch`, then `codex plugin marketplace add githonllc/avouch` and `codex plugin add avouch@avouch` (it does not check if the plugin is already installed, and runs the commands again on each run). Without a flag, it asks in a terminal for each host and only prints the commands otherwise. When `claude` or `codex` is not on `PATH`, it prints the two commands of that host. Codex runs the hook only after you approve it. `--no-plugin` skips the step. Step 2 is the instructions for coding agents (`templates/agents-block.md`). `--append` adds them, between the lines `<!-- BEGIN avouch -->` and `<!-- END avouch -->`, to `AGENTS.md` and `CLAUDE.md` at the top level. It never creates a file: when neither file exists, it prints the instructions. It replaces an earlier block in place, keeps all other bytes and the line endings (CRLF or LF) of the file, and a second run changes nothing. A file that does not have exactly one BEGIN line and then one END line is an error, and the file is not changed. It skips `CLAUDE.md` when the file has the line `@AGENTS.md` and `AGENTS.md` exists. `--print` writes the instructions to stdout. Without a flag, it asks in a terminal and prints otherwise. `--dry-run` runs no command and writes no file; it prints the commands and, for each file, `append`, `replace` or `unchanged`. Step 3 tells you to run `/avouch:scan` in Claude Code. Exit code 0 means done (also a print and a dry run); 1 means a plugin command failed or a file could not be changed; 2 means invalid arguments or no git repository.
|
|
111
111
|
|
|
112
112
|
### facts
|
|
113
113
|
|
|
@@ -299,9 +299,9 @@ Exit code 2, with one line on stderr, means:
|
|
|
299
299
|
|
|
300
300
|
The gate does not check that a person read a unit, that `claims` lists every claim of the unit, or that the claimed places say what the unit says. Review the ledger diff in the pull request, next to the document diff. Known limit: two changes to adjacent ledger lines (for example two units of one document that follow each other) can still give a merge conflict in git.
|
|
301
301
|
|
|
302
|
-
## Claude Code plugin
|
|
302
|
+
## Claude Code and Codex plugin
|
|
303
303
|
|
|
304
|
-
This repository is also a Claude Code
|
|
304
|
+
This repository is also a plugin marketplace for Claude Code and for Codex. Install the plugin in Claude Code:
|
|
305
305
|
|
|
306
306
|
```sh
|
|
307
307
|
claude plugin marketplace add githonllc/avouch
|
|
@@ -310,6 +310,15 @@ claude plugin install avouch@avouch
|
|
|
310
310
|
|
|
311
311
|
Inside a Claude Code session, the same two steps are `/plugin marketplace add githonllc/avouch` and `/plugin install avouch@avouch`.
|
|
312
312
|
|
|
313
|
+
Install the plugin in Codex (the same marketplace file is used):
|
|
314
|
+
|
|
315
|
+
```sh
|
|
316
|
+
codex plugin marketplace add githonllc/avouch
|
|
317
|
+
codex plugin add avouch@avouch
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
In Codex, call the skills as `$avouch:scan` and `$avouch:cli`. Codex runs the hook only after you approve it.
|
|
321
|
+
|
|
313
322
|
The plugin has two skills and one hook. The skills:
|
|
314
323
|
- `cli` (`/avouch:cli`): checks an ontology and runs `avouch query`.
|
|
315
324
|
- `scan` (`/avouch:scan [project-dir]`): drafts or updates a project's ontology from its design documents, and records the review decision of each document section in the ledger (`avouch gate docs` must pass). It uses the adapter that the project has configured and never writes an adapter. The result is a candidate. `avouch check` must exit 0, and each source gap is listed with a proposed fix to the document. When most objects have no documented field list, it also writes `avouch/doc-patch.md`: field lists, foreign keys and store names derived from the code, for a human to review and merge into the documents. It never drafts states, permissions or rules from code.
|
|
@@ -322,18 +331,21 @@ The skills run the CLI with `npx -y avouch@<version>`, pinned to the version of
|
|
|
322
331
|
|
|
323
332
|
## Publishing
|
|
324
333
|
|
|
325
|
-
The npm package is `avouch`, and its command is `avouch`. Versions 0.1.0 to 0.1.21 were published as `@githonllc/avouch
|
|
334
|
+
The npm package is `avouch`, and its command is `avouch`. Versions 0.1.0 to 0.1.21 were published only as `@githonllc/avouch`. Version 0.1.22 was published only as `avouch`. From 0.1.23, each release publishes the same files as `avouch` and as `@githonllc/avouch`; the docs use `avouch`. The name `avouch` was transferred to Githon LLC in 2026, and the earlier, unrelated versions 1.0.0 to 1.0.7 were unpublished. The two packages declare the same command `avouch`, so a project installs one of them, not both.
|
|
335
|
+
|
|
336
|
+
`avouch-cli` is a separate package in `alias/avouch-cli/`. It only forwards to `avouch`, so that `npx -y avouch-cli` does not run a stranger's package. It is published by hand and depends on `"avouch": "*"`. It needs a new version only when the forwarding code changes.
|
|
326
337
|
|
|
327
338
|
`package.json` has `"private": true` in the repository, so an accidental `npm publish` from a working copy is refused. The release workflow removes that line only in its own checkout.
|
|
328
339
|
|
|
329
340
|
A release needs the explicit approval of the project owner. Releases are published by the GitHub Actions workflow `.github/workflows/release.yml` through npm trusted publishing: no npm token is stored, and npm adds provenance. Do these steps in this sequence:
|
|
330
341
|
|
|
331
342
|
1. Set the new `0.x` version in `package.json`, `.claude-plugin/plugin.json` and the `npx -y avouch@<version>` pins in `skills/*/SKILL.md`, merge it to `main`, and wait for CI to pass. Check the file list that the CI step `npm pack --dry-run` prints.
|
|
332
|
-
2. Tag the merge commit `v<version>` (the same version as `package.json`) and push the tag. The workflow checks that the tag matches the version, runs `npm ci`, the type check and the tests, removes `"private"`, and publishes with `--access public --tag latest`.
|
|
343
|
+
2. Tag the merge commit `v<version>` (the same version as `package.json`) and push the tag. The workflow checks that the tag matches the version, runs `npm ci`, the type check and the tests, removes `"private"`, and publishes as `avouch` and then as `@githonllc/avouch`, with `--access public --tag latest`. A name that already has the version is skipped, so a re-run of a failed release publishes only the missing name.
|
|
333
344
|
3. The job waits in the `npm` environment until the owner approves it in GitHub. The owner's approval is the release approval.
|
|
334
345
|
4. Make sure that the release works:
|
|
335
|
-
- `npm view avouch version`
|
|
336
|
-
- in an empty directory, `npx -y avouch@<version>` (no arguments) prints the
|
|
346
|
+
- `npm view avouch version` and `npm view @githonllc/avouch version` show the new version (a new version can take a few minutes to become available);
|
|
347
|
+
- in an empty directory, `npx -y avouch@<version>` (no arguments) prints the help and exits with code 2;
|
|
348
|
+
- `npx -y avouch@<version> --version` prints the version.
|
|
337
349
|
|
|
338
350
|
Version 0.1.0 was published by hand, because npm accepts a trusted publisher only for a package that exists.
|
|
339
351
|
|
package/dist/cli/avouch.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { resolveProject, runCheck } from "./check.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { expectPositionals, parseOptions,
|
|
4
|
+
import { runFacts } from "./facts.js";
|
|
5
|
+
import { runInit } from "./init.js";
|
|
6
|
+
import { runGate } from "./gate.js";
|
|
7
|
+
import { runQuery } from "./query.js";
|
|
8
|
+
import { expectPositionals, parseOptions, runReconcile, wantsHelp } from "./reconcile.js";
|
|
8
9
|
const CHECK_USAGE = "usage: avouch check [-f <ontology.yaml>] [--config <avouch.config.json>] [--adapter <module|config.json>]";
|
|
9
10
|
async function check(args) {
|
|
10
11
|
if (wantsHelp(args, ["-f", "--config", "--adapter"])) {
|
|
@@ -35,12 +36,34 @@ async function check(args) {
|
|
|
35
36
|
console.log(`${ok ? "PASS" : "FAIL"}: ${errors.length} schema error(s), ${report.violations.length} violation(s), ${report.waived.length} waived`);
|
|
36
37
|
return ok ? 0 : 1;
|
|
37
38
|
}
|
|
38
|
-
const
|
|
39
|
+
const HELP = `usage: avouch <command> [options]
|
|
40
|
+
|
|
41
|
+
Check and query an Avouch ontology: a spec whose every claim cites its source.
|
|
42
|
+
|
|
43
|
+
Commands:
|
|
44
|
+
init Set up a repository: agent plugin, agent instructions
|
|
45
|
+
check Check an ontology against the schema, rules and documents
|
|
46
|
+
query Read a rule: an action, object, property or citation
|
|
47
|
+
facts Show what the Markdown adapter reads from design documents
|
|
48
|
+
gate docs Require a recorded review decision for each document change
|
|
49
|
+
gate verify Require a verified case for each decision row
|
|
50
|
+
reconcile Compare runtime results with the evaluator and expectations
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
-h, --help Show this help, or the help of a command
|
|
54
|
+
-v, --version Show the version
|
|
55
|
+
|
|
56
|
+
Run "avouch <command> --help" for the options of a command.
|
|
57
|
+
Docs: https://avouch.dev
|
|
58
|
+
`;
|
|
39
59
|
async function main() {
|
|
40
60
|
const args = process.argv.slice(2);
|
|
41
61
|
if (args[0] === "--help" || args[0] === "-h") {
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
process.stdout.write(HELP);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
66
|
+
console.log(JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8")).version);
|
|
44
67
|
return 0;
|
|
45
68
|
}
|
|
46
69
|
if (args[0] === "check")
|
|
@@ -55,8 +78,10 @@ async function main() {
|
|
|
55
78
|
return runFacts(args.slice(1));
|
|
56
79
|
if (args[0] === "init")
|
|
57
80
|
return runInit(args.slice(1));
|
|
58
|
-
|
|
59
|
-
console.error(
|
|
81
|
+
if (args.length > 0)
|
|
82
|
+
console.error(`avouch: unknown command "${args[0]}"\nRun "avouch --help" for the commands.`);
|
|
83
|
+
else
|
|
84
|
+
process.stderr.write(HELP);
|
|
60
85
|
return 2;
|
|
61
86
|
}
|
|
62
87
|
try {
|
package/dist/cli/init.d.ts
CHANGED
|
@@ -9,10 +9,10 @@ export declare function createAsker(input: NodeJS.ReadableStream, output: NodeJS
|
|
|
9
9
|
close: () => void;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
|
-
* How to run `claude` with fixed arguments. On Windows
|
|
13
|
-
* arguments are constants, so the command line is safe for the shell. Elsewhere no shell.
|
|
12
|
+
* How to run a host (`claude` or `codex`) with fixed arguments. On Windows the host is usually `<host>.cmd`, which only a shell
|
|
13
|
+
* can run; the arguments are constants, so the command line is safe for the shell. Elsewhere no shell.
|
|
14
14
|
*/
|
|
15
|
-
export declare function pluginSpawn(args: string[], platform?: NodeJS.Platform): {
|
|
15
|
+
export declare function pluginSpawn(args: string[], platform?: NodeJS.Platform, host?: string): {
|
|
16
16
|
command: string;
|
|
17
17
|
args: string[];
|
|
18
18
|
options: SpawnSyncOptions;
|
package/dist/cli/init.js
CHANGED
|
@@ -7,15 +7,17 @@ import { gitTop } from "./check.js";
|
|
|
7
7
|
import { expectPositionals, parseOptions, wantsHelp } from "./reconcile.js";
|
|
8
8
|
export const INIT_USAGE = "usage: avouch init [--append | --print] [--plugin | --no-plugin] [--dry-run]";
|
|
9
9
|
const FLAGS = ["--append", "--print", "--plugin", "--no-plugin", "--dry-run"];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
["plugin", "install", "avouch@avouch"],
|
|
10
|
+
// The hosts of the plugin, in the order that init handles them, and the commands that install it into each.
|
|
11
|
+
const HOSTS = [
|
|
12
|
+
{ name: "claude", label: "Claude Code", suffix: "", commands: [["plugin", "marketplace", "add", "githonllc/avouch"], ["plugin", "install", "avouch@avouch"]] },
|
|
13
|
+
{ name: "codex", label: "Codex", suffix: " for Codex", commands: [["plugin", "marketplace", "add", "githonllc/avouch"], ["plugin", "add", "avouch@avouch"]] },
|
|
13
14
|
];
|
|
15
|
+
const CODEX_HOOK_NOTE = "In Codex, the hook runs only after you approve it: approve the avouch hook when Codex asks.";
|
|
14
16
|
const BEGIN = "<!-- BEGIN avouch -->";
|
|
15
17
|
const END = "<!-- END avouch -->";
|
|
16
18
|
const TARGETS = ["AGENTS.md", "CLAUDE.md"];
|
|
17
19
|
const isTty = () => process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
18
|
-
const commandLine = (args) =>
|
|
20
|
+
const commandLine = (host, args) => `${host} ${args.join(" ")}`;
|
|
19
21
|
/**
|
|
20
22
|
* Yes/no questions on one readline interface, made at the first question. Lines that arrive before a question is asked
|
|
21
23
|
* (typed ahead) are queued and answer the next questions in order; at the end of input a question gets no (an empty answer).
|
|
@@ -57,21 +59,21 @@ export function createAsker(input, output) {
|
|
|
57
59
|
let asker = createAsker(process.stdin, process.stdout);
|
|
58
60
|
const ask = (question) => asker.ask(question);
|
|
59
61
|
/**
|
|
60
|
-
* How to run `claude` with fixed arguments. On Windows
|
|
61
|
-
* arguments are constants, so the command line is safe for the shell. Elsewhere no shell.
|
|
62
|
+
* How to run a host (`claude` or `codex`) with fixed arguments. On Windows the host is usually `<host>.cmd`, which only a shell
|
|
63
|
+
* can run; the arguments are constants, so the command line is safe for the shell. Elsewhere no shell.
|
|
62
64
|
*/
|
|
63
|
-
export function pluginSpawn(args, platform = process.platform) {
|
|
65
|
+
export function pluginSpawn(args, platform = process.platform, host = "claude") {
|
|
64
66
|
return platform === "win32"
|
|
65
|
-
? { command: commandLine(args), args: [], options: { stdio: "inherit", shell: true } }
|
|
66
|
-
: { command:
|
|
67
|
+
? { command: commandLine(host, args), args: [], options: { stdio: "inherit", shell: true } }
|
|
68
|
+
: { command: host, args, options: { stdio: "inherit" } };
|
|
67
69
|
}
|
|
68
|
-
// True when an executable file named `
|
|
69
|
-
function
|
|
70
|
+
// True when an executable file named `name` is in a PATH directory.
|
|
71
|
+
function onPath(name) {
|
|
70
72
|
for (const dir of (process.env.PATH ?? "").split(delimiter)) {
|
|
71
73
|
if (dir === "")
|
|
72
74
|
continue;
|
|
73
|
-
for (const
|
|
74
|
-
const path = join(dir,
|
|
75
|
+
for (const file of process.platform === "win32" ? [`${name}.exe`, `${name}.cmd`, name] : [name]) {
|
|
76
|
+
const path = join(dir, file);
|
|
75
77
|
try {
|
|
76
78
|
if (!statSync(path).isFile())
|
|
77
79
|
continue;
|
|
@@ -130,27 +132,22 @@ function printBlock() {
|
|
|
130
132
|
process.stdout.write(wrappedBlock("\n"));
|
|
131
133
|
console.log("-----8<----- end of the Avouch agent instructions -----8<-----");
|
|
132
134
|
}
|
|
133
|
-
/** Step 1: the
|
|
134
|
-
async function
|
|
135
|
-
console.log("Step 1: the Avouch plugin for Claude Code (a hook that blocks text reads of an ontology, and the skills /avouch:scan and /avouch:cli).");
|
|
136
|
-
if (opts.has("--no-plugin")) {
|
|
137
|
-
console.log("Skipped (--no-plugin).");
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
135
|
+
/** Step 1, one host: install the plugin or print the commands. Returns false when a plugin command failed. */
|
|
136
|
+
async function pluginFor(host, opts, dryRun) {
|
|
140
137
|
const printCommands = (why) => {
|
|
141
|
-
console.log(`${why} To install the plugin, run:`);
|
|
142
|
-
for (const c of
|
|
143
|
-
console.log(` ${commandLine(c)}`);
|
|
138
|
+
console.log(`${why} To install the plugin${host.suffix}, run:`);
|
|
139
|
+
for (const c of host.commands)
|
|
140
|
+
console.log(` ${commandLine(host.name, c)}`);
|
|
144
141
|
};
|
|
145
|
-
if (!
|
|
146
|
-
printCommands(
|
|
142
|
+
if (!onPath(host.name)) {
|
|
143
|
+
printCommands(`No \`${host.name}\` executable is on PATH.`);
|
|
147
144
|
return true;
|
|
148
145
|
}
|
|
149
146
|
if (dryRun) {
|
|
150
147
|
if (opts.has("--plugin")) {
|
|
151
148
|
console.log("Dry run. These commands would run:");
|
|
152
|
-
for (const c of
|
|
153
|
-
console.log(` ${commandLine(c)}`);
|
|
149
|
+
for (const c of host.commands)
|
|
150
|
+
console.log(` ${commandLine(host.name, c)}`);
|
|
154
151
|
}
|
|
155
152
|
else
|
|
156
153
|
printCommands(`Dry run. Without --plugin, init would ${isTty() ? "ask before it runs these commands" : "only print these commands"}.`);
|
|
@@ -162,7 +159,7 @@ async function plugin(opts, dryRun) {
|
|
|
162
159
|
printCommands("No terminal, so init does not run the commands.");
|
|
163
160
|
return true;
|
|
164
161
|
}
|
|
165
|
-
run = await ask(
|
|
162
|
+
run = await ask(`Install the Avouch plugin for ${host.label} (user scope)?`);
|
|
166
163
|
if (!run) {
|
|
167
164
|
printCommands("Not installed.");
|
|
168
165
|
return true;
|
|
@@ -170,17 +167,33 @@ async function plugin(opts, dryRun) {
|
|
|
170
167
|
}
|
|
171
168
|
let ok = true;
|
|
172
169
|
// Both commands run even when the first fails: adding a marketplace that is already added can fail while the install still works.
|
|
173
|
-
for (const c of
|
|
174
|
-
console.log(`Running: ${commandLine(c)}`);
|
|
175
|
-
const s = pluginSpawn(c);
|
|
170
|
+
for (const c of host.commands) {
|
|
171
|
+
console.log(`Running: ${commandLine(host.name, c)}`);
|
|
172
|
+
const s = pluginSpawn(c, process.platform, host.name);
|
|
176
173
|
const r = spawnSync(s.command, s.args, s.options);
|
|
177
174
|
if (r.error !== undefined || r.status !== 0) {
|
|
178
175
|
ok = false;
|
|
179
|
-
console.error(`FAIL: ${commandLine(c)}: ${r.error !== undefined ? r.error.message : r.status !== null ? `exit ${r.status}` : `signal ${r.signal}`}`);
|
|
176
|
+
console.error(`FAIL: ${commandLine(host.name, c)}: ${r.error !== undefined ? r.error.message : r.status !== null ? `exit ${r.status}` : `signal ${r.signal}`}`);
|
|
180
177
|
}
|
|
181
178
|
}
|
|
182
179
|
return ok;
|
|
183
180
|
}
|
|
181
|
+
/** Step 1: the plugin for Claude Code and Codex. Returns false when a plugin command failed. */
|
|
182
|
+
async function plugin(opts, dryRun) {
|
|
183
|
+
console.log("Step 1: the Avouch plugin for Claude Code and Codex (a hook that blocks text reads of an ontology, and the skills avouch:scan and avouch:cli).");
|
|
184
|
+
if (opts.has("--no-plugin")) {
|
|
185
|
+
console.log("Skipped (--no-plugin).");
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
let ok = true;
|
|
189
|
+
for (const host of HOSTS) {
|
|
190
|
+
const hostOk = await pluginFor(host, opts, dryRun);
|
|
191
|
+
ok = hostOk && ok;
|
|
192
|
+
if (host.name === "codex" && hostOk)
|
|
193
|
+
console.log(CODEX_HOOK_NOTE);
|
|
194
|
+
}
|
|
195
|
+
return ok;
|
|
196
|
+
}
|
|
184
197
|
/** Step 2: the agent instructions. Returns false when a file could not be written. */
|
|
185
198
|
async function instructions(top, opts, dryRun) {
|
|
186
199
|
console.log("Step 2: the Avouch instructions for coding agents (AGENTS.md, CLAUDE.md).");
|
package/package.json
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avouch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
|
+
"description": "Avouch: an ontology spec whose every claim cites its source, with a checker and a CLI.",
|
|
4
5
|
"license": "Apache-2.0",
|
|
6
|
+
"author": "Githon LLC",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"avouch",
|
|
9
|
+
"ontology",
|
|
10
|
+
"specification",
|
|
11
|
+
"design-docs",
|
|
12
|
+
"ai-agents",
|
|
13
|
+
"claude-code",
|
|
14
|
+
"checker",
|
|
15
|
+
"cli"
|
|
16
|
+
],
|
|
5
17
|
"repository": {
|
|
6
18
|
"type": "git",
|
|
7
19
|
"url": "git+https://github.com/githonllc/avouch.git"
|
|
@@ -7,6 +7,6 @@ The business rules of this project are in an Avouch ontology (`*.ontology.yaml`,
|
|
|
7
7
|
- Do not read the ontology file with grep, cat, sed or a script. Comments and neighbouring entries in the text look like rules, but the checker does not read them.
|
|
8
8
|
- If the rule is `unspecified` or is in `knownSourceGaps`, the documents do not decide it. Do not invent the behavior: tell your user, and say so in the pull request.
|
|
9
9
|
- If the ontology, the documents and the code disagree, do not decide in code. Tell your user which texts disagree.
|
|
10
|
-
- To change a rule, change the design document first, or ask your user to. Then update the ontology so that each claim quotes the new text: in Claude Code with `/avouch:scan`, otherwise with the writing rules in https://avouch.dev/llms.txt. Do not add a rule that no document states.
|
|
10
|
+
- To change a rule, change the design document first, or ask your user to. Then update the ontology so that each claim quotes the new text: in Claude Code with `/avouch:scan`, in Codex with `$avouch:scan`, otherwise with the writing rules in https://avouch.dev/llms.txt. Do not add a rule that no document states.
|
|
11
11
|
- After you change the ontology or a cited document section, run `npx -y avouch check`, and `npx -y avouch gate docs` if the project has a ledger (`avouch.ledger.jsonl`). Both must exit 0. `check` covers the format rules only; it does not replace the project's tests.
|
|
12
12
|
- Do not edit the ledger to make the gate pass without reading the changed section.
|