@codeledger/cli 0.5.0 → 0.6.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/dist/artifacts/summary.d.ts +6 -0
- package/dist/artifacts/summary.d.ts.map +1 -0
- package/dist/artifacts/summary.js +49 -0
- package/dist/artifacts/summary.js.map +1 -0
- package/dist/commands/activate.d.ts.map +1 -1
- package/dist/commands/activate.js +64 -23
- package/dist/commands/activate.js.map +1 -1
- package/dist/commands/bundle.d.ts.map +1 -1
- package/dist/commands/bundle.js +28 -5
- package/dist/commands/bundle.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +10 -12
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/intent.d.ts.map +1 -1
- package/dist/commands/intent.js +17 -2
- package/dist/commands/intent.js.map +1 -1
- package/dist/commands/manifest.d.ts +8 -0
- package/dist/commands/manifest.d.ts.map +1 -0
- package/dist/commands/manifest.js +144 -0
- package/dist/commands/manifest.js.map +1 -0
- package/dist/commands/policy.d.ts +8 -0
- package/dist/commands/policy.d.ts.map +1 -0
- package/dist/commands/policy.js +27 -0
- package/dist/commands/policy.js.map +1 -0
- package/dist/commands/progress-check.d.ts +14 -0
- package/dist/commands/progress-check.d.ts.map +1 -0
- package/dist/commands/progress-check.js +153 -0
- package/dist/commands/progress-check.js.map +1 -0
- package/dist/commands/review-coverage.d.ts +12 -0
- package/dist/commands/review-coverage.d.ts.map +1 -0
- package/dist/commands/review-coverage.js +142 -0
- package/dist/commands/review-coverage.js.map +1 -0
- package/dist/commands/review-gate.d.ts +12 -0
- package/dist/commands/review-gate.d.ts.map +1 -0
- package/dist/commands/review-gate.js +130 -0
- package/dist/commands/review-gate.js.map +1 -0
- package/dist/commands/session-summary.d.ts.map +1 -1
- package/dist/commands/session-summary.js +39 -5
- package/dist/commands/session-summary.js.map +1 -1
- package/dist/commands/setup-ci.d.ts +9 -0
- package/dist/commands/setup-ci.d.ts.map +1 -0
- package/dist/commands/setup-ci.js +139 -0
- package/dist/commands/setup-ci.js.map +1 -0
- package/dist/commands/sign-manifest.d.ts +8 -0
- package/dist/commands/sign-manifest.d.ts.map +1 -0
- package/dist/commands/sign-manifest.js +58 -0
- package/dist/commands/sign-manifest.js.map +1 -0
- package/dist/commands/vendor.d.ts +20 -0
- package/dist/commands/vendor.d.ts.map +1 -0
- package/dist/commands/vendor.js +157 -0
- package/dist/commands/vendor.js.map +1 -0
- package/dist/commands/verify.d.ts +13 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +288 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/github-actions.d.ts +17 -0
- package/dist/integrations/github-actions.d.ts.map +1 -0
- package/dist/integrations/github-actions.js +64 -0
- package/dist/integrations/github-actions.js.map +1 -0
- package/dist/manifest/build.d.ts +19 -0
- package/dist/manifest/build.d.ts.map +1 -0
- package/dist/manifest/build.js +82 -0
- package/dist/manifest/build.js.map +1 -0
- package/dist/manifest/schema.d.ts +2 -0
- package/dist/manifest/schema.d.ts.map +1 -0
- package/dist/manifest/schema.js +2 -0
- package/dist/manifest/schema.js.map +1 -0
- package/dist/manifest/write.d.ts +13 -0
- package/dist/manifest/write.d.ts.map +1 -0
- package/dist/manifest/write.js +69 -0
- package/dist/manifest/write.js.map +1 -0
- package/dist/policy/load.d.ts +21 -0
- package/dist/policy/load.d.ts.map +1 -0
- package/dist/policy/load.js +63 -0
- package/dist/policy/load.js.map +1 -0
- package/dist/policy/resolve.d.ts +18 -0
- package/dist/policy/resolve.d.ts.map +1 -0
- package/dist/policy/resolve.js +86 -0
- package/dist/policy/resolve.js.map +1 -0
- package/dist/policy/schema.d.ts +22 -0
- package/dist/policy/schema.d.ts.map +1 -0
- package/dist/policy/schema.js +82 -0
- package/dist/policy/schema.js.map +1 -0
- package/dist/session-paths.d.ts +6 -0
- package/dist/session-paths.d.ts.map +1 -1
- package/dist/session-paths.js +12 -0
- package/dist/session-paths.js.map +1 -1
- package/dist/signing/canonicalize.d.ts +17 -0
- package/dist/signing/canonicalize.d.ts.map +1 -0
- package/dist/signing/canonicalize.js +50 -0
- package/dist/signing/canonicalize.js.map +1 -0
- package/dist/signing/hmac.d.ts +8 -0
- package/dist/signing/hmac.d.ts.map +1 -0
- package/dist/signing/hmac.js +16 -0
- package/dist/signing/hmac.js.map +1 -0
- package/dist/signing/signer.d.ts +16 -0
- package/dist/signing/signer.d.ts.map +1 -0
- package/dist/signing/signer.js +2 -0
- package/dist/signing/signer.js.map +1 -0
- package/dist/templates/claude-md.d.ts.map +1 -1
- package/dist/templates/claude-md.js +61 -3
- package/dist/templates/claude-md.js.map +1 -1
- package/dist/templates/config.d.ts.map +1 -1
- package/dist/templates/config.js +3 -0
- package/dist/templates/config.js.map +1 -1
- package/dist/templates/hooks.d.ts.map +1 -1
- package/dist/templates/hooks.js +35 -2
- package/dist/templates/hooks.js.map +1 -1
- package/dist/verify/evaluate.d.ts +10 -0
- package/dist/verify/evaluate.d.ts.map +1 -0
- package/dist/verify/evaluate.js +117 -0
- package/dist/verify/evaluate.js.map +1 -0
- package/dist/verify/policy-snapshot.d.ts +7 -0
- package/dist/verify/policy-snapshot.d.ts.map +1 -0
- package/dist/verify/policy-snapshot.js +36 -0
- package/dist/verify/policy-snapshot.js.map +1 -0
- package/dist/verify/report.d.ts +11 -0
- package/dist/verify/report.d.ts.map +1 -0
- package/dist/verify/report.js +64 -0
- package/dist/verify/report.js.map +1 -0
- package/package.json +10 -10
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedPolicyV1, ContextManifestV1, ViolationV1, CoverageAttestationV1 } from '@codeledger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a manifest against a resolved policy. Returns violations sorted
|
|
4
|
+
* by code then path for deterministic output.
|
|
5
|
+
*
|
|
6
|
+
* This function does NOT make pass/fail decisions — it only detects violations.
|
|
7
|
+
* The calling code decides exit codes based on policy mode.
|
|
8
|
+
*/
|
|
9
|
+
export declare function evaluatePolicy(manifest: ContextManifestV1, policy: ResolvedPolicyV1, coverageAttestation?: CoverageAttestationV1): ViolationV1[];
|
|
10
|
+
//# sourceMappingURL=evaluate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/verify/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,qBAAqB,EACtB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,gBAAgB,EACxB,mBAAmB,CAAC,EAAE,qBAAqB,GAC1C,WAAW,EAAE,CAsGf"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluate a manifest against a resolved policy. Returns violations sorted
|
|
3
|
+
* by code then path for deterministic output.
|
|
4
|
+
*
|
|
5
|
+
* This function does NOT make pass/fail decisions — it only detects violations.
|
|
6
|
+
* The calling code decides exit codes based on policy mode.
|
|
7
|
+
*/
|
|
8
|
+
export function evaluatePolicy(manifest, policy, coverageAttestation) {
|
|
9
|
+
const violations = [];
|
|
10
|
+
// LOW_CONFIDENCE — overall_confidence < min_confidence
|
|
11
|
+
if (manifest.confidence.overall < policy.min_confidence) {
|
|
12
|
+
violations.push({
|
|
13
|
+
code: 'LOW_CONFIDENCE',
|
|
14
|
+
message: `Overall confidence ${manifest.confidence.overall.toFixed(2)} below minimum ${policy.min_confidence.toFixed(2)}`,
|
|
15
|
+
value: manifest.confidence.overall,
|
|
16
|
+
threshold: policy.min_confidence,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// HIGH_DRIFT — drift_score > max_drift
|
|
20
|
+
if (manifest.intent.drift_score > policy.max_drift) {
|
|
21
|
+
violations.push({
|
|
22
|
+
code: 'HIGH_DRIFT',
|
|
23
|
+
message: `Drift score ${manifest.intent.drift_score.toFixed(2)} exceeds maximum ${policy.max_drift.toFixed(2)}`,
|
|
24
|
+
value: manifest.intent.drift_score,
|
|
25
|
+
threshold: policy.max_drift,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// DENY_PATH_MATCH — selected file matches deny_paths pattern
|
|
29
|
+
for (const file of manifest.bundle.files) {
|
|
30
|
+
for (const pattern of policy.deny_paths) {
|
|
31
|
+
if (matchDenyPattern(file.path, pattern)) {
|
|
32
|
+
violations.push({
|
|
33
|
+
code: 'DENY_PATH_MATCH',
|
|
34
|
+
message: `Selected file ${file.path} matches deny pattern ${pattern}`,
|
|
35
|
+
path: file.path,
|
|
36
|
+
pattern,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// MISSING_TESTS — test_presence below threshold when require_tests is true
|
|
42
|
+
if (policy.require_tests) {
|
|
43
|
+
const testPresence = manifest.confidence.envelope.test_presence;
|
|
44
|
+
// require_tests uses a fixed threshold of 0.50
|
|
45
|
+
const threshold = 0.50;
|
|
46
|
+
if (testPresence < threshold) {
|
|
47
|
+
violations.push({
|
|
48
|
+
code: 'MISSING_TESTS',
|
|
49
|
+
message: `Test presence ${testPresence.toFixed(2)} below required threshold ${threshold.toFixed(2)}`,
|
|
50
|
+
value: testPresence,
|
|
51
|
+
threshold,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// BUNDLE_TOO_LARGE — file count or byte count exceeds policy limits
|
|
56
|
+
if (manifest.bundle.file_count > policy.bundle_max_files) {
|
|
57
|
+
violations.push({
|
|
58
|
+
code: 'BUNDLE_TOO_LARGE',
|
|
59
|
+
message: `Bundle file count ${manifest.bundle.file_count} exceeds limit ${policy.bundle_max_files}`,
|
|
60
|
+
dimension: 'file_count',
|
|
61
|
+
value: manifest.bundle.file_count,
|
|
62
|
+
threshold: policy.bundle_max_files,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (manifest.bundle.total_bytes > policy.bundle_max_bytes) {
|
|
66
|
+
violations.push({
|
|
67
|
+
code: 'BUNDLE_TOO_LARGE',
|
|
68
|
+
message: `Bundle byte size ${manifest.bundle.total_bytes} exceeds limit ${policy.bundle_max_bytes}`,
|
|
69
|
+
dimension: 'byte_size',
|
|
70
|
+
value: manifest.bundle.total_bytes,
|
|
71
|
+
threshold: policy.bundle_max_bytes,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
// INSUFFICIENT_COVERAGE — review coverage below policy minimum
|
|
75
|
+
if (coverageAttestation && policy.min_review_coverage !== undefined) {
|
|
76
|
+
if (coverageAttestation.file_coverage < policy.min_review_coverage) {
|
|
77
|
+
violations.push({
|
|
78
|
+
code: 'INSUFFICIENT_COVERAGE',
|
|
79
|
+
message: `Review file coverage ${coverageAttestation.file_coverage.toFixed(2)} below minimum ${policy.min_review_coverage.toFixed(2)}`,
|
|
80
|
+
value: coverageAttestation.file_coverage,
|
|
81
|
+
threshold: policy.min_review_coverage,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// POST_HOC_READS — reads that occurred after claims were written
|
|
86
|
+
if (coverageAttestation && policy.block_post_hoc_reads && coverageAttestation.post_hoc_read_count > 0) {
|
|
87
|
+
violations.push({
|
|
88
|
+
code: 'POST_HOC_READS',
|
|
89
|
+
message: `${coverageAttestation.post_hoc_read_count} file(s) were read after review claims were written`,
|
|
90
|
+
value: coverageAttestation.post_hoc_read_count,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Sort by code, then by path (if present) for deterministic output
|
|
94
|
+
violations.sort((a, b) => {
|
|
95
|
+
const codeCmp = a.code.localeCompare(b.code);
|
|
96
|
+
if (codeCmp !== 0)
|
|
97
|
+
return codeCmp;
|
|
98
|
+
return (a.path ?? '').localeCompare(b.path ?? '');
|
|
99
|
+
});
|
|
100
|
+
return violations;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Match a file path against a deny pattern.
|
|
104
|
+
* Supports simple glob patterns with * wildcard.
|
|
105
|
+
*/
|
|
106
|
+
function matchDenyPattern(filePath, pattern) {
|
|
107
|
+
// Convert glob pattern to regex
|
|
108
|
+
const escaped = pattern
|
|
109
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
110
|
+
.replace(/\*/g, '.*');
|
|
111
|
+
const regex = new RegExp(`^${escaped}$|/${escaped}$|^${escaped}/|/${escaped}/`);
|
|
112
|
+
// Also match against the basename
|
|
113
|
+
const basename = filePath.split('/').pop() ?? filePath;
|
|
114
|
+
const baseRegex = new RegExp(`^${escaped}$`);
|
|
115
|
+
return regex.test(filePath) || baseRegex.test(basename);
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=evaluate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/verify/evaluate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ResolvedPolicyV1 } from '@codeledger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build and write a policy snapshot — records the resolved policy used
|
|
4
|
+
* during a verify run, including its hash for audit trail.
|
|
5
|
+
*/
|
|
6
|
+
export declare function writePolicySnapshot(policy: ResolvedPolicyV1, outPath: string): void;
|
|
7
|
+
//# sourceMappingURL=policy-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-snapshot.d.ts","sourceRoot":"","sources":["../../src/verify/policy-snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAqC,MAAM,mBAAmB,CAAC;AAG7F;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,MAAM,GACd,IAAI,CA6BN"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { canonicalize } from '../signing/canonicalize.js';
|
|
5
|
+
/**
|
|
6
|
+
* Build and write a policy snapshot — records the resolved policy used
|
|
7
|
+
* during a verify run, including its hash for audit trail.
|
|
8
|
+
*/
|
|
9
|
+
export function writePolicySnapshot(policy, outPath) {
|
|
10
|
+
// Strip resolved_from to get the base policy for hashing
|
|
11
|
+
const basePolicyForHash = {
|
|
12
|
+
schema_version: policy.schema_version,
|
|
13
|
+
mode: policy.mode,
|
|
14
|
+
min_confidence: policy.min_confidence,
|
|
15
|
+
max_drift: policy.max_drift,
|
|
16
|
+
require_tests: policy.require_tests,
|
|
17
|
+
deny_paths: policy.deny_paths,
|
|
18
|
+
bundle_max_files: policy.bundle_max_files,
|
|
19
|
+
bundle_max_bytes: policy.bundle_max_bytes,
|
|
20
|
+
redact_actor_identity: policy.redact_actor_identity,
|
|
21
|
+
store_file_paths: policy.store_file_paths,
|
|
22
|
+
};
|
|
23
|
+
const hash = createHash('sha256')
|
|
24
|
+
.update(canonicalize(basePolicyForHash))
|
|
25
|
+
.digest('hex');
|
|
26
|
+
const snapshot = {
|
|
27
|
+
schema_version: 'mustang/policy-snapshot/v1',
|
|
28
|
+
policy: basePolicyForHash,
|
|
29
|
+
hash,
|
|
30
|
+
resolved_from: policy.resolved_from,
|
|
31
|
+
resolved_at: new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
34
|
+
writeFileSync(outPath, JSON.stringify(snapshot, null, 2) + '\n');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=policy-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-snapshot.js","sourceRoot":"","sources":["../../src/verify/policy-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAwB,EACxB,OAAe;IAEf,yDAAyD;IACzD,MAAM,iBAAiB,GAAoB;QACzC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;IAEF,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC;SAC9B,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;SACvC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjB,MAAM,QAAQ,GAAqB;QACjC,cAAc,EAAE,4BAA4B;QAC5C,MAAM,EAAE,iBAAiB;QACzB,IAAI;QACJ,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;IAEF,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ContextManifestV1, ResolvedPolicyV1, ViolationV1, VerifyReportV1 } from '@codeledger/types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a verify report from manifest, policy, and violations.
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildVerifyReport(opts: {
|
|
6
|
+
manifest: ContextManifestV1;
|
|
7
|
+
policy: ResolvedPolicyV1;
|
|
8
|
+
violations: ViolationV1[];
|
|
9
|
+
codeledgerVersion: string;
|
|
10
|
+
}): VerifyReportV1;
|
|
11
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/verify/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAI3B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,cAAc,CA+CjB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { canonicalize } from '../signing/canonicalize.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build a verify report from manifest, policy, and violations.
|
|
5
|
+
*/
|
|
6
|
+
export function buildVerifyReport(opts) {
|
|
7
|
+
const { manifest, policy, violations, codeledgerVersion } = opts;
|
|
8
|
+
// Compute policy hash using Phase 2 canonicalization
|
|
9
|
+
const policyForHash = {
|
|
10
|
+
schema_version: policy.schema_version,
|
|
11
|
+
mode: policy.mode,
|
|
12
|
+
min_confidence: policy.min_confidence,
|
|
13
|
+
max_drift: policy.max_drift,
|
|
14
|
+
require_tests: policy.require_tests,
|
|
15
|
+
deny_paths: policy.deny_paths,
|
|
16
|
+
bundle_max_files: policy.bundle_max_files,
|
|
17
|
+
bundle_max_bytes: policy.bundle_max_bytes,
|
|
18
|
+
redact_actor_identity: policy.redact_actor_identity,
|
|
19
|
+
store_file_paths: policy.store_file_paths,
|
|
20
|
+
};
|
|
21
|
+
const policyHash = createHash('sha256')
|
|
22
|
+
.update(canonicalize(policyForHash))
|
|
23
|
+
.digest('hex');
|
|
24
|
+
// Determine decision based on mode
|
|
25
|
+
const passed = determineDecision(policy.mode, violations);
|
|
26
|
+
return {
|
|
27
|
+
schema_version: 'mustang/verify-report/v1',
|
|
28
|
+
codeledger_version: codeledgerVersion,
|
|
29
|
+
repo: {
|
|
30
|
+
name: manifest.repo.name,
|
|
31
|
+
commit_sha: manifest.repo.commit_sha,
|
|
32
|
+
},
|
|
33
|
+
policy: {
|
|
34
|
+
schema_version: 'mustang/policy/v1',
|
|
35
|
+
mode: policy.mode,
|
|
36
|
+
hash: policyHash,
|
|
37
|
+
},
|
|
38
|
+
metrics: {
|
|
39
|
+
overall_confidence: manifest.confidence.overall,
|
|
40
|
+
drift_score: manifest.intent.drift_score,
|
|
41
|
+
bundle_file_count: manifest.bundle.file_count,
|
|
42
|
+
bundle_total_bytes: manifest.bundle.total_bytes,
|
|
43
|
+
},
|
|
44
|
+
decision: {
|
|
45
|
+
passed,
|
|
46
|
+
mode: policy.mode,
|
|
47
|
+
},
|
|
48
|
+
violations,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Determine pass/fail based on mode and violations.
|
|
53
|
+
*
|
|
54
|
+
* - observe: always true (violations are informational only)
|
|
55
|
+
* - warn: always true (violations printed as warnings)
|
|
56
|
+
* - block: true only if no violations
|
|
57
|
+
*/
|
|
58
|
+
function determineDecision(mode, violations) {
|
|
59
|
+
if (mode === 'block') {
|
|
60
|
+
return violations.length === 0;
|
|
61
|
+
}
|
|
62
|
+
return true; // observe and warn always pass
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/verify/report.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAKjC;IACC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,IAAI,CAAC;IAEjE,qDAAqD;IACrD,MAAM,aAAa,GAA4B;QAC7C,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;IACF,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC;SACpC,MAAM,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;SACnC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjB,mCAAmC;IACnC,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAE1D,OAAO;QACL,cAAc,EAAE,0BAA0B;QAC1C,kBAAkB,EAAE,iBAAiB;QACrC,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI;YACxB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU;SACrC;QACD,MAAM,EAAE;YACN,cAAc,EAAE,mBAAmB;YACnC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,UAAU;SACjB;QACD,OAAO,EAAE;YACP,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,OAAO;YAC/C,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;YACxC,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;YAC7C,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW;SAChD;QACD,QAAQ,EAAE;YACR,MAAM;YACN,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB;QACD,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,IAAgB,EAAE,UAAyB;IACpE,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,+BAA+B;AAC9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeledger/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for CodeLedger — deterministic context selection for AI coding agents",
|
|
6
|
-
"license": "
|
|
6
|
+
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "https://github.com/codeledgerECF/codeledger-blackbox.git",
|
|
@@ -27,14 +27,14 @@
|
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@codeledger/types": "0.
|
|
31
|
-
"@codeledger/core": "0.
|
|
32
|
-
"@codeledger/core-engine": "0.
|
|
33
|
-
"@codeledger/
|
|
34
|
-
"@codeledger/
|
|
35
|
-
"@codeledger/
|
|
36
|
-
"@codeledger/
|
|
37
|
-
"@codeledger/
|
|
30
|
+
"@codeledger/types": "0.6.0",
|
|
31
|
+
"@codeledger/core": "0.6.0",
|
|
32
|
+
"@codeledger/core-engine": "0.6.0",
|
|
33
|
+
"@codeledger/repo": "0.6.0",
|
|
34
|
+
"@codeledger/instrument": "0.6.0",
|
|
35
|
+
"@codeledger/harness": "0.6.0",
|
|
36
|
+
"@codeledger/cowork": "0.6.0",
|
|
37
|
+
"@codeledger/selector": "0.6.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"typescript": "^5.4.0"
|