Skip to content

Commit 92ed795

Browse files
dhaneshclaude
andcommitted
feat: add v3 schema with temporal non-linearity and reality grounding
Phase A - Reality Grounding: - Add Evidence system types (file_exists, content_match, test_passes, etc.) - Create evidence.ts verification module with strategy pattern verifiers - Add --verify-evidence and --run-tests flags to verify command Phase B & C - Constraint Graph & Execution Planning: - Add ConstraintGraph, ConstraintNode, ExecutionPlan, Wave types - Create solver.ts with constraint network builder - Implement parallel wave generation and critical path detection - Add bidirectional queries: whatMustBeTrue(), whatDoesThisBlock() Phase D - New Command: - Add /m-solve slash command for constraint solving - Support --backward, --visualize, --dot flags - ASCII visualization and GraphViz DOT export Documentation: - Update SCHEMA_REFERENCE.md with v3 types and templates - Document evidence system, constraint graph, execution plans Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1e16cc7 commit 92ed795

7 files changed

Lines changed: 1683 additions & 4 deletions

File tree

cli/commands/verify.ts

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
listFeatures,
1313
type FeatureData,
1414
type Manifold,
15-
type Constraint
15+
type Constraint,
16+
type Evidence
1617
} from '../lib/parser.js';
1718
import { countConstraints, countConstraintsByType } from '../lib/schema.js';
1819
import {
@@ -23,11 +24,19 @@ import {
2324
style,
2425
toJSON
2526
} from '../lib/output.js';
27+
import {
28+
verifyAllEvidence,
29+
normalizeEvidence,
30+
formatVerificationReport,
31+
type VerificationReport
32+
} from '../lib/evidence.js';
2633

2734
interface VerifyOptions {
2835
json?: boolean;
2936
artifacts?: boolean;
3037
strict?: boolean;
38+
verifyEvidence?: boolean;
39+
runTests?: boolean;
3140
}
3241

3342
interface ArtifactVerification {
@@ -53,6 +62,7 @@ interface VerificationResult {
5362
requiredTruthsSatisfied: number;
5463
percentage: number;
5564
};
65+
evidence?: VerificationReport;
5666
issues: string[];
5767
}
5868

@@ -66,6 +76,8 @@ export function registerVerifyCommand(program: Command): void {
6676
.option('--json', 'Output as JSON')
6777
.option('--artifacts', 'Verify generated artifacts exist')
6878
.option('--strict', 'Require all artifacts and coverage')
79+
.option('--verify-evidence', 'Verify concrete evidence for required truths (v3)')
80+
.option('--run-tests', 'Execute test evidence verification (requires --verify-evidence)')
6981
.action(async (feature: string | undefined, options: VerifyOptions) => {
7082
const exitCode = await verifyCommand(feature, options);
7183
process.exit(exitCode);
@@ -217,6 +229,23 @@ async function verifyFeature(
217229
}
218230
}
219231

232+
// Verify concrete evidence (v3 feature)
233+
if (options.verifyEvidence) {
234+
const projectRoot = dirname(manifoldDir);
235+
const evidenceReport = await verifyEvidenceForFeature(manifold, projectRoot, options);
236+
result.evidence = evidenceReport;
237+
238+
if (evidenceReport.failed > 0) {
239+
issues.push(`${evidenceReport.failed} evidence item(s) failed verification`);
240+
result.result = options.strict ? 'FAIL' : 'PARTIAL';
241+
}
242+
243+
if (evidenceReport.pending > 0 && options.strict) {
244+
issues.push(`${evidenceReport.pending} evidence item(s) pending`);
245+
result.result = 'PARTIAL';
246+
}
247+
}
248+
220249
// Phase check for strict mode
221250
if (options.strict && manifold.phase !== 'VERIFIED') {
222251
issues.push(`Phase is ${manifold.phase}, expected VERIFIED`);
@@ -315,6 +344,42 @@ function calculateCoverage(manifold: Manifold): NonNullable<VerificationResult['
315344
};
316345
}
317346

347+
/**
348+
* Verify concrete evidence for required truths (v3 feature)
349+
* Satisfies: Phase A - Reality Grounding
350+
*/
351+
async function verifyEvidenceForFeature(
352+
manifold: Manifold,
353+
projectRoot: string,
354+
options: VerifyOptions
355+
): Promise<VerificationReport> {
356+
// Collect all evidence from required truths
357+
const allEvidence: Evidence[] = [];
358+
359+
const requiredTruths = manifold.anchors?.required_truths ?? [];
360+
for (const rt of requiredTruths) {
361+
const evidence = normalizeEvidence(rt.evidence);
362+
allEvidence.push(...evidence);
363+
}
364+
365+
// Also collect evidence from constraints (v3)
366+
const constraintCategories = ['business', 'technical', 'user_experience', 'security', 'operational'] as const;
367+
for (const category of constraintCategories) {
368+
const constraints = manifold.constraints?.[category] ?? [];
369+
for (const constraint of constraints) {
370+
if (constraint.verified_by) {
371+
allEvidence.push(...constraint.verified_by);
372+
}
373+
}
374+
}
375+
376+
// Verify all evidence
377+
return verifyAllEvidence(allEvidence, {
378+
runTests: options.runTests,
379+
projectRoot
380+
});
381+
}
382+
318383
/**
319384
* Print verification output to console
320385
*/
@@ -363,6 +428,26 @@ function printVerificationOutput(result: VerificationResult, options: VerifyOpti
363428
}
364429
}
365430

431+
// Evidence (v3)
432+
if (result.evidence) {
433+
const e = result.evidence;
434+
const evidenceStatus = e.failed === 0
435+
? style.success(`${e.verified}/${e.total} verified`)
436+
: style.warning(`${e.verified}/${e.total} verified, ${e.failed} failed`);
437+
438+
println(formatKeyValue('Evidence', evidenceStatus));
439+
440+
// Show detailed evidence results
441+
if ((e.failed > 0 || e.pending > 0) && !options.json) {
442+
println();
443+
for (const r of e.results) {
444+
const icon = r.passed ? '✓' : r.evidence.status === 'PENDING' ? '⏳' : '✗';
445+
const colorFn = r.passed ? style.success : r.evidence.status === 'PENDING' ? style.dim : style.error;
446+
println(` ${colorFn(icon)} [${r.evidence.type}] ${r.message}`);
447+
}
448+
}
449+
}
450+
366451
// Issues
367452
if (result.issues.length > 0) {
368453
println();

0 commit comments

Comments
 (0)