Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Opcore is the code-intelligence and robustness monorepo for graph context, edit
- #244 `python.syntax` resolves one concrete interpreter through the Python project resolver, executes that exact interpreter with an isolated versioned JSON compile protocol over sorted `.py`/`.pyi` after-state content, and reports ranged/provenanced compiler diagnostics plus fine-grained outcomes. Parser-success overrides and hand-written grammar heuristics are forbidden; malformed output, nonzero exits, signals, and timeouts fail closed - WHY: syntax truth, target-version truth, and tool provenance must come from the same compiler invocation without mutating the source repo.
- #246 makes `@the-open-engine/opcore-validation-python` the sole dynamic owner of `opcore.python.project-context.v1`: every Python target resolves against its nearest project boundary through an injected read/list/exists/realpath workspace view, smol-toml AST config/build metadata, exact interpreter/tool/build probes, and after-state content. Missing realpath evidence is ambiguous, deleted overlays cannot remain discovery markers, and declared constraints never become invented exact versions. Validation, status, scan, init/install preview, metrics, ASP, and installed execution must reuse the resulting project key, context fingerprint, outcome, and provenance; ASP workspace/config reads must remain host-callback-only. Static descriptors advertise only the schema, outcome vocabulary, read-only behavior, and no-install guarantee - WHY: root-scoped and duplicate project/environment discovery validates nested monorepo files with the wrong interpreter and makes surfaces disagree.
- #209 makes Rust graph-core the sole parser/resolver for Python repo imports. `@the-open-engine/opcore-graph` materializes supplied `.py`/`.pyi` after-state files only in an isolated temporary repo and returns canonical directed `IMPORTS_FROM` file edges; validation-python owns only the structural analyzer contract, visible-file enumeration, cached target/transitive closure, and edge consumption. Opcore, advanced validation, validation-policy, and ASP inject the graph adapter; missing/failed/malformed analysis is an infrastructure failure, never empty success - WHY: a second TypeScript import grammar/resolver diverges on multiline syntax, overlays, packages, stubs, namespaces, and src layouts.
- #197 makes hypothetical graph evaluation exact-state: validation creates one `ValidationFileView` per before/after state and owns one disposable graph session for that view; graph materializes the complete visible TS/TSX/JS/JSX, Python `.py`/`.pyi`, and Rust `.rs` universe into a bounded isolated root, builds graph-core once, shares the immutable session across checks, and removes it on every exit. Introduced mode must use distinct before/after snapshots, ASP listings must preserve host truncation, and exact-state construction/query failure is non-pass even when persistent graph mode is optional - WHY: a persistent target-repo graph or incomplete listing cannot describe hypothetical file contents and must never produce a false clean pre-write result.
- #19 requires graph status to preserve real WAL checkpoint evidence from the latest pipeline summary and release gates to fail missing/fabricated WAL evidence - WHY: freshness and checkpoint pressure must remain host-visible provider facts.
- #19 treats `opcore graph serve` as the stdio/MCP hot-query replacement, not a Unix socket, with parallel independent serve sessions as the supported concurrency evidence.
- #19 keeps current external CRG receipts as non-implementation compatibility evidence only - WHY: old CRG remains a guardrail until downstream cutover issues consume the Opcore proof.
Expand Down Expand Up @@ -126,6 +127,7 @@ Opcore is the code-intelligence and robustness monorepo for graph context, edit
- ALWAYS emit boolean `attributes.exported` on supported TS/JS graph symbol nodes and file-node `attributes.exports[]` for default/re-export/barrel forms - WHY: dead-export metrics must distinguish unsupported export coverage from zero dead exports.
- ALWAYS make validation checks read file content through `ValidationCheckContext.fileView` - WHY: validation overlays are hypothetical and checks must see the same before/after file state without mutating disk.
- ALWAYS make validation checks consume GraphProvider facts through `ValidationCheckContext.graph` and injected `ValidationGraphProviderClient` sessions - WHY: validation must depend only on public contracts, not graph package internals, CLI execution, or store layouts.
- ALWAYS bind every hypothetical graph-backed check to the disposable exact-state graph session owned by its `ValidationFileView`, and share one session per state across all selected checks - WHY: request-scoped or persistent sessions make graph facts disagree with the contents read by the check; optional graph policy must not hide exact-state failures.
- ALWAYS make Python import-dependent validation consume an injected `PythonImportAnalyzer` backed by graph-core and derive closure from its directed after-state edges - WHY: validation-owned parsing or module candidates create a second semantic owner and cannot represent overlays consistently.
- ALWAYS preserve validation diagnostic source ranges, tool provenance, and fine-grained check outcomes across contracts, manifests, sorting/fingerprints, reporting, and ASP mapping when an adapter supplies them - WHY: transport layers must not collapse actionable compiler evidence or turn tool failures into clean passes.
- Native repo validation policy lives under `.opcore/config` `validation`; active checks, thresholds, path policy, docs policy, clone policy, TypeScript policy, Rust command gates, and check packs must be parsed and composed through `packages/validation-policy`.
Expand Down
2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Opcore is the code-intelligence and robustness monorepo for graph context, edit
- #244 `python.syntax` resolves one concrete interpreter through the Python project resolver, executes that exact interpreter with an isolated versioned JSON compile protocol over sorted `.py`/`.pyi` after-state content, and reports ranged/provenanced compiler diagnostics plus fine-grained outcomes. Parser-success overrides and hand-written grammar heuristics are forbidden; malformed output, nonzero exits, signals, and timeouts fail closed - WHY: syntax truth, target-version truth, and tool provenance must come from the same compiler invocation without mutating the source repo.
- #246 makes `@the-open-engine/opcore-validation-python` the sole dynamic owner of `opcore.python.project-context.v1`: every Python target resolves against its nearest project boundary through an injected read/list/exists/realpath workspace view, smol-toml AST config/build metadata, exact interpreter/tool/build probes, and after-state content. Missing realpath evidence is ambiguous, deleted overlays cannot remain discovery markers, and declared constraints never become invented exact versions. Validation, status, scan, init/install preview, metrics, ASP, and installed execution must reuse the resulting project key, context fingerprint, outcome, and provenance; ASP workspace/config reads must remain host-callback-only. Static descriptors advertise only the schema, outcome vocabulary, read-only behavior, and no-install guarantee - WHY: root-scoped and duplicate project/environment discovery validates nested monorepo files with the wrong interpreter and makes surfaces disagree.
- #209 makes Rust graph-core the sole parser/resolver for Python repo imports. `@the-open-engine/opcore-graph` materializes supplied `.py`/`.pyi` after-state files only in an isolated temporary repo and returns canonical directed `IMPORTS_FROM` file edges; validation-python owns only the structural analyzer contract, visible-file enumeration, cached target/transitive closure, and edge consumption. Opcore, advanced validation, validation-policy, and ASP inject the graph adapter; missing/failed/malformed analysis is an infrastructure failure, never empty success - WHY: a second TypeScript import grammar/resolver diverges on multiline syntax, overlays, packages, stubs, namespaces, and src layouts.
- #197 makes hypothetical graph evaluation exact-state: validation creates one `ValidationFileView` per before/after state and owns one disposable graph session for that view; graph materializes the complete visible TS/TSX/JS/JSX, Python `.py`/`.pyi`, and Rust `.rs` universe into a bounded isolated root, builds graph-core once, shares the immutable session across checks, and removes it on every exit. Introduced mode must use distinct before/after snapshots, ASP listings must preserve host truncation, and exact-state construction/query failure is non-pass even when persistent graph mode is optional - WHY: a persistent target-repo graph or incomplete listing cannot describe hypothetical file contents and must never produce a false clean pre-write result.
- #19 requires graph status to preserve real WAL checkpoint evidence from the latest pipeline summary and release gates to fail missing/fabricated WAL evidence - WHY: freshness and checkpoint pressure must remain host-visible provider facts.
- #19 treats `opcore graph serve` as the stdio/MCP hot-query replacement, not a Unix socket, with parallel independent serve sessions as the supported concurrency evidence.
- #19 keeps current external CRG receipts as non-implementation compatibility evidence only - WHY: old CRG remains a guardrail until downstream cutover issues consume the Opcore proof.
Expand Down Expand Up @@ -126,6 +127,7 @@ Opcore is the code-intelligence and robustness monorepo for graph context, edit
- ALWAYS emit boolean `attributes.exported` on supported TS/JS graph symbol nodes and file-node `attributes.exports[]` for default/re-export/barrel forms - WHY: dead-export metrics must distinguish unsupported export coverage from zero dead exports.
- ALWAYS make validation checks read file content through `ValidationCheckContext.fileView` - WHY: validation overlays are hypothetical and checks must see the same before/after file state without mutating disk.
- ALWAYS make validation checks consume GraphProvider facts through `ValidationCheckContext.graph` and injected `ValidationGraphProviderClient` sessions - WHY: validation must depend only on public contracts, not graph package internals, CLI execution, or store layouts.
- ALWAYS bind every hypothetical graph-backed check to the disposable exact-state graph session owned by its `ValidationFileView`, and share one session per state across all selected checks - WHY: request-scoped or persistent sessions make graph facts disagree with the contents read by the check; optional graph policy must not hide exact-state failures.
- ALWAYS make Python import-dependent validation consume an injected `PythonImportAnalyzer` backed by graph-core and derive closure from its directed after-state edges - WHY: validation-owned parsing or module candidates create a second semantic owner and cannot represent overlays consistently.
- ALWAYS preserve validation diagnostic source ranges, tool provenance, and fine-grained check outcomes across contracts, manifests, sorting/fingerprints, reporting, and ASP mapping when an adapter supplies them - WHY: transport layers must not collapse actionable compiler evidence or turn tool failures into clean passes.
- Native repo validation policy lives under `.opcore/config` `validation`; active checks, thresholds, path policy, docs policy, clone policy, TypeScript policy, Rust command gates, and check packs must be parsed and composed through `packages/validation-policy`.
Expand Down
6 changes: 4 additions & 2 deletions docs/architecture/runtime-cli-ard.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ Canonical `opcore graph`, `opcore edit`, `opcore check`, and `opcore validate` c

