testguard-cli 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/dependabot.yml +1 -2
  2. testguard_cli-0.1.1/.github/scripts/install-smoke.mjs +39 -0
  3. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/scripts/sync-release-version.mjs +1 -0
  4. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/workflows/auto-merge.yml +1 -1
  5. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/workflows/ci.yml +8 -1
  6. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/workflows/release.yml +2 -0
  7. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/workflows/scheduled-release.yml +1 -1
  8. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.npmrc +2 -2
  9. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/AGENTS.md +3 -1
  10. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/CHANGELOG.md +18 -0
  11. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/CONTRIBUTING.md +5 -3
  12. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/PKG-INFO +4 -4
  13. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/README.md +3 -3
  14. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/SECURITY.md +3 -1
  15. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/action.yml +1 -1
  16. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/package-lock.json +8 -8
  17. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/package.json +6 -3
  18. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/packaging/homebrew/testguard.rb +3 -3
  19. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/pyproject.toml +1 -1
  20. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.gitattributes +0 -0
  21. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  22. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  23. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  24. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.github/workflows/supply-chain.yml +0 -0
  25. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.gitignore +0 -0
  26. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.npmignore +0 -0
  27. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/.pre-commit-hooks.yaml +0 -0
  28. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/CLAUDE.md +0 -0
  29. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/CODE_OF_CONDUCT.md +0 -0
  30. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/LICENSE +0 -0
  31. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/PRIVACY.md +0 -0
  32. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/SUPPORT.md +0 -0
  33. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/bench/README.md +0 -0
  34. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/cli/testguard.mjs +0 -0
  35. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/.gitignore +0 -0
  36. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/README.md +0 -0
  37. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/expected.json +0 -0
  38. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/package.json +0 -0
  39. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/src/export.mjs +0 -0
  40. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/src/redact.mjs +0 -0
  41. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/test/flaky.test.mjs +0 -0
  42. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/test/redact.test.mjs +0 -0
  43. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/testguard.claims.json +0 -0
  44. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/fixtures/known-answer/vitest.config.mjs +0 -0
  45. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/GATE-SEMANTICS.md +0 -0
  46. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/README.md +0 -0
  47. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/baseline.json +0 -0
  48. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/brief.json +0 -0
  49. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/calibration.json +0 -0
  50. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/claims.json +0 -0
  51. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/evidence.json +0 -0
  52. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/examples/ignore.json +0 -0
  53. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/baseline.bad-fingerprint-key.json +0 -0
  54. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/baseline.zero-count.json +0 -0
  55. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/brief.text-without-heading.json +0 -0
  56. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/brief.unknown-verdict-key.json +0 -0
  57. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/calibration.p-outside-ci.json +0 -0
  58. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/calibration.positives-exceed-n.json +0 -0
  59. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.absolute-path.json +0 -0
  60. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.duplicate-fault-id.json +0 -0
  61. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.missing-provenance.json +0 -0
  62. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.noop-fault.json +0 -0
  63. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.occurrence-exceeds-hits.json +0 -0
  64. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/claims.parent-traversal.json +0 -0
  65. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.flaky-defender-without-flakiness.json +0 -0
  66. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.killed-by-non-assertion.json +0 -0
  67. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.killed-on-red-baseline.json +0 -0
  68. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.killed-without-n-runs.json +0 -0
  69. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.rank-extra-property.json +0 -0
  70. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.unknown-verdict.json +0 -0
  71. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.unverifiable-without-reason.json +0 -0
  72. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/evidence.wrong-fingerprint.json +0 -0
  73. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/ignore.missing-reason.json +0 -0
  74. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/invalid/ignore.short-reason.json +0 -0
  75. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/conformance/schemas.test.mjs +0 -0
  76. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/lib/fingerprint.mjs +0 -0
  77. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/lib/validate.mjs +0 -0
  78. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/baseline.schema.json +0 -0
  79. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/brief.schema.json +0 -0
  80. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/calibration.schema.json +0 -0
  81. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/claims.schema.json +0 -0
  82. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/common.schema.json +0 -0
  83. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/evidence.schema.json +0 -0
  84. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/spec/schemas/ignore.schema.json +0 -0
  85. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/baseline/baseline.mjs +0 -0
  86. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/brief/brief.mjs +0 -0
  87. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/claims/annotations.mjs +0 -0
  88. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/claims/load.mjs +0 -0
  89. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/cli.mjs +0 -0
  90. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/commands/baseline.mjs +0 -0
  91. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/commands/brief.mjs +0 -0
  92. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/commands/claims.mjs +0 -0
  93. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/commands/probe.mjs +0 -0
  94. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/evidence/writer.mjs +0 -0
  95. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/git.mjs +0 -0
  96. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/classify.mjs +0 -0
  97. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/inject.mjs +0 -0
  98. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/probe.mjs +0 -0
  99. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/rank.mjs +0 -0
  100. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/runner-vitest.mjs +0 -0
  101. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/probe/worktree.mjs +0 -0
  102. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/render.mjs +0 -0
  103. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/util/glob.mjs +0 -0
  104. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/src/util/hash.mjs +0 -0
  105. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/annotations.test.mjs +0 -0
  106. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/baseline.test.mjs +0 -0
  107. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/brief.test.mjs +0 -0
  108. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/classify.test.mjs +0 -0
  109. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/glob.test.mjs +0 -0
  110. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/inject.test.mjs +0 -0
  111. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/probe.fixture.test.mjs +0 -0
  112. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/runner-vitest.test.mjs +0 -0
  113. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/worktree.test.mjs +0 -0
  114. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/test/writer.test.mjs +0 -0
  115. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/testguard.claims.json +0 -0
  116. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/testguard_cli/__init__.py +0 -0
  117. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/testguard_cli/wrapper.py +0 -0
  118. {testguard_cli-0.1.0 → testguard_cli-0.1.1}/vitest.config.mjs +0 -0
