harness-everything 0.41.3 → 0.42.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +6 -0
- package/benchmarks/results/h1-provider-independence-qualification/README.md +72 -0
- package/ci/mechanism-325-3b-h1-qualification.test.js +206 -0
- package/ci/mechanism-341-opencode-lane.test.js +465 -0
- package/hooks/scripts/lib/doc-reconciliation-pilot.js +40 -10
- package/hooks/scripts/lib/doc-reconciliation-provider.js +159 -11
- package/hooks/scripts/workflow-stop-gate.js +4 -1
- package/opencode-plugin/index.mjs +77 -5
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +40 -10
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +159 -11
- package/plugins/harness-everything/hooks/scripts/workflow-stop-gate.js +4 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/sbom.cdx.json +7 -7
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"name": "harness-everything",
|
|
11
11
|
"source": "./",
|
|
12
12
|
"description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
|
|
13
|
-
"version": "0.
|
|
13
|
+
"version": "0.42.0",
|
|
14
14
|
"author": {
|
|
15
15
|
"name": "Miya Daniel"
|
|
16
16
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harness-everything",
|
|
3
3
|
"description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.42.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Miya Daniel"
|
|
7
7
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.42.0](https://github.com/dyphn1/Harness-everything/compare/v0.41.3...v0.42.0) (2026-10-25)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **opencode:** wire bounded reconciliation ([039cf21](https://github.com/dyphn1/Harness-everything/commit/039cf2194ea232dc5bea715b67684a234a6a1ac4)), closes [#341](https://github.com/dyphn1/Harness-everything/issues/341) [#325](https://github.com/dyphn1/Harness-everything/issues/325)
|
|
10
|
+
|
|
5
11
|
## [0.41.3](https://github.com/dyphn1/Harness-everything/compare/v0.41.2...v0.41.3) (2026-10-25)
|
|
6
12
|
|
|
7
13
|
### Bug Fixes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# H1 provider-independence qualification (preparation)
|
|
2
|
+
|
|
3
|
+
This directory records the bounded #325 H1 preparation/non-interference qualification scope. It is preparation evidence only; it is not full H1, Phase 3c, E1, paired evidence, benefit evidence, or #320 promotion.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
- H1 preparation/non-interference only.
|
|
8
|
+
- `suggestDocProviders` is called as an independent side input. Suggestions and provider identity are never passed to the F4 consumer, workflow, binding, or reconciliation path.
|
|
9
|
+
- No runtime, shared harness, package, manifest, lockfile, fixture JSON, or issue edits are part of this qualification.
|
|
10
|
+
- The registered F4 evidence and executor remain the only evidence path: executor `f4-pos-body-edit-session`; provenance `claude-code-capture:<captureId>`.
|
|
11
|
+
|
|
12
|
+
## Matrix
|
|
13
|
+
|
|
14
|
+
Cross product: 3 provider inputs × 2 evidence modes × 2 distributions = 12 cells.
|
|
15
|
+
|
|
16
|
+
Provider inputs:
|
|
17
|
+
|
|
18
|
+
- A: only `fixture-lint-a` metadata; expected exactly the A suggestion.
|
|
19
|
+
- B: only `fixture-lint-b` metadata; expected exactly the B suggestion.
|
|
20
|
+
- Omitted: no provider metadata; expected `suggestions: []` and one unavailable `doc-lint` record.
|
|
21
|
+
|
|
22
|
+
Evidence modes:
|
|
23
|
+
|
|
24
|
+
- Valid evidence: actual registered doc-check `hostRun` and correlated `PostToolUse` capture.
|
|
25
|
+
- Zero evidence: same F4-POS-body-edit task definition and loaded `verification-loop` binding, with only `lint-run` and `post-lint` removed.
|
|
26
|
+
|
|
27
|
+
Distributions: `source` and `packaged`.
|
|
28
|
+
|
|
29
|
+
## Fixed expected full applicable MUST objects
|
|
30
|
+
|
|
31
|
+
- `{id:"doc-change:doc-lint", capability:"doc-lint", strength:"MUST", applicability:"applicable", scope:{paths:["docs/a.md"]}, acceptance:"Run document lifecycle lint for every changed governed document."}`
|
|
32
|
+
- `{id:"doc-change:link-check", capability:"link-check", strength:"MUST", applicability:"applicable", scope:{paths:["docs/a.md"]}, acceptance:"Check in-repository links for every changed governed document."}`
|
|
33
|
+
|
|
34
|
+
`expectedMustIds` must equal those IDs. The pilot runtime report `results` field is empty and is not asserted. A non-blocking missing-path-coverage diagnostic for the SHOULD `prose-reminder` is expected; diagnostics are not asserted empty.
|
|
35
|
+
|
|
36
|
+
## Asserted fields
|
|
37
|
+
|
|
38
|
+
Valid evidence cells assert:
|
|
39
|
+
|
|
40
|
+
- `reportOrigin: runtime`
|
|
41
|
+
- `expectedMustIds` exact
|
|
42
|
+
- no unsatisfied MUSTs
|
|
43
|
+
- `creditedCapabilities` and accepted refs for both capabilities
|
|
44
|
+
- `pilotCredit: true`, `pilotStatus: credited`
|
|
45
|
+
- verification step pass
|
|
46
|
+
- Stop exit `0`, workflow state `satisfied`
|
|
47
|
+
|
|
48
|
+
Zero evidence cells assert:
|
|
49
|
+
|
|
50
|
+
- both MUSTs remain expected and unsatisfied
|
|
51
|
+
- `creditedCapabilities` and `acceptedRefs` empty
|
|
52
|
+
- `pilotCredit: false`, `pilotStatus: unresolved`
|
|
53
|
+
- verification step pending
|
|
54
|
+
- Stop exit `0`, workflow state `running` (not satisfied)
|
|
55
|
+
|
|
56
|
+
## Test approach and execution
|
|
57
|
+
|
|
58
|
+
This is an integration qualification because each F4 cell crosses real child processes, filesystem state, hook entries, and workflow disposition. Expectations come from #325 H1 and the fixed F4 fixture. The existing valid-evidence and zero-evidence cases are positive and negative controls; this does not manufacture a runtime-bug RED or authorize runtime edits.
|
|
59
|
+
|
|
60
|
+
| Command | Result |
|
|
61
|
+
|---|---|
|
|
62
|
+
| `node ci/mechanism-325-3b-h1-qualification.test.js` | 36 PASS, 0 FAIL, 0 INFRA; all 12 matrix cells and source/package MUST derivations passed |
|
|
63
|
+
| Initial `npm run verify:all -- --fast` | 3 PASS, 2 FAIL, 11 UNCHECKED. Environment preflight failure: this worktree had no node_modules; self-regression lacked node_modules and the #341 C2 AST checker/mutation controls reported AST_PARSER_UNAVAILABLE. This is not counted as a product defect. |
|
|
64
|
+
| Focused dependency controls after installation | Node 24.22.1: mechanism-2i-crlf-frontmatter passed; mechanism-341-boundary-enforcement passed all C1/C2 controls; npm run test:mutations passed 113 mutants and 2 source probe suites. |
|
|
65
|
+
| Final `npm run verify:all` | Node 24.22.1: 13 PASS, 0 FAIL, 3 UNCHECKED. The unchecked items are Node 22 self-regression smoke, Node 22 installer roundtrip, and npm ci under Node 22. No CI or live-host evidence is claimed. |
|
|
66
|
+
|
|
67
|
+
The initial fast run was retained as the environment-preflight result and was not rerun. After confirming the missing dependencies with npm ls and resolving pinned acorn/acorn-walk, the full verification gate passed. Dependencies were installed with npm ci --ignore-scripts; the only package lifecycle script is prepare: husky install.
|
|
68
|
+
|
|
69
|
+
## Pending
|
|
70
|
+
|
|
71
|
+
- Full H1 and Phase 3c remain pending.
|
|
72
|
+
- E1, paired evidence, benefit evidence, and #320 promotion remain pending.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// #325 H1 deterministic qualification: provider independence/preparation.
|
|
5
|
+
// H1 only: advisory suggestions are never passed to the F4 consumer.
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const fx = require(path.join(__dirname, 'lib', 'doc-reconciliation-prep-fixtures'));
|
|
11
|
+
const { stage } = require(path.join(__dirname, 'lib', 'doc-reconciliation-staged-tree'));
|
|
12
|
+
const F4_CASES = path.join(__dirname, 'fixtures', 'doc-obligations', 'reconciliation-s2b', 'f4', 'cases.json');
|
|
13
|
+
|
|
14
|
+
const REPO_ROOT = path.resolve(__dirname, '..');
|
|
15
|
+
const SOURCE_OBLIGATIONS = require(path.join(REPO_ROOT, 'harness-everything', 'scripts', 'doc-obligations.js'));
|
|
16
|
+
const PACKAGED_OBLIGATIONS = require(path.join(REPO_ROOT, 'plugins', 'harness-everything', 'skills', 'harness-everything', 'scripts', 'doc-obligations.js'));
|
|
17
|
+
const SOURCE_PROVIDER = require(path.join(REPO_ROOT, 'harness-everything', 'scripts', 'doc-providers.js'));
|
|
18
|
+
const PACKAGED_PROVIDER = require(path.join(REPO_ROOT, 'plugins', 'harness-everything', 'skills', 'harness-everything', 'scripts', 'doc-providers.js'));
|
|
19
|
+
|
|
20
|
+
const LEGS = ['source', 'packaged'];
|
|
21
|
+
const CASE = id => fx.readCaseCorpus(F4_CASES).cases.find(item => item.id === id);
|
|
22
|
+
|
|
23
|
+
const EXPECTED_MUSTS = [
|
|
24
|
+
{ id: 'doc-change:doc-lint', capability: 'doc-lint', strength: 'MUST', applicability: 'applicable', scope: { paths: ['docs/a.md'] }, acceptance: 'Run document lifecycle lint for every changed governed document.' },
|
|
25
|
+
{ id: 'doc-change:link-check', capability: 'link-check', strength: 'MUST', applicability: 'applicable', scope: { paths: ['docs/a.md'] }, acceptance: 'Check in-repository links for every changed governed document.' }
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const PROVIDER_A_INPUT = {
|
|
29
|
+
activeStep: { id: 'verify-docs', stepType: 'verification' },
|
|
30
|
+
neededCapabilities: ['doc-lint'],
|
|
31
|
+
availableProviderMetadata: [
|
|
32
|
+
{ providerId: 'fixture-lint-a', capabilities: ['doc-lint'], stepTypes: ['verification'], requiresHostCapabilities: ['execution-events'], locator: { kind: 'tool', id: 'fixture-lint-a' } }
|
|
33
|
+
],
|
|
34
|
+
hostCapabilities: ['execution-events']
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const PROVIDER_B_INPUT = {
|
|
38
|
+
activeStep: { id: 'verify-docs', stepType: 'verification' },
|
|
39
|
+
neededCapabilities: ['doc-lint'],
|
|
40
|
+
availableProviderMetadata: [
|
|
41
|
+
{ providerId: 'fixture-lint-b', capabilities: ['doc-lint'], stepTypes: ['verification'], requiresHostCapabilities: ['execution-events'], locator: { kind: 'tool', id: 'fixture-lint-b' } }
|
|
42
|
+
],
|
|
43
|
+
hostCapabilities: ['execution-events']
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const PROVIDER_OMITTED_INPUT = {
|
|
47
|
+
activeStep: { id: 'verify-docs', stepType: 'verification' },
|
|
48
|
+
neededCapabilities: ['doc-lint'],
|
|
49
|
+
availableProviderMetadata: [],
|
|
50
|
+
hostCapabilities: []
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const PROVIDER_A_SUGGESTION = [{ capability: 'doc-lint', providerId: 'fixture-lint-a', availability: 'available', reason: 'active-step capability and host requirements match' }];
|
|
54
|
+
const PROVIDER_B_SUGGESTION = [{ capability: 'doc-lint', providerId: 'fixture-lint-b', availability: 'available', reason: 'active-step capability and host requirements match' }];
|
|
55
|
+
const PROVIDER_OMITTED_UNAVAILABLE = [{ capability: 'doc-lint', reason: 'no available provider metadata for the active-step capability' }];
|
|
56
|
+
|
|
57
|
+
let passCount = 0;
|
|
58
|
+
let failCount = 0;
|
|
59
|
+
let infraCount = 0;
|
|
60
|
+
|
|
61
|
+
function deepEqual(left, right) {
|
|
62
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function record(status, id, detail) {
|
|
66
|
+
const suffix = detail ? ` - ${detail}` : '';
|
|
67
|
+
if (status === 'PASS') passCount += 1;
|
|
68
|
+
else if (status === 'FAIL') failCount += 1;
|
|
69
|
+
else infraCount += 1;
|
|
70
|
+
console.log(` ${status.padEnd(5)} ${id}${suffix}`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function cloneZero(caseDef) {
|
|
74
|
+
return {
|
|
75
|
+
...caseDef,
|
|
76
|
+
id: `${caseDef.id}-zero-evidence`,
|
|
77
|
+
actions: caseDef.actions.filter(action => action.id !== 'lint-run' && action.id !== 'post-lint')
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function checkProvider(leg, providerCase) {
|
|
82
|
+
const module = leg === 'source' ? SOURCE_PROVIDER : PACKAGED_PROVIDER;
|
|
83
|
+
let input;
|
|
84
|
+
let expectedSuggestions;
|
|
85
|
+
let expectedUnavailable;
|
|
86
|
+
if (providerCase === 'A') {
|
|
87
|
+
input = PROVIDER_A_INPUT;
|
|
88
|
+
expectedSuggestions = PROVIDER_A_SUGGESTION;
|
|
89
|
+
expectedUnavailable = [];
|
|
90
|
+
} else if (providerCase === 'B') {
|
|
91
|
+
input = PROVIDER_B_INPUT;
|
|
92
|
+
expectedSuggestions = PROVIDER_B_SUGGESTION;
|
|
93
|
+
expectedUnavailable = [];
|
|
94
|
+
} else {
|
|
95
|
+
input = PROVIDER_OMITTED_INPUT;
|
|
96
|
+
expectedSuggestions = [];
|
|
97
|
+
expectedUnavailable = PROVIDER_OMITTED_UNAVAILABLE;
|
|
98
|
+
}
|
|
99
|
+
const result = module.suggestDocProviders(input);
|
|
100
|
+
const ok = deepEqual(result.suggestions, expectedSuggestions) && deepEqual(result.unavailable, expectedUnavailable);
|
|
101
|
+
record(ok ? 'PASS' : 'FAIL', `H1.${leg}.${providerCase}.provider-suggestion`, ok ? '' : `suggestions=${JSON.stringify(result.suggestions)}, unavailable=${JSON.stringify(result.unavailable)}`);
|
|
102
|
+
return ok;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function checkDerivedMusts(leg, label) {
|
|
106
|
+
const module = leg === 'source' ? SOURCE_OBLIGATIONS : PACKAGED_OBLIGATIONS;
|
|
107
|
+
const caseDef = CASE('F4-POS-body-edit');
|
|
108
|
+
const config = JSON.parse(caseDef.input.baseFiles['.agents/harness-everything/project-docs.json']);
|
|
109
|
+
const base = { files: caseDef.input.baseFiles };
|
|
110
|
+
const candidate = { files: { ...caseDef.input.baseFiles, ...caseDef.input.candidateFiles } };
|
|
111
|
+
const { facts } = module.deriveDocFacts({ base, candidate, config, inventory: { complete: true } });
|
|
112
|
+
const obligations = module.deriveDocObligations(facts);
|
|
113
|
+
const fullMusts = obligations.filter(item => item.strength === 'MUST' && item.applicability === 'applicable');
|
|
114
|
+
|
|
115
|
+
let ok = deepEqual(fullMusts, EXPECTED_MUSTS);
|
|
116
|
+
for (const item of fullMusts) {
|
|
117
|
+
if (!item.id || !item.capability || !item.strength || !item.applicability || !item.scope || !Array.isArray(item.scope.paths) || item.scope.paths.some(pathValue => !pathValue) || !item.acceptance) ok = false;
|
|
118
|
+
}
|
|
119
|
+
record(ok ? 'PASS' : 'FAIL', `${label}.derived-full-musts`, ok ? '' : JSON.stringify(fullMusts));
|
|
120
|
+
return ok;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function runCell(leg, providerCase, evidenceMode) {
|
|
124
|
+
const label = `H1.${leg}.${providerCase}.${evidenceMode}`;
|
|
125
|
+
const staged = stage(leg);
|
|
126
|
+
try {
|
|
127
|
+
checkProvider(leg, providerCase);
|
|
128
|
+
checkDerivedMusts(leg, label);
|
|
129
|
+
|
|
130
|
+
staged.writeExport(staged.validExport());
|
|
131
|
+
|
|
132
|
+
const baseCase = CASE('F4-POS-body-edit');
|
|
133
|
+
const caseDef = evidenceMode === 'valid' ? baseCase : cloneZero(baseCase);
|
|
134
|
+
|
|
135
|
+
const root = fx.replayCase(caseDef, staged.dist, { pilot: '1' });
|
|
136
|
+
const faults = fx.infrastructureFaults(caseDef, root, 'on');
|
|
137
|
+
if (faults.length) {
|
|
138
|
+
record('INFRA', label, faults.map(fault => `${fault.actionId}: ${fault.message}`).join('; '));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const pilot = root.pilot || {};
|
|
143
|
+
const checks = [];
|
|
144
|
+
|
|
145
|
+
checks.push(deepEqual(root.pilotReportOrigin, 'runtime'));
|
|
146
|
+
checks.push(deepEqual(pilot.reportOrigin, 'runtime'));
|
|
147
|
+
checks.push(deepEqual(pilot.expectedMustIds, ['doc-change:doc-lint', 'doc-change:link-check']));
|
|
148
|
+
const verifyAction = root.actions && root.actions['verify-pass'];
|
|
149
|
+
const verifyRequirement = verifyAction?.state?.obligations?.requirements?.find(item => item.id === 'req-verify');
|
|
150
|
+
checks.push(verifyRequirement?.requiredBindings?.some(binding => binding.id === 'verification-loop' && binding.status === 'loaded') === true);
|
|
151
|
+
|
|
152
|
+
if (evidenceMode === 'valid') {
|
|
153
|
+
checks.push(pilot.pilotCredit === true);
|
|
154
|
+
checks.push(pilot.pilotStatus === 'credited');
|
|
155
|
+
checks.push(deepEqual(pilot.unsatisfied, []));
|
|
156
|
+
checks.push(deepEqual(pilot.creditedCapabilities, ['doc-lint', 'link-check']));
|
|
157
|
+
checks.push(Array.isArray(pilot.acceptedRefs) && pilot.acceptedRefs.some(ref => ref.endsWith('#doc-lint')) && pilot.acceptedRefs.some(ref => ref.endsWith('#link-check')));
|
|
158
|
+
checks.push(verifyAction && verifyAction.exitCode === 0);
|
|
159
|
+
const stopAction = root.actions && root.actions.stop;
|
|
160
|
+
checks.push(stopAction && stopAction.exitCode === 0);
|
|
161
|
+
checks.push(stopAction && stopAction.state && stopAction.state.workflow && stopAction.state.workflow.state === 'satisfied');
|
|
162
|
+
} else {
|
|
163
|
+
checks.push(pilot.pilotCredit === false);
|
|
164
|
+
checks.push(pilot.pilotStatus === 'unresolved');
|
|
165
|
+
checks.push(Array.isArray(pilot.unsatisfied) && pilot.unsatisfied.length >= 2);
|
|
166
|
+
checks.push(pilot.unsatisfied.some(item => item.obligationId === 'doc-change:doc-lint'));
|
|
167
|
+
checks.push(pilot.unsatisfied.some(item => item.obligationId === 'doc-change:link-check'));
|
|
168
|
+
checks.push(deepEqual(pilot.creditedCapabilities, []));
|
|
169
|
+
checks.push(deepEqual(pilot.acceptedRefs, []));
|
|
170
|
+
checks.push(verifyAction && verifyAction.exitCode === 2);
|
|
171
|
+
const stopAction = root.actions && root.actions.stop;
|
|
172
|
+
checks.push(stopAction && stopAction.exitCode === 0);
|
|
173
|
+
checks.push(stopAction && stopAction.state && stopAction.state.workflow && stopAction.state.workflow.state === 'running');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
record(checks.every(Boolean) ? 'PASS' : 'FAIL', label, checks.every(Boolean) ? '' : `checks=${JSON.stringify(checks)}, pilot=${JSON.stringify(pilot).slice(0, 500)}`);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
record('FAIL', label, error.message);
|
|
179
|
+
} finally {
|
|
180
|
+
staged.cleanup();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function main() {
|
|
185
|
+
console.log('\n== H1 qualification: provider side input and F4 replay matrix ==');
|
|
186
|
+
for (const leg of LEGS) {
|
|
187
|
+
for (const providerCase of ['A', 'B', 'omitted']) {
|
|
188
|
+
for (const evidenceMode of ['valid', 'zero']) {
|
|
189
|
+
runCell(leg, providerCase, evidenceMode);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
console.log('\n== H1 qualification evidence ==');
|
|
195
|
+
console.log(`passing checks: ${passCount}`);
|
|
196
|
+
console.log(`unexpected failures: ${failCount}`);
|
|
197
|
+
console.log(`infrastructure faults: ${infraCount}`);
|
|
198
|
+
if (failCount === 0 && infraCount === 0) {
|
|
199
|
+
console.log('\nSTATUS: GREEN (all assertions passed)');
|
|
200
|
+
return 0;
|
|
201
|
+
}
|
|
202
|
+
console.log('\nSTATUS: NOT-GREEN');
|
|
203
|
+
return 1;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
process.exitCode = main();
|