#58 adds `opcore validate pre-write --request-file <validation-request.json> --timeout-ms 30000 --json` for hook integration. The route is validation-owned, file-based, fail-closed, overlay-only, and emits a typed `PreWriteValidationReceipt` with timing, repo, scope, checks, graph, overlay, status, and failure summary data.

#197 makes hypothetical graph-backed validation state-exact. `packages/validation` creates the before/after `ValidationFileView`, acquires one disposable exact graph session for each state, shares that immutable session across every selected check and streaming/fail-fast path, and disposes it on every exit. `reportMode:"introduced"` uses distinct before and after snapshots. `packages/graph` owns bounded temporary source materialization, one graph-core build, bound queries, and recursive cleanup; product, advanced, and ASP composition inject that implementation through validation-owned types. Exact materialization, build, listing, or query failures are non-pass even under optional persistent-graph policy. ASP continues to obtain all source content through host callbacks and preserves `workspace/listTree.truncated`. The target source tree, persistent `.opcore/graph`, configuration, lockfiles, environments, and caches remain untouched.

#30 adds `ReleaseCutoverReceipt` and `npm run cutover:check` as the installed-artifact cutover proof. The gate packs the public release packages, installs them into a clean temporary project, clears current-tool environment resolution, excludes local wrapper/sibling paths, verifies installed canonical bins (`opcore` and `opcore-asp-provider`), binds every command receipt id to its expected canonical command/status/exit, and fails on old-tool/private-path markers or advertised `not_implemented` release commands.

