@dzhechkov/harness-cli 0.8.20 → 0.8.21

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": "c0a20ecaf17559f5493f7b8ca5b23c946daa7f0e218a5e64bc2030bf609e8463"
12
+ "sha256": "2a3c1e1f9f922913c45df3482f2055ac2efc726108e1d4377195739e026a4034"
13
13
  },
14
14
  {
15
15
  "path": "dist/bin.d.ts",
@@ -49,15 +49,15 @@
49
49
  },
50
50
  {
51
51
  "path": "dist/cli.d.ts.map",
52
- "sha256": "22cddd1ff809cea9301af0905195bc1f2ff29730ce1b8a257c99c518457cff34"
52
+ "sha256": "ef3852bb748f37d4e78a9a973505c3993eae2b996cc0cdd0659f531aa76621f4"
53
53
  },
54
54
  {
55
55
  "path": "dist/cli.js",
56
- "sha256": "724695fafaa2a68b6c279ea1f55f14732888ee7ba6919f991ace14fa54620b08"
56
+ "sha256": "9d0a6cc044810b31d261b36913e3f63445f5e96550176fedd0faf606d8cbcd75"
57
57
  },
58
58
  {
59
59
  "path": "dist/cli.js.map",
60
- "sha256": "2935abfc89e4a704d9615b0417ff19279487c05a8a97347b2de6c88908276d33"
60
+ "sha256": "3049258ffd0972b6a748eda703221911dd33e3450486c1dec0f598a431faa038"
61
61
  },
62
62
  {
63
63
  "path": "dist/command-inventory.d.ts",
@@ -149,7 +149,7 @@
149
149
  },
150
150
  {
151
151
  "path": "package.json",
152
- "sha256": "061c6ef25e82139629e9653eec4d8ef2e3e5249220a4c4eedf0ca1f5229bbdd3"
152
+ "sha256": "52e0e71990b14cf8dc5b07046c30d6d9807f7cec1cdef4463ac6bd155b0312d4"
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": "f0bc9f52737064a3d5b26fb2ef07c0aa79e003dfca5e1277cd0988a65cdeeb8e"
164
+ "sha256": "f34208b28b53697118db5370f82c6aaab883bb7be10d99789a96a39a06acfac7"
165
165
  },
166
166
  {
167
167
  "path": "src/command-inventory.ts",
@@ -185,5 +185,5 @@
185
185
  }
186
186
  ]
187
187
  },
188
- "signature": "QSY8d8zh9pIN95GmytJ9L5yfhQgHeUgLjSCFfx8fxiVJL7DPD/gi/XrlDDEAz6cr1oMqObxvOgFJdL/O9kPGBw=="
188
+ "signature": "xGTyQNnFIlVTZIRDcbaTCfyuQL3fbW3qReGYhLbjlFQ9k9wsYflwDXPDq/Ukge4VHEirdmE10W2RV1XQZEhUDA=="
189
189
  }
package/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  The **`dz`** CLI — the main entry point to the DZ Harness Hub. Install AI skills for **Claude Code, Codex, OpenCode, Hermes, OpenClaude, GitHub Copilot** from a single command.
4
4
 
5
+ ## Test execution
6
+
7
+ `npx vitest run` uses two projects and returns one combined verdict: `parallel` runs the ordinary
8
+ suites concurrently, while `serial` runs process-spawning and real-time suites one file at a time.
9
+ The serial paths in `test/serial-suites.txt` are regenerated from
10
+ `test/serial-suites-census.test.ts`, which scans test sources for synchronous and asynchronous
11
+ process markers, including `execSync(` and `execFile(`, and fails when the list and census differ.
12
+
5
13
  ## Why dz?
6
14
 
7
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.
@@ -3091,6 +3099,8 @@ if the registry answers, the publish DID land and only the local bump was rolled
3091
3099
  Registry probes run `npm view … --prefer-online`, because the publisher itself warms the packument cache before publishing (measured 2026-09-10: 30 misses on a landed package).
3092
3100
  On an error, `dz publish` prints the last three probe records (attempt, exit code, elapsed milliseconds,
3093
3101
  and the first captured stderr/stdout line); `--json` returns the complete, untruncated `probeLog`.
