@decantr/verifier 3.4.1 → 3.5.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/README.md +13 -7
- package/dist/index.d.ts +262 -50
- package/dist/index.js +377 -18
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
- package/schema/authority-resolution.v2.json +116 -0
- package/schema/decantr-ci-report.v2.json +55 -0
- package/schema/evidence-bundle.v2.json +35 -4
- package/schema/loop-readiness.v2.json +87 -0
- package/schema/project-health-report.v2.json +119 -0
- package/schema/proof-field-report.v2.json +51 -0
- package/schema/verification-report.common.v2.json +91 -0
- package/schema/workspace-health-report.v2.json +51 -0
package/dist/index.js
CHANGED
|
@@ -344,6 +344,300 @@ function auditComponentReuse(projectRoot, sourceFiles) {
|
|
|
344
344
|
};
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
+
// src/contracts-v2.ts
|
|
348
|
+
var VERIFICATION_COMMON_V2_SCHEMA_URL = "https://decantr.ai/schemas/verification-report.common.v2.json";
|
|
349
|
+
var PROJECT_HEALTH_REPORT_V2_SCHEMA_URL = "https://decantr.ai/schemas/project-health-report.v2.json";
|
|
350
|
+
var DECANTR_CI_REPORT_V2_SCHEMA_URL = "https://decantr.ai/schemas/decantr-ci-report.v2.json";
|
|
351
|
+
var WORKSPACE_HEALTH_REPORT_V2_SCHEMA_URL = "https://decantr.ai/schemas/workspace-health-report.v2.json";
|
|
352
|
+
var EVIDENCE_BUNDLE_V2_SCHEMA_URL = "https://decantr.ai/schemas/evidence-bundle.v2.json";
|
|
353
|
+
var RUNTIME_PROBE_PAYLOAD_V2_SCHEMA_URL = "https://decantr.ai/schemas/runtime-probe-payload.v2.json";
|
|
354
|
+
var LOOP_READINESS_V2_SCHEMA_URL = "https://decantr.ai/schemas/loop-readiness.v2.json";
|
|
355
|
+
var AUTHORITY_RESOLUTION_V2_SCHEMA_URL = "https://decantr.ai/schemas/authority-resolution.v2.json";
|
|
356
|
+
var PROOF_FIELD_REPORT_V2_SCHEMA_URL = "https://decantr.ai/schemas/proof-field-report.v2.json";
|
|
357
|
+
function unique(values) {
|
|
358
|
+
return [...new Set(values)];
|
|
359
|
+
}
|
|
360
|
+
function rounded(value) {
|
|
361
|
+
return Number(Math.max(0, Math.min(1, value)).toFixed(2));
|
|
362
|
+
}
|
|
363
|
+
function createEvidenceTier(report, options = {}) {
|
|
364
|
+
const runtimeProbeCount = options.runtimeProbeCount ?? (report.summary.runtimeAuditChecked ? 1 : 0);
|
|
365
|
+
const visualArtifactCount = options.visualArtifactCount ?? 0;
|
|
366
|
+
const findingsAnchored = report.findings.filter((finding) => finding.graph).length;
|
|
367
|
+
const findingsWithRepairPlan = report.findings.filter((finding) => finding.repairPlan).length;
|
|
368
|
+
const capabilities = ["static-audit", "project-health"];
|
|
369
|
+
if (report.graph.ready) capabilities.push("typed-graph");
|
|
370
|
+
if (runtimeProbeCount > 0) capabilities.push("runtime-probe");
|
|
371
|
+
if (report.summary.runtimeAuditChecked || visualArtifactCount > 0)
|
|
372
|
+
capabilities.push("browser-evidence");
|
|
373
|
+
if (visualArtifactCount > 0) capabilities.push("visual-baseline");
|
|
374
|
+
if (findingsWithRepairPlan > 0) capabilities.push("repair-plan");
|
|
375
|
+
if (options.benchmarkReplay) capabilities.push("benchmark-replay");
|
|
376
|
+
let stage = "static";
|
|
377
|
+
if (options.benchmarkReplay) stage = "proof";
|
|
378
|
+
else if (findingsWithRepairPlan > 0) stage = "repair";
|
|
379
|
+
else if (visualArtifactCount > 0) stage = "visual";
|
|
380
|
+
else if (runtimeProbeCount > 0 || report.summary.runtimeAuditChecked) stage = "runtime";
|
|
381
|
+
else if (report.graph.ready) stage = "graph";
|
|
382
|
+
const routeCoverage = report.routes.declared.length > 0 ? Math.min(1, report.routes.runtimeChecked.length / report.routes.declared.length) : report.summary.runtimeAuditChecked ? 1 : 0;
|
|
383
|
+
const graphCoverage = report.findings.length > 0 ? findingsAnchored / report.findings.length : report.graph.ready ? 1 : 0;
|
|
384
|
+
const repairCoverage = report.findings.length > 0 ? findingsWithRepairPlan / report.findings.length : 1;
|
|
385
|
+
const runtimeCoverage = runtimeProbeCount > 0 || report.summary.runtimeAuditChecked ? 1 : 0;
|
|
386
|
+
const score = rounded(
|
|
387
|
+
0.22 + (report.graph.ready ? 0.22 : 0) + routeCoverage * 0.16 + graphCoverage * 0.16 + repairCoverage * 0.14 + runtimeCoverage * 0.1
|
|
388
|
+
);
|
|
389
|
+
const level = score >= 0.78 ? "high" : score >= 0.48 ? "moderate" : "low";
|
|
390
|
+
const reasons = [];
|
|
391
|
+
reasons.push(report.graph.ready ? "typed graph is ready" : "typed graph is missing or stale");
|
|
392
|
+
reasons.push(
|
|
393
|
+
runtimeProbeCount > 0 || report.summary.runtimeAuditChecked ? "runtime evidence is present" : "runtime evidence has not run"
|
|
394
|
+
);
|
|
395
|
+
reasons.push(
|
|
396
|
+
report.findings.length === 0 ? "no open findings" : `${findingsAnchored}/${report.findings.length} finding(s) have graph anchors`
|
|
397
|
+
);
|
|
398
|
+
reasons.push(
|
|
399
|
+
report.findings.length === 0 ? "repair context is not needed" : `${findingsWithRepairPlan}/${report.findings.length} finding(s) include repair plans`
|
|
400
|
+
);
|
|
401
|
+
return {
|
|
402
|
+
schemaVersion: 2,
|
|
403
|
+
stage,
|
|
404
|
+
status: report.status === "healthy" ? "healthy" : report.status,
|
|
405
|
+
capabilities: unique(capabilities),
|
|
406
|
+
coverage: {
|
|
407
|
+
declaredRoutes: report.routes.declared.length,
|
|
408
|
+
runtimeRoutesChecked: report.routes.runtimeChecked.length,
|
|
409
|
+
findingsAnchored,
|
|
410
|
+
findingsWithRepairPlan,
|
|
411
|
+
runtimeProbeCount,
|
|
412
|
+
visualArtifactCount
|
|
413
|
+
},
|
|
414
|
+
confidence: {
|
|
415
|
+
level,
|
|
416
|
+
score,
|
|
417
|
+
reasons
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function createAuthorityOrder() {
|
|
422
|
+
return [
|
|
423
|
+
{
|
|
424
|
+
id: "production-source",
|
|
425
|
+
label: "Production source",
|
|
426
|
+
role: "Existing runtime/source wins first in Brownfield unless a human explicitly accepts a contract change.",
|
|
427
|
+
rank: 1
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
id: "local-law",
|
|
431
|
+
label: "Accepted local law",
|
|
432
|
+
role: "Project-owned rules and codified patterns constrain edits after they are accepted locally.",
|
|
433
|
+
rank: 2
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: "style-bridge",
|
|
437
|
+
label: "Accepted style bridge",
|
|
438
|
+
role: "Mapped native style tokens/components govern Hybrid styling once accepted locally.",
|
|
439
|
+
rank: 3
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
id: "essence-contract",
|
|
443
|
+
label: "Essence V4 contract",
|
|
444
|
+
role: "Structural route, section, page, guard, and DNA contract for Decantr context.",
|
|
445
|
+
rank: 4
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
id: "registry-guidance",
|
|
449
|
+
label: "Hosted packs and registry",
|
|
450
|
+
role: "Advisory guidance unless mapped into accepted local law or the local style bridge.",
|
|
451
|
+
rank: 5
|
|
452
|
+
}
|
|
453
|
+
];
|
|
454
|
+
}
|
|
455
|
+
function laneForFinding(finding) {
|
|
456
|
+
if (finding.source === "style-bridge") return "style-bridge";
|
|
457
|
+
if (finding.source === "brownfield" || finding.category.toLowerCase().includes("drift")) {
|
|
458
|
+
return "production-source";
|
|
459
|
+
}
|
|
460
|
+
if (finding.source === "check" || finding.source === "assertion") return "essence-contract";
|
|
461
|
+
if (finding.source === "pack") return "registry-guidance";
|
|
462
|
+
return "local-law";
|
|
463
|
+
}
|
|
464
|
+
function actionsForFinding(finding) {
|
|
465
|
+
const commands = finding.repairPlan?.commands ?? finding.remediation?.commands ?? [];
|
|
466
|
+
const repairCommand = commands[0] ?? null;
|
|
467
|
+
const source = finding.source;
|
|
468
|
+
const actions = [];
|
|
469
|
+
if (source === "graph") {
|
|
470
|
+
actions.push({
|
|
471
|
+
kind: "regenerate_graph",
|
|
472
|
+
label: "Regenerate graph/context evidence",
|
|
473
|
+
command: "decantr graph --check || decantr graph",
|
|
474
|
+
writes: true,
|
|
475
|
+
rationale: "Graph drift should be resolved by regenerating derived graph artifacts from current source."
|
|
476
|
+
});
|
|
477
|
+
} else if (source === "style-bridge") {
|
|
478
|
+
actions.push({
|
|
479
|
+
kind: "update_style_bridge",
|
|
480
|
+
label: "Update accepted style bridge",
|
|
481
|
+
command: "decantr codify --style-bridge",
|
|
482
|
+
writes: true,
|
|
483
|
+
rationale: "Style conflicts should be accepted through the explicit Hybrid style bridge workflow."
|
|
484
|
+
});
|
|
485
|
+
} else if (source === "brownfield") {
|
|
486
|
+
actions.push({
|
|
487
|
+
kind: "accept_observed_source",
|
|
488
|
+
label: "Accept observed source into contract",
|
|
489
|
+
command: "decantr init --existing --merge-proposal",
|
|
490
|
+
writes: true,
|
|
491
|
+
rationale: "Brownfield source is first authority; accept it explicitly before treating contract drift as repaired."
|
|
492
|
+
});
|
|
493
|
+
} else if (source === "pack") {
|
|
494
|
+
actions.push({
|
|
495
|
+
kind: "regenerate_context",
|
|
496
|
+
label: "Regenerate Decantr context",
|
|
497
|
+
command: "decantr refresh",
|
|
498
|
+
writes: true,
|
|
499
|
+
rationale: "Generated context and pack artifacts are derived from the local contract."
|
|
500
|
+
});
|
|
501
|
+
} else {
|
|
502
|
+
actions.push({
|
|
503
|
+
kind: "repair_source",
|
|
504
|
+
label: "Repair source to satisfy accepted authority",
|
|
505
|
+
command: repairCommand,
|
|
506
|
+
writes: false,
|
|
507
|
+
rationale: "The finding can be repaired by editing the relevant application source under human/agent control."
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
actions.push({
|
|
511
|
+
kind: "defer_to_drift_log",
|
|
512
|
+
label: "Defer to drift log",
|
|
513
|
+
command: `decantr resolve --defer ${finding.id}`,
|
|
514
|
+
writes: true,
|
|
515
|
+
rationale: "Record an explicit human deferral when this conflict should not block the current task."
|
|
516
|
+
});
|
|
517
|
+
if (finding.severity !== "error") {
|
|
518
|
+
actions.push({
|
|
519
|
+
kind: "mark_advisory",
|
|
520
|
+
label: "Mark advisory",
|
|
521
|
+
command: `decantr resolve --mark-advisory ${finding.id}`,
|
|
522
|
+
writes: true,
|
|
523
|
+
rationale: "Warnings can be documented as advisory when the observed source is intentionally different."
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
return actions;
|
|
527
|
+
}
|
|
528
|
+
function createAuthorityResolution(report) {
|
|
529
|
+
const conflicts = report.findings.filter((finding) => finding.severity !== "info").map((finding) => ({
|
|
530
|
+
id: finding.id,
|
|
531
|
+
source: finding.source,
|
|
532
|
+
category: finding.category,
|
|
533
|
+
severity: finding.severity,
|
|
534
|
+
message: finding.message,
|
|
535
|
+
...finding.graph ? { graphAnchor: finding.graph } : {},
|
|
536
|
+
lane: laneForFinding(finding),
|
|
537
|
+
status: finding.severity === "error" ? "blocking" : finding.source === "brownfield" || finding.source === "style-bridge" ? "repairable" : "advisory",
|
|
538
|
+
recommendedActions: actionsForFinding(finding)
|
|
539
|
+
}));
|
|
540
|
+
const activeLane = report.summary.workflowMode === "brownfield-attach" ? "production-source" : "essence-contract";
|
|
541
|
+
return {
|
|
542
|
+
schemaVersion: 2,
|
|
543
|
+
order: createAuthorityOrder(),
|
|
544
|
+
activeLane,
|
|
545
|
+
summary: activeLane === "production-source" ? "Brownfield authority: preserve observed production source first, then accepted local law/style bridge, then Essence V4 structure, with hosted packs advisory." : "Contract authority: Essence V4 and accepted local project law guide source changes; hosted packs remain advisory until accepted locally.",
|
|
546
|
+
conflicts,
|
|
547
|
+
stopRule: "If runtime source and Decantr context disagree, stop and report drift instead of guessing which truth to overwrite."
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
function readTargetsForFindings(report) {
|
|
551
|
+
const targets = /* @__PURE__ */ new Set(["DECANTR.md", "decantr.essence.json"]);
|
|
552
|
+
for (const finding of report.findings) {
|
|
553
|
+
for (const target of finding.repairPlan?.readTargets ?? []) targets.add(target);
|
|
554
|
+
if (finding.file) targets.add(finding.file);
|
|
555
|
+
if (finding.source === "graph") targets.add(".decantr/graph/graph.manifest.json");
|
|
556
|
+
if (finding.source === "style-bridge") targets.add(".decantr/style-bridge.json");
|
|
557
|
+
}
|
|
558
|
+
return [...targets].sort();
|
|
559
|
+
}
|
|
560
|
+
function createLoopReadiness(report, authority = createAuthorityResolution(report), evidenceTier = createEvidenceTier(report)) {
|
|
561
|
+
const hasEssence = Boolean(report.summary.essenceVersion);
|
|
562
|
+
const graphMissing = !report.graph.ready;
|
|
563
|
+
const blockingConflicts = authority.conflicts.filter(
|
|
564
|
+
(conflict) => conflict.status === "blocking"
|
|
565
|
+
);
|
|
566
|
+
const repairableConflicts = authority.conflicts.filter(
|
|
567
|
+
(conflict) => conflict.status === "repairable"
|
|
568
|
+
);
|
|
569
|
+
let state = "verified";
|
|
570
|
+
const blockingReasons = [];
|
|
571
|
+
if (!hasEssence) {
|
|
572
|
+
state = "blocked_missing_context";
|
|
573
|
+
blockingReasons.push("Essence V4 context is missing.");
|
|
574
|
+
} else if (graphMissing) {
|
|
575
|
+
state = "blocked_missing_graph";
|
|
576
|
+
blockingReasons.push("Typed Contract graph is missing, stale, or incomplete.");
|
|
577
|
+
} else if (blockingConflicts.length > 0 && repairableConflicts.length > 0) {
|
|
578
|
+
state = "human_resolution_required";
|
|
579
|
+
blockingReasons.push("Blocking findings conflict with Brownfield or Hybrid authority.");
|
|
580
|
+
} else if (blockingConflicts.length > 0 || report.summary.errorCount > 0) {
|
|
581
|
+
state = "repair_required";
|
|
582
|
+
blockingReasons.push("Project Health has blocking errors.");
|
|
583
|
+
} else if (repairableConflicts.length > 0 || report.summary.warnCount > 0) {
|
|
584
|
+
state = "repair_required";
|
|
585
|
+
blockingReasons.push("Project Health has repairable warnings or drift.");
|
|
586
|
+
} else if (report.status === "healthy") {
|
|
587
|
+
state = "verified";
|
|
588
|
+
} else {
|
|
589
|
+
state = "verify_required";
|
|
590
|
+
blockingReasons.push("Verification needs to be rerun before the loop is complete.");
|
|
591
|
+
}
|
|
592
|
+
const nextActions = state === "verified" ? ["Continue normal route/task workflow."] : state === "blocked_missing_context" ? ["Run `decantr scan` for a read-only preview, then `decantr adopt` when ready."] : state === "blocked_missing_graph" ? ["Run `decantr graph` to regenerate typed graph artifacts, then rerun verification."] : state === "human_resolution_required" ? ["Run `decantr resolve` and choose an explicit resolution action before editing."] : state === "repair_required" ? ["Repair the highest-severity finding, then rerun the verify command."] : ["Run the verify command before treating the task as complete."];
|
|
593
|
+
const status = state.startsWith("blocked") || state === "human_resolution_required" ? "blocked" : report.status;
|
|
594
|
+
return {
|
|
595
|
+
schemaVersion: 2,
|
|
596
|
+
state,
|
|
597
|
+
status,
|
|
598
|
+
verdict: state === "verified" ? "Loop verified." : "Loop needs attention before it should be considered complete.",
|
|
599
|
+
summary: `${report.status} Project Health, ${evidenceTier.confidence.level} evidence confidence, ${authority.conflicts.length} authority conflict(s).`,
|
|
600
|
+
authority: {
|
|
601
|
+
activeLane: authority.activeLane,
|
|
602
|
+
summary: authority.summary,
|
|
603
|
+
stopRule: authority.stopRule
|
|
604
|
+
},
|
|
605
|
+
evidenceTier,
|
|
606
|
+
blockingReasons,
|
|
607
|
+
nextActions,
|
|
608
|
+
maker: {
|
|
609
|
+
title: "Maker instructions",
|
|
610
|
+
instructions: [
|
|
611
|
+
"Read the route/task context before editing source.",
|
|
612
|
+
"Preserve production source behavior and accepted local law unless a human chooses a resolution action.",
|
|
613
|
+
"Stop and report drift when runtime source and Decantr context disagree."
|
|
614
|
+
]
|
|
615
|
+
},
|
|
616
|
+
checker: {
|
|
617
|
+
title: "Checker instructions",
|
|
618
|
+
instructions: [
|
|
619
|
+
"Rerun the verify command after edits.",
|
|
620
|
+
"Check graph anchors and repair plans before accepting a fix.",
|
|
621
|
+
"Treat critique-only or advisory evidence as warning-level unless runtime evidence proves a failure."
|
|
622
|
+
]
|
|
623
|
+
},
|
|
624
|
+
readTargets: readTargetsForFindings(report),
|
|
625
|
+
graphImpact: {
|
|
626
|
+
status: !report.graph.present ? "missing" : report.graph.ready && report.graph.current !== false ? "ready" : "stale",
|
|
627
|
+
snapshotId: report.graph.snapshotId,
|
|
628
|
+
sourceHash: report.graph.sourceHash,
|
|
629
|
+
sourceArtifactCount: report.graph.sourceArtifactCount,
|
|
630
|
+
staleArtifacts: report.graph.staleArtifacts
|
|
631
|
+
},
|
|
632
|
+
stopConditions: [
|
|
633
|
+
"Runtime source and Decantr context disagree.",
|
|
634
|
+
"Typed graph is missing for the route or changed file.",
|
|
635
|
+
"A finding requires contract/source/local-law mutation outside the current explicit workflow."
|
|
636
|
+
],
|
|
637
|
+
verifyCommand: report.ci.recommendedCommand
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
|
|
347
641
|
// src/runtime.ts
|
|
348
642
|
import { existsSync, readdirSync, readFileSync as readFileSync2, statSync } from "fs";
|
|
349
643
|
import { createServer } from "http";
|
|
@@ -2010,9 +2304,9 @@ function sourceLineCount(source) {
|
|
|
2010
2304
|
}
|
|
2011
2305
|
function verifyInteractionsInSource(interactions, sources) {
|
|
2012
2306
|
if (interactions.length === 0 || sources.size === 0) return [];
|
|
2013
|
-
const
|
|
2307
|
+
const unique2 = Array.from(new Set(interactions));
|
|
2014
2308
|
const missing = [];
|
|
2015
|
-
for (const interaction of
|
|
2309
|
+
for (const interaction of unique2) {
|
|
2016
2310
|
const requirement = INTERACTION_SIGNALS[interaction];
|
|
2017
2311
|
if (!requirement) {
|
|
2018
2312
|
continue;
|
|
@@ -3734,17 +4028,17 @@ function resolveSourceSymbolOrigin(context, pathOrSourceFile, localName, options
|
|
|
3734
4028
|
|
|
3735
4029
|
// src/index.ts
|
|
3736
4030
|
var VERIFICATION_SCHEMA_URLS = {
|
|
3737
|
-
common:
|
|
4031
|
+
common: VERIFICATION_COMMON_V2_SCHEMA_URL,
|
|
3738
4032
|
projectAudit: "https://decantr.ai/schemas/project-audit-report.v1.json",
|
|
3739
|
-
projectHealth:
|
|
3740
|
-
decantrCi:
|
|
3741
|
-
evidenceBundle:
|
|
4033
|
+
projectHealth: PROJECT_HEALTH_REPORT_V2_SCHEMA_URL,
|
|
4034
|
+
decantrCi: DECANTR_CI_REPORT_V2_SCHEMA_URL,
|
|
4035
|
+
evidenceBundle: EVIDENCE_BUNDLE_V2_SCHEMA_URL,
|
|
3742
4036
|
scanReport: "https://decantr.ai/schemas/scan-report.v1.json",
|
|
3743
|
-
workspaceHealth:
|
|
4037
|
+
workspaceHealth: WORKSPACE_HEALTH_REPORT_V2_SCHEMA_URL,
|
|
3744
4038
|
fileCritique: "https://decantr.ai/schemas/file-critique-report.v1.json",
|
|
3745
4039
|
showcaseShortlist: "https://decantr.ai/schemas/showcase-shortlist-report.v1.json"
|
|
3746
4040
|
};
|
|
3747
|
-
var EVIDENCE_BUNDLE_SCHEMA_URL =
|
|
4041
|
+
var EVIDENCE_BUNDLE_SCHEMA_URL = EVIDENCE_BUNDLE_V2_SCHEMA_URL;
|
|
3748
4042
|
function hashString(value) {
|
|
3749
4043
|
return createHash("sha256").update(value).digest("hex").slice(0, 16);
|
|
3750
4044
|
}
|
|
@@ -4033,6 +4327,8 @@ function createContractAssertions(projectRoot, audit) {
|
|
|
4033
4327
|
}
|
|
4034
4328
|
function createEvidenceBundle(input) {
|
|
4035
4329
|
const assertions = input.assertions ?? createContractAssertions(input.projectRoot, input.audit);
|
|
4330
|
+
const evidenceTier = input.report.evidenceTier ?? createEvidenceTier(input.report);
|
|
4331
|
+
const authority = input.report.authority ?? createAuthorityResolution(input.report);
|
|
4036
4332
|
let resolvedProjectRoot = input.projectRoot;
|
|
4037
4333
|
try {
|
|
4038
4334
|
resolvedProjectRoot = realpathSync2(input.projectRoot);
|
|
@@ -4045,13 +4341,18 @@ function createEvidenceBundle(input) {
|
|
|
4045
4341
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4046
4342
|
project: {
|
|
4047
4343
|
id: projectId,
|
|
4048
|
-
rootLabel: basename2(input.projectRoot) || "project"
|
|
4344
|
+
rootLabel: basename2(input.projectRoot) || "project",
|
|
4345
|
+
workflowMode: input.report.summary.workflowMode,
|
|
4346
|
+
adoptionMode: input.report.summary.adoptionMode
|
|
4049
4347
|
},
|
|
4050
4348
|
toolchain: {
|
|
4051
|
-
verifierVersion: input.verifierVersion ?? null
|
|
4349
|
+
verifierVersion: input.verifierVersion ?? null,
|
|
4350
|
+
cliVersion: input.cliVersion ?? null,
|
|
4351
|
+
mcpServerVersion: input.mcpServerVersion ?? null
|
|
4052
4352
|
},
|
|
4053
4353
|
privacy: {
|
|
4054
4354
|
localOnly: true,
|
|
4355
|
+
sourceIncluded: false,
|
|
4055
4356
|
redactedFields: [
|
|
4056
4357
|
"source",
|
|
4057
4358
|
"prompt",
|
|
@@ -4060,8 +4361,10 @@ function createEvidenceBundle(input) {
|
|
|
4060
4361
|
"absolute_path",
|
|
4061
4362
|
"repository_name"
|
|
4062
4363
|
],
|
|
4063
|
-
screenshotsLocalOnly: true
|
|
4364
|
+
screenshotsLocalOnly: true,
|
|
4365
|
+
hostedUploadAllowed: false
|
|
4064
4366
|
},
|
|
4367
|
+
evidenceTier,
|
|
4065
4368
|
health: {
|
|
4066
4369
|
status: input.report.status,
|
|
4067
4370
|
score: input.report.score,
|
|
@@ -4079,7 +4382,9 @@ function createEvidenceBundle(input) {
|
|
|
4079
4382
|
graphDiff: provenanceEntry(input.projectRoot, ".decantr/graph/graph.diff.json"),
|
|
4080
4383
|
contractCapsule: provenanceEntry(input.projectRoot, ".decantr/graph/contract-capsule.json"),
|
|
4081
4384
|
...input.workspaceConfigPath ? { workspaceConfig: provenanceForPath(input.projectRoot, input.workspaceConfigPath) } : {},
|
|
4082
|
-
...input.designTokensPath ? { designTokens: provenanceForPath(input.projectRoot, input.designTokensPath) } : {}
|
|
4385
|
+
...input.designTokensPath ? { designTokens: provenanceForPath(input.projectRoot, input.designTokensPath) } : {},
|
|
4386
|
+
...input.runtimeProbePath ? { runtimeProbe: provenanceForPath(input.projectRoot, input.runtimeProbePath) } : {},
|
|
4387
|
+
...input.visualManifestPath ? { visualManifest: provenanceForPath(input.projectRoot, input.visualManifestPath) } : {}
|
|
4083
4388
|
},
|
|
4084
4389
|
assertions,
|
|
4085
4390
|
findings: input.report.findings.map((finding) => ({
|
|
@@ -4096,10 +4401,37 @@ function createEvidenceBundle(input) {
|
|
|
4096
4401
|
graph: finding.graph,
|
|
4097
4402
|
repair: redactRepairAction(input.projectRoot, finding.repair),
|
|
4098
4403
|
repairPlan: buildProjectHealthRepairPlan(input.projectRoot, finding),
|
|
4404
|
+
evidenceTier: finding.evidenceTier ?? evidenceTier,
|
|
4405
|
+
authorityLane: finding.authorityLane ?? authority.conflicts.find((conflict) => conflict.id === finding.id)?.lane ?? authority.activeLane,
|
|
4406
|
+
resolutionActions: finding.resolutionActions ?? authority.conflicts.find((conflict) => conflict.id === finding.id)?.recommendedActions,
|
|
4407
|
+
privacy: finding.privacy ?? {
|
|
4408
|
+
sourceIncluded: false,
|
|
4409
|
+
redacted: true,
|
|
4410
|
+
localOnly: true
|
|
4411
|
+
},
|
|
4412
|
+
loopVerdict: finding.loopVerdict ?? input.report.loop?.state,
|
|
4099
4413
|
remediationSummary: finding.remediation.summary,
|
|
4100
4414
|
commands: finding.remediation.commands,
|
|
4101
4415
|
promptCommand: `decantr health --prompt ${finding.id}`
|
|
4102
4416
|
})),
|
|
4417
|
+
runtimeProbe: input.runtimeProbe ?? null,
|
|
4418
|
+
artifacts: input.artifacts ?? [
|
|
4419
|
+
{
|
|
4420
|
+
id: "artifact:project-health",
|
|
4421
|
+
kind: "project-health",
|
|
4422
|
+
path: "decantr-health.json",
|
|
4423
|
+
hash: null,
|
|
4424
|
+
localOnly: true,
|
|
4425
|
+
redacted: true
|
|
4426
|
+
}
|
|
4427
|
+
],
|
|
4428
|
+
dashboard: {
|
|
4429
|
+
safeToUpload: false,
|
|
4430
|
+
retentionClass: "local-only",
|
|
4431
|
+
redactionNotes: [
|
|
4432
|
+
"Evidence Bundle v2 does not include raw source, prompts, secrets, absolute paths, or uploaded screenshots by default."
|
|
4433
|
+
]
|
|
4434
|
+
},
|
|
4103
4435
|
...input.browser ? { browser: input.browser } : {},
|
|
4104
4436
|
...input.designTokens ? { designTokens: input.designTokens } : {}
|
|
4105
4437
|
};
|
|
@@ -4854,6 +5186,10 @@ function buildRegistryContext(projectRoot) {
|
|
|
4854
5186
|
const patternRegistry = /* @__PURE__ */ new Map();
|
|
4855
5187
|
const cacheDir = join6(projectRoot, ".decantr", "cache");
|
|
4856
5188
|
const customDir = join6(projectRoot, ".decantr", "custom");
|
|
5189
|
+
const addPattern = (id, source, data = null) => {
|
|
5190
|
+
if (typeof id !== "string" || !id.trim() || patternRegistry.has(id)) return;
|
|
5191
|
+
patternRegistry.set(id, data ?? { id, source });
|
|
5192
|
+
};
|
|
4857
5193
|
const cachedThemesDir = join6(cacheDir, "@official", "themes");
|
|
4858
5194
|
try {
|
|
4859
5195
|
if (existsSync6(cachedThemesDir)) {
|
|
@@ -4887,17 +5223,27 @@ function buildRegistryContext(projectRoot) {
|
|
|
4887
5223
|
(name) => name.endsWith(".json") && name !== "index.json"
|
|
4888
5224
|
)) {
|
|
4889
5225
|
const data = JSON.parse(readFileSync6(join6(cachedPatternsDir, file), "utf-8"));
|
|
4890
|
-
|
|
4891
|
-
patternRegistry.set(data.id, data);
|
|
4892
|
-
}
|
|
5226
|
+
addPattern(data.id, "cache", data);
|
|
4893
5227
|
}
|
|
4894
5228
|
}
|
|
4895
5229
|
} catch {
|
|
4896
5230
|
}
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
5231
|
+
const customPatternsDir = join6(customDir, "patterns");
|
|
5232
|
+
try {
|
|
5233
|
+
if (existsSync6(customPatternsDir)) {
|
|
5234
|
+
for (const file of readdirSync5(customPatternsDir).filter((name) => name.endsWith(".json"))) {
|
|
5235
|
+
const data = JSON.parse(readFileSync6(join6(customPatternsDir, file), "utf-8"));
|
|
5236
|
+
addPattern(data.id, "custom", data);
|
|
5237
|
+
}
|
|
4900
5238
|
}
|
|
5239
|
+
} catch {
|
|
5240
|
+
}
|
|
5241
|
+
const localPatterns = readJsonIfExists(join6(projectRoot, ".decantr", "local-patterns.json"));
|
|
5242
|
+
for (const pattern of localPatterns?.patterns ?? []) {
|
|
5243
|
+
addPattern(pattern.id, "local-law", pattern);
|
|
5244
|
+
}
|
|
5245
|
+
for (const id of ["content-section", "footer", "form-basic", "hero", "nav-header"]) {
|
|
5246
|
+
addPattern(id, "bundled");
|
|
4901
5247
|
}
|
|
4902
5248
|
return { themeRegistry, patternRegistry };
|
|
4903
5249
|
}
|
|
@@ -15678,14 +16024,23 @@ async function critiqueFile(filePath, projectRoot) {
|
|
|
15678
16024
|
});
|
|
15679
16025
|
}
|
|
15680
16026
|
export {
|
|
16027
|
+
AUTHORITY_RESOLUTION_V2_SCHEMA_URL,
|
|
15681
16028
|
COMPONENT_REUSE_RULE_ID,
|
|
16029
|
+
DECANTR_CI_REPORT_V2_SCHEMA_URL,
|
|
15682
16030
|
EVIDENCE_BUNDLE_SCHEMA_URL,
|
|
16031
|
+
EVIDENCE_BUNDLE_V2_SCHEMA_URL,
|
|
15683
16032
|
INTERACTION_SIGNALS,
|
|
15684
16033
|
KNOWN_VERIFICATION_DIAGNOSTICS,
|
|
16034
|
+
LOOP_READINESS_V2_SCHEMA_URL,
|
|
16035
|
+
PROJECT_HEALTH_REPORT_V2_SCHEMA_URL,
|
|
16036
|
+
PROOF_FIELD_REPORT_V2_SCHEMA_URL,
|
|
15685
16037
|
RAW_CONTROL_REUSE_RULE_ID,
|
|
16038
|
+
RUNTIME_PROBE_PAYLOAD_V2_SCHEMA_URL,
|
|
15686
16039
|
SCAN_REPORT_SCHEMA_URL,
|
|
15687
16040
|
STYLE_BRIDGE_ARBITRARY_VALUE_RULE_ID,
|
|
16041
|
+
VERIFICATION_COMMON_V2_SCHEMA_URL,
|
|
15688
16042
|
VERIFICATION_SCHEMA_URLS,
|
|
16043
|
+
WORKSPACE_HEALTH_REPORT_V2_SCHEMA_URL,
|
|
15689
16044
|
anchorFindingsToGraph,
|
|
15690
16045
|
auditBuiltDist,
|
|
15691
16046
|
auditComponentReuse,
|
|
@@ -15695,8 +16050,12 @@ export {
|
|
|
15695
16050
|
collectMissingPackManifestFiles,
|
|
15696
16051
|
collectProjectSourceFiles,
|
|
15697
16052
|
collectSourceImports,
|
|
16053
|
+
createAuthorityOrder,
|
|
16054
|
+
createAuthorityResolution,
|
|
15698
16055
|
createContractAssertions,
|
|
15699
16056
|
createEvidenceBundle,
|
|
16057
|
+
createEvidenceTier,
|
|
16058
|
+
createLoopReadiness,
|
|
15700
16059
|
createProjectSourceProgram,
|
|
15701
16060
|
createSourceInventory,
|
|
15702
16061
|
createUnavailableScanReport,
|