@dzhechkov/harness-cli 0.8.21 → 0.8.22

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/.dz-manifest.json CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "README.md",
12
- "sha256": "2a3c1e1f9f922913c45df3482f2055ac2efc726108e1d4377195739e026a4034"
12
+ "sha256": "469aec881b39fe2b3e032bf75354fb7e998a08695327a74a69e0de90ad36a934"
13
13
  },
14
14
  {
15
15
  "path": "dist/bin.d.ts",
@@ -45,19 +45,19 @@
45
45
  },
46
46
  {
47
47
  "path": "dist/cli.d.ts",
48
- "sha256": "a4f6ad121c0e81336e517b10ba656af428cc07d9f41fdc00967d1cd0122be1ee"
48
+ "sha256": "9c58b7696526c47244bf5933ddc7ae3d7d43f025f1e74096cd90bfbe5aaada53"
49
49
  },
50
50
  {
51
51
  "path": "dist/cli.d.ts.map",
52
- "sha256": "ef3852bb748f37d4e78a9a973505c3993eae2b996cc0cdd0659f531aa76621f4"
52
+ "sha256": "613f870e75033657b8f68ee4650c4699dce036c08393b588b2ff7ca399dd688f"
53
53
  },
54
54
  {
55
55
  "path": "dist/cli.js",
56
- "sha256": "9d0a6cc044810b31d261b36913e3f63445f5e96550176fedd0faf606d8cbcd75"
56
+ "sha256": "112231fa1707bde97a6529c9cf2ad5c81e9d5e382b3a2b1fae89782b9918748a"
57
57
  },
58
58
  {
59
59
  "path": "dist/cli.js.map",
60
- "sha256": "3049258ffd0972b6a748eda703221911dd33e3450486c1dec0f598a431faa038"
60
+ "sha256": "dae7aacba3d82f15c882ebadaca268161159e5b9dfd278ace4e8b802e12d858e"
61
61
  },
62
62
  {
63
63
  "path": "dist/command-inventory.d.ts",
@@ -129,15 +129,15 @@
129
129
  },
130
130
  {
131
131
  "path": "dist/known-flags.d.ts.map",
132
- "sha256": "703058c8bbf0307ab29f12f8355c8984508f38214c32ab85da790446f0cb9699"
132
+ "sha256": "6b514318ec7c607ce7c6e9f7faccc98f2ddde0f2949aec4b730f0f104ef476c6"
133
133
  },
134
134
  {
135
135
  "path": "dist/known-flags.js",
136
- "sha256": "6bae6e7f551b6024e3212655f4c5a8f9e426ae0858ff3e65f08d0539bb617028"
136
+ "sha256": "a787a333c01e1e0c323581ac605884546011f9d2dbcbc1a0e8cadadb62e70695"
137
137
  },
138
138
  {
139
139
  "path": "dist/known-flags.js.map",
140
- "sha256": "9edabc481a2545ac56ddfdfba82623cd3ac1cf8a37551b5ff43930bf5f2ef48f"
140
+ "sha256": "8d182f4b1175c8b89cf48fe2cea671f060dc89850b9564669efd4e516b9e61bf"
141
141
  },
142
142
  {
143
143
  "path": "keys/README.md",
@@ -149,7 +149,7 @@
149
149
  },
150
150
  {
151
151
  "path": "package.json",
152
- "sha256": "52e0e71990b14cf8dc5b07046c30d6d9807f7cec1cdef4463ac6bd155b0312d4"
152
+ "sha256": "dd1df9b570449d53d4ec48e40df48cc23d78aefd0d2724cbf4aaede96645ebb6"
153
153
  },
154
154
  {
155
155
  "path": "src/bin.ts",
@@ -161,7 +161,7 @@
161
161
  },
162
162
  {
163
163
  "path": "src/cli.ts",
164
- "sha256": "f34208b28b53697118db5370f82c6aaab883bb7be10d99789a96a39a06acfac7"
164
+ "sha256": "695b4d6e3d50b78c8ff388a935a8f80634c7f92f64ab9f27d83eac4c7fe02bba"
165
165
  },
166
166
  {
167
167
  "path": "src/command-inventory.ts",
@@ -181,9 +181,9 @@
181
181
  },
182
182
  {
183
183
  "path": "src/known-flags.ts",
184
- "sha256": "f00496dde83db529d8dde54cf1a5a0048c4c08c49c085e035ad1c90d6a602b30"
184
+ "sha256": "d55cf907dda7b0357ffa66e374825f13ab99de69eecf49384f732f443160e76f"
185
185
  }
186
186
  ]
187
187
  },
