@dzhechkov/harness-cli 0.3.231 → 0.3.233
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 +137 -0
- package/README.md +26 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +29 -28
- package/dist/cli.js.map +1 -1
- package/package.json +5 -3
- package/sbom.json +333 -0
- package/src/cli.ts +25 -20
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifest": {
|
|
3
|
+
"version": 1,
|
|
4
|
+
"pack": "harness-cli",
|
|
5
|
+
"files": [
|
|
6
|
+
{
|
|
7
|
+
"path": ".agentic-qe/brain.rvf",
|
|
8
|
+
"sha256": "8136cd4cc145d3dbe6ed3ae4489946bbc26e3e44172f0e5241ac45dde38bfead"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"path": ".agentic-qe/brain.rvf.lock",
|
|
12
|
+
"sha256": "028658845c4fc1e9bd9487b575be0aee727d477fa9ad1b08c26299ce61f622c3"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": ".agentic-qe/memory.db",
|
|
16
|
+
"sha256": "456372cb9a8c12f98ae6378338b8469d9be6df05cbe03a99b412d83d962b3d11"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": ".agentic-qe/memory.db-shm",
|
|
20
|
+
"sha256": "23ae1f330a8fad23eabe444e89dc9d4588297cc1abca5929356eb6fec9f5079d"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"path": ".agentic-qe/memory.db-wal",
|
|
24
|
+
"sha256": "2eade3dbce1a9fd33a0775269af13fe97c62fdf1dbf44a8569ba0e7341315433"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": ".agentic-qe/patterns.rvf",
|
|
28
|
+
"sha256": "9090b2e6d339eaa183672ac0cf9f625dbd5f9fc76d64afcdb34a3f5871c31c5a"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"path": ".agentic-qe/patterns.rvf.idmap.json",
|
|
32
|
+
"sha256": "c2693f9a7f47a2d2bffe3004188e70ce08411bf8db47d07c60551d18ff7640c4"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"path": ".agentic-qe/patterns.rvf.lock",
|
|
36
|
+
"sha256": "b28a956544f4358d57df98fc6c8df0b8f5d5cd8e8b102cee80ed3aabdf0a112b"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "CHANGELOG.md",
|
|
40
|
+
"sha256": "9555ead768fef7963e735b0c6af21a64412811531534108be3df61bc65b51021"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"path": "README.md",
|
|
44
|
+
"sha256": "406be5cb9294367793daed191b2418bb99669186c8ead8a3a3f994f0db36e1b6"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"path": "coverage/coverage-final.json",
|
|
48
|
+
"sha256": "1abb00d07ab57ad413d2747baa6a68cda0876a9e0c6f75db89c205fbf4863530"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"path": "coverage/coverage-summary.json",
|
|
52
|
+
"sha256": "42d2a98f54c2ec773b49a0a43c959a78d070c8c427724f4affbd5bafef35621d"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"path": "dist/bin.d.ts",
|
|
56
|
+
"sha256": "58be9f04d2fe63cca2efe3957b9933068e443a0e57f9838ff9ef800cc191e03f"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"path": "dist/bin.d.ts.map",
|
|
60
|
+
"sha256": "b1e41c8c19fa56ae9dec2267740eb4389bc785431478861a8843867f99c1b25b"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"path": "dist/bin.js",
|
|
64
|
+
"sha256": "ad24e06de21b036e2b5a43abc4efd6e7ceb2ae126177b218a3ee13a026641f83"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"path": "dist/bin.js.map",
|
|
68
|
+
"sha256": "c2dd399fec3f26e48e23971b29e27c508c1a1f96376a193e72dc8042015c8e65"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"path": "dist/cli.d.ts",
|
|
72
|
+
"sha256": "d304769099f8a7f79ba6c295e0348c2aa211527b050dbfff597f7e87c2b80505"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"path": "dist/cli.d.ts.map",
|
|
76
|
+
"sha256": "680727bef753625ed99fd9d79ab846c9024608ef0f88d19ee2c8aec25eccf130"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"path": "dist/cli.js",
|
|
80
|
+
"sha256": "672bc2fd640d9a92b5af7bfe2880843a770bfedd610f679ae022892fa7c8e66c"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"path": "dist/cli.js.map",
|
|
84
|
+
"sha256": "08ec7cf51a49ec818b789cbb6f32b8fc71756e498c99d8756212d16329a8b147"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"path": "dist/index.d.ts",
|
|
88
|
+
"sha256": "c1ddc3aa44ca13264d54a72ad8376d8321de06ab48262eb2a6c8d5023c011bb6"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"path": "dist/index.d.ts.map",
|
|
92
|
+
"sha256": "a8697ddfabf35947e17a255fce26dfee141f2184f6789c32ba1de75dcd80e36c"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "dist/index.js",
|
|
96
|
+
"sha256": "15ff1e6b84537b91b73b6a7e2d1c45f1120b25af9d1139df8da8ad094e99cf0e"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "dist/index.js.map",
|
|
100
|
+
"sha256": "2f61a3be1af4ab9f7bbcbacb912ccbd89e3b73414f9fd24766598bfbdc1f8655"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"path": "keys/README.md",
|
|
104
|
+
"sha256": "204deec657a7f147bf3016441082c2f868f6f11051776f4edc13ec6b44745192"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"path": "package.json",
|
|
108
|
+
"sha256": "b48c494a4d4e2126e033c2d0019e463b9ad6cd3bae7a2aa0da296eba1ab66fcf"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"path": "src/bin.ts",
|
|
112
|
+
"sha256": "a0d4e20fafc5cba35816f1f0c6cd03d9ce7c4434d2ca049384491079d2408fd4"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"path": "src/cli.ts",
|
|
116
|
+
"sha256": "14ca947c27f366c1377c129b3def86cdd4577536249e44f0009f31884fff9018"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"path": "src/index.ts",
|
|
120
|
+
"sha256": "f0aea91d07867603d177da6029f97851ced0b91b62e9db5d0bab5b464f794a91"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"path": "test/cli.test.ts",
|
|
124
|
+
"sha256": "d9374e1cc23923c2d5c4cca1e228f31e2c3465f187d1c84cf3f50ad947401537"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"path": "tsconfig.json",
|
|
128
|
+
"sha256": "e80ef2911c3347a713dc3dca6a5f6034d91e938e58e71345ea920dd9833bcdbb"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"path": "vitest.config.ts",
|
|
132
|
+
"sha256": "a6ffc6172b50a3a59010f8f8c66e2204e7d298b62a7f2bc5de33cbf39c99899d"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"signature": "Vt+64ve0S3VUr7RQQ1sKTxBPCcNyOcMW/F1auDLC8k9ljNGhORaNolB0WZ9xdXN2ZsGz8jQLH0ttajx6eHLxCA=="
|
|
137
|
+
}
|
package/README.md
CHANGED
|
@@ -307,7 +307,9 @@ dz sbom --pack packages/@dzhechkov/skills-qe --out sbom.json # write to a file
|
|
|
307
307
|
```
|
|
308
308
|
|
|
309
309
|
A single flipped byte, a deleted file, or an **added** file all fail verification and the offending
|
|
310
|
-
path is named.
|
|
310
|
+
path is named. `node_modules`/`.git` are unsigned territory by design (npm ships neither) — the sign and
|
|
311
|
+
verify walks share those exclusions, while a symlink smuggled anywhere ELSE in the pack still fails loudly.
|
|
312
|
+
Re-sign after ANY pack change (the manifest hashes `package.json` too) — sign is the LAST step before publish. Every degenerate input (no manifest, empty file list, empty signature, no public key)
|
|
311
313
|
fails **closed** — absence never reads as success. `dz doctor` **and** `dz drift-check` run this check
|
|
312
314
|
over the installed packs: a **tampered** pack is fatal (blocks); an **unsigned** pack or a missing trust
|
|
313
315
|
root is reported, not fatal (transitional — the existing packs are not yet signed).
|
|
@@ -327,7 +329,7 @@ every run; `--require-signing` turns that into a refusal today.
|
|
|
327
329
|
verifies what it just installed. A pack that does not match its signed manifest is **fatal**:
|
|
328
330
|
|
|
329
331
|
```bash
|
|
330
|
-
dz doctor # ... signatures:
|
|
332
|
+
dz doctor # ... signatures: 23 verified, 0 unsigned, 0 TAMPERED (the gate is ARMED: keys/dz.pub committed)
|
|
331
333
|
dz doctor --require-signing # an unsigned pack becomes fatal too
|
|
332
334
|
dz upgrade # a TAMPERED pack aborts the upgrade
|
|
333
335
|
dz doctor --pubkey ./my.pub # verify against a key you pinned yourself
|
|
@@ -501,6 +503,7 @@ dz discrimination-check --test <f[,f]> [--base <ref>] [--name <filter>] [--runne
|
|
|
501
503
|
dz sign --init --out <path> | --pack <dir> --key <path> # --init: generate the Ed25519 keypair (private OUTSIDE the repo, prints the public key for keys/dz.pub); else sign a pack's manifest + CycloneDX SBOM
|
|
502
504
|
dz sbom --pack <dir> [--out <file>] # emit the CycloneDX 1.5 SBOM for a pack standalone (file-level bill of materials); print to stdout or write to a file
|
|
503
505
|
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)
|
|
506
|
+
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
|
|
504
507
|
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)
|
|
505
508
|
dz auto-canonicalize --source <github-url> --pack <skills-pack>
|
|
506
509
|
dz sync-upstream [--package <dir>] [--list] [--all]
|
|
@@ -1619,6 +1622,27 @@ visible, never silent. Calibrated against false gates: in a pnpm workspace, `wor
|
|
|
1619
1622
|
*correct* (pnpm rewrites it at publish), so the rule resolves each workspace dep to the version it would
|
|
1620
1623
|
ship as and blocks only a dep that would ship raw.
|
|
1621
1624
|
|
|
1625
|
+
### `dz feature-adr-setup --guards` — when a project rule should be a TEST, not a reviewer's memory
|
|
1626
|
+
|
|
1627
|
+
A 700-line cap enforced by reviewer judgment catches one file and misses its sibling in the same change;
|
|
1628
|
+
`wc -l` catches both, always (the cost-of-detection ladder). `--guards` scaffolds a deterministic guard set
|
|
1629
|
+
into the TARGET project — no framework, no dependency, any stack with Node:
|
|
1630
|
+
```bash
|
|
1631
|
+
dz feature-adr-setup --guards # preview (existing files are never clobbered)
|
|
1632
|
+
dz feature-adr-setup --guards --apply # writes architecture/guards/{guards.config.json,check.mjs}
|
|
1633
|
+
node architecture/guards/check.mjs # run locally / wire into CI or the test command
|
|
1634
|
+
```
|
|
1635
|
+
```
|
|
1636
|
+
guards: ✗ 1 violation(s)
|
|
1637
|
+
[loc-cap] src/huge.ts — 801 lines > cap 700
|
|
1638
|
+
```
|
|
1639
|
+
Three deterministic rules, each with a **waiver mechanism that requires a reason** (a waiver without one is
|
|
1640
|
+
itself a violation — a conscious exception is recorded, not silently allowed): **loc-cap** (god-object
|
|
1641
|
+
guard, `--loc-cap <n>` tunes, default 700), **secret-scan** (the same high-signal credential shapes as
|
|
1642
|
+
`dz guard`), **frozen-files** (sha256 pins for files that must not change silently). The config is data —
|
|
1643
|
+
edit caps/paths/waivers in `guards.config.json`; the project-critic role should then *not* re-flag these
|
|
1644
|
+
rules, only waivers without a reason.
|
|
1645
|
+
|
|
1622
1646
|
### Semantic recall (vector tier)
|
|
1623
1647
|
|
|
1624
1648
|
`dz recall` is **hybrid** when the vector tier is available and **exactly the old lexical command** when it is not — enabling it never changes behavior for projects that skip it.
|
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;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkPH,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAg8JD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA4I5E"}
|
package/dist/cli.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
9
9
|
import { execSync } from 'node:child_process';
|
|
10
10
|
import { homedir, tmpdir } from 'node:os';
|
|
11
11
|
import { createRequire } from 'node:module';
|
|
12
|
-
import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, 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, TARGET_NAMES, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, 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, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, assertKeyOutsideTree, decidePublishGate, 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, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, } from '@dzhechkov/harness-core';
|
|
12
|
+
import { createSkill, getSkillInfo, getWorkflow, isTargetName, listSkills, runDoctor, runInit, 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, TARGET_NAMES, WORKFLOW_NAMES, importEcc, recordPattern, resolveLearningBackend, storeStats, consolidateSessions, pruneNoisePatterns, lessonDeltaReport, removePatternsByIds, snapshotStore, recallHybrid, teachGuard, mirrorPatternsToVector, vectorMirrorEnabled, vectorTierStatus, resolveVectorEngine, reindexVectorStore, harmonizeVectorStore, importRvfCheckpoint, statuslineData, writeFeatureAdrState, computeUsage, deriveUsageCalibration, normalizeClaudeUsageModelKey, readUsageLimits, 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, buildManifest, buildSbom, resolveTrustRoot, decideVerifyPolicy, generateSigningKeypair, evaluateGuard, resolveRules, auditRecord, guardExitCode, DEFAULT_RULES, decideProvenance, isInsideTree, signManifest, verifyManifest, listSignablePackFiles, assertKeyOutsideTree, decidePublishGate, 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, pickAdversaryModel, CHALLENGE_QUESTIONS, loadOutcomes, renderOutcomes, statsForKey, selectAutoCost, recordProvisional, finalizeOutcome, COST_LADDER, splitScenarios, budgetPlan, selectWinner, proseScopeOk, renderProseDiff, readScenarioIds, DEFAULT_MAX_JUDGE_RUNS, } from '@dzhechkov/harness-core';
|
|
13
13
|
import { getPreset, PRESET_NAMES } from '@dzhechkov/harness-presets';
|
|
14
14
|
import { scanGitHub, analyzeRepo, generateReport, deepAnalyze, scanAllSources, ScoutMemory } from '@dzhechkov/scout';
|
|
15
15
|
const USAGE = `dz - DZ cross-platform harness CLI
|
|
@@ -2784,25 +2784,9 @@ async function cmdAutoCanonicalize(options, cwd, write) {
|
|
|
2784
2784
|
}
|
|
2785
2785
|
/** The pinned trust root. A key inside the artifact under verification is data, not a key (ADR-001). */
|
|
2786
2786
|
const TRUST_ROOT_REL = 'keys/dz.pub';
|
|
2787
|
-
function
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
for (const e of readdirSync(d, { withFileTypes: true })) {
|
|
2791
|
-
if (e.name === 'node_modules' || e.name === '.git')
|
|
2792
|
-
continue;
|
|
2793
|
-
if (e.name === MANIFEST_NAME || e.name === SBOM_NAME)
|
|
2794
|
-
continue;
|
|
2795
|
-
const abs = join(d, e.name);
|
|
2796
|
-
const r = rel ? rel + '/' + e.name : e.name;
|
|
2797
|
-
if (e.isDirectory())
|
|
2798
|
-
walk(abs, r);
|
|
2799
|
-
else if (e.isFile())
|
|
2800
|
-
out.push(r);
|
|
2801
|
-
}
|
|
2802
|
-
};
|
|
2803
|
-
walk(dir, '');
|
|
2804
|
-
return out.sort();
|
|
2805
|
-
}
|
|
2787
|
+
// One walk to rule both: the SIGN file list is core's listPackFiles — the SAME function verify uses for
|
|
2788
|
+
// its added-file sweep, so the two can never drift apart again (the 10-false-TAMPERED lesson, task #36).
|
|
2789
|
+
const packFiles = (dir) => listSignablePackFiles(dir);
|
|
2806
2790
|
/**
|
|
2807
2791
|
* The consumer-side apply-leg (ADR-001, verify-apply-leg). All security content lives in the two pure
|
|
2808
2792
|
* functions in harness-core; this only resolves paths, reads bytes, and reports.
|
|
@@ -4512,11 +4496,21 @@ async function cmdRetro(options, flags, cwd, write) {
|
|
|
4512
4496
|
function cmdFeatureAdrSetup(options, flags, cwd, write) {
|
|
4513
4497
|
let repoRoot = cwd;
|
|
4514
4498
|
try {
|
|
4515
|
-
repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8' }).trim() || cwd;
|
|
4499
|
+
repoRoot = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || cwd;
|
|
4516
4500
|
}
|
|
4517
4501
|
catch { /* not git */ }
|
|
4502
|
+
// P3 (fa-improvements): --guards scaffolds the deterministic guard set (guards.config.json + the
|
|
4503
|
+
// zero-dependency check.mjs runner) — usable standalone (`dz feature-adr-setup --guards --apply`) or
|
|
4504
|
+
// together with --from-spec. --loc-cap <n> tunes the LOC cap (default 700).
|
|
4505
|
+
const wantGuards = flags.has('guards');
|
|
4506
|
+
const locCapRaw = options.get('loc-cap');
|
|
4507
|
+
const locCap = locCapRaw !== undefined ? Number(locCapRaw) : undefined;
|
|
4508
|
+
if (locCapRaw !== undefined && (!Number.isFinite(locCap) || locCap <= 0)) {
|
|
4509
|
+
write('dz feature-adr-setup: --loc-cap must be a positive finite number');
|
|
4510
|
+
return 1;
|
|
4511
|
+
}
|
|
4518
4512
|
const specPath = options.get('from-spec');
|
|
4519
|
-
if (specPath === undefined) {
|
|
4513
|
+
if (specPath === undefined && !wantGuards) {
|
|
4520
4514
|
// default + --plan: the read-only "which documents, and where?" answer.
|
|
4521
4515
|
const plan = buildSetupPlan(scanForSetup(repoRoot));
|
|
4522
4516
|
if (flags.has('json')) {
|
|
@@ -4538,15 +4532,22 @@ function cmdFeatureAdrSetup(options, flags, cwd, write) {
|
|
|
4538
4532
|
write(' → the `configure-feature-adr` skill walks you through the missing docs; or pass a filled spec with --from-spec.');
|
|
4539
4533
|
return 0;
|
|
4540
4534
|
}
|
|
4541
|
-
// --from-spec: scaffold (preview, or --apply to write).
|
|
4535
|
+
// --from-spec and/or --guards: scaffold (preview, or --apply to write).
|
|
4542
4536
|
let spec;
|
|
4543
|
-
|
|
4544
|
-
|
|
4537
|
+
if (specPath !== undefined) {
|
|
4538
|
+
try {
|
|
4539
|
+
spec = JSON.parse(readFileSync(resolve(cwd, specPath), 'utf-8'));
|
|
4540
|
+
}
|
|
4541
|
+
catch (e) {
|
|
4542
|
+
write(`dz feature-adr-setup: cannot read spec ${specPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
4543
|
+
return 1;
|
|
4544
|
+
}
|
|
4545
4545
|
}
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
return 1;
|
|
4546
|
+
else {
|
|
4547
|
+
spec = {}; // --guards standalone: scaffold just the guard set
|
|
4549
4548
|
}
|
|
4549
|
+
if (wantGuards)
|
|
4550
|
+
spec = { ...spec, guards: locCap !== undefined ? { locCap } : true };
|
|
4550
4551
|
const result = scaffoldFromSpec(spec, readExistingForScaffold(repoRoot));
|
|
4551
4552
|
if (flags.has('json') && !flags.has('apply')) {
|
|
4552
4553
|
write(JSON.stringify(result, null, 2));
|