3102
+ The text report also prints every post-publish warning and each README whose release line was synchronized;
3103
+ `--json` keeps those same facts in `warnings` and `releaseLineSynced` without extra human-output lines.
3094
3104
  In a multi-package batch, a dependent is not bumped or published after one of its workspace dependencies
3095
3105
  has failed in that batch; its error names the dependency and preserves the dependency's failure reason.
3096
3106
 
@@ -3856,7 +3866,7 @@ invariants: HARD rules **block** the operation, SOFT rules warn. Zero config nee
3856
3866
  cover the known rakes; `.dz/guard.json` (via `dz guard --init`) exists only if you want to tune a severity
3857
3867
  or disable a rule.
3858
3868
  ```bash
3859
- dz guard check --op publish # no-workspace-star · no-skill-drift · no-secrets · readme-consistency · readme-first · skills-registrable · lockfile-in-sync · marketplace-parity · no-stubs · review-round · licence-hold
3869
+ dz guard check --op publish # no-workspace-star · no-skill-drift · no-secrets · readme-consistency · readme-first · signature-fresh · skills-registrable · lockfile-in-sync · marketplace-parity · no-stubs · review-round · licence-hold
3860
3870
  dz guard check --op teach --text "the fix: export sk-abc..." # → BLOCK (exit 1): looks like a credential
3861
3871
  dz guard log # append-only audit: every verdict + every forced override
3862
3872
  ```
@@ -3869,10 +3879,15 @@ dz guard (teach): ✗ BLOCK [checked: no-secrets, store-bloat-cap]
3869
3879
  hatch `--no-guard "<reason>"` requires a reason and is logged to `.dz/guard-audit.jsonl` — an override is
3870
3880
  visible, never silent. Calibrated against false gates: in a pnpm workspace, `workspace:*` in source is
3871
3881
  *correct* (pnpm rewrites it at publish), so the rule resolves each workspace dep to the version it would
3872
- ship as and blocks only a dep that would ship raw. The `readme-consistency` rule also holds the **docs
3882
+ ship as and blocks only a dep that would ship raw. The SOFT `signature-fresh` rule checks only signed
3883
+ packs with changed non-manifest files and names the `dz sign` repair before publish. The
3884
+ `readme-consistency` rule also holds the **docs
3873
3885
  site** in the contour: the command count on the Starlight CLI overview and the front-page tagline must
3874
3886
  match the cli README (the site once drifted 35→55 silently; now a mismatch is a warning here and a red
3875
3887
  test in CI). In a repo without the docs site those pairs simply aren't gathered — no false gate.
3888
+ `readme-first` compares the package's `version` field with `HEAD`, so changing `repository` or other
3889
+ package metadata alone does not masquerade as a version bump; unreadable version evidence is reported as
3890
+ an `unknown` observation and never becomes a violation.
3876
3891
 
3877
3892
  The SOFT `lockfile-in-sync` rule closes the CI break that follows a dependency bump: when a workspace
3878
3893
  `packages/*/package.json` declares a `@dzhechkov/*` spec that differs from the specifier `pnpm-lock.yaml`
@@ -4698,21 +4713,25 @@ refusal as the honest answer.
4698
4713
 
4699
4714
  ## Status
4700
4715
 