188
- "signature": "xGTyQNnFIlVTZIRDcbaTCfyuQL3fbW3qReGYhLbjlFQ9k9wsYflwDXPDq/Ukge4VHEirdmE10W2RV1XQZEhUDA=="
188
+ "signature": "x1PZNEgjHR12BIoxEtzFW/pTbOnMdwHhVBXhu4mHMlOY6WQdS86sfcnN0bgqm9Kp8i2Fv6Kn0jijx97hYMNmAQ=="
189
189
  }
package/README.md CHANGED
@@ -14,7 +14,7 @@ process markers, including `execSync(` and `execFile(`, and fails when the list
14
14
 
15
15
  > **`dz` is a package manager + cross-compiler for your AI agent harness.** Write a skill once in one canonical form; `dz` installs it into any agent's harness, holds it to a quality bar, and lets the harness learn over time.
16
16
 
17
- **The problem.** You accumulate ~179 skills (design-thinking, QE, devops, web3, MCP, academic…). Five pains follow:
17
+ **The problem.** You accumulate 260 skills (design-thinking, QE, devops, web3, MCP, academic…). Five pains follow:
18
18
 
19
19
  1. **Every agent wants a different layout.** Claude Code reads `.claude/skills/`, Codex `.codex/`, OpenCode/Hermes/OpenClaude their own. Hand-maintaining N copies is sync hell.
20
20
  2. **Skills arrive from many upstream repos** — they must be *canonicalized* (brought to one form) and kept in sync without losing provenance.
@@ -353,9 +353,9 @@ dz help # see all commands
353
353
  dz pretrain # analyze project files → recommend by tech stack
354
354
  dz recommend "build API and deploy to K8s" # keyword match → skills + toolkits
355
355
  dz recommend "work on this project" # unmatched? → labels suggestions as PROJECT-STACK, not task-derived
356
- dz stats # 54 packages, 201 skills, 10 targets, 14 presets
356
+ dz stats # 58 packages, 260 skills, 10 targets, 14 presets
357
357
  dz dashboard # visual panel — packages, adapters, skill packs
358
- dz registry # browse all 179 skills by category
358
+ dz registry # browse all 260 skills by category
359
359
  dz registry search kubernetes # find specific skills
360
360
  dz registry --category devops # filter by domain
361
361
  dz downloads # npm weekly download stats
@@ -503,12 +503,36 @@ dz release # gates for the whole workspace;
503
503
  dz publish --dry-run # preview
504
504
  dz publish --filter skills-devops # publish specific package
505
505
  dz publish # publish all changed packages
506
+ dz publish --yes --mirror-cmd "node scripts/publish-mirror.mjs" # live publish + required mirror receipt
507
+ dz publish --yes --no-mirror # explicit one-run mirror opt-out
506
508
 
507
509
  # Export portable, self-contained skill bundles for a generic consumer (e.g. a LangGraph app):
508
510
  dz bundle --preset news --out ./dist # → ./dist/skills/<id>/ (SKILL.md + references/scripts/assets)
509
511
  dz bundle --select news-digest,goap-research-ed25519 --out ./dist
