polydeukes 0.6.0 → 0.6.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.
Files changed (55) hide show
  1. package/README.ko.md +54 -80
  2. package/README.md +55 -94
  3. package/dist/bin.js +8 -5
  4. package/dist/docs/README.ko.md +60 -0
  5. package/dist/docs/README.md +64 -0
  6. package/dist/docs/catalog.json +464 -0
  7. package/dist/docs/concepts/judgment.ko.md +113 -0
  8. package/dist/docs/concepts/judgment.md +113 -0
  9. package/dist/docs/how-to/configure-project.ko.md +99 -0
  10. package/dist/docs/how-to/configure-project.md +95 -0
  11. package/dist/docs/how-to/connect-surfaces.ko.md +115 -0
  12. package/dist/docs/how-to/connect-surfaces.md +118 -0
  13. package/dist/docs/how-to/write-disciplines.ko.md +124 -0
  14. package/dist/docs/how-to/write-disciplines.md +125 -0
  15. package/dist/docs/index.json +2046 -0
  16. package/dist/docs/reference/cli/covenant-check.ko.md +101 -0
  17. package/dist/docs/reference/cli/covenant-check.md +98 -0
  18. package/dist/docs/reference/cli/docs.ko.md +97 -0
  19. package/dist/docs/reference/cli/docs.md +95 -0
  20. package/dist/docs/reference/cli/explain.ko.md +79 -0
  21. package/dist/docs/reference/cli/explain.md +84 -0
  22. package/dist/docs/reference/cli/init.ko.md +119 -0
  23. package/dist/docs/reference/cli/init.md +131 -0
  24. package/dist/docs/reference/configuration/index.ko.md +448 -0
  25. package/dist/docs/reference/{configuration.md → configuration/index.md} +48 -30
  26. package/dist/docs/reference/packages/adapter-claude-code.ko.md +83 -0
  27. package/dist/docs/reference/{adapter-claude-code.md → packages/adapter-claude-code.md} +10 -6
  28. package/dist/docs/reference/packages/adapter-git.ko.md +101 -0
  29. package/dist/docs/reference/{adapter-git.md → packages/adapter-git.md} +20 -12
  30. package/dist/docs/reference/packages/core.ko.md +128 -0
  31. package/dist/docs/reference/{core.md → packages/core.md} +21 -8
  32. package/dist/docs/reference/packages/covenant.ko.md +115 -0
  33. package/dist/docs/reference/{covenant.md → packages/covenant.md} +18 -11
  34. package/dist/docs/reference/packages/polydeukes.ko.md +134 -0
  35. package/dist/docs/reference/packages/polydeukes.md +139 -0
  36. package/dist/docs/troubleshooting.ko.md +142 -0
  37. package/dist/docs/troubleshooting.md +98 -150
  38. package/dist/docs/tutorials/first-judgment.ko.md +82 -0
  39. package/dist/docs/tutorials/first-judgment.md +81 -0
  40. package/dist/docs-catalog.d.ts +25 -0
  41. package/dist/docs-catalog.js +450 -0
  42. package/dist/docs-library.d.ts +23 -0
  43. package/dist/docs-library.js +347 -0
  44. package/dist/docs-markdown.d.ts +32 -0
  45. package/dist/docs-markdown.js +150 -0
  46. package/dist/docs-query.d.ts +11 -40
  47. package/dist/docs-query.js +28 -122
  48. package/dist/docs-types.d.ts +105 -0
  49. package/dist/docs-types.js +2 -0
  50. package/dist/init-claude-code.d.ts +1 -1
  51. package/dist/init-claude-code.js +159 -42
  52. package/package.json +5 -5
  53. package/dist/docs/configuration.md +0 -103
  54. package/dist/docs/installation.md +0 -241
  55. package/dist/docs/reference/polydeukes.md +0 -315
