@dogfood-lab/findings 1.7.0 → 1.9.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/cli.js +20 -3
- package/package.json +2 -2
- package/review/index.js +1 -1
- package/review/review-engine.js +23 -0
package/cli.js
CHANGED
|
@@ -45,7 +45,8 @@ import {
|
|
|
45
45
|
performAction,
|
|
46
46
|
performMerge,
|
|
47
47
|
getReviewQueue,
|
|
48
|
-
getEventsForFinding
|
|
48
|
+
getEventsForFinding,
|
|
49
|
+
EDITABLE_FIELDS
|
|
49
50
|
} from './review/index.js';
|
|
50
51
|
import {
|
|
51
52
|
reviewArtifact,
|
|
@@ -291,7 +292,8 @@ Commands:
|
|
|
291
292
|
accept <id> Accept a finding (--actor, --reason)
|
|
292
293
|
reject <id> Reject a finding (--actor, --reason, --reject-reason)
|
|
293
294
|
review <id> Move finding to reviewed (--actor)
|
|
294
|
-
edit <id> Edit finding fields (--actor, --set field=value)
|
|
295
|
+
edit <id> Edit finding fields (--actor, --set field=value).
|
|
296
|
+
Editable fields: ${EDITABLE_FIELDS.join(', ')}.
|
|
295
297
|
merge <ids...> Merge findings (--into <id>, --actor, --reason)
|
|
296
298
|
reopen <id> Reopen a rejected/accepted finding (--actor, --reason)
|
|
297
299
|
invalidate <id> Invalidate an accepted finding (--actor, --reason)
|
|
@@ -744,6 +746,7 @@ Structured output:
|
|
|
744
746
|
const findingId = positional[0];
|
|
745
747
|
if (!findingId) {
|
|
746
748
|
console.error('Usage: dogfood findings edit <finding_id> --actor <name> --set field=value [--set field=value]');
|
|
749
|
+
console.error(`Editable fields: ${EDITABLE_FIELDS.join(', ')}`);
|
|
747
750
|
process.exit(2);
|
|
748
751
|
}
|
|
749
752
|
// Parse --set flags
|
|
@@ -1323,6 +1326,20 @@ Structured output:
|
|
|
1323
1326
|
}
|
|
1324
1327
|
|
|
1325
1328
|
main().catch(err => {
|
|
1326
|
-
|
|
1329
|
+
// F-26179cb8 (Stage C humanization): render the repo-wide structured envelope
|
|
1330
|
+
// sibling bins use (report/cli.js emitError, report/init.js) instead of
|
|
1331
|
+
// dumping the raw Error/stack. The raw stack is a triage aid, not a default —
|
|
1332
|
+
// it stays behind DEBUG so a mis-rooted checkout or an un-caught throw gives
|
|
1333
|
+
// the operator `ERROR [<CODE>]:` + a next step, not a bare Node stack.
|
|
1334
|
+
const code = err && err.code ? err.code : 'UNEXPECTED';
|
|
1335
|
+
const message = err && err.message ? err.message : String(err);
|
|
1336
|
+
console.error(`ERROR [${code}]: ${message}`);
|
|
1337
|
+
console.error(
|
|
1338
|
+
' Next: run from the testing-os repo root, or set FINDINGS_REPO_ROOT to it; ' +
|
|
1339
|
+
'run `dogfood findings --help` for usage. Re-run with DEBUG=1 for the stack.'
|
|
1340
|
+
);
|
|
1341
|
+
if (process.env.DEBUG && err && err.stack) {
|
|
1342
|
+
console.error(err.stack);
|
|
1343
|
+
}
|
|
1327
1344
|
process.exit(2);
|
|
1328
1345
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dogfood-lab/findings",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Finding contract spine for testing-os. Validates, reads, lists, and queries evidence-bound findings — the fourth contract alongside record, scenario, and policy.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"findings": "./cli.js"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "node --test
|
|
21
|
+
"test": "node --test"
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"index.js",
|
package/review/index.js
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { isLawfulTransition, validateTransition, ACTION_TARGET_STATUS, REASON_REQUIRED } from './transitions.js';
|
|
5
5
|
export { createEvent, appendEvent, getEventsForFinding, getAllEvents, getLogPath, generateEventId } from './event-log.js';
|
|
6
|
-
export { performAction, performMerge, getReviewQueue } from './review-engine.js';
|
|
6
|
+
export { performAction, performMerge, getReviewQueue, EDITABLE_FIELDS } from './review-engine.js';
|
package/review/review-engine.js
CHANGED
|
@@ -15,6 +15,29 @@ import { parseFinding, validateFinding } from '../validate.js';
|
|
|
15
15
|
import { findById, loadFindings } from '../reader.js';
|
|
16
16
|
import { atomicWriteFileSync } from '../lib/atomic-write.js';
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* The prose + classification fields an operator may safely target with
|
|
20
|
+
* `edit --set field=value`. This is the human-facing subset of the finding
|
|
21
|
+
* contract: free-text prose and the four classification enums. Identity,
|
|
22
|
+
* lineage, and evidence fields (finding_id, schema_version, source_record_ids,
|
|
23
|
+
* evidence, status, …) are excluded — they are set by the pipeline, not edited
|
|
24
|
+
* in place. The downstream write gate (dogfood-finding.schema.json's
|
|
25
|
+
* additionalProperties:false + enum checks) is the enforcement boundary; this
|
|
26
|
+
* list is what the CLI help renders so the documented set and the gate's
|
|
27
|
+
* intent share one source. Editing an unlisted field is still refused post-hoc
|
|
28
|
+
* by the schema gate — this constant narrows the help, not the enforcement.
|
|
29
|
+
*/
|
|
30
|
+
export const EDITABLE_FIELDS = Object.freeze([
|
|
31
|
+
'title',
|
|
32
|
+
'summary',
|
|
33
|
+
'doctrine_statement',
|
|
34
|
+
'notes',
|
|
35
|
+
'issue_kind',
|
|
36
|
+
'root_cause_kind',
|
|
37
|
+
'remediation_kind',
|
|
38
|
+
'transfer_scope'
|
|
39
|
+
]);
|
|
40
|
+
|
|
18
41
|
/**
|
|
19
42
|
* Perform a review action on a finding.
|
|
20
43
|
*
|