510
512
  ```
511
513
 
514
+ For a live sweep that publishes at least one package, `dz publish` can run a command-hook epilogue.
515
+ Set it for one invocation with `--mirror-cmd`, or persist the command in `.dz/config.json`:
516
+
517
+ ```json
518
+ {
519
+ "publish": {
520
+ "mirrorCommand": "node scripts/publish-mirror.mjs"
521
+ }
522
+ }
523
+ ```
524
+
525
+ The CLI exports `DZ_PUBLISHED=name@version,…` and appends `--expect name@version,… --json`. It marks
526
+ the mirror `confirmed` only when the command returns JSON containing the live-manifest receipt;
527
+ `unconfirmed`, `skipped`, and `not-configured` remain separate report states. If npm publication
528
+ failed, the command returns exit `1`. If npm publication landed but a configured mirror was not
529
+ confirmed, it returns exit `3` and prints a usable `re-run:` command. `--dry-run`, `--no-mirror`,
530
+ `--bump-only`, and a live sweep with zero published packages do not execute the hook. A malformed or
531
+ unreadable `.dz/config.json` leaves the mirror `not-configured`, returns the ordinary publish exit code,
532
+ and prints `⚠ mirror: .dz/config.json unreadable — …`; an explicit `--mirror-cmd` still takes precedence.
533
+ The repository wrapper prints human-readable output by default; `scripts/publish-mirror.mjs --json`
534
+ prints exactly one JSON document (the `dz publish` epilogue always selects this mode).
535
+
512
536
  ---
513
537
 
514
538
  ## Three Ways to Install Skills
@@ -1434,6 +1458,7 @@ Each pack is an npm package — click through for the **full per-skill documenta
1434
1458
  | [@dzhechkov/skills-book-digitizer](https://www.npmjs.com/package/@dzhechkov/skills-book-digitizer) | 8 | *dz-original* — book → installable methodology pack: `digitize-book` (orchestrator) + ingest/extract/distill/pack/kb-index + `book-brain-register` (CP6 promote → cross-project brain) + `source-brain-ingest` (repo sibling). Verified provenance, IP-safe, resumable (`dz init --select digitize-book`) ([ADR-001](https://github.com/djd1m/dz-harness-hub/blob/main/features/book-knowledge-digitizer/03_adr/001-book-to-skillpack-pipeline.md)) |
1435
1459
  | [@dzhechkov/skills-12factor](https://www.npmjs.com/package/@dzhechkov/skills-12factor) | 12 | *generated by the digitizer, CC BY 4.0* — The Twelve-Factor App distilled into 12 decision-moment skills (one per factor). The first PUBLIC digitized-book pack; paraphrased (shingling-gated), routing-gated (every factor carries triggers), attributed (`NOTICE`) (`dz init --select 12factor-config-in-environment,…`) |
1436
1460
  | [@dzhechkov/skills-book-ai-apps](https://www.npmjs.com/package/@dzhechkov/skills-book-ai-apps) | 17 | *generated by the digitizer, CP5-published* — «Building Applications with AI Agents» (Albada, рус. пер.) distilled into 17 decision-moment skills across the whole agent-building arc: agent-fit & model choice, single-vs-multi, orchestration, tool design, knowledge & memory, context engineering, evaluation, probabilistic behaviour checks, release gates, improvement loops, drift, human-in-the-loop, agent UX, governance, security. Ships our page-anchored Knowledge Units, NOT the book text — shingling-gated at 0 uncited verbatim runs >=8 words; publication is the recorded CP5 owner decision; `trust_tier 1` (routing-gated, not human-reviewed) Since 0.2.2 it also ships `brain/ai-apps.sqlite`, the 223-KU knowledge slice: `dz brain add --from-pack @dzhechkov/skills-book-ai-apps` loads it into your `~/.dz/brain`, then `dz brain query --source ai-apps` answers in any project (`dz install @dzhechkov/skills-book-ai-apps --target claude-code`) |
1461
+ | [@dzhechkov/skills-book-clean-code](https://www.npmjs.com/package/@dzhechkov/skills-book-clean-code) | 9 | *generated by the digitizer, CP5-published 2026-09-11* — «Чистый код» (Robert C. Martin, рус. пер.): intent/comment contract, source layout, function contracts, object/data ownership, error and boundary handling, test-suite feedback, legacy refactoring loop, architecture assembly, concurrency safety; ships `brain/clean-code.sqlite` (259 KU). Shingling IP gate 0 violations on the published bytes; trust tier 1. |
1437
1462
 
1438
1463
  ### Available Presets (14)
1439
1464
 
@@ -2049,7 +2074,7 @@ dz verify-pack --pack <dir> [--pubkey <path>] # signature check of a pack: fai
2049
2074
  dz guard check --op <publish|teach|consolidate|reindex> [--text <s>] [--json] [--force <reason>] # declarative constraint layer before self-mutating ops: HARD violation → block (exit 1), SOFT → warn; zero-config defaults, .dz/guard.json to customise; dz guard --init | dz guard log (append-only audit). dz publish runs it automatically (--no-guard "<reason>" = logged escape hatch)
2050
2075
  dz guard promote [--dry-run | --apply] [--window-days <N>] [--periods <N>] [--json] # lesson → guard-rule promotion: ranks lessons by firings × cost, SHADOW-replays each candidate over real commits, and proposes a rule only after TWO consecutive wins AND two window-lengths of REAL elapsed time since first observation. Non-dry runs add bounded prospective funnel evidence to .dz/promotion-state.json without feeding the verdict; --dry-run remains write-free. --apply installs SOFT rules only; promotions/refusals remain under features/guard-promotion/promotions/
2051
2076
  dz feature-adr-setup --guards [--loc-cap <n>] [--apply] # P3: scaffold DETERMINISTIC guard tests into the project — guards.config.json + a zero-dependency check.mjs runner (LOC cap, secret scan, frozen-file sha256 pins, waivers-with-reasons); wire `node architecture/guards/check.mjs` into CI
2052
- dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] (dry-run by default; pass --yes/--confirm to go live; claim-check gate defaults to warn surfaces README claim findings, never blocks)
2077
+ dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] [--mirror-cmd <cmd>|--no-mirror] (dry-run by default; pass --yes/--confirm to go live; a configured mirror must return a live receipt or the published run exits 3; config: publish.mirrorCommand)
2053
2078
  dz parity [--target <name>] [--json] # honest feature×target map COMPUTED from the capability model — full / manual (via which form) / absent, per target
2054
2079
  dz release [--filter <name>] [--affected] [--audit-dev] [--tag] [--publish] [--json] [--dry-run] [--no-issue] # VERIFIED release: 4 HARD gates in front of dz publish — package test suites, pnpm audit --prod >=high (--audit-dev widens), node --check of every dist/bin file (unbuilt package with a build script ⇒ MISSING_DIST fail), bin smoke-boot "node <bin> --help" (temp cwd + timeout); --affected narrows to git-touched packages (fail-open); any red gate STOPS the release (exit 1) + best-effort gh issue; green ⇒ re-sign reminder, then the ready dz publish command (never with --yes injected)
2055
2080
  dz auto-canonicalize --source <github-url> --pack <skills-pack>
@@ -4713,23 +4738,19 @@ refusal as the honest answer.
4713
4738
 
4714
4739
  ## Status
4715
4740
 
4716
- `harness-core v0.8.29` · `harness-cli v0.8.21` — **this release: the release itself is checked
4717
- before it is pressed, and the repository boundary is honest.** (1) `dz guard` gains two rules:
4718
- `release-line-in-sync` the version line in the root README and the CLI README must name the
4719
- versions `package.json` carries, and `dz publish` now rewrites those lines itself; `signature-fresh`
4720
- a changed pack whose Ed25519 manifest was signed over older bytes is named BEFORE publication
4721
- (`workspace:` specs are rewritten before hashing, exactly as the pack is published). (2) `readme-first`
4722
- compares the `version` field against HEAD instead of "package.json changed", so a repository-field
4723
- edit no longer reads as a release. (3) All 56 workspace `package.json` files carry the real
4724
- `repository` origin, pinned by a test. (4) Suites that spawn processes or hold real locks run in a
4725
- serial vitest project (`test/serial-suites.txt`, audited by a census test); the CLI suite dropped from
4726
- ~6 minutes to ~2m20 once the in-process marketplace guard left the worker-RPC path. (5) `isRepoBoundary`:
4727
- a `.git` directory is a repository boundary only with a real `HEAD` (or a worktree `gitdir:` file), so
4728
- `dz` run from `/tmp` beside a stray empty `.git` no longer adopts it as a project and no longer creates
4729
- `/tmp/.dz`. A planned fallback lock location was MEASURED unsound (two processes could hold two
4730
- different locks for one root) and withdrawn before release — named locks stay `<root>/.dz/locks`, a
4731
- pure function of the root. (6) `dz amendment-check` recognises the Russian challenge-panel placeholder
4732
- as a stub.
4741
+ `harness-core v0.8.30` · `harness-cli v0.8.22` — **this release: the store guard tells "busy" from "broken",
4742
+ and a publish is not finished until the public mirror confirms it.** (1) The learning-store guard used to
4743
+ turn ANY read failure into `unreadable` and refuse the write; a neighbour holding the SQLite write lock
4744
+ (`SQLITE_BUSY`) or a store still being initialised (`no such table`) now gets bounded retries and, if still
4745
+ busy, the verdict `busy` = **NOT MEASURED** the write proceeds under the store lock, the high-water mark
4746
+ is left untouched, and both the text panel and `dz statusline --json` say so from one verdict. MEASURED:
4747
+ eight barrier-synchronised `dz teach` writers from two worktrees no longer lose a lesson to a false
4748
+ refusal. (2) `dz publish` gained a mirror epilogue: after a live sweep lands at least one package it runs
4749
+ `publish.mirrorCommand` from `.dz/config.json` (or `--mirror-cmd`), passes the published versions, and reads
4750
+ a JSON receipt whose proof is the live raw `MIRROR-MANIFEST.json` carrying those versions. Publication
4751
+ errors stay exit `1`; packages published but the mirror NOT confirmed exit **`3`** with the exact `re-run:`
4752
+ command; dry runs, `--no-mirror`, `--bump-only` and zero-package sweeps never invoke the hook, and each of
4753
+ those states is named in the report. This is the first release published THROUGH that epilogue.
4733
4754
 
4734
4755
  `dz guard check --op publish` now warns when either release line disagrees with the core/CLI package versions, and a registry-confirmed live core or CLI publish synchronizes the first such line in both release READMEs: each README is rewritten atomically; the pair is not one transaction (dry-run and bump-only never write them).
4735
4756
 
package/dist/cli.d.ts CHANGED
@@ -59,6 +59,8 @@ export interface CliIo {
59
59
  * without spawning anything.
60
60
  */
61
61
  readonly releaseRunner?: ReleaseExecRunner;
62
+ /** Post-publish mirror command seam; production uses synchronous shell execution. */
63
+ readonly publishMirrorRunner?: PublishMirrorRunner;
62
64
  /**
63
65
  * Test seam for `dz install`: overrides the `npm install` subprocess (production leaves
64
66
  * it unset → real `execSync`, stdio piped). A stub runner that pre-stages a fixture
@@ -81,6 +83,10 @@ export type ReleaseExecRunner = (cmd: string, opts: {
81
83
  stderr: string;
82
84
  timedOut?: boolean;
83
85
  };
86
+ export type PublishMirrorRunner = (command: string, options: {
87
+ readonly cwd: string;
88
+ readonly env: NodeJS.ProcessEnv;
89
+ }) => string;
84
90
  type Write = (line: string) => void;
85
91
  /**
86
92
  * Команда npm для установки пакета В ЦЕЛЕВОЙ КАТАЛОГ, а не куда решит npm.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -104,7 +104,7 @@ Usage:
104
104
  dz upgrade [--target <name>] [--pubkey <path>] [--require-signing] (a TAMPERED pack aborts the upgrade)
105
105
  dz sign --pack <dir> --key <path-outside-repo> (Ed25519 manifest + CycloneDX SBOM for a pack)
106
106
  dz verify-pack --pack <dir> [--pubkey <path>] (signature check; fail-closed; key from the repo, never the pack)
107
- dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] [--require-signing] [--provenance|--no-provenance] (dry-run by default; pass --yes/--confirm/--no-dry-run to go live; claim-check gate default warn — surfaces README claim findings, never blocks; error fails an offending package)
107
+ dz publish [--filter <name>] [--bump-only] [--claim-check <off|warn|error>] [--mirror-cmd <cmd>|--no-mirror] [--require-signing] [--provenance|--no-provenance] (dry-run by default; pass --yes/--confirm/--no-dry-run to go live; claim-check gate default warn — surfaces README claim findings, never blocks; error fails an offending package)
108
108
  dz release [--filter <name>] [--tag] [--publish] [--json] [--dry-run] [--no-issue] (VERIFIED release: 4 HARD gates in FRONT of dz publish — full package test suites, audit >=high, node --check of every dist/bin file, bin smoke-boot via "node <bin> --help" — any red gate STOPS the release (exit 1) + best-effort gh issue; all green ⇒ re-sign reminder, then prints the ready dz publish command (or chains with --publish); never duplicates publish's own gates)
109
109
  dz parity [--target <name>] [--json] (the honest feature×target map, COMPUTED from the capability model — which harness feature is full / manual / absent on each of the ${TARGET_NAMES.length} targets, and via which form)
110
110
  dz delivery-check --slug <slug> [--context-only] [--findings <f.json>] [--strict] [--author <model>] [--json] (portable Step-10 Delivery Gate: prints the 4-plane review brief + artifact probes; --findings classifies a fed-back review into a fail-closed ready|blocked hand-off and writes features/<slug>/10_delivery_review.md; --strict exits 1 on blocked)
@@ -2331,6 +2331,9 @@ function cmdStatusline(options, flags, cwd, write, readStdin, writeErr) {
2331
2331
  line += ` ⛔ STORE UNREADABLE${data.storeHealth.unreadableFiles !== undefined && data.storeHealth.unreadableFiles.length > 0
2332
2332
  ? `: ${data.storeHealth.unreadableFiles.join(', ')}` : ''}`;
2333
2333
  }
2334
+ else if (data.storeHealth?.verdict === 'busy') {
2335
+ line += ' ⏳ STORE BUSY';
2336
+ }
2334
2337
  else if (data.storeHealth?.verdict === 'source-changed') {
2335
2338
  line += ' ⚠ store source changed';
2336
2339
  }
@@ -2940,9 +2943,9 @@ function learningStoreLine(storeRoot, projectOption, target, verb) {
2940
2943
  const reason = teachReasonPhrase(target.reason);
2941
2944
  return storeLocationLine(describeStoreLocation(storeRoot, projectOption, target.store === 'global' ? 'global' : undefined), verb) + (reason ? ' [' + reason + ']' : '');
2942
2945
  }
2943
- function inspectLearningStore(projectRoot) {
2946
+ function inspectLearningStore(projectRoot, countOptions) {
2944
2947
  const mark = readStoreMark(projectRoot);
2945
- const rows = countLearningStoreRowsReadonly(projectRoot);
2948
+ const rows = countLearningStoreRowsReadonly(projectRoot, countOptions);
2946
2949
  return { mark, rows, health: checkStoreHealth({ projectRoot, ...rows, mark }) };
2947
2950
  }
2948
2951
  function shellQuote(value) {
@@ -3014,7 +3017,8 @@ function refreshLearningStoreMark(projectRoot, writeErr, command, options = {})
3014
3017
  const rows = countLearningStoreRowsReadonly(projectRoot);
3015
3018
  const counts = observedRows(rows);
3016
3019
  if (counts === undefined) {
3017
- writeErr(`⚠ dz store guard: ${options.reader ? 'reader observation' : 'store operation'} completed but the external mark was not updated — a store tier is unreadable`);
3020
+ const busy = rows.lexicalRows === 'busy' || rows.vectorRows === 'busy';
3021
+ writeErr(`⚠ dz store guard: ${options.reader ? 'reader observation' : 'store operation'} completed but the external mark was not updated — ${busy ? 'store busy; health not measured this run' : 'a store tier is unreadable'}`);
3018
3022
  return;
3019
3023
  }
3020
3024
  writeStoreMark(projectRoot, {
@@ -3045,7 +3049,7 @@ function storeGuardResetReminder(projectRoot, writeErr, command) {
3045
3049
  function allowLearningStoreWrite(projectRoot, flags, writeErr, command) {
3046
3050
  let inspection;
3047
3051
  try {
3048
- inspection = inspectLearningStore(projectRoot);
3052
+ inspection = inspectLearningStore(projectRoot, { busyTimeoutMs: 250, attempts: 3 });
3049
3053
  }
3050
3054
  catch (error) {
3051
3055
  const health = {
@@ -3063,6 +3067,10 @@ function allowLearningStoreWrite(projectRoot, flags, writeErr, command) {
3063
3067
  // own row had landed.
3064
3068
  return true;
3065
3069
  }
3070
+ if (inspection.health.verdict === 'busy') {
3071
+ writeErr(`dz store guard: NOT MEASURED — ${inspection.health.reason}`);
3072
+ return true;
3073
+ }
3066
3074
  if (inspection.health.verdict === 'source-changed') {
3067
3075
  const counts = observedRows(inspection.rows);
3068
3076
  if (counts === undefined)
@@ -3105,6 +3113,8 @@ function warnLearningStoreRead(projectRoot, writeErr, command) {
3105
3113
  writeErr(line);
3106
3114
  return;
3107
3115
  }
3116
+ if (health.verdict === 'busy')
3117
+ return;
3108
3118
  const counts = observedRows(rows);
3109
3119
  if (counts !== undefined && counts.lexicalRows + counts.vectorRows > 0
3110
3120
  && (mark === undefined || mark.lexicalLast !== counts.lexicalRows || mark.vectorLast !== counts.vectorRows
@@ -6140,7 +6150,33 @@ function cmdSbom(options, flags, cwd, write) {
6140
6150
  write(out);
6141
6151
  return 0;
6142
6152
  }
6143
- function cmdPublish(options, flags, cwd, writeOutput) {
6153
+ function mirrorCommandFromConfig(cwd) {
6154
+ const configPath = join(cwd, '.dz', 'config.json');
6155
+ if (!existsSync(configPath))
6156
+ return {};
6157
+ try {
6158
+ const config = JSON.parse(readFileSync(configPath, 'utf8'));
6159
+ const command = typeof config.publish?.mirrorCommand === 'string' ? config.publish.mirrorCommand.trim() : '';
6160
+ return command === '' ? {} : { command };
6161
+ }
6162
+ catch (error) {
6163
+ const reason = error instanceof Error ? error.message : String(error);
6164
+ return { warning: `.dz/config.json unreadable — ${reason}` };
6165
+ }
6166
+ }
6167
+ function mirrorShellToken(value) {
6168
+ if (value === '')
6169
+ return "''";
6170
+ if (!/^[A-Za-z0-9@/.,+_-]+$/.test(value))
6171
+ throw new Error('published package/version list is not shell-safe');
6172
+ return value;
6173
+ }
6174
+ function mirrorFailureMessage(error) {
6175
+ if (error instanceof Error && error.message.trim() !== '')
6176
+ return error.message.trim().split(/\r?\n/, 1)[0] ?? 'mirror command failed';
6177
+ return String(error);
6178
+ }
6179
+ function cmdPublish(options, flags, cwd, writeOutput, mirrorRunner) {
6144
6180
  const json = flags.has('json');
6145
6181
  // Under --json stdout carries exactly one JSON document, so every human line — guard notes, refusals,
6146
6182
  // progress — goes to stderr instead of being dropped: a refusal that prints nothing is the silent
@@ -6148,9 +6184,9 @@ function cmdPublish(options, flags, cwd, writeOutput) {
6148
6184
  const write = json ? (line) => { process.stderr.write(`${line}\n`); } : writeOutput;
6149
6185
  // Reject unknown flags/options so a typo (e.g. `--dry-rum`) can NEVER be
6150
6186
  // silently swallowed and flip the command into live-publish mode.
6151
- const allowedFlags = new Set(['dry-run', 'no-dry-run', 'yes', 'confirm', 'bump-only', 'help', 'require-signing', 'provenance', 'no-provenance', 'json']);
6152
- const allowedOptions = new Set(['filter', 'claim-check', 'no-guard', 'sign-key']);
6153
- const allowedHelp = ' allowed: --dry-run (default), --yes/--confirm/--no-dry-run (go live), --bump-only, --filter <substr>, --claim-check <off|warn|error>, --no-guard "<reason>" (skip the guard pre-flight; logged)';
6187
+ const allowedFlags = new Set(['dry-run', 'no-dry-run', 'yes', 'confirm', 'bump-only', 'help', 'require-signing', 'provenance', 'no-provenance', 'json', 'no-mirror']);
6188
+ const allowedOptions = new Set(['filter', 'claim-check', 'no-guard', 'sign-key', 'mirror-cmd']);
6189
+ const allowedHelp = ' allowed: --dry-run (default), --yes/--confirm/--no-dry-run (go live), --bump-only, --filter <substr>, --claim-check <off|warn|error>, --mirror-cmd <cmd>, --no-mirror, --no-guard "<reason>" (skip the guard pre-flight; logged)';
6154
6190
  for (const flag of flags) {
6155
6191
  if (!allowedFlags.has(flag)) {
6156
6192
  write(`dz publish: unknown option --${flag}`);
@@ -6332,7 +6368,7 @@ function cmdPublish(options, flags, cwd, writeOutput) {
6332
6368
  // longer exist. Default to the same path `dz sign --init` writes, so the ordinary operator needs no
6333
6369
  // new flag; `--sign-key` overrides it.
6334
6370
  const signKey = (options.get('sign-key') ?? join(homedir(), '.dz', 'keys', 'dz.key')).trim();
6335
- const report = publishPackages(cwd, {
6371
+ const publishReport = publishPackages(cwd, {
6336
6372
  provenance,
6337
6373
  dryRun,
6338
6374
  filter,
@@ -6414,9 +6450,82 @@ function cmdPublish(options, flags, cwd, writeOutput) {
6414
6450
  }
6415
6451
  },
6416
6452
  });
6453
+ const configMirror = mirrorCommandFromConfig(cwd);
6454
+ const configuredCommand = (options.get('mirror-cmd') ?? configMirror.command ?? '').trim();
6455
+ const publishedVersions = publishReport.packages
6456
+ .filter((pkg) => pkg.status === 'published')
6457
+ .map((pkg) => `${pkg.name}@${pkg.newVersion}`);
6458
+ const expected = publishedVersions.join(',');
6459
+ const fullMirrorCommand = configuredCommand === ''
6460
+ ? ''
6461
+ : `${configuredCommand} --expect ${mirrorShellToken(expected)} --json`;
6462
+ let mirror;
6463
+ // This exact conjunction is the Step-7/8 mutation anchor: an epilogue is eligible only after a
6464
+ // live sweep that actually landed at least one package. Other explicit skip states are handled
6465
+ // before command resolution so each reason remains distinguishable in text and JSON.
6466
+ const mirrorEligible = !dryRun && publishReport.published >= 1;
6467
+ if (bumpOnly) {
6468
+ mirror = { status: 'skipped', command: fullMirrorCommand, reason: 'bump-only' };
6469
+ }
6470
+ else if (!mirrorEligible) {
6471
+ mirror = {
6472
+ status: 'skipped',
6473
+ command: fullMirrorCommand,
6474
+ reason: dryRun ? 'dry-run' : 'published=0',
6475
+ };
6476
+ }
6477
+ else if (flags.has('no-mirror')) {
6478
+ mirror = { status: 'skipped', command: fullMirrorCommand, reason: '--no-mirror' };
6479
+ }
6480
+ else if (configMirror.warning !== undefined && options.get('mirror-cmd') === undefined) {
6481
+ mirror = { status: 'not-configured', command: '', warning: configMirror.warning };
6482
+ }
6483
+ else if (configuredCommand === '') {
6484
+ mirror = { status: 'not-configured', command: '' };
6485
+ }
6486
+ else {
6487
+ const runMirror = mirrorRunner
6488
+ ?? ((command, runnerOptions) => execSync(command, {
6489
+ cwd: runnerOptions.cwd,
6490
+ env: runnerOptions.env,
6491
+ encoding: 'utf8',
6492
+ stdio: 'pipe',
6493
+ }));
6494
+ try {
6495
+ const stdout = runMirror(fullMirrorCommand, {
6496
+ cwd,
6497
+ env: { ...process.env, DZ_PUBLISHED: expected },
6498
+ });
6499
+ const parsed = JSON.parse(stdout);
6500
+ if (parsed.ok !== true)
6501
+ throw new Error(typeof parsed.error === 'string' ? parsed.error : 'mirror command returned ok:false');
6502
+ if (typeof parsed.commit !== 'string' || parsed.commit === '')
6503
+ throw new Error('mirror command returned no commit');
6504
+ if (typeof parsed.receipt?.manifestUrl !== 'string'
6505
+ || typeof parsed.receipt.confirmedAt !== 'string'
6506
+ || typeof parsed.receipt.waitedMs !== 'number') {
6507
+ throw new Error('mirror command returned no live-manifest receipt');
6508
+ }
6509
+ mirror = {
6510
+ status: 'confirmed',
6511
+ command: fullMirrorCommand,
6512
+ commit: parsed.commit,
6513
+ receipt: {
6514
+ manifestUrl: parsed.receipt.manifestUrl,
6515
+ confirmedAt: parsed.receipt.confirmedAt,
6516
+ waitedMs: parsed.receipt.waitedMs,
6517
+ },
6518
+ };
6519
+ }
6520
+ catch (error) {
6521
+ mirror = { status: 'unconfirmed', command: fullMirrorCommand, error: mirrorFailureMessage(error) };
6522
+ }
6523
+ }
6524
+ const report = { ...publishReport, mirror };
6525
+ const exitCode = report.errors > 0 ? 1 : mirror.status === 'unconfirmed' ? 3 : 0;
6417
6526
  if (json) {
6418
6527
  writeOutput(JSON.stringify(report));
6419
- return report.errors > 0 ? 1 : 0;
6528
+ return exitCode;
6420
6529
  }
6421
6530
  write(`\ndz publish${dryRun ? ' --dry-run' : ''}${bumpOnly ? ' --bump-only' : ''}${claimCheckOpt !== 'warn' ? ` --claim-check ${claimCheckOpt}` : ''}`);
6422
6531
  write(` Published: ${report.published} Skipped: ${report.skipped} Errors: ${report.errors}\n`);
@@ -6463,7 +6572,24 @@ function cmdPublish(options, flags, cwd, writeOutput) {
6463
6572
  write(` ⚠ warning: ${warning}`);
6464
6573
  for (const path of report.releaseLineSynced ?? [])
6465
6574
  write(` ↳ release line synced: ${path}`);
6466
- return report.errors > 0 ? 1 : 0;
6575
+ if (mirror.status === 'confirmed') {
6576
+ write(` ✓ mirror: confirmed — ${mirror.commit} (${mirror.receipt?.manifestUrl})`);
6577
+ }
6578
+ else if (mirror.status === 'not-configured') {
6579
+ if (mirror.warning !== undefined)
6580
+ write(` ⚠ mirror: ${mirror.warning}`);
6581
+ else
6582
+ write(' ℹ mirror: not configured');
6583
+ }
6584
+ else if (mirror.status === 'skipped') {
6585
+ write(` ℹ mirror: skipped (${mirror.reason})`);
6586
+ }
6587
+ else {
6588
+ write(` ✗ mirror: unconfirmed — ${mirror.error}`);
6589
+ const rerun = mirror.command || 'configure publish.mirrorCommand, then run it';
6590
+ write(`dz publish: published, mirror NOT confirmed — ${mirror.error}; re-run: ${rerun}`);
6591
+ }
6592
+ return exitCode;
6467
6593
  }
6468
6594
  /* ------------------------------------------------------------------ */
6469
6595
  /* dz parity — the honest feature×target map (target-parity-matrix, */
@@ -17990,7 +18116,7 @@ export async function runCli(argv, io = {}) {
17990
18116
  case 'auto-canonicalize':
17991
18117
  return await cmdAutoCanonicalize(options, cwd, write);
17992
18118
  case 'publish':
17993
- return cmdPublish(options, flags, cwd, write);
18119
+ return cmdPublish(options, flags, cwd, write, io.publishMirrorRunner);
17994
18120
  case 'release':
17995
18121
  return cmdRelease(options, flags, cwd, write, io.releaseRunner);
17996
18122
  case 'parity':