4701
- `harness-core v0.8.27` · `harness-cli v0.8.20` — **this release: the instruments stopped lying in
4702
- four measured ways.** (1) A test run's exit code no longer conflates "a test failed" with "the runner
4703
- choked": `classifyRunFailure` names `runner-infrastructure` with the closed reason
4704
- `worker-rpc-timeout` when zero tests failed AND the runner's own worker-RPC pattern is present an
4705
- infrastructure outcome is NEVER green, it only stops being anonymous. (2) The Codex routing table is
4706
- PER-STAGE, following the owner's 2026-09-08 note: router Terra, requirements Sol, research Terra,
4707
- ADR and architecture Astra, plan Astra on L/XL and Sol otherwise, code Sol — and the plan cell reads
4708
- the tier the ROUTER produced, not only an explicitly passed argument, which is what kept half the
4709
- matrix dead. (3) The owner panel gains a mirror indicator (lexical lessons vs mirrored lessons,
4710
- silent on parity, silent when there is no mirror at all, loud when a mirror EXISTS and cannot be
4711
- read) and per-source KU volumes next to the brain count; panel text is English. (4) A mutation
4712
- registry entry may DECLARE an uncoverable protection with a mandatory reason: gaps are counted on
4713
- their own line with their own `⚠` marker and no longer fail the aggregate verdict a lamp that is
4714
- always on is read exactly like a lamp that is off. Six such gaps are declared for the orchestrator
4715
- script, which lives outside every package and is guarded today only by source-text assertions.
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.
4733
+
4734
+ `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).
4716
4735
 
4717
4736
  **Previously (`v0.8.12`):** ONE definition of "a dz
4718
4737
  command" (ADR-001, feature `command-count-triad`). `src/command-inventory.ts` is the single pure
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
@@ -22,7 +22,7 @@ import { createSkill, getSkillInfo, listSkillsDetailed, formatSkillLoadFailures,
22
22
  // dz workflow run (feature dz-workflow-run): the pure scheduler + the dispatch adapters.
23
23
  TRACE_RUNID_RE, WF_RUN_OWNER_HOST, preflight, runWorkflow, makeClaudePDispatcher, makeCodexExecDispatcher, NamedLockTimeoutError, NamedLockCompromisedError, POLICY_SOURCES, detectPolicyDrift, hasPolicyFence, TARGET_NAMES, buildParityMatrix, downgradeForStaleEvidence, findStaleTranscriptEvidence, TARGET_CAPABILITIES, TARGET_SHORT_LABELS, WORKFLOW_TEMPLATES_RETIRED_MESSAGE, parsePlan, isParseErrors, validatePlan, normalizePlan, planDigest, toTraceProjection, renderPlan, mergeRender, lint, lintExitCode, LOOP_BLOBS, parseTrace, assembleTimeline, runInvariants, deriveAttestation, stampAttestation, corroborate, NOT_WITNESSED, renderTimelineHtml, importEcc, recordPattern, recordLessonForms, normalizeLessonForms, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, renderFeatureAdrPhaseLine, statuslineData, countLearningStoreRowsReadonly, readStoreMark, writeStoreMark, resetStoreMark, checkStoreHealth, storeGuardPath, storeSnapshotPath, writeFeatureAdrState, writeFeatureAdrStateDetailed, CHECKPOINT_STAGES, estimateEta, extractStageSamples, formatEta, parseCheckpointLines, segmentRun, computeUsage, deriveCostLedger, planLedgerBackfill, listCostLedgerRuns, resolveLedgerRunId, AMBIGUOUS, stampCheckpointLine, LEDGER_FILL_SOURCE, renderCostLedger, verifyCostLedgerReport, writeCostLedgerJsonl, COST_LEDGER_SCOPE, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, parseWeeklyResetAnchor, claimCheck, summarize, BUNDLED_SLOP_REGISTRY_URL, DEFAULT_SLOP_CONFIG, parseSlopRegistry, slopLint, validateSlopLintConfig, queryBookKnowledge, loadStorePatternsSync, patternRecordId, patternIdentityOf, mergeLessonMatchedForms, SWARM_BRIEF_CONTRACT, checkSwarmBrief, visibleText, loadStoreRecords, findExactLesson, recordToPattern, bundleSkills, brainHome, listBrain, bookKbPath, promoteProjectToBrain, updateBrainSource, queryBrain, groundPrompt, expandKu, reindexBrainVectors, buildPrimer, exportBrainSlice, importBrainSlice, registerKusToBrain, RECALL_USAGE_LOG_RELATIVE, RECALL_USAGE_LOG_MAX_BYTES, parseRecallUsageLog, buildRecallUsageReport, EVENT_CHAIN_TAIL_BYTES, EMPTY_LOG_TAIL, readTailInfo, appendChainedLines, verifyEventChainText, classifyChainDefects, CHAINED_JOURNALS, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, appendTransition, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, parsePnpmLockImporters, scannableStubPath,
24
24
  // guard-promotion (feature guard-promotion, scout idea #1)
25
- assembleCandidates, renderPromotionReport, renderPromotionAdr, normalizePromotionState, nextPromotionState, recordPromotionRunEvidence, isLessonRuleContentAnchor, isOffsetIsoTimestamp, globMatch, promotionAdrRelPath, DEFAULT_WINDOW_DAYS, DEFAULT_PERIODS, MAX_CONTENT_FETCHES, BUILTIN_COVERAGE, decideProvenance, isInsideTree, signManifest, verifyManifest, listPackFiles, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, resolveScanTailTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, runRetroTailScan, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, classifyExecutionEvidence, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, harvestStageOutcomes, recommendModels, planFeed, unfedRuns, GRADE_SUCCESS_FLOOR, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, declaredPluginSurface, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, assembleCompoundingReport, buildDeadwoodReport, compactCmdUsageIfNeeded, measureCmdUsageDepthDays, recordCommandInvocation, resolveCmdUsageRoot, renderDeadwoodReport, CMD_USAGE_LOG_RELATIVE, banditStats, narrowBanditReport, renderBanditHealth,
25
+ assembleCandidates, renderPromotionReport, renderPromotionAdr, normalizePromotionState, nextPromotionState, recordPromotionRunEvidence, isLessonRuleContentAnchor, isOffsetIsoTimestamp, globMatch, promotionAdrRelPath, DEFAULT_WINDOW_DAYS, DEFAULT_PERIODS, MAX_CONTENT_FETCHES, BUILTIN_COVERAGE, decideProvenance, isInsideTree, signManifest, verifyManifest, hashPackBytes, rewriteWorkspaceSpecs, listPackFiles, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, collectPackageFacts, planReleaseGates, selectAffectedPackages, classifyGateExecutions, buildFailureIssue, buildReleaseNotes, releaseTagName, firstOutputLine, formatPublishError, MANIFEST_NAME, SBOM_NAME, buildArchitectureMap, renderMapHuman, findArchitectureDrift, renderDriftReport, scanWorkspacePackages, loadSubsystemManifest, loadProductVision, checkFeatureAgainstArchitecture, renderArchCheck, planProjectSkills, guidanceForStage, renderInjectionReport, analyzeCorpus, renderRakeReport, renderCriticSection, rakeAsLesson, rakeReward, DEFAULT_RAKE_THRESHOLDS, streamSessionEvents, findLatestTranscript, resolveScanTailTranscript, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, runRetroTailScan, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, classifyExecutionEvidence, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, harvestStageOutcomes, recommendModels, planFeed, unfedRuns, GRADE_SUCCESS_FLOOR, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, collectDeliveryFacts, planDeliveryCheck, renderDeliveryBrief, classifyDelivery, isUsablePlaneResult, renderDeliveryReview, scanSkillsLayout, declaredPluginSurface, parseInitFacts, verifyRegistration, buildContentProbePrompt, classifyContentProbe, renderContentProbe, findNonRegistrableSkillDirs, assembleCompoundingReport, buildDeadwoodReport, compactCmdUsageIfNeeded, measureCmdUsageDepthDays, recordCommandInvocation, resolveCmdUsageRoot, renderDeadwoodReport, CMD_USAGE_LOG_RELATIVE, banditStats, narrowBanditReport, renderBanditHealth,
26
26
  // Cold-vs-warm EPOCH RUNNER (feature epoch-replay) — orchestrates + scores, never calls a model.
27
27
  replayableInstances, buildWorkOrder, buildJudgePrompts, unblindJudgments, verifyWorkOrder, isValidMargin, DIGEST_HONEST_SCOPE, scoreEpochReplay, generateMockOutcomes, renderEpochReplayResult, renderWorkOrderSummary, renderJudgePromptsSummary, WORK_ORDER_KIND, DEFAULT_MOCK_N, DEFAULT_MOCK_SEED, scoreRun, readQeGrade, scoreReceiptToAggregateRow, readScoreAggregateRows, dedupeScoreAggregateRows, buildScoreAggregateReport, renderScoreAggregateReport, recapWindow, decideHorizon, withinWindow, buildRecap, renderRecap, parseSourceManifest, tgPostHtmlIssues, tgVisibleLength, decideTgSend, TG_TEXT_LIMIT, countRecallEventsForRun, unknownFlagNotice, mirrorWriterExplanation, appendRecallUsage, closenessLine, anyAboveFloor, decideNameCheck, renderNameCheck, exportedNamesIn, dispatchedCommandsIn, decideSourceProvenance, renderSourceProvenance, REFUSED_HORIZONS, renderScorecard, renderCompoundingReport, readReinforcementState, readQuarantineState, registrationExitCode, renderRegistrationReport,
28
28
  // Smart Backlog (feature smart-backlog) — goal-directed idea pipeline over the Brain vector engine.
@@ -6459,6 +6459,10 @@ function cmdPublish(options, flags, cwd, writeOutput) {
6459
6459
  write(` · ${item}`);
6460
6460
  }
6461
6461
  }
6462
+ for (const warning of report.warnings ?? [])
6463
+ write(` ⚠ warning: ${warning}`);
6464
+ for (const path of report.releaseLineSynced ?? [])
6465
+ write(` ↳ release line synced: ${path}`);
6462
6466
  return report.errors > 0 ? 1 : 0;
6463
6467
  }
6464
6468
  /* ------------------------------------------------------------------ */
@@ -8936,9 +8940,10 @@ function gatherGuardFacts(op, root, text, storeCap, publishFilter) {
8936
8940
  const out = volumeGitText(root, ['ls-files', 'packages/@dzhechkov/*/package.json']);
8937
8941
  for (const rel of out.split('\n').map((s) => s.trim()).filter(Boolean)) {
8938
8942
  try {
8939
- const m = JSON.parse(readFileSync(join(root, rel), 'utf8'));
8943
+ const packageJsonText = readFileSync(join(root, rel), 'utf8');
8944
+ const m = JSON.parse(packageJsonText);
8940
8945
  manifests.push(m);
8941
- located.push({ dir: rel.replace(/\/package\.json$/, ''), m });
8946
+ located.push({ dir: rel.replace(/\/package\.json$/, ''), m, text: packageJsonText });
8942
8947
  }
8943
8948
  catch { /* skip unreadable */ }
8944
8949
  }
@@ -8948,6 +8953,45 @@ function gatherGuardFacts(op, root, text, storeCap, publishFilter) {
8948
8953
  for (const m of manifests)
8949
8954
  if (m.name && typeof m.version === 'string')
8950
8955
  versionByName.set(m.name, m.version);
8956
+ // release-line-in-sync: filesystem access belongs in the CLI gatherer. The core evaluator receives
8957
+ // only immutable evidence, so evaluateGuard(facts) stays deterministic and independent of cwd.
8958
+ const coreManifestPath = join(root, 'packages', '@dzhechkov', 'harness-core', 'package.json');
8959
+ const cliManifestPath = join(root, 'packages', '@dzhechkov', 'harness-cli', 'package.json');
8960
+ if (existsSync(coreManifestPath) || existsSync(cliManifestPath)) {
8961
+ const readText = (path) => {
8962
+ try {
8963
+ return readFileSync(path, 'utf8');
8964
+ }
8965
+ catch {
8966
+ return null;
8967
+ }
8968
+ };
8969
+ const readVersion = (path) => {
8970
+ const raw = readText(path);
8971
+ if (raw === null)
8972
+ return null;
8973
+ try {
8974
+ const parsed = JSON.parse(raw);
8975
+ return typeof parsed.version === 'string' && /^\d+\.\d+\.\d+$/.test(parsed.version)
8976
+ ? parsed.version
8977
+ : null;
8978
+ }
8979
+ catch {
8980
+ return null;
8981
+ }
8982
+ };
8983
+ facts['releaseLines'] = {
8984
+ coreVersion: readVersion(coreManifestPath),
8985
+ cliVersion: readVersion(cliManifestPath),
8986
+ readmes: [
8987
+ { path: 'README.md', text: readText(join(root, 'README.md')) },
8988
+ {
8989
+ path: 'packages/@dzhechkov/harness-cli/README.md',
8990
+ text: readText(join(root, 'packages', '@dzhechkov', 'harness-cli', 'README.md')),
8991
+ },
8992
+ ],
8993
+ };
8994
+ }
8951
8995
  publishPackageRoots.push(...located
8952
8996
  .filter(({ dir, m }) => m.private !== true && (publishFilter === undefined
8953
8997
  || publishFilter.length === 0
@@ -9142,25 +9186,136 @@ function gatherGuardFacts(op, root, text, storeCap, publishFilter) {
9142
9186
  }
9143
9187
  catch { /* нечитаемо — правило молчит */ }
9144
9188
  facts['counts'] = gatherReadmeCounts(root);
9145
- // readme-first: from the WORKING-TREE diff (publishes happen pre-commit here), per package: does the
9146
- // change set contain its package.json (the version-bump signal) without its README.md?
9189
+ // One package-scoped WORKING-TREE diff feeds both readme-first and signature-fresh. A second
9190
+ // porcelain call could observe a different tree and let the two publish guards disagree.
9191
+ let changedPackageFiles;
9192
+ // readme-first: from the WORKING-TREE diff (publishes happen pre-commit here), per package: did
9193
+ // the version FIELD change from HEAD without its README.md changing? A package.json edit alone
9194
+ // says nothing about version; repository/metadata-only edits must not manufacture a bump.
9147
9195
  try {
9148
- const status = execSync('git status --porcelain -- "packages/@dzhechkov/"', { cwd: root, encoding: 'utf-8' });
9196
+ const status = execSync('git status --porcelain -uall -- "packages/@dzhechkov/"', { cwd: root, encoding: 'utf-8' });
9197
+ changedPackageFiles = status
9198
+ .split('\n')
9199
+ .map((line) => line.slice(3).trim())
9200
+ .map((path) => (path.includes(' -> ') ? path.split(' -> ')[1].trim() : path))
9201
+ .filter(Boolean);
9149
9202
  const perPack = new Map();
9150
- for (const line of status.split('\n')) {
9151
- const m = line.match(/packages\/@dzhechkov\/([^/]+)\/(.+)$/);
9203
+ for (const rel of changedPackageFiles) {
9204
+ const m = rel.match(/^packages\/@dzhechkov\/([^/]+)\/(.+)$/);
9152
9205
  if (!m || !m[1] || !m[2])
9153
9206
  continue;
9154
- const e = perPack.get(m[1]) ?? { pkgJson: false, readme: false };
9155
- if (m[2] === 'package.json')
9156
- e.pkgJson = true;
9207
+ const e = perPack.get(m[1]) ?? { readme: false };
9157
9208
  if (m[2] === 'README.md')
9158
9209
  e.readme = true;
9159
9210
  perPack.set(m[1], e);
9160
9211
  }
9161
- facts['readmeFirst'] = [...perPack.entries()].map(([name, e]) => ({ name: '@dzhechkov/' + name, versionBumped: e.pkgJson, readmeChanged: e.readme }));
9212
+ const readVersion = (raw) => {
9213
+ const version = JSON.parse(raw).version;
9214
+ if (typeof version !== 'string')
9215
+ throw new Error('package version is unreadable');
9216
+ return version;
9217
+ };
9218
+ facts['readmeFirst'] = [...perPack.entries()].map(([name, e]) => {
9219
+ const packagePath = `packages/@dzhechkov/${name}/package.json`;
9220
+ let versionBumped = false;
9221
+ let versionUnknown = false;
9222
+ try {
9223
+ const treeVersion = readVersion(readFileSync(join(root, packagePath), 'utf8'));
9224
+ try {
9225
+ const headVersion = readVersion(execFileSync('git', ['show', `HEAD:${packagePath}`], {
9226
+ cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
9227
+ }));
9228
+ versionBumped = treeVersion !== headVersion;
9229
+ }
9230
+ catch {
9231
+ try {
9232
+ const trackedAtHead = execFileSync('git', ['ls-tree', '--name-only', 'HEAD', '--', packagePath], {
9233
+ cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'],
9234
+ }).trim() === packagePath;
9235
+ if (trackedAtHead)
9236
+ versionUnknown = true;
9237
+ else
9238
+ versionBumped = true;
9239
+ }
9240
+ catch {
9241
+ versionUnknown = true;
9242
+ }
9243
+ }
9244
+ }
9245
+ catch {
9246
+ versionUnknown = true;
9247
+ }
9248
+ return {
9249
+ name: '@dzhechkov/' + name,
9250
+ versionBumped,
9251
+ readmeChanged: e.readme,
9252
+ ...(versionUnknown ? { versionUnknown: true } : {}),
9253
+ };
9254
+ });
9162
9255
  }
9163
9256
  catch { /* not a git repo — rule skips */ }
9257
+ // signature-fresh: verify only signed packs whose non-signature files changed in the same
9258
+ // porcelain listing above. Manifest/SBOM churn is the remedy, not another reason to verify.
9259
+ // The trust key and every byte read here stay in the CLI; the guard core receives facts only.
9260
+ const trustRootPath = join(root, TRUST_ROOT_REL);
9261
+ if (changedPackageFiles !== undefined && existsSync(trustRootPath)) {
9262
+ try {
9263
+ const trustRootPem = readFileSync(trustRootPath, 'utf8');
9264
+ const signedPacks = [];
9265
+ for (const { dir, m, text: packageJsonText } of located) {
9266
+ const manifestPath = join(root, dir, MANIFEST_NAME);
9267
+ if (!existsSync(manifestPath))
9268
+ continue;
9269
+ const prefix = dir + '/';
9270
+ const changedPackFiles = new Set(changedPackageFiles
9271
+ .filter((rel) => rel.startsWith(prefix))
9272
+ .map((rel) => rel.slice(prefix.length))
9273
+ .filter((packRel) => packRel !== MANIFEST_NAME && packRel !== SBOM_NAME));
9274
+ const changed = changedPackFiles.size > 0;
9275
+ let ok = null;
9276
+ let failures = [];
9277
+ let note;
9278
+ if (changed) {
9279
+ try {
9280
+ const signed = JSON.parse(readFileSync(manifestPath, 'utf8'));
9281
+ const verified = verifyManifest(join(root, dir), signed, trustRootPem);
9282
+ // A source checkout contains dev files outside package.json#files. They are absent
9283
+ // from the tarball by design, so an unchanged "present but not signed" source file
9284
+ // is not evidence about signature freshness. A changed/new unsigned file stays loud.
9285
+ const relevantFailures = verified.failures.filter((failure) => failure.reason !== 'present in the pack but not signed' || changedPackFiles.has(failure.path));
9286
+ ok = verified.ok || relevantFailures.length === 0;
9287
+ if (!ok && relevantFailures.length > 0 && relevantFailures.every(({ path }) => path === 'package.json')) {
9288
+ const signedPackageHash = signed.manifest?.files?.find(({ path }) => path === 'package.json')?.sha256;
9289
+ if (typeof signedPackageHash === 'string') {
9290
+ const rewritten = rewriteWorkspaceSpecs(packageJsonText, versionByName);
9291
+ // MEASURED 2026-09-10 on keysarium/skills-meta/core: pnpm also removes only
9292
+ // prepublishOnly from the packed scripts table. Keep that I/O-adapter concern
9293
+ // outside the workspace-only core helper.
9294
+ const packedShape = JSON.parse(rewritten);
9295
+ const scripts = packedShape['scripts'];
9296
+ if (scripts !== null && typeof scripts === 'object' && !Array.isArray(scripts)) {
9297
+ delete scripts['prepublishOnly'];
9298
+ }
9299
+ const rewrittenHash = hashPackBytes('package.json', Buffer.from(JSON.stringify(packedShape, null, 2) + '\n'), signed.manifest?.version);
9300
+ if (rewrittenHash === signedPackageHash) {
9301
+ ok = true;
9302
+ note = 'package.json matches after workspace rewrite';
9303
+ }
9304
+ }
9305
+ }
9306
+ failures = relevantFailures.slice(0, 3).map((failure) => `${failure.path}: ${failure.reason}`);
9307
+ }
9308
+ catch (error) {
9309
+ ok = false;
9310
+ failures = [`${MANIFEST_NAME}: ${error instanceof Error ? error.message : String(error)}`];
9311
+ }
9312
+ }
9313
+ signedPacks.push({ name: m.name ?? dir, dir, changed, ok, failures, ...(note !== undefined ? { note } : {}) });
9314
+ }
9315
+ facts['signedPacks'] = signedPacks;
9316
+ }
9317
+ catch { /* unreadable trust root — absence of evidence, so the rule is not established */ }
9318
+ }
9164
9319
  // review-round: the same WORKING-TREE diff, asked a different question — does a package that
9165
9320
  // bumps its version and changes SOURCE bring a GRADED QE report with it? Scoped to source so a
9166
9321
  // docs-only republish is never blocked (ADR-001, features/publish-needs-a-review). A throw here