@@ -7,8 +7,7 @@ updates:
7
7
  groups:
8
8
  all-npm:
9
9
  patterns: ["*"]
10
- # devDependencies only (ajv for the conformance suite, vitest as the test
11
- # runner). The published package has zero runtime dependencies.
10
+ # One runtime dependency (ajv, exact-pinned) plus vitest for tests.
12
11
  - package-ecosystem: "pip"
13
12
  directory: "/"
14
13
  schedule:
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Prove the package works AS INSTALLED, not as checked out: pack it, install
4
+ * the tarball into a scratch project with production dependencies only, and
5
+ * run the CLI from there. This is the gate that would have caught 0.1.0,
6
+ * which shipped with its schema validator's dependency declared as a
7
+ * devDependency and crashed on startup for every npm/npx/pip/brew user.
8
+ */
9
+ import { execFileSync } from 'node:child_process';
10
+ import { mkdtempSync, mkdirSync, rmSync, cpSync, readdirSync } from 'node:fs';
11
+ import { tmpdir } from 'node:os';
12
+ import { join, resolve } from 'node:path';
13
+
14
+ const root = resolve(process.argv[1], '..', '..', '..');
15
+ const run = (cmd, args, cwd) => execFileSync(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'inherit'] });
16
+ const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
17
+
18
+ const scratch = mkdtempSync(join(tmpdir(), 'testguard-install-smoke-'));
19
+ try {
20
+ const packDir = join(scratch, 'pack');
21
+ mkdirSync(packDir);
22
+ run(npm, ['pack', '--pack-destination', packDir, '--ignore-scripts'], root);
23
+ const tgz = join(packDir, readdirSync(packDir).find((f) => f.endsWith('.tgz')));
24
+
25
+ const consumer = join(scratch, 'consumer');
26
+ cpSync(join(root, 'fixtures', 'known-answer'), consumer, { recursive: true, filter: (s) => !/node_modules|\.flake-counter|\.testguard/.test(s) });
27
+ run(npm, ['init', '-y'], consumer);
28
+ run(npm, ['install', '--omit=dev', '--ignore-scripts', '--no-audit', '--no-fund', tgz], consumer);
29
+
30
+ const bin = join(consumer, 'node_modules', '.bin', process.platform === 'win32' ? 'testguard.cmd' : 'testguard');
31
+ const version = run(bin, ['--version'], consumer).trim();
32
+ const claims = run(bin, ['claims', '.'], consumer);
33
+ if (!/^\d+\.\d+\.\d+/.test(version)) throw new Error(`unexpected --version output: ${version}`);
34
+ if (!claims.includes('8 claims')) throw new Error(`claims did not list the fixture:\n${claims}`);
35
+ const deps = Object.keys(JSON.parse(run(npm, ['ls', '--omit=dev', '--json', '--depth=0'], consumer)).dependencies ?? {});
36
+ console.log(`install smoke OK — testguard ${version} runs from the installed tarball; consumer deps: ${deps.join(', ')}`);
37
+ } finally {
38
+ rmSync(scratch, { recursive: true, force: true });
39
+ }
@@ -20,6 +20,7 @@ const surfaces = [
20
20
  ['pyproject.toml', /^version = "[^"]+"/m, `version = "${version}"`],
21
21
  ['action.yml', /(\n version:\n description: [^\n]*\n required: false\n default: ')[^']*(')/, `$1${version}$2`],
22
22
  ['packaging/homebrew/testguard.rb', /testguard-cli-\d+\.\d+\.\d+\.tgz/g, `testguard-cli-${version}.tgz`],
23
+ ['README.md', /raccioly\/testguard@v\d+\.\d+\.\d+/g, `raccioly/testguard@v${version}`],
23
24
  ];
24
25
 
25
26
  let drift = 0;
@@ -46,7 +46,7 @@ jobs:
46
46
 
47
47
  const { data: files } = await github.rest.pulls.listFiles({ owner, repo, pull_number: num, per_page: 300 });
48
48
  const paths = files.map((f) => f.filename);
49
- const RELEASE_SURFACES = new Set(['package.json', 'package-lock.json', 'pyproject.toml', 'CHANGELOG.md', 'action.yml', 'packaging/homebrew/testguard.rb']);
49
+ const RELEASE_SURFACES = new Set(['package.json', 'package-lock.json', 'pyproject.toml', 'CHANGELOG.md', 'action.yml', 'packaging/homebrew/testguard.rb', 'README.md']);
50
50
 
51
51
  if (author === 'dependabot[bot]') {
52
52
  const m = /from (\d+)\.(\d+)\.\S+ to (\d+)\.(\d+)\./.exec(pr.title || '');
@@ -30,7 +30,7 @@ jobs:
30
30
  with:
31
31
  node-version: ${{ matrix.node-version }}
32
32
 
33
- - name: Install (devDependencies only; zero runtime deps)
33
+ - name: Install
34
34
  run: npm ci
35
35
 
36
36
  # ── Syntax-check EVERY source, not just what the entry point eagerly
@@ -38,6 +38,13 @@ jobs:
38
38
  - name: Syntax-check all sources
39
39
  run: find cli src spec -name '*.mjs' -print0 | xargs -0 -n1 node --check
40
40
 
41
+ # ── Install-from-tarball smoke: the package must run as INSTALLED, with
42
+ # production dependencies only. 0.1.0 shipped unrunnable because the
43
+ # schema validator's dependency was a devDependency; the suite, which
44
+ # runs from the checkout, could not see it. ──
45
+ - name: Install smoke (pack → install --omit=dev → run)
46
+ run: npm run test:install
47
+
41
48
  - name: Python wrapper imports (PyPI surface)
42
49
  run: python3 -c "import testguard_cli.wrapper; print('testguard_cli.wrapper OK')"
43
50
 
@@ -77,6 +77,8 @@ jobs:
77
77
  node-version: 24
78
78
  - run: npm ci
79
79
  - run: npm test
80
+ - name: Install smoke — the tarball must run with production deps only
81
+ run: npm run test:install
80
82
  - name: Self-probe must be fully defended before anything ships
81
83
  run: node cli/testguard.mjs probe . --budget 180000 --out "$RUNNER_TEMP/self-evidence.json" --quiet
82
84
  - name: Version surfaces are in sync
@@ -102,7 +102,7 @@ jobs:
102
102
  # Only release surfaces may change in a release PR.
103
103
  CHANGED=$(git diff --name-only HEAD --)
104
104
  for f in $CHANGED; do
105
- case "$f" in package.json|package-lock.json|pyproject.toml|CHANGELOG.md|action.yml|packaging/homebrew/testguard.rb) ;;
105
+ case "$f" in package.json|package-lock.json|pyproject.toml|CHANGELOG.md|action.yml|packaging/homebrew/testguard.rb|README.md) ;;
106
106
  *) echo "::error::unexpected file in release diff: $f"; exit 1;;
