@dzhechkov/harness-cli 0.5.1 → 0.5.3
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 +18 -10
- package/README.md +42 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +79 -4
- package/dist/cli.js.map +1 -1
- package/dist/core-compat.d.ts +1 -1
- package/dist/core-compat.js +1 -1
- package/package.json +11 -11
- package/sbom.json +29 -9
- package/src/cli.ts +81 -3
- package/src/core-compat.ts +1 -1
- package/LICENSE +0 -21
package/.dz-manifest.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "README.md",
|
|
12
|
-
"sha256": "
|
|
12
|
+
"sha256": "0d475969dbc98308bf0e23a15700c537ed4947b3cf910b334e647e3972fc78fe"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "coverage/coverage-final.json",
|
|
@@ -41,19 +41,19 @@
|
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"path": "dist/cli.d.ts.map",
|
|
44
|
-
"sha256": "
|
|
44
|
+
"sha256": "7c64ed0d976d79fd8f3970ced13e664db1e97c43f96a7b153d7b993948cc5f9f"
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
"path": "dist/cli.js",
|
|
48
|
-
"sha256": "
|
|
48
|
+
"sha256": "8052367d84a5a1c4a9f7fb3397a6297edf707031bbfa59b945d240d17e221f04"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"path": "dist/cli.js.map",
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "f759949bcfaa04c3f4eaebbccde688192d44f129b61115313533f8828f7376f8"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "dist/core-compat.d.ts",
|
|
56
|
-
"sha256": "
|
|
56
|
+
"sha256": "f89dbd282c83fa64f23c8fff3c83bc85c08c8deef451fd4d525e33784c2a0e13"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"path": "dist/core-compat.d.ts.map",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
"path": "dist/core-compat.js",
|
|
64
|
-
"sha256": "
|
|
64
|
+
"sha256": "66fd34797f007aa0607698a159fb367a772f32f5be1c2a90748c20cbf4b973cf"
|
|
65
65
|
},
|
|
66
66
|
{
|
|
67
67
|
"path": "dist/core-compat.js.map",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"path": "package.json",
|
|
92
|
-
"sha256": "
|
|
92
|
+
"sha256": "797bfd035a68dc039ca33393f02f4ed1fe97e1021559e01906a0fbbc9b28c1dc"
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
"path": "src/bin.ts",
|
|
@@ -97,11 +97,11 @@
|
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"path": "src/cli.ts",
|
|
100
|
-
"sha256": "
|
|
100
|
+
"sha256": "9338e5f5dd5cbb1f3692cb7db53531f103bc28450c109765bf161664a7598a5b"
|
|
101
101
|
},
|
|
102
102
|
{
|
|
103
103
|
"path": "src/core-compat.ts",
|
|
104
|
-
"sha256": "
|
|
104
|
+
"sha256": "ba96d37f80c98618a1d8ca61cf071c9d26c74dab8d277106e9079068428a5b71"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
"path": "src/index.ts",
|
|
@@ -271,6 +271,10 @@
|
|
|
271
271
|
"path": "test/qe-bridge-manifest-drift.test.ts",
|
|
272
272
|
"sha256": "b7b4d9e0c1dcee32e972aab97273b04bdde9634433e7c22345793a677dfff300"
|
|
273
273
|
},
|
|
274
|
+
{
|
|
275
|
+
"path": "test/roam-nested-archive.test.ts",
|
|
276
|
+
"sha256": "0c078b6e03cc749a64e0ac327885de1eea3c13e940c8e3f231174ab84076d44c"
|
|
277
|
+
},
|
|
274
278
|
{
|
|
275
279
|
"path": "test/skills-verify-static-advisories.test.ts",
|
|
276
280
|
"sha256": "b1140c20ec04d1c8ae67f97a42dbcece1e8e63c98a5de2c087f0359d27c25f17"
|
|
@@ -311,6 +315,10 @@
|
|
|
311
315
|
"path": "test/workflow-run-read-plane.test.ts",
|
|
312
316
|
"sha256": "c56111e578500d690190f9fdb4ec44182a892c7a6c2c289896509c1229d7b06d"
|
|
313
317
|
},
|
|
318
|
+
{
|
|
319
|
+
"path": "test/workflow-trace-attestation-cli.test.ts",
|
|
320
|
+
"sha256": "dad2efd147d9186b29989ef36f6e62614c4ded983d7894a7c1f9b1628e621871"
|
|
321
|
+
},
|
|
314
322
|
{
|
|
315
323
|
"path": "test/workflow-trace-cli-surface.test.ts",
|
|
316
324
|
"sha256": "28df4b51fff1dc80bb38671d56f548d859949d7a9e2f00e7045e732efc7c2e3d"
|
|
@@ -325,5 +333,5 @@
|
|
|
325
333
|
}
|
|
326
334
|
]
|
|
327
335
|
},
|
|
328
|
-
"signature": "/
|
|
336
|
+
"signature": "8n7bGx5j0Y+txpJ/aT6tprAsMiId19Wna+BUKC+G1/Vu3xOUAGWitkU4dvRjnmNgfyMmvC5VWjBYpzjS/dPaAQ=="
|
|
329
337
|
}
|
package/README.md
CHANGED
|
@@ -1368,6 +1368,41 @@ per-agent `agent-*.jsonl` transcripts do carry `timestamp` and `uuid`/`parentUui
|
|
|
1368
1368
|
order AGENT runs — but a join, a gate redo and a typed pause are steps of the loop, not agents, and
|
|
1369
1369
|
leave no record there at all.
|
|
1370
1370
|
|
|
1371
|
+
**Since 0.5.2 the reader SAYS which of the two it is looking at.** `dz workflow-trace` opens every
|
|
1372
|
+
report with one plain sentence — `ATTESTATION instrument | agent | unknown` — and `--json` carries
|
|
1373
|
+
the same value at the top level AND on every invariant verdict, so a stored verdict cannot lose its
|
|
1374
|
+
qualifier in transit.
|
|
1375
|
+
|
|
1376
|
+
The trust answer is derived by the READER, never read out of the trace. The trace carries only
|
|
1377
|
+
`emitterPath` (`dz-process` / `rendered-script`), an explicitly non-authoritative hint: the rendered
|
|
1378
|
+
script's flush is performed by an AGENT, which controls those bytes before the file exists and could
|
|
1379
|
+
write any value there. `instrument` requires a co-located `run-state.json` — which `dz workflow run`
|
|
1380
|
+
writes and the sandboxed script cannot — binding the same `runId`, `planDigest`, `execFp`, plus the
|
|
1381
|
+
trace's `traceSha256` and `traceLines`.
|
|
1382
|
+
|
|
1383
|
+
Stated at its real size, because two cross-family review rounds cut it down to this:
|
|
1384
|
+
|
|
1385
|
+
> `instrument` means **the bytes read match the identifiers, the hash and the line count asserted by
|
|
1386
|
+
> the co-located `run-state.json`**. It does NOT mean `dz` historically wrote those bytes, nor that
|
|
1387
|
+
> this is the directory it wrote them in. A byte-identical replay passes; so does copying the matched
|
|
1388
|
+
> trace+run-state pair elsewhere. Against an actor with write access to the run directory nothing
|
|
1389
|
+
> local proves authorship — the signing key is readable by the same account — and that is named here
|
|
1390
|
+
> rather than papered over. `unknown` is kept DISTINCT from `agent`: a legacy run, a stripped field
|
|
1391
|
+
> and explicit agent testimony are different facts.
|
|
1392
|
+
|
|
1393
|
+
`dz workflow-trace --corroborate <hostRunDir>` compares the trace against the Claude host's own
|
|
1394
|
+
records for the half they can witness, and reports `agreesWithinScope` — never a bare `agrees`:
|
|
1395
|
+
|
|
1396
|
+
| | |
|
|
1397
|
+
|---|---|
|
|
1398
|
+
| witnessed | agent multiset, agent count, wall-clock order |
|
|
1399
|
+
| **not** witnessed | `join`, `gate-redo`, `typed-pause`, `file-deliverable` |
|
|
1400
|
+
| binding | `by-directory` — trace and `journal.jsonl` share NO identifier (MEASURED: `invocationId`/`stepId` vs `agentId`/`v2:<sha>` key), so containment is the only binding available and pointing at the wrong directory is a user error this check cannot detect |
|
|
1401
|
+
|
|
1402
|
+
A fabricated join or gate redo therefore still lands as `agreesWithinScope`. That limit is asserted
|
|
1403
|
+
by a test, so it cannot be quietly lost. Corroboration never raises the attestation: full agreement
|
|
1404
|
+
leaves `agent` exactly where it was.
|
|
1405
|
+
|
|
1371
1406
|
Consequently the cross-host structural equivalence proved by the committed fixture (`pkg-audit-1`)
|
|
1372
1407
|
covers a bounded fanout, an all-activated join, a dep chain and a gate. It does **not** cover the
|
|
1373
1408
|
gate redo route, the typed terminal route, the typed pause or the file deliverable: those four are
|
|
@@ -3957,7 +3992,13 @@ npx @dzhechkov/p-replicator init
|
|
|
3957
3992
|
|
|
3958
3993
|
## Status
|
|
3959
3994
|
|
|
3960
|
-
`v0.5.
|
|
3995
|
+
`v0.5.3` — **published 2026-08-20**. No CLI behavior change of its own: released in lockstep with
|
|
3996
|
+
`@dzhechkov/harness-core@0.5.3` and pinned to it, so a fresh install gets the per-sibling design
|
|
3997
|
+
checkpoint in `/feature-adr` (one dead design agent no longer discards three finished siblings) and
|
|
3998
|
+
its refusal gate (an incomplete design fan stops at the Step-5/6 boundary instead of planning off a
|
|
3999
|
+
partial design). The compat floor is unchanged — this CLI uses no new core export.
|
|
4000
|
+
|
|
4001
|
+
**v0.5.1** — published 2026-08-20. Ships `dz workflow run`, the portable plan enactor: it INTERPRETS a `loop-plan/1` plan instead of executing a rendered script, dispatching to `codex exec` or an isolated `claude -p`, exit 0/1/2/75 (75 = a typed pause whose last stdout line is a `wf-pause-envelope/1`). Requires `@dzhechkov/harness-core >= 0.5.1` (the compat guard refuses below it by name). See "Who writes the trace" above for the stated scope of the cross-host equivalence claim — it is narrower than "the two hosts agree".
|
|
3961
4002
|
|
|
3962
4003
|
`v0.5.0` — published. Also available as [Claude Plugin](#claude-plugin). Part of [DZ Harness Hub](https://github.com/djd1m/dz-harness-hub).
|
|
3963
4004
|
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAA0B,KAAK,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKtF,OAAO,EA2CL,iBAAiB,EAmBjB,KAAK,oBAAoB,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -12,7 +12,7 @@ import { homedir, tmpdir } from 'node:os';
|
|
|
12
12
|
import { createRequire } from 'node:module';
|
|
13
13
|
import { createSkill, getSkillInfo, listSkillsDetailed, formatSkillLoadFailures, formatSkillApplyFailures, resolveTargetName, formatTargetProblem, formatTargetAliasNote, TARGET_NAMES_SORTED, runDoctor, runInit, resolvePackageSkillRoots, PACKAGE_SKILL_LAYOUTS, benchmarkSkill, benchmarkSkills, scanMcp, reconcileCapabilities, RECONCILE_BANNER, buildRegistry, discoverSkillPackDirs, checkUpstream, compareSkills, checkAllUpstream, sweepSkillDrift, syncCanonicalSkill, checkUpgrades, discoverPackages, discoverSourcePackages, fetchAllDownloads, filterByCategory, pretrain, recommend, generatePlugin, publishPackages, runSetup, runMigrate, searchRegistry, runSync, runVerify, runInitAgentsMd, runInitGeminiMd, runSyncAgentsPolicy, runSyncCodexHooks, resolveCodexHome, withNamedLockSync,
|
|
14
14
|
// dz workflow run (feature dz-workflow-run): the pure scheduler + the dispatch adapters.
|
|
15
|
-
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, renderTimelineHtml, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveCostLedger, renderCostLedger, verifyCostLedgerReport, writeCostLedgerJsonl, COST_LEDGER_SCOPE, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, parseWeeklyResetAnchor, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, 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, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, parsePnpmLockImporters, scannableStubPath,
|
|
15
|
+
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, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, mirrorEntriesToVector, patternVectorEntry, readMemoryLearningConfig, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns, clearAgentdbQuarantine, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveCostLedger, renderCostLedger, verifyCostLedgerReport, writeCostLedgerJsonl, COST_LEDGER_SCOPE, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, parseWeeklyResetAnchor, claimCheck, summarize, queryBookKnowledge, loadStorePatternsSync, patternRecordId, loadStoreRecords, recordToPattern, bundleSkills, brainHome, listBrain, 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, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, parsePnpmLockImporters, scannableStubPath,
|
|
16
16
|
// guard-promotion (feature guard-promotion, scout idea #1)
|
|
17
17
|
assembleCandidates, renderPromotionReport, renderPromotionAdr, normalizePromotionState, nextPromotionState, globMatch, promotionAdrRelPath, DEFAULT_WINDOW_DAYS, DEFAULT_PERIODS, MAX_CONTENT_FETCHES, BUILTIN_COVERAGE, decideProvenance, isInsideTree, signManifest, verifyManifest, 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, detectProcessRakes, buildRetro, renderRetro, retroLessonText, PROCESS_SIGNATURES, RETRO_DOMAIN, scanForSetup, buildSetupPlan, scaffoldFromSpec, renderScaffoldPreview, readExistingForScaffold, assembleChallengeContext, buildChallengeBrief, planDiscriminationCheck, classifyDiscrimination, classifyExecutionEvidence, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, harvestStageOutcomes, recommendModels, planFeed, 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,
|
|
18
18
|
// Cold-vs-warm EPOCH RUNNER (feature epoch-replay) — orchestrates + scores, never calls a model.
|
|
@@ -42,7 +42,7 @@ Usage:
|
|
|
42
42
|
dz workflow render <plan.json> --o <script.js> [--check] [--force] (plan → region-delimited loop script; USER regions preserved)
|
|
43
43
|
dz workflow blobs [--check] (list/self-check the subsystem blob registry)
|
|
44
44
|
dz workflow-lint <script.js> [--plan <plan.json>] [--require-plan|--legacy] [--json] (layer-1 gate; exit 0/1/3 — inconclusive is never a pass)
|
|
45
|
-
dz workflow-trace <runDir|--slug <s>|--run <id>> [--invariants <plan.json>] [--html <out.html>] [--json] (timeline + SEQ invariant runner)
|
|
45
|
+
dz workflow-trace <runDir|--slug <s>|--run <id>> [--invariants <plan.json>] [--corroborate <hostRunDir>] [--html <out.html>] [--json] (timeline + SEQ invariant runner; ALWAYS reports who attested the trace — instrument|agent|unknown — and --corroborate checks the Claude host's own records for the half they can witness)
|
|
46
46
|
dz workflow-trace export <run> --o <file> [--include-pairs --yes] [--strict] (one run's telemetry as ONE movable file: events, not aggregates; degradation is typed and LOUD, --strict fails closed)
|
|
47
47
|
dz workflow-trace import <bundle> --into <root> [--force] [--with-pairs] (reconstruct that run under an explicit root; FAIL-CLOSED — never writes over a run that already has content)
|
|
48
48
|
dz install <npm-pkg> [--target <name>] [--project <dir>] [--force]
|
|
@@ -1146,6 +1146,58 @@ function cmdWorkflowTrace(options, flags, cwd, write) {
|
|
|
1146
1146
|
const ckptFile = join(runDir, '.fa-state', 'checkpoints.jsonl');
|
|
1147
1147
|
const ledgerFile = resolve(cwd, '.dz', 'feature-adr', 'run-cost-ledger.jsonl');
|
|
1148
1148
|
const journalFile = join(runDir, 'journal.jsonl');
|
|
1149
|
+
// ── provenance (feature honest-trace-provenance) ──────────────────────────────────────────────
|
|
1150
|
+
// The attestation is DERIVED here, from run-state.json — an artifact the sandboxed rendered
|
|
1151
|
+
// script cannot write. It is never read out of the trace itself (ADR-001).
|
|
1152
|
+
const parsedRun = parseTrace(traceText);
|
|
1153
|
+
const runStateFile = join(runDir, 'run-state.json');
|
|
1154
|
+
const runStateForAttestation = existsSync(runStateFile)
|
|
1155
|
+
? (() => {
|
|
1156
|
+
try {
|
|
1157
|
+
return JSON.parse(readFileSync(runStateFile, 'utf8'));
|
|
1158
|
+
}
|
|
1159
|
+
catch {
|
|
1160
|
+
return null; // an unreadable state binds nothing — the reader will say `unknown`
|
|
1161
|
+
}
|
|
1162
|
+
})()
|
|
1163
|
+
: null;
|
|
1164
|
+
const attestation = deriveAttestation(parsedRun, runStateForAttestation, {
|
|
1165
|
+
sha256: createHash('sha256').update(traceText, 'utf8').digest('hex'),
|
|
1166
|
+
lines: traceText.split('\n').filter((l) => l.trim() !== '').length,
|
|
1167
|
+
});
|
|
1168
|
+
const ATTESTATION_SENTENCE = {
|
|
1169
|
+
instrument: 'ATTESTATION instrument — the bytes read match the identifiers, hash and line count asserted by the co-located run-state.json. That is NOT proof that dz historically wrote them, nor that this is the directory it wrote them in.',
|
|
1170
|
+
agent: 'ATTESTATION agent — this trace was appended by an AGENT asked to run the flush command, not by an instrument. Treat every verdict below as testimony.',
|
|
1171
|
+
unknown: 'ATTESTATION unknown — no binding run-state.json and no emitter declaration. Not instrument; treat as testimony.',
|
|
1172
|
+
};
|
|
1173
|
+
// ── corroboration (ADR-002, opt-in) ───────────────────────────────────────────────────────────
|
|
1174
|
+
// The host's OWN records, for the half they can witness. Directory containment is the ONLY
|
|
1175
|
+
// binding available — trace and journal.jsonl share no identifier — and every result says so.
|
|
1176
|
+
const corroborateDir = options.get('corroborate');
|
|
1177
|
+
let corroboration = null;
|
|
1178
|
+
if (corroborateDir !== undefined) {
|
|
1179
|
+
const hostDir = resolve(cwd, corroborateDir);
|
|
1180
|
+
const jf = join(hostDir, 'journal.jsonl');
|
|
1181
|
+
const transcripts = {};
|
|
1182
|
+
try {
|
|
1183
|
+
for (const f of readdirSync(hostDir)) {
|
|
1184
|
+
const m = /^agent-(.+)\.jsonl$/.exec(f);
|
|
1185
|
+
if (m)
|
|
1186
|
+
transcripts[m[1]] = readFileSync(join(hostDir, f), 'utf8');
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
catch {
|
|
1190
|
+
/* an unreadable host dir is INCONCLUSIVE, decided by corroborate() below — never a throw */
|
|
1191
|
+
}
|
|
1192
|
+
// The trace side, projected: the agent ids the trace claims took part, in seq order. The trace
|
|
1193
|
+
// has no agentId of its own, so the invocationId is what we can offer — and that is exactly why
|
|
1194
|
+
// the binding is by-directory and the verdict is scoped.
|
|
1195
|
+
const claimed = [];
|
|
1196
|
+
for (const e of parsedRun.events)
|
|
1197
|
+
if (e.event === 'dispatched')
|
|
1198
|
+
claimed.push(e.invocationId);
|
|
1199
|
+
corroboration = corroborate({ agentIds: claimed }, { journal: existsSync(jf) ? readFileSync(jf, 'utf8') : null, agentTranscripts: transcripts }, hostDir);
|
|
1200
|
+
}
|
|
1149
1201
|
const timeline = assembleTimeline({
|
|
1150
1202
|
trace: traceText,
|
|
1151
1203
|
checkpoints: existsSync(ckptFile) ? readFileSync(ckptFile, 'utf8') : null,
|
|
@@ -1168,7 +1220,7 @@ function cmdWorkflowTrace(options, flags, cwd, write) {
|
|
|
1168
1220
|
return 1;
|
|
1169
1221
|
}
|
|
1170
1222
|
projection = toTraceProjection(parsed);
|
|
1171
|
-
verdicts = runInvariants(projection,
|
|
1223
|
+
verdicts = stampAttestation(runInvariants(projection, parsedRun), attestation);
|
|
1172
1224
|
}
|
|
1173
1225
|
const htmlOut = options.get('html');
|
|
1174
1226
|
if (htmlOut !== undefined) {
|
|
@@ -1177,9 +1229,14 @@ function cmdWorkflowTrace(options, flags, cwd, write) {
|
|
|
1177
1229
|
write(`dz workflow-trace: wrote ${absHtml} (self-contained: mermaid topology + HTML waterfall)`);
|
|
1178
1230
|
}
|
|
1179
1231
|
if (flags.has('json')) {
|
|
1180
|
-
write(JSON.stringify({ timeline, verdicts }, null, 2));
|
|
1232
|
+
write(JSON.stringify({ timeline, attestation, corroboration, verdicts }, null, 2));
|
|
1181
1233
|
return verdicts.some((v) => v.status === 'fail') ? 1 : 0;
|
|
1182
1234
|
}
|
|
1235
|
+
write(ATTESTATION_SENTENCE[attestation]);
|
|
1236
|
+
if (corroboration !== null) {
|
|
1237
|
+
write(`CORROBORATION ${corroboration.verdict} (binding: ${corroboration.binding}, ${corroboration.hostDir}) — ${corroboration.detail}`);
|
|
1238
|
+
write(` witnessed: ${corroboration.witnessed.join(', ')} NOT witnessed: ${NOT_WITNESSED.join(', ')}`);
|
|
1239
|
+
}
|
|
1183
1240
|
write(`run ${timeline.runId ?? '(unknown)'}${timeline.incomplete ? ' — INCOMPLETE (no run.closed; unflushed tail may be lost)' : ''}; sources: ${timeline.sources.join(', ')}`);
|
|
1184
1241
|
for (const r of timeline.rows.filter((x) => x.kind === 'trace')) {
|
|
1185
1242
|
write(` ${String(r.seq).padStart(5)} ${r.label} ${r.detail}${r.wallTime ? ` [wall ${r.wallTime} — diagnostic only]` : ''}`);
|
|
@@ -1228,6 +1285,16 @@ function cmdRoam(options, flags, cwd, write) {
|
|
|
1228
1285
|
write('dz roam: not a git repository');
|
|
1229
1286
|
return 1;
|
|
1230
1287
|
}
|
|
1288
|
+
// The roam archive is its OWN git repository (owner decision 2026-08-20), so `git rev-parse` run
|
|
1289
|
+
// from inside it resolves to the archive, not the project. Left unguarded that computes
|
|
1290
|
+
// `<repo>/roam/roam/claude-state` and, with --apply, creates a symlink under a fabricated slug.
|
|
1291
|
+
// Detect the nested archive by its own shape rather than by its name alone: a directory called
|
|
1292
|
+
// `roam` that CONTAINS `claude-state` is the archive, wherever it lives.
|
|
1293
|
+
if (basename(repoRoot) === 'roam' && existsSync(join(repoRoot, 'claude-state'))) {
|
|
1294
|
+
write('dz roam: this is the roam ARCHIVE, not the project — its git root is its own.');
|
|
1295
|
+
write(` Run from the project root instead: cd ${dirname(repoRoot)} && dz roam`);
|
|
1296
|
+
return 1;
|
|
1297
|
+
}
|
|
1231
1298
|
const roamDir = join(repoRoot, 'roam', 'claude-state');
|
|
1232
1299
|
const claudeProjectsDir = process.env['CLAUDE_PROJECTS_DIR'] ?? join(homedir(), '.claude', 'projects');
|
|
1233
1300
|
// Slug: replace every : \ / with -
|
|
@@ -8086,6 +8153,14 @@ function wfMakeStore(runDir, repoRoot, targetCwd) {
|
|
|
8086
8153
|
runDirExists: () => existsSync(runDir),
|
|
8087
8154
|
hasTrace: () => existsSync(tracePath),
|
|
8088
8155
|
readTraceText: () => (existsSync(tracePath) ? readFileSync(tracePath, 'utf8') : null),
|
|
8156
|
+
// The CONTENT half of the attestation binding. Hashes the file AS IT STANDS, so it must be
|
|
8157
|
+
// called after the final flush — the scheduler's stampTraceBinding is the single caller.
|
|
8158
|
+
measureTrace: () => {
|
|
8159
|
+
if (!existsSync(tracePath))
|
|
8160
|
+
return null;
|
|
8161
|
+
const text = readFileSync(tracePath, 'utf8');
|
|
8162
|
+
return { sha256: createHash('sha256').update(text, 'utf8').digest('hex'), lines: text.split('\n').filter((l) => l.trim() !== '').length };
|
|
8163
|
+
},
|
|
8089
8164
|
readRunState: () => wfReadJson(statePath),
|
|
8090
8165
|
writeRunState: (s) => {
|
|
8091
8166
|
mkdirSync(runDir, { recursive: true });
|