#120 adds `AspDogfoodReceipt` and `npm run asp-dogfood:check` as advisory/shadow evidence that the independent ASP manager can install/enroll Opcore as a Core check provider and record host-owned decisions separately from provider assessments. The receipt uses temporary `ASP_HOME` state, records `opcore-asp-provider --stdio` manifest/bin evidence, co-records retained current-tool guardrails, and keeps `oldToolReplacementClaimed: false`; it is not a cutover, host authority claim, public standard-readiness claim, or `opcore asp` route.
Expand All @@ -72,9 +74,9 @@ There is no public `opcore asp` router group in this release. ASP Core check int
|---|---|
| `packages/contracts` | Public wire contracts, schemas, command payloads, adapter request/result envelopes, validation shapes, graph query contracts, and generated TypeScript types. |
| `crates/graph-core` | Planned Rust graph core for source extraction, parser integration, SQLite/WAL persistence, freshness metadata, watch daemon state, hot query execution, and clone index analysis through the existing native binary. |
| `packages/graph` | npm facade/package track for graph commands, public graph command adapter, native graph-core loading, and graph JSON output. It must not duplicate graph-core internals or depend on the aggregate CLI. |
| `packages/graph` | npm facade/package track for graph commands, public graph command adapter, native graph-core loading, graph JSON output, and bounded disposable exact-state source snapshots. It must not duplicate graph-core internals or depend on the aggregate CLI. |
| `packages/edit` | Edit planner, public edit command adapter, patch/tree edits, symbol-aware orchestration, graph-backed discovery integration, and whole-plan validation. It consumes contracts and graph queries, not graph internals or the aggregate CLI. |
| `packages/validation` | Mechanical checks, public check/validate command adapters, validation manifests, failure policy, hypothetical validation, graph-aware rule orchestration, and `check`/`validate` reporting. It consumes contracts and adapters, not edit internals or the aggregate CLI. |
| `packages/validation` | Mechanical checks, public check/validate command adapters, validation manifests, failure policy, hypothetical validation, file-view-state graph-session lifecycle, graph-aware rule orchestration, and `check`/`validate` reporting. It consumes contracts and injected graph adapters, not graph internals, edit internals, or the aggregate CLI. |
| `packages/validation-rust` | Rust validation adapter rules, temporary workspace materialization from validation file views, and Cargo/native-tool-backed checks exposed to validation through contracts. It does not own host decisions or current external guardrail replacement policy. |
| `packages/validation-typescript` | TypeScript adapter rules, compiler-backed checks, and TypeScript graph-aware validations exposed to validation through contracts. |
| `packages/validation-clone` | Duplicate-code validation adapter rules over `ValidationCheckContext.fileView`, with an injected native clone invoker supplied by CLI composition. It does not own graph-provider status, daemon lifecycle, host decisions, SAST/security policy, or scoring. |
Expand Down
10 changes: 9 additions & 1 deletion packages/asp-provider/src/validation-composition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { GRAPH_SCHEMA_VERSION, validateProviderStatus } from "@the-open-engine/o
import {
createValidationCheckManifest,
createValidationRunner,
createStateAwareValidationGraphSessionFactory,
createValidationExactGraphSnapshotFactory,
type ValidationCheckDefinition,
type ValidationGraphProviderClient,
type ValidationWorkspace
Expand All @@ -38,6 +40,7 @@ import {
graphProviderQuery,
graphProviderReviewContext,
graphProviderStatus,
createEphemeralGraphSnapshot,
graphPythonImportAnalyzer
} from "@the-open-engine/opcore-graph";
import type { PythonProjectWorkspace } from "@the-open-engine/opcore-validation-python";
Expand All @@ -55,10 +58,15 @@ export function createAspProviderValidationRunner(workspace: ValidationWorkspace
return {
async runValidation(request) {
const config = await readHostConfig(workspace, request);
const graphProviderClient = createAspValidationGraphProviderClient();
return createValidationRunner({
workspace,
checks: createBuiltInValidationChecks(config, { ...aspProviderPolicyOptions, pythonWorkspace }),
graphProviderClient: createAspValidationGraphProviderClient()
graphProviderClient,
graphSessionFactory: createStateAwareValidationGraphSessionFactory({
persistentClient: graphProviderClient,
exactSnapshotFactory: createValidationExactGraphSnapshotFactory(createEphemeralGraphSnapshot)
})
}).runValidation(request);
}
};
Expand Down
6 changes: 5 additions & 1 deletion packages/asp-provider/src/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export function createAspHostValidationWorkspace(
const entryByPath = new Map<string, TreeEntry>();
const blobTextById = new Map<string, string>();
const readSet = new Set<string>();
let fullTreeTruncated = false;

async function listTree(paths?: readonly string[]): Promise<readonly TreeEntry[]> {
const params: JsonObject = {
Expand All @@ -43,6 +44,7 @@ export function createAspHostValidationWorkspace(
truncated?: boolean;
};
const entries = (result.entries ?? []).map(normalizeTreeEntry).filter((entry): entry is TreeEntry => entry !== undefined);
if (paths === undefined) fullTreeTruncated = result.truncated === true;
for (const entry of entries) entryByPath.set(entry.path, entry);
return entries;
}
Expand Down Expand Up @@ -74,7 +76,8 @@ export function createAspHostValidationWorkspace(
async function listRepoFiles(): Promise<ValidationWorkspaceFileSet> {
const entries = await listTree();
return {
files: entries.map((entry) => ({ path: entry.path, status: "unchanged" as const }))
files: entries.map((entry) => ({ path: entry.path, status: "unchanged" as const })),
...(fullTreeTruncated ? { truncated: true, message: "Host workspace/listTree returned a truncated file universe" } : {})
};
}

Expand All @@ -85,6 +88,7 @@ export function createAspHostValidationWorkspace(
listPackageFiles: async (_packageName, packageRoot) => {
const files = await listRepoFiles();
return {
...files,
files: files.files.filter((file) => {
const path = typeof file === "string" ? file : file.path;
return path === packageRoot || path.startsWith(`${packageRoot}/`);
Expand Down
Loading
Loading