107
107
  esac
108
108
  done
@@ -1,7 +1,7 @@
1
1
  # Supply-chain hardening.
2
2
  # ignore-scripts: never run a dependency's install/postinstall scripts — the
3
- # main supply-chain attack vector. TestGuard has zero runtime dependencies;
4
- # its devDependencies (ajv, vitest) work without install scripts.
3
+ # main supply-chain attack vector. TestGuard's one runtime dependency (ajv)
4
+ # and its devDependency (vitest) work without install scripts.
5
5
  # audit-level: surface moderate-and-above advisories.
6
6
  ignore-scripts=true
7
7
  audit-level=moderate
@@ -6,7 +6,8 @@ Read this before changing anything. It is short on purpose.
6
6
 
7
7
  A CLI that proves a test suite defends the claims a project makes, by
8
8
  injecting the faults those claims forbid and reporting every one the tests
9
- miss. **Not a test generator.** Node ≥ 20, ESM, zero runtime dependencies.
9
+ miss. **Not a test generator.** Node ≥ 20, ESM, one exact-pinned runtime
10
+ dependency (`ajv`).
10
11
  The shared formats under `spec/` are a contract other tools adopt; the CLI is
11
12
  their first consumer.
12
13
 
@@ -16,6 +17,7 @@ their first consumer.
16
17
  npm test # unit + fixture acceptance (~15s)