@@ -1,315 +0,0 @@
1
- # `polydeukes` — the umbrella
2
-
3
- **English** · [한국어](./polydeukes.ko.md)
4
-
5
- > Alpha. Everything below is read from the shipped package — the `pdks` bin, the barrel, and
6
- > the exports map. For the procedures that use these, see [installation](../installation.md)
7
- > and [troubleshooting](../troubleshooting.md).
8
-
9
- The umbrella is the only package you install. It carries the core, the judge, and both
10
- adapters as its own dependencies, and it is the only package allowed to assemble them —
11
- every other dependency in this repository runs one way, through the core alone. That makes
12
- this page the consumer-facing surface: the four scoped packages are transitive dependencies
13
- you do not install and do not import.
14
-
15
- The judge and the two adapters take the core as a `peerDependency` rather than a dependency
16
- of their own, so they share one copy of the vocabulary instead of each carrying its own. The
17
- umbrella's ordinary dependency on the core is what satisfies that peer, which is why
18
- installing this one package is still all a consumer does.
19
-
20
- | Package | Reference | Owns |
21
- |---|---|---|
22
- | `@polydeukes/core` | [core](./core.md) | The protocol, the config schema, telemetry |
23
- | `@polydeukes/covenant` | [covenant](./covenant.md) | The judge — dispatcher, disciplines, meta-covenants, the valve |
24
- | `@polydeukes/adapter-claude-code` | [adapter-claude-code](./adapter-claude-code.md) | Session surface — PreToolUse payloads → input IR |
25
- | `@polydeukes/adapter-git` | [adapter-git](./adapter-git.md) | Commit surface — staged diffs → input IR |
26
-
27
- ## Subcommands
28
-
29
- The bin is `pdks`, with `polydeukes` as an alias. Every argument form is matched against a
30
- finite table: `covenant check` takes an optional domain flag, `init claude-code` and
31
- `init grok` are exact, `explain` takes one word, and `docs` takes an optional topic.
32
-
33
- ### `pdks covenant check`
34
-
35
- `pdks covenant check [--worktree | --range <base>..<head>]` — the commit-surface judgment
36
- runner. It discovers the config at the working directory,
37
- collects one observation of the repository through the git adapter, translates it into the
38
- covenant input IR, and dispatches it through the same in-process judges the session hook calls.
39
- Which observation is the domain flag's choice — the same violation receives the same verdict
40
- in all three:
41
-
42
- | Form | Domain | `pre` → `post` |
43
- |---|---|---|
44
- | `pdks covenant check` | The staging area — what a pre-commit hook judges | HEAD blob → staged blob |
45
- | `pdks covenant check --worktree` | The working tree, untracked (non-ignored) files included | HEAD blob → bytes on disk |
46
- | `pdks covenant check --range <base>..<head>` | Two refs; `<base>...<head>` reads from their merge-base, the PR reading | base blob → head blob |
47
-
48
- `--worktree` and `--range` are diagnostic calls — run them after a task, before a PR, or in
49
- CI. Only the staged form is a gate, so only it can prompt for the witness token; the other
50
- two report exit `2` without a prompt, since there is no commit for a human to open.
51
-
52
- | Situation | Result |
53
- |---|---|
54
- | The domain's changes break nothing | exit `0` |
55
- | A staged change breaks a covenant, `enforce: block`, config has a `witness` block | Prompts once on `/dev/tty` for the witness token; an unanswered or wrong answer exits `2` |
56
- | The same, with no `witness` block in the config | exit `2` with no prompt — the valve is built from that block, so without it nothing can open a block |
57
- | A worktree or range change breaks a covenant, `enforce: block` | exit `2`, never a prompt |
58
- | A change breaks a covenant, `enforce: advise` | One advisory line on stderr, exit `0`, recorded `advised` |
59
- | Empty domain (nothing staged, a clean tree, identical refs) | exit `0` — an explicit pass, not a skipped run |
60
- | A range naming a ref git cannot resolve, or two refs with no merge-base | exit `2`, one `blocked` row |
61
- | `--range` without an argument, an argument without `..`, both flags at once, or an unknown flag | The usage line on stderr, exit `2` |
62
- | No config, more than one config, or an invalid one | exit `2` |
63
- | A judge body that cannot be loaded | exit `2` |
64
-
65
- Declarations that read the session (`precedent` and the other history mechanisms) assemble
66
- here like any other entry, but this surface has no session to read: a match records
67
- `skipped` and the commit proceeds. That is a permanent condition of the commit surface, not a
68
- fault.
69
-
70
- ### `pdks init claude-code`
71
-
72
- The session-surface installer. It proves that `polydeukes` resolves from the directory it
73
- was invoked in **before writing anything**, then creates six artifacts:
74
-
75
- | Artifact | Kind |
76
- |---|---|
77
- | `.claude/hooks/covenant-pretooluse.mjs` | Created — a delegator that loads the judge from the installed package |
78
- | `.claude/settings.json` | Merged — the PreToolUse registration is added to whatever the file already carries |
79
- | `polydeukes.config.yaml` | Created — the starter policy, with a placeholder `languages` block |
80
- | `.claude/rules/polydeukes.md` | Created — tells the AI partner to ask [`pdks docs`](#pdks-docs-topic) instead of searching the web |
81
- | `.claude/skills/discipline-draft/SKILL.md` | Created — the classification procedure: a described problem becomes a config entry (judged at advise, or `draft: true`), and advised rows are consulted in the telemetry log |
82
- | `.gitignore` | Appended — one line for `.polydeukes/` |
83
-
84
- Nothing existing is overwritten: an artifact already present is reported as skipped and left
85
- alone, so a re-run is a no-op. A precondition failure — the package not resolving, two
86
- coexisting config spellings, an unparseable settings file — writes zero files and exits `2`,
87
- never a half-wired tree.
88
-
89
- ### `pdks init grok`
90
-
91
- The Grok session-surface installer. Same preflight and the same shared scaffold (config and
92
- the `.polydeukes/` ignore line). A Grok-only tree gets four artifacts (hook JSON, the grok
93
- delegator, config, ignore line) and no `.claude/` directory. The JSON registration carries
94
- `timeout` 60 (the host default is 5 seconds; a timed-out hook fails open). If
95
- `.claude/hooks/covenant-pretooluse.mjs` already exists, the JSON command points at that file
96
- so the host does not spawn two judges. A later run of either installer retargets an
97
- installer-generated grok-mjs command the same way, and the JSON matcher follows the
98
- `.claude/settings.json` entry for that command (Grok collapses two registrations only when
99
- command and matcher both match); a command pointed elsewhere is left alone.
100
-
101
- An already-open Grok session keeps the hook snapshot from start; reload from the Hooks tab
102
- (`r`) or start a new session. The witness valve does not open on Grok: the session log is
103
- ACP `updates.jsonl`, not Claude's JSONL.
104
-
105
- ### `pdks docs [topic]`
106
-
107
- The offline documentation reader. The guides and this reference layer ship inside the
108
- package, so the answer comes from the installed version rather than from the network.
109
-
110
- | Call | Result |
111
- |---|---|
112
- | `pdks docs` | The topic list on stdout, exit `0` |
113
- | `pdks docs <topic>` | That topic's section, followed by a `See also:` line, exit `0` |
114
- | `pdks docs <unknown>` | The known topics named on stderr, exit `2` |
115
- | `pdks docs a b` | The usage line on stderr, exit `2` |
116
-
117
- | Topic | Answers from |
118
- |---|---|
119
- | `install` | [installation](../installation.md), in full |
120
- | `config` | [the configuration reference](./configuration.md), in full |
121
- | `discipline` | [the configuration reference](./configuration.md) — the `disciplines` section |
122
- | `covenant` | [configuration](../configuration.md) — What enforcement looks like |
123
- | `witness` | [the configuration reference](./configuration.md)'s `witness` section, then [troubleshooting](../troubleshooting.md)'s valve section |
124
-
125
- **Every failure leaves stdout at zero bytes.** A missing bundled document, a heading the
126
- document no longer carries, an unknown topic — each names what was missing on stderr and
127
- exits `2`. A partially written answer is one an agent reads as the document and quotes
128
- onward, so there is no such state.
129
-
130
- The bundle carries the English text only. Answers are returned verbatim, so the
131
- `[한국어](./X.ko.md)` link at the top of each document points at a mirror that lives in the
132
- [repository](https://github.com/huskyhoochu/polydeukes/tree/main/docs) rather than inside
133
- the package.
134
-
135
- `pdks init claude-code` writes a discovery file that points an AI partner at this
136
- subcommand; see the artifact table above.
137
-
138
- ### `pdks explain`
139
-
140
- The assembly reader. It loads the config at the working directory, assembles both surfaces'
141
- registration sets through the same functions the two judgment runners use, and prints them
142
- without judging — no judge thunk is called, no telemetry row is written, no transcript is
143
- read.
144
-
145
- ```text
146
- pdks explain — polydeukes.config.yaml
147
-
148
- surface: session (claude-code hook) · disciplines: advise unless enforce: block · meta: block
149
- registrations 43 · declare 21 · skip 19 · meta 3 · draft 1
150
- meta self-mod paths 14 (common; includes the config file itself)
151
- declare covenant-vocabulary added-only · change · empty nothing-added · scope target.path · include 1 · exclude 1 · sources 0 · valve — · why ✓
152
- declare pnpm-only forbidden-command · change · empty no-npm-mutation · scope command · include 0 · exclude 0 · sources 0 · valve — · why ✓
153
- declare manifest-needs-evidence precedent · history · nonEmpty npm-view, context7 · scope target.path · include 1 · exclude 0 · sources 1 (transcript 1) · valve — · why ✓
154
- skip covenant-vocabulary a shell write in scope whose result this layer cannot compute
155
- ...
156
- surface: commit (git pre-commit) · enforce: advise · disciplines: advise unless enforce: block
157
- registrations 24 · declare 22 · skip 1 · meta 1 · draft 1
158
- declare manifest-needs-evidence precedent · history · nonEmpty npm-view, context7 · scope target.path · include 1 · exclude 0 · sources 1 (transcript 1) · valve — · why ✓
159
- declare sqlite-only-under-knowledge naming · change · empty placed · scope target.path · include 1 · exclude 0 · sources 0 · valve — · why ✓
160
- ```
161
-
162
- One line per registration, in the order the surface dispatches them. The kind column has
163
- four words: `meta` (the registrations protecting the judging chain — `self-mod`,
164
- `shell-mod`, and on the session surface `transcript-mod`), `declare` (a declaration entry,
165
- with its mechanism, axes and relations, its scope source, the sizes of its include and
166
- exclude lists, its sources, and whether it carries a valve and a `why`), `skip` (a
167
- registration that records `skipped` instead of judging, with the reason the compiler gave —
168
- the reason that otherwise reaches stderr only on a config fault), and `draft` (an unpromoted
169
- `draft: true` entry, shown on both surfaces since it belongs to neither). `registrations`
170
- counts `meta`, `declare`, and `skip`; `draft` is tallied apart because it never becomes a
171
- registration.
172
- The commit surface's header also names its `adapters.git.enforce` level, since an advising
173
- surface records the same table but blocks nothing.
174
-
175
- The session surface is rendered as the hook sees it under a normal payload — with a
176
- transcript present — so `transcript-mod` and the session-reading declarations appear as they
177
- do in a session; on the commit surface those declarations record `skipped` when matched,
178
- which is that surface's permanent condition.
179
-
180
- | Call | Result |
181
- |---|---|
182
- | `pdks explain` | Both surfaces on stdout, exit `0` |
183
- | `pdks explain <anything>` | The usage line on stderr, exit `2` |
184
- | no config, two configs, or an invalid one | `pdks explain: <reason>` on stderr, stdout at zero bytes, exit `2` |
185
-
186
- ### Any other argument form
187
-
188
- Anything that is not one of these forms writes the usage line —
189
- `usage: pdks covenant check [--worktree | --range <base>..<head>] | pdks explain |
190
- pdks init claude-code | pdks init grok | pdks docs [topic]` — to stderr and exits `2`.
191
-
192
- ## Exit codes
193
-
194
- Three codes exist, and they live at two layers. **What a consumer's hook observes is only
195
- `0` or `2`** — both composition roots resolve to a named outcome carrying `exitCode: 0 | 2`.
196
-
197
- | Code | Constant | Emitted by | Means |
198
- |---|---|---|---|
199
- | `0` | `EXIT_UPHOLD` | Judge outcome, wrapper, bin | The promise was upheld — the call or commit proceeds |
200
- | `1` | `EXIT_BREAK_NON_BLOCKING` | Judge outcome only | A break reported as a signal. The wrapper translates it — into `2` under `enforce: block`, into `0` + an `advised` row under `advise`. It never reaches the surface either way |
201
- | `2` | `EXIT_BREAK_BLOCKING` | Wrapper, bin, fail-closed paths | The call or commit is refused |
202
-
203
- The asymmetry is the protocol's responsibility boundary. A judge decides *whether* a
204
- promise was broken and answers `0` or `1` in its outcome; deciding what a break *costs* belongs
205
- to the wrapper, and that is the one place `enforce` is read. A judge can therefore be run,
206
- tested, and reasoned about without knowing whether the surface it runs under blocks or advises.
207
- Only the verdict relaxes: every unjudgeable outcome — an outcome of `2` or higher, a throw
208
- from the judge — stays `2` at either level.
209
-
210
- **Everything unjudgeable resolves to `2`.** A missing config, an invalid one, an
211
- unparseable payload, a judge body that was never built — each fails closed. The one
212
- direction that stays open is measurement: a telemetry write that fails never changes a
213
- verdict.
214
-
215
- ## Programmatic surface
216
-
217
- The barrel (`import … from 'polydeukes'`) exports six symbols plus one re-exported type.
218
- This is the whole public API; the scoped packages are not part of it.
219
-
220
- ### `loadConfig`
221
-
222
- **Type signature:**
223
-
224
- ```ts
225
- function loadConfig(spec: LoadConfigSpec): LoadedConfig;
226
-
227
- type LoadConfigSpec = { rootDir: string };
228
-
229
- type LoadedConfig = {
230
- config: ResolvedConfig; // protectedPaths already includes the config file itself
231
- configPath: string; // rootDir-relative path of the discovered file
232
- };
233
- ```
234
-
235
- Discovers exactly one `polydeukes.config` file (`.yaml`, `.yml`, or `.json`) directly under
236
- `rootDir`. **Every failure branch throws** — none found, more than one found, a parse error,
237
- a schema violation. There are no silent defaults, because a silently defaulted config means
238
- a silently unprotected project.
239
-
240
- ### `runCovenantCheck`
241
-
242
- **Type signature:**
243
-
244
- ```ts
245
- function runCovenantCheck(spec: CovenantCheckSpec): Promise<CovenantCheckOutcome>;
246
-
247
- type CovenantCheckOutcome = { exitCode: 0 | 2 };
248
-
249
- type CovenantCheckSpec = {
250
- repoRoot: string; // config discovery and collection anchor here
251
- telemetryPath?: string; // overrides the config's log path
252
- covenantDist?: string; // overrides the resolved judge directory
253
- ttyPrompt?: (prompt: string) => string | null; // the TTY valve seam
254
- domain?: CheckDomain; // which observation to judge; absent = staged
255
- };
256
-
257
- type CheckDomain =
258
- | { kind: 'staged' }
259
- | { kind: 'worktree' }
260
- | { kind: 'range'; base: string; head: string; ancestry?: 'merge-base' };
261
- ```
262
-
263
- The commit surface's composition root — what [`pdks covenant
264
- check`](#pdks-covenant-check) runs. `ancestry: 'merge-base'` is the `<base>...<head>`
265
- reading; the adapter resolves the merge-base.
266
-
267
- `ttyPrompt` absent means a non-TTY environment, and the valve then has no way to open — an
268
- agent-spawned commit and a CI run reach the same state. The valve is a human at a terminal
269
- or nothing.
270
-
271
- ### `runClaudeCodeHook`
272
-
273
- **Type signature:**
274
-
275
- ```ts
276
- function runClaudeCodeHook(spec: ClaudeCodeHookSpec): Promise<ClaudeCodeHookOutcome>;
277
-
278
- type ClaudeCodeHookOutcome = { exitCode: 0 | 2 };
279
-
280
- type ClaudeCodeHookSpec = {
281
- repoRoot: string; // config discovery and discipline glob scoping anchor here
282
- rawPayload?: string; // absent means read fd 0 — the hook's real stdin
283
- telemetryPath?: string;
284
- covenantDist?: string;
285
- };
286
- ```
287
-
288
- The session surface's composition root — what the generated hook delegator calls. Reach it
289
- through the [`polydeukes/claude-code`](#subpaths) subpath rather than the barrel.
290
-
291
- **Neither composition root throws.** An uncaught rejection would exit the delegator
292
- non-blocking, which is the cheapest bypass there is, so both resolve their failures into
293
- `{ exitCode: 2 }` with a telemetry record instead.
294
-
295
- ### `ResolvedConfig`
296
-
297
- Re-exported from [`@polydeukes/core`](./core.md) so a consumer reading `loadConfig`'s result
298
- needs no second dependency.
299
-
300
- ## Subpaths
301
-
302
- | Specifier | Carries |
303
- |---|---|
304
- | `polydeukes` | The barrel — `loadConfig`, `runCovenantCheck`, their spec and outcome types, `ResolvedConfig`. The session hook lives on its own subpath below and nowhere else |
305
- | `polydeukes/claude-code` | `runClaudeCodeHook`, `ClaudeCodeHookSpec`, and `ClaudeCodeHookOutcome` alone |
306
- | `polydeukes/schema.json` | The config JSON Schema, copied from the core at build time |
307
-
308
- The generated hook delegator imports the subpath, not the barrel. ESM imports are eager, so
309
- importing the barrel would load the commit-surface runner — and the git adapter behind it —
310
- on every session tool call that will never use them. The subpath is the session surface's
311
- own entry point, and the barrel is for programmatic consumers.
312
-
313
- `polydeukes/schema.json` is for code that reads the schema. A `$schema` line names the file
314
- path instead — an editor reads that string statically, so no module resolver runs on it. Both
315
- spellings are in [configuration.md's IDE section](../configuration.md#ide-support).