17
18
  npm run test:spec # conformance suite only
18
19
  npm run self:probe # TestGuard probes its own claims; must exit 0
20
+ npm run test:install # the packed tarball must run with production deps only
19
21
  node cli/testguard.mjs claims fixtures/known-answer
20
22
  ```
21
23
 
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.1.1] - 2026-09-17
11
+
12
+ ### Fixed
13
+
14
+ - **0.1.0 did not run when installed.** `ajv`, which validates every document
15
+ against the spec, was declared as a devDependency, so `testguard` crashed on
16
+ startup from npm, `npx`, `pip` and Homebrew. It is now an exact-pinned
17
+ runtime dependency — the project's one dependency.
18
+ - CI and the release job now pack the tarball, install it into a scratch
19
+ project with production dependencies only, and run the CLI from there
20
+ (`npm run test:install`). The suite alone runs from the checkout and could
21
+ not see this class of defect.
22
+
23
+ ### Changed
24
+
25
+ - Homebrew formula carries the sha256 of the published tarball; description
26
+ shortened to satisfy `brew audit --strict`.
27
+
10
28
  ## [0.1.0] - 2026-09-17
11
29
 
12
30
  First release. A claim verifier, not a test generator.
@@ -8,9 +8,10 @@ follow from that.
8
8
 
9
9
  ```bash
10
10
  git clone https://github.com/raccioly/testguard && cd testguard
11
- npm install # devDependencies only; the package itself has none
11
+ npm install
12
12
  npm test # ~15s: unit tests + probing the fixture end to end
13
13
  npm run self:probe # TestGuard's own claims, probed by TestGuard
14
+ npm run test:install # pack → install with prod deps only → run; what 0.1.0 lacked
14
15
  ```
15
16
 
16
17
  Node ≥ 20. Python ≥ 3.8 only if you touch `testguard_cli/`.
@@ -41,8 +42,9 @@ Node ≥ 20. Python ≥ 3.8 only if you touch `testguard_cli/`.
41
42
  load failure, or an exit code count as detection.
42
43
  5. **N-run confirmation everywhere** — baseline, probe, and escalation
43
44
  attribution. A single run is never evidence.
44
- 6. **Zero runtime dependencies.** Adding one needs a very good reason and a
45
- discussion first.
45
+ 6. **One runtime dependency** (`ajv`, exact-pinned). Adding another needs a
46
+ very good reason and a discussion first. `npm run test:install` proves
47
+ the package runs as installed with production dependencies only.
46
48
  7. **No client-identifying material.** Fixtures and examples use neutral
47
49
  domains. Benchmarks against real codebases live outside this repository
48
50
  (`bench/README.md`).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: testguard-cli
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Proves a test suite actually defends the claims a project makes: injects the faults those claims forbid and reports every one the tests miss. Python wrapper for the Node.js CLI (requires Node.js 20+).
5
5
  Project-URL: Homepage, https://github.com/raccioly/testguard
6
6
  Project-URL: Documentation, https://github.com/raccioly/testguard#readme
@@ -29,7 +29,7 @@ Description-Content-Type: text/markdown
29
29
  [![PyPI](https://img.shields.io/pypi/v/testguard-cli.svg)](https://pypi.org/project/testguard-cli/)
30
30
  [![node](https://img.shields.io/node/v/testguard-cli.svg)](https://nodejs.org)
31
31
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
32
- [![zero deps](https://img.shields.io/badge/runtime%20deps-0-brightgreen.svg)](./package.json)
32
+ [![deps](https://img.shields.io/badge/runtime%20deps-1%20pinned-brightgreen.svg)](./package.json)
33
33
 
34
34
  > Proves that a test suite actually defends the claims a project makes — by
35
35
  > injecting the faults those claims say cannot happen, and reporting every
@@ -67,7 +67,7 @@ on known-broken code. The largest gap was a compliance-critical path with
67
67
  | npm | `npm i -D testguard-cli` then `npx testguard probe` |
68
68
  | pip | `pip install testguard-cli` then `testguard probe` (needs Node ≥ 20) |
69
69
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
70
- | GitHub Action | `uses: raccioly/testguard@v0.1.0` — see [`action.yml`](./action.yml) |
70
+ | GitHub Action | `uses: raccioly/testguard@v0.1.1` — see [`action.yml`](./action.yml) |
71
71
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-probe` |
72
72
 
73
73
  ## How it works
@@ -147,7 +147,7 @@ through every verdict.
147
147
 
148
148
  **v0.1.** Four commands, vitest runner, hand-authored faults. The contract
149
149
  spine — six JSON Schemas shared with the other Guard tools — is under
150
- [`spec/`](spec/). Zero runtime dependencies; Node ≥ 20.
150
+ [`spec/`](spec/). One exact-pinned runtime dependency (`ajv`, for schema validation); Node ≥ 20.
151
151
 
152
152
  Not yet: test generation (the two-gate acceptance loop), other runners,
153
153
  mechanical fault producers, and calibration of fault classes against real
@@ -5,7 +5,7 @@
5
5
  [![PyPI](https://img.shields.io/pypi/v/testguard-cli.svg)](https://pypi.org/project/testguard-cli/)
6
6
  [![node](https://img.shields.io/node/v/testguard-cli.svg)](https://nodejs.org)
7
7
  [![license](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)
8
- [![zero deps](https://img.shields.io/badge/runtime%20deps-0-brightgreen.svg)](./package.json)
8
+ [![deps](https://img.shields.io/badge/runtime%20deps-1%20pinned-brightgreen.svg)](./package.json)
9
9
 
10
10
  > Proves that a test suite actually defends the claims a project makes — by
11
11
  > injecting the faults those claims say cannot happen, and reporting every
@@ -43,7 +43,7 @@ on known-broken code. The largest gap was a compliance-critical path with
43
43
  | npm | `npm i -D testguard-cli` then `npx testguard probe` |
44
44
  | pip | `pip install testguard-cli` then `testguard probe` (needs Node ≥ 20) |
45
45
  | Homebrew | `brew tap raccioly/tap && brew install testguard` |
46
- | GitHub Action | `uses: raccioly/testguard@v0.1.0` — see [`action.yml`](./action.yml) |
46
+ | GitHub Action | `uses: raccioly/testguard@v0.1.1` — see [`action.yml`](./action.yml) |
47
47
  | pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-probe` |
48
48
 
49
49
  ## How it works
@@ -123,7 +123,7 @@ through every verdict.
123
123
 
124
124
  **v0.1.** Four commands, vitest runner, hand-authored faults. The contract
125
125
  spine — six JSON Schemas shared with the other Guard tools — is under
126
- [`spec/`](spec/). Zero runtime dependencies; Node ≥ 20.
126
+ [`spec/`](spec/). One exact-pinned runtime dependency (`ajv`, for schema validation); Node ≥ 20.
127
127
 
128
128
  Not yet: test generation (the two-gate acceptance loop), other runners,
129
129
  mechanical fault producers, and calibration of fault classes against real
@@ -18,7 +18,9 @@ You will get an acknowledgement within 48 hours and a timeline for a fix.
18
18
 
19
19
  TestGuard is a local CLI with a deliberately small surface:
20
20
 
21
- - **Zero runtime dependencies.** `ajv` and `vitest` are development-only.
21
+ - **One runtime dependency, exact-pinned:** `ajv`, which validates every
22
+ document the tool reads or writes against the spec. Install scripts are
23
+ disabled (`.npmrc`). `vitest` is development-only.
22
24
  - **No network access.** Nothing is uploaded, fetched, or reported anywhere.
23
25
  - **No credentials.** There is nothing to authenticate to.
24
26
  - **Writes are confined** to `.testguard/` in the probed project and to
@@ -38,7 +38,7 @@ inputs:
38
38
  version:
39
39
  description: 'testguard-cli version to run'
40
40
  required: false
41
- default: '0.1.0'
41
+ default: '0.1.1'
42
42
  node-version:
43
43
  description: 'Node.js version (20+)'
44
44
  required: false
@@ -1,15 +1,20 @@
1
1
  {
2
2
  "name": "testguard-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "testguard-cli",
9
- "version": "0.1.0",
9
+ "version": "0.1.1",
10
10
  "license": "MIT",
11
+ "dependencies": {
12
+ "ajv": "8.20.0"
13
+ },
14
+ "bin": {
15
+ "testguard": "cli/testguard.mjs"
16
+ },
11
17
  "devDependencies": {
12
- "ajv": "^8.20.0",
13
18
  "vitest": "^5.0.1"
14
19
  },
15
20
  "engines": {
@@ -418,7 +423,6 @@
418
423
  "version": "8.20.0",
419
424
  "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
420
425
  "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
421
- "dev": true,
422
426
  "license": "MIT",
423
427
  "dependencies": {
424
428
  "fast-deep-equal": "^3.1.3",
@@ -493,14 +497,12 @@
493
497
  "version": "3.1.3",
494
498
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
495
499
  "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
496
- "dev": true,
497
500
  "license": "MIT"
498
501
  },
499
502
  "node_modules/fast-uri": {
500
503
  "version": "3.1.8",
501
504
  "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.8.tgz",
502
505
  "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==",
503
- "dev": true,
504
506
  "funding": [
505
507
  {
506
508
  "type": "github",
@@ -551,7 +553,6 @@
551
553
  "version": "1.0.0",
552
554
  "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
553
555
  "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
554
- "dev": true,
555
556
  "license": "MIT"
556
557
  },
557
558
  "node_modules/lightningcss": {
@@ -938,7 +939,6 @@
938
939
  "version": "2.0.2",
939
940
  "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
940
941
  "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
941
- "dev": true,
942
942
  "license": "MIT",
943
943
  "engines": {
944
944
  "node": ">=0.10.0"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testguard-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Proves a test suite defends the claims a project makes: injects the faults those claims forbid and reports every one the tests fail to detect.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -28,7 +28,8 @@
28
28
  "test:spec": "vitest run spec/conformance",
29
29
  "self:probe": "node cli/testguard.mjs probe . --budget 180000",
30
30
  "release:sync": "node .github/scripts/sync-release-version.mjs",
31
- "prepublishOnly": "node cli/testguard.mjs --version && node .github/scripts/sync-release-version.mjs --check"
31
+ "prepublishOnly": "node cli/testguard.mjs --version && node .github/scripts/sync-release-version.mjs --check",
32
+ "test:install": "node .github/scripts/install-smoke.mjs"
32
33
  },
33
34
  "keywords": [
34
35
  "testing",
@@ -45,7 +46,6 @@
45
46
  "quality-gate"
46
47
  ],
47
48
  "devDependencies": {
48
- "ajv": "^8.20.0",
49
49
  "vitest": "^5.0.1"
50
50
  },
51
51
  "bin": {
@@ -62,5 +62,8 @@
62
62
  },
63
63
  "publishConfig": {
64
64
  "access": "public"
65
+ },
66
+ "dependencies": {
67
+ "ajv": "8.20.0"
65
68
  }
66
69
  }
@@ -11,10 +11,10 @@
11
11
  # and set `sha256` from the published tarball:
12
12
  # curl -sL https://registry.npmjs.org/testguard-cli/-/testguard-cli-<VER>.tgz | shasum -a 256
13
13
  class Testguard < Formula
14
- desc "Proves a test suite defends the claims a project makes, by injecting the faults those claims forbid"
14
+ desc "Proves a test suite defends the claims a project makes"
15
15
  homepage "https://github.com/raccioly/testguard"
16
- url "https://registry.npmjs.org/testguard-cli/-/testguard-cli-0.1.0.tgz"
17
- sha256 "SET_AFTER_FIRST_NPM_PUBLISH"
16
+ url "https://registry.npmjs.org/testguard-cli/-/testguard-cli-0.1.1.tgz"
17
+ sha256 "fb7de3fa96886ca55a860bb6b2ed03dea1a6df13fb9fa7ad1bb12d860f9a971a"
18
18
  license "MIT"
19
19
 
20
20
  depends_on "node"
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "testguard-cli"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Proves a test suite actually defends the claims a project makes: injects the faults those claims forbid and reports every one the tests miss. Python wrapper for the Node.js CLI (requires Node.js 20+)."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes