Skip to content

Latest commit

 

History

History
1005 lines (683 loc) · 123 KB

File metadata and controls

1005 lines (683 loc) · 123 KB

Codeguard Architecture

Purpose: explain system ownership, component contracts, repair flow, and the gap between current implementation and target behavior.

Document version: 1.2.4 · Updated: 2026-10-04 · Source baseline: current checkout and the implementation evidence; software version 0.1.4.

简体中文 · README · Technical design

Topic owners: commands, initialization, remediation, false positives, adapters, trust/distribution, acceptance and legacy compatibility. Detailed contracts live in these guides; OpenSpec owns requirements and tasks.

The source build wires ESLint into the node.lint task in check all, sharing native concurrency and the request deadline. Discovered JS/TS/TSX files select their nearest module manifest, local ESLint 10, unique flat config and Node without searching above the selected root. Execution collects reports; aggregation synchronizes the workbench serially and reuses stable tasks. Only completed native results for identical source bytes suppress duplicate WASM; ignored files, configuration errors and tool failures retain both their reasons and fallback. Protocols are current aggregate check_feedback 0.38.0 for both bound and unbound checks and check_aborted 0.13.0, with older schemas archived. native_results.node_lint carries per-file feedback, unexecuted paths, synchronization status and next action. See acceptance scope. This does not qualify grammars or replace real host acceptance.

The source-built Erlang slice now applies native-first selection through lint erlang FILE --erl-tool ABS_PATH: fixed OTP 28 scanner/parser calls operate on stdin bytes, with a non-project cwd and project startup disabled. Native diagnostics take precedence; preprocessing/macro coverage remains unresolved. Without an explicit tool, lint erlang searches absolute PATH directories once and records the selected canonical executable in 0.2 feedback. Only absence of an executable enables the pinned WASM candidate; a selected tool failure remains unresolved. No task closure, complete project lint or release qualification follows from this local result; see acceptance.

The source configuration entry now reuses the discovery service through a bounded projection instead of inspecting only legacy files. config validate/explain 0.3 keeps checker declaration states and source hashes separate from effective rules, suppressions and approval. Human feedback identifies the source, reason and next action. This does not execute a checker or change project state; truncation remains incomplete. Evidence and limits.

1. Reading contract and evidence

This is the architecture of the Rust Codeguard CLI repository, not the implementation manual for the existing Python host plugin. It addresses adapter authors, CLI/runtime maintainers, agent integrators, and reviewers.

  • Implemented building block: code and a bounded testable contract exist; this does not imply an end-to-end product feature.
  • Partial workflow: a callable path exists with explicit scope and unresolved requirements.
  • Target: agreed architectural intent whose complete integration or acceptance remains pending.
  • Unknown: no sufficient observation; never replace this with an optimistic assumption.

The existing OpenSpec change now lives in this Rust repository and is the sole specification and task authority. Implemented slices and remaining work are tracked separately; these documents do not maintain a second task ledger.

Evidence What it establishes
Workspace manifest and each crate manifest Names, dependency direction, version/toolchain declarations
CLI dispatch Callable command branches and platform guards
Full-check orchestration Current aggregation, native scheduling, and sync integrations
Initialization, contract tests Actual workspace artifacts and refresh behavior
Core aggregation, delivery gate Pure result semantics, not trusted public gate availability
Acceptance records Scoped observations, test method, and residual gaps

WASM requirements and 19 implementation tasks are recorded in the existing change. An opt-in Rust worker and narrow Java/TypeScript/TSX single-file feedback paths and a Python Ruff-unavailable candidate path now exist. All thirty-two candidate grammars remain unqualified; ArkTS, C, C++, C#, Go, JavaScript, Lua, Luau, Nix, Rust, Terraform, Zig, Objective-C, Solidity, R, Ruby, PHP, Kotlin, Dart, Erlang, Pascal, CFML, CFQuery, CFScript, COBOL, Scala, Swift and VB.NET are pinned Rust-loadable candidates without language-qualified lint routes. Project-wide native-first routing, qualified grammar ranges, capability-matched task closure, and host integrations remain incomplete; design examples are not current command output.

A source build with --features wasm-precheck now exposes codeguard grammar probe <language> <file> --format=json for all 32 pinned candidates. It uses the isolated Rust worker and reports unqualified observations with exit 3, not a lint or delivery verdict. Successful observations and input failures for a valid language share the closed 0.1.0 JSON schema and remain incomplete. Native-first lint/check, language/dialect acceptance, task/host feedback and distribution remain separate open work; current discovery also groups JavaScript/TSX under TypeScript and has no separate CFQuery/CFScript source mapping.

The source-built check all now runs a bounded candidate pass after its existing native checks. A separate grammar router distinguishes .tsx, JavaScript, and .cfs; complete <cfquery>...</cfquery> bodies are parsed with CFQuery, while ordinary .sql and ambiguous .h are not guessed. Shared .m requires an Objective-C line marker, and .sc is not guessed as Scala without project evidence; see the ambiguity regression. Four bounded real CLI fixtures collectively invoked all 32 pinned workers. Check feedback 0.38.0 records selected dialect, source/grammar digests, file-relative recovery positions, bounded known limitations, skipped work and incomplete status; Python files with completed, source-matched Ruff scans skip duplicate WASM; style-only P3C does not confirm syntax. Candidate observations never become confirmed violations or delivery permission. The pass has a 64-file/64-fragment/90-second cap and was about 54 seconds for four bounded fixtures on this Mac; the prior sequential implementation observed 26/32 in one 31-file Linux run before its 90-second cap. It is a partial candidate route with task projection; language qualification and actual-host integration remain open; npm 0.1.3 distributes it as an unqualified candidate. See acceptance evidence.

The source-built candidate scheduler now prepares bounded fragments in stable path order and runs up to min(--jobs, 2) isolated workers concurrently. It emits observations in that same order and rereads each source before accepting a worker result. A local 31-file, one-project fixture observed all 32 candidates within the unchanged 90-second pass; the Linux WASM integration step for source commit ff60184 passed the same one-project test; the complete CI run passed. This changes candidate throughput, not its authority.

The Java 17 native differential adds a 13-case javac 21 oracle for one grammar. It is local precision evidence only; Java remains an unqualified candidate.

The Kotlin native differential now records 11 decidable agreements and two unresolved hidden-error cases, one native-invalid and one native-valid. Swift similarly has 12 decidable agreements and one unresolved case. Incomplete scans cannot become valid/invalid labels merely because their recovery arrays are empty; unknown coverage is reported separately and both grammars remain unqualified.

flowchart LR
    A[check all discovery] --> B[Native adapters and blockers]
    B --> C[Source and scope recheck]
    C -->|stable| D[Dialect router]
    C -->|changed| G[Incomplete report]
    D --> E[Selected isolated WASM worker]
    E --> F[Unqualified observations]
    B --> G
    F --> G
Loading

A first narrow native-first route is now available for Zig: lint zig FILE --zig-tool ABS_PATH --format=json runs a Zig 0.16.0 ast-check executable with stable bytes on the selected source bytes before considering WASM. Native AST positions remain visible without source snippets; when no explicit tool is supplied, the pinned Zig grammar remains an unqualified fallback. Both outcomes stay incomplete because AST checking is narrower than full lint, build and tests. See the 0.1.0 feedback schema.

2. Architectural drivers

The product exists because generic output matching and ambiguous failures produce false positives, while repeated errors encourage agents to suppress checks instead of fixing code.

Driver Architectural response Acceptance intent
Preserve native rule meaning Adapter-specific command/report contracts Environment failures never become invented source violations
Low false positives Configuration-aware scope, explicit unknowns, exact exceptions Unsupported configuration remains unresolved; valid findings retain origin
Actionable repair Stable facts, repair brief, attempt history, original-tool recheck A finding yields an appropriate next action rather than repeated raw logs
Multi-language consistency Six categories and versioned report semantics Every advertised language/category has its own tested evidence
Predictable execution Bounded processes, resource-aware scheduling, cancellation Failure cannot silently erase other completed observations
Minimal onboarding Discover existing configuration first Initialization does not execute project scripts or fabricate architecture

Rust is the orchestration language, selected for a deployable binary and explicit state/resource handling. No comparative performance result is available. Native analyzer runtime and database costs can dominate total scan time.

3. Scope and system context

flowchart LR
    Human[Developer] --> CLI[Codeguard Rust CLI]
    Agent[Coding agent] --> CLI
    Plugin[Host plugin: target integration] -.-> CLI
    Project[Source, manifests, locks, native configs] --> CLI
    CLI --> Native[Native checkers and their runtimes]
    Native --> Results[Diagnostics and execution status]
    Results --> CLI
    CLI --> Feedback[Conversation-ready feedback]
    CLI --> Workbench[Project-local repair files]
    Authority[Policy / exception authority: incomplete integration] -.-> CLI
Loading

Codeguard owns discovery, command selection, bounded invocation, interpretation, result presentation, and local repair coordination. Native tools own language semantics, rule execution, dependency resolution, and advisory lookup within their contracts. The agent owns proposed code/environment changes. A policy authority must own exception approval; writing a local proposal is not approval.

The CLI does not own a model provider, chat transport, IDE UI, RAG store, distributed scheduler, or SaaS tenant database. Plugins and skills remain separate integration/distribution layers. Their automatic check → sync → brief behavior is a target integration, not established by this repository's CLI tests.

4. Current state and target state

Capability Current state Target / remaining work
Native checks Partial Python, Rust, Java, Node and Go paths Complete supported scopes and language/category matrix
Discovery Static configuration and manifest observations Effective models under explicit controlled resolution
Project architecture Unknown plus static module declarations Evidence-labelled observed/inferred/confirmed views and conflicts
Repair Stable tasks, local attempts, selected native rechecks Reliable verified closure, recurrence, and full event reconciliation
False-positive exceptions Candidate inspection/proposals, exact matching and signature-related building blocks Trusted approval source, lifecycle integration, and usable activation
Quality gates Core algebra; public scans remain partial; index path safety End-to-end checks against actual worktree/index/ref/CI content
Distribution Source build and npm 0.1.3 for Apple Silicon macOS; artifact verification/download/install primitives Supported binary releases, platform tests and host runtime bindings

Current check all includes Rust build scheduling and persistence; build recheck is also present. Older notes saying these integrations are wholly absent must not be used as the current status. Complete build combinations and formal closure remain missing.

5. Components and dependency direction

flowchart TB
    CLI[codeguard-cli: entry and application services] --> Core[codeguard-core: domain contracts]
    CLI --> Runtime[codeguard-runtime: execution and I/O]
    CLI --> Adapters[codeguard-adapters: native semantics]
    Runtime --> Core
    Adapters --> Core
    Runtime --> OS[OS / filesystem / native processes]
Loading
Component Input → output State / failure responsibility
CLI Arguments/configuration → selected operation and feedback Owns workspace orchestration, command-specific errors, protocol projection
Core Typed observations and scope → deterministic evaluation No native process or filesystem access; does not establish trust from a boolean by itself
Runtime Literal process specification / snapshot request → bounded observation Process lifecycle, bytes, locks, resource cleanup, explicit I/O failures
Adapters Native configuration/output → checker-specific observations Rule identity, scope and exit/report coherence; unknown protocols remain unresolved

The four crates are real compile-time boundaries. Application services currently live in codeguard-cli, including substantial scan/persistence logic. There is no separate application crate or universal runtime-loaded adapter ABI. Future extraction should follow cohesive responsibilities, not add empty crates to match a diagram.

5.1 Application services and extension boundaries

Discovery/Plan/Check/Work/Fix/Gate services in the earlier design are logical responsibilities, not a claim that corresponding public traits or separate crates exist. Argument parsing and application services currently live in the CLI. Scoped threads and bounded processes must not be described as an already implemented clap/Tokio scheduler. An adapter must declare configuration discovery, input scope, native report semantics and recheck capability; registering a language name is insufficient.

Project build scripts and checked code are untrusted inputs. The full CI gate is intended to isolate the validator, policy source and final credentials from project processes. Current local process controls and offline options do not establish network isolation or protection from a malicious process under the same user. See trust and distribution for the detailed boundary.

6. Domain model and result semantics

Concept Meaning Important distinction
Configuration observation configured / missing / invalid / unknown Declaration is not effective-model resolution or execution
Check obligation Selected checker/category/target/rule scope A planned inventory row is not an executed obligation
Finding Native rule, tool, location, severity, identity Native severity and policy gate impact are separate
Completion complete / incomplete / not_applicable Independent of finding count
Blocker Environment, configuration, scope, or evidence issue Not a source-code violation
Repair task Actionable projection of a persistent problem Checking a Markdown box is not resolution
Disposition Exact false-positive or exception decision Does not delete the raw finding or rewrite tool output
flowchart LR
    O[Native observation] --> F[Findings]
    O --> C[Completion]
    F --> A[Request aggregation]
    C --> A
    A --> R[Result + unresolved reasons]
    R --> G[Delivery evaluation if trusted full context exists]
Loading

Core aggregation priority is cancellation → internal error → incomplete → violations → not applicable/passed. It retains findings from partial runs. The core delivery calculator separately checks scope, obligations, coverage and exception bindings. It can model allow, allow_with_exceptions, deny, incomplete, not_applicable, and not_evaluated; current public partial checks do not supply the complete trusted context needed to claim delivery success.

The user-facing contract is practical: show what is configured, what was found, what failed to run or resolve, and what to do next. Internal identity checks prevent stale or mismatched observations; they should not turn ordinary usage into a separate exercise in manually proving execution.

7. Initialization and project knowledge

flowchart LR
    Root[Explicit project root] --> Observe[Read manifests, locks, configs and source paths]
    Observe --> Profile[Project profile]
    Observe --> Graph[Typed module declarations]
    Profile --> Preview[Dry-run plan and conversation summary]
    Graph --> Preview
    Preview --> Apply[Explicit apply with ownership checks]
    Apply --> Files[Workspace and managed AGENTS block]
Loading

init defaults to dry-run. Static observation does not execute wrapper scripts, Maven extensions, JavaScript configs, or service startup. Declared package versions, language targets, resolved dependency versions, and installed runtimes are distinct; unknown values stay unknown.

Maven and Cargo support selected direct module/dependency declarations. Aggregation, containment and build dependency are distinct edges. Variables, inherited models, optional/target conditions, missing targets and ambiguous identities are unresolved. An incomplete graph cannot justify a narrower scan or prove independence.

AGENTS.md contains bounded summaries of languages, roots, versions, checkers and graph observations, with links and content digests. Human text outside the managed markers is retained. Duplicate/missing markers, modified managed content and detected concurrent edits produce conflicts. Current write checks do not establish perfect exclusion against an uncooperative external editor. Source strings are escaped as data; unknown MVC/DDD architecture does not activate a blocking rule.

8. Scan, feedback, and repair flow

sequenceDiagram
    participant A as Agent / developer
    participant C as CLI application
    participant R as Runtime
    participant N as Native checker
    participant W as Local workbench
    A->>C: check with project and selected tool context
    C->>C: discover configuration and freeze relevant input
    C->>R: task graph + common deadline
    R->>N: literal arguments, selected environment
    N-->>R: output + termination state
    R-->>C: bounded observation
    C->>C: adapter interpretation and input recheck
    C->>W: save eligible local report and sync
    W-->>C: stable tasks / sync failure
    C-->>A: findings + blockers + next action
    A->>A: repair within task scope
    A->>C: task verify with original checker
    C-->>A: still present / blocked / candidate absent
Loading

Local saving and sync are implemented for selected paths. Uninitialized projects can still receive feedback; they do not silently receive a persistent workbench. A sync error must remain visible without erasing native findings. Malformed or stale reports cannot close unrelated tasks.

The desired complete loop is:

flowchart LR
    N[Native checks] --> M[Merge findings and environment blockers]
    M --> T[Stable repair tasks]
    T --> Next[Next action]
    Next --> Fix[Repair code or environment]
    Fix --> V[Original-tool recheck]
    V -->|Still present| T
    V -->|No progress| D[Specific diagnosis / decision]
    V -->|Verified resolution: target| Close[Record resolution]
    Close --> Full[Full delivery checks: target]
Loading

The final two nodes are target behavior. Current candidate-absent observations do not automatically close tasks. Each task should carry evidence, rule basis, allowed scope, repair steps, recheck command, attempt history, and closure conditions.

8.1 Native-first routing with bundled WASM precheck — target

Target contract, partly implemented in the published 0.1.3 candidate package. Keep a single entry point; callers select a language or project, not a parser backend:

codeguard lint java .
codeguard lint typescript .
codeguard check all .

These entry points already exist with bounded native adapters and adapter-specific prerequisites. Automatic fallback described below is new target behavior. Resolve checker availability per module, language/version, dialect and effective configuration. An ESLint-ready frontend and a Java module missing its JDK take different paths in the same run.

flowchart TD
    A[Observe modules, language versions and checker configuration] --> B{Native checker ready?}
    B -->|Available with valid configuration| C[Run native checker]
    C --> D[Native findings, completion and repair guidance]
    B -->|Tool missing or configuration unavailable| E[Run bundled WASM syntax precheck]
    E --> F{Precheck result}
    F -->|No anomaly in checked scope| G[Return precheck report; recommend native setup]
    F -->|Suspected syntax issue| H[Return locations; require native setup and confirmation]
    F -->|Incomplete or unsupported| I[Explain coverage gap; restore valid checking capability]
    G --> J[Sync eligible workbench observations and return agent brief]
    H --> J
    I --> J
    D --> J
    H --> K[Install or restore the applicable native checker]
    K --> C
Loading

A completed native violation never selects fallback to obtain a clean result. A native execution failure may receive supplementary precheck feedback, but the original failure remains visible. WASM covers syntax only: it does not replace configured style rules, Javadoc, type checking, dependency/CVE analysis or security checks. Already-required native obligations remain required even after a clean precheck.

Situation User-facing conclusion Next action
Native checker ready Native report with actual scope and completion Follow native diagnostics
Native tool missing; precheck clean No syntax anomaly in checked scope; native lint not run Recommend installation unless the project already requires it
Native tool missing; suspected syntax issue Suspected issue awaiting native confirmation, not a confirmed violation Require installation/restoration and an applicable native recheck
Tool installed; configuration invalid Configuration blocker plus scoped precheck Restore configuration; do not reinstall an already available tool
Grammar incompatible, worker timeout or load failure Precheck incomplete/unsupported Restore native checking or repair parser support; do not blame source
No files checked or partial embedded-language coverage Empty/incomplete scope, never an all-clear Resolve scope or show exactly which regions remain unchecked

“Required” controls verification and task closure; it does not authorize installation outside the user's existing scope or freeze unrelated work. If installation is unavailable, keep one environment task with a concrete reason. A grammar anomaly can be false positive, but still requires valid native confirmation before the escalated task is resolved.

8.2 Grammar assets and Rust ownership — target

Reuse pinned CodeGraph grammar WASM artifacts and applicable upstream licenses, source references, patches and corpus cases. Do not copy CodeGraph's graph extraction or source-blanking heuristics into a syntax verdict. CodeGraph's src/extraction/grammars.ts loads language artifacts through web-tree-sitter; successful loading there does not prove compatibility with Codeguard's Rust runtime. The local source review on 2026-09-28 found modified grammar artifacts and about 65 MB of grammar files, so a live directory is not a release input.

The read-only codeguard grammar status command projects a pinned CodeGraph coverage inventory: 30 vendored WASM files and two dependency-provided grammars. CodeGuard currently pins 32 Rust-loadable candidates, including ArkTS, Nix and Terraform; none is qualified for release. ArkTS, Nix and Terraform provenance and worker evidence are recorded in the candidate acceptance. ArkTS, Nix and Terraform have pinned bytes, licenses and narrow Rust worker evidence, but no language-qualified standalone lint route or release qualification; see the limited acceptance record. The corrected Zig source WASM requires a pinned import adaptation to load in Rust; language-qualified lint zig remains open. Python has a narrow unqualified fallback for unavailable or undeclared Ruff, with native results taking priority and no delivery approval. An initialized single-file scope now syncs one stable native-confirmation task; candidate zero recoveries do not close it. This inventory is deliberately separate from the pinned candidate asset manifest. COBOL now loads under a bounded 20 MiB input limit, but its cold-start and memory budget remain unqualified. Inventory rows never trigger loading or count as supported parser capability.

R, Ruby, PHP and Kotlin now also have pinned CodeGraph bytes, licenses, measured Rust ABI and narrow positive/negative worker samples; the PHP fixture covers mixed HTML/PHP. They remain unqualified candidates. The original CodeGraph Dart WASM remains incompatible with Rust, but CodeGuard now has a byte-reproducible Zig rebuild that compiles the real external scanner and uses a pinned WASI import adaptation. Rust loader and isolated-worker fixtures pass; Dart remains unqualified for public lint and release. See the Dart rebuild record. Erlang has pinned CodeGraph bytes, the upstream 0.19 license and ABI 14, Rust worker samples and an OTP 28 native comparison. Current source builds include explicit native-first lint and task verification; the original WASM still misses function terminators, while full language and public release qualification remain open. See the native comparison and task verification. Pascal now has pinned CodeGraph bytes and its original Isopod dependency commit and license; ABI 14 and narrow worker tests pass, but native comparison and public lint remain open. See the Pascal candidate record. The remaining CFML/CFQuery/CFScript/COBOL/Scala/Swift/VB.NET assets also load in the Rust worker, bringing the candidate inventory to 32/32 with zero released syntax capabilities. CFQuery misses SELECT FROM, VB.NET misparses a valid unindented method, and COBOL has a high load cost; see the seven-asset acceptance record.

grammars/                         # proposed release assets, not project state
├── manifest.json                 # immutable source, digest, ABI and capability map
├── java/
│   ├── parser.wasm
│   └── LICENSE
└── typescript/
    ├── parser.wasm
    └── LICENSE

For each artifact, record language/dialect, upstream commit and patch identity, WASM SHA-256, Tree-sitter ABI/runtime compatibility, tested language versions, known limitations, license and corpus reference. File presence, load compatibility and syntax-check acceptance are three separate capability states. Bundled grammars must work offline; load only the languages needed. Additional language-pack updates require a versioned manifest and compatibility check.

Owner Responsibility added by this design
codeguard-core Backend selection policy, precheck outcomes, required/recommended setup actions and reconciliation
codeguard-runtime Rust Tree-sitter WASM host, bounded parser worker, asset validation, caches and cancellation
codeguard-adapters Language/dialect interpretation, syntax observations and native confirmation capability mapping
codeguard-cli Compose adapters with runtime; commands, persistence and human/JSON brief
Separate codeguard-plugin Host triggers, bounded conversation delivery and feedback deduplication

Retain the four-crate dependency direction: adapters interpret observations; CLI composes them with runtime. WASM workers receive bounded source bytes without general filesystem/network imports. Parent-owned deadlines, process termination, memory limits and output bounds must be verified on each supported host; “WASM” alone does not prove resource isolation. Runtime and grammar versions must also fit the declared Rust MSRV or follow an explicit compatibility change. Rust's Tree-sitter WasmStore provides a loading API, not a guarantee that every copied grammar is compatible (reference checked 2026-09-28).

S14.2 Rust-loader acceptance covers offline fixed assets, malformed/hash/ABI rejection and actual Rust1.85 checks. All32 candidates being loadable does not change the zero-qualified-grammar count. Precision, provenance governance, isolation and release remain separate unfinished tasks; see loader verification.

8.3 Agent feedback and verification lifecycle — target

Report precheck status separately from native execution and delivery. clean means only no observed syntax anomaly; suspected_issue needs confirmation; incomplete and unsupported identify missing coverage. Detect both Tree-sitter ERROR and MISSING recovery, group related recovery nodes and preserve source spans. Version/dialect uncertainty is diagnostic context, not proof of a source defect. See Tree-sitter query syntax.

The plugin sends a short report containing method, checked/uncovered scope, observation, native-tool state, next action and an actual task reference when persistence succeeded. The CLI alone cannot inject messages into arbitrary hosts. AGENTS.md stores standing workflow guidance, not repeated run logs. Repository text and checker output remain data; installation actions come from reviewed adapter recipes, not copied diagnostic shell strings.

Illustrative target brief, not captured output (path and task ID are synthetic):

Codeguard: Java syntax precheck found 1 suspected issue
Method/scope: bundled WASM; 18 of 18 selected Java files checked.
Native check: not run; the project's required JDK is unavailable.
Location: src/main/java/example/UserService.java:42; MISSING recovery node.
Next step (required): prepare the declared JDK and applicable native checker,
then confirm this file's syntax before repairing according to native diagnostics.
Task: CG-example-java-setup (only emit an actual persisted task in real use).
This is not yet a confirmed code violation; delivery is not evaluated.
sequenceDiagram
    participant A as Agent host
    participant P as Codeguard plugin
    participant C as Rust CLI
    participant W as WASM worker
    participant T as Workbench
    A->>P: Check changed module
    P->>C: lint with project context
    C->>C: Native checker unavailable
    C->>W: Parse bounded source with pinned grammar
    W-->>C: Syntax observations and coverage
    C->>T: Sync if initialized; reuse setup/confirmation task
    T-->>C: Actual task reference or sync error
    C-->>P: Precheck + native state + next action
    P-->>A: Bounded brief, with changed results only
    A->>P: After authorized native setup, request verification
    P->>C: task verify with original project context
    C-->>P: Native confirmation, contradiction or unresolved coverage
    P-->>A: Repair action or resolved verification outcome
Loading

For required setup, create one setup/confirmation task per module/checker obligation and attach suspect source observations to it. Optional setup remains a recommendation, not a blocking repair task; next must not repeatedly select it. Installing a tool alone does not close that task. Native confirmation must cover the same syntax capability, file/dialect and current input: Java style-only output is not compiler-level syntax proof. Confirmed issues become native repair work; a sufficiently scoped native contradiction records a parser false-positive candidate. Ambiguous coverage stays unresolved. A later clean WASM run alone cannot satisfy a previously required native confirmation.

Allowlist dispositions bind rule, source target, grammar identity and reason; retain observations and reevaluate after relevant changes. They cannot remove required native checking or fabricate coverage. Repeated runs update stable tasks and attempt history. Emit the initial brief, then meaningful changes; preserve a status view instead of repeating unchanged installation requests. See the technical design's 7.3–7.4 for bilingual report examples and the proposed data contract.

8.4 Host events and check tiers — target

Host hooks pass events, workspace identity and known targets. Rust core selects the check tier; the formal CheckPlan then chooses native checkers and resource budgets. An agent cannot change delivery obligations through a prompt, an old soft cache entry or a project-local skipGate. The pure domain router now bounds per-file feedback selection; bulk edits above that budget request a batch-scope decision with a distinct reason. The read-only codeguard hook plan CLI returns only a candidate tier with exit 3; it does not execute a checker or connect the plugin, real Git/CI or any verified automatic host trigger. The complete event-driven execution remains a target design.

Separately, lint python . --file REL_PATH can invoke native Ruff within the same path budget and report only the selected files. hook plan does not yet invoke it automatically, and this local result is neither a real Git-scope check nor a full workbench scan.

hook execute PATH --timeout DURATION --format=json consumes the same versioned host event and core route. Session start performs read-only discovery; Stop reads a bounded local next-step view without invoking a checker; a confirmed bounded edit runs selected Python/Ruff and JS/TS/ESLint native checks, then optional WASM candidates for uncovered files. Stop examines at most 64 findings and 64 reports, with an 8 MiB total report-byte budget; exceeding either returns guidance_scope_exceeded and leaves the check unrun. repair_ready bounds one task history to 128 events and 1 MiB, resolves the stable task fact, then invokes the existing task verify path in a bounded child process; its response contains a small summary of the original checker observation and whether the local event was saved. It never closes the task or approves delivery. With an explicit --git-tool ABS_PATH, pre_commit observes the live staged index (including GIT_INDEX_FILE) under the event deadline, reports path violations and verified-object status, and never reads an old edit result as a gate. Missing tools or unstable index observations remain incomplete. Uncertain or failed writes, push and CI remain not_run. hook_execution_feedback 0.6 remains candidate evidence; historical 0.1–0.5 schemas are retained. Prompt submission now returns constant non-blocking timing guidance without interpreting prompt text or running a checker; this does not establish delivery intent or a Git gate. Plugin Hooks, cache reuse and complete Git/CI quality gates are still unwired.

The Rust CLI also has candidate Claude Code SessionStart, PostToolUse, PostToolUseFailure, and Stop soft entries. Session start delegates to read-only project discovery. A successful file edit checks the absolute target against the project root and regular-file boundary, then calls the same executor. A failed edit invokes the no-check route without reading the tool error as instructions. Stop reads bounded local task facts without invoking a checker; only a stable task on an initial Stop yields one additionalContext continuation, while stop_hook_active=true and an empty backlog yield a user-visible message without another continuation. All outputs are bounded and omit source text, raw errors, and editable task Markdown. Invalid or over-budget events say the check was not run. Host exit 0 means only soft feedback, never quality or delivery approval. The separate codeguard-plugin does not yet bind or invoke this binary; see the candidate acceptance record.

flowchart LR
    H[Host event] --> R[Pure Rust event routing]
    R -->|Session start| D[Read-only discovery]
    R -->|Confirmed edit| F[Changed-file feedback]
    R -->|Repair ready| V[Original task and checker recheck]
    R -->|Commit / push| G[Acquire current Git content scope]
    R -->|CI| A[Full project obligations]
    F --> P[Unified report / task / next action]
    V --> P
    G --> P
    A --> P
Loading
Event Requested tier Required boundary
Start/resume, prompt, stop Read-only discovery, nonblocking intent guidance, session summary Prompt text cannot replace a real Git gate or claim delivery
Confirmed write Affected-file fast check Reuse a complete soft result only when content and all configuration identities match; queue project-wide work
Failed/unknown write No source check / resolve scope Unknown cannot mean unchanged or checked
Repair attempt completed Original task verify Installing a tool, ticking a task or WASM clean alone does not close it
Commit, push, CI Strict commit scope, actual pushed refs, full project obligations Ignore host-supplied path guesses and old save feedback; disclose missing enforcement support

Coalescing applies only to duplicate fast feedback for the same content snapshot; it cannot swallow new input, failed rechecks or delivery events. Cache identity must cover source and dependency closure, tool, rules, configuration, platform and vulnerability database freshness. Strict gates revalidate full obligations and identities, then recompute or report incomplete when proof is missing. Measure latency percentiles, repeat execution, invalidations, missed findings and false positives per tier before fixing budgets.

9. Persistence and ownership

checked-project/
├── AGENTS.md                       # only Codeguard's marked block is managed
└── .codeguard/
    ├── .gitignore / README.md
    ├── workspace.json              # local workspace identity and managed digests
    ├── project.json                # static observations
    ├── module-graph.json            # typed relations plus unresolved conditions
    ├── architecture.md             # observation projection
    ├── findings/                   # redacted facts and append-oriented events
    ├── tasks/                      # readable projections and correction attachments
    ├── decisions/                  # references; no local self-approval
    ├── reports/                    # ignored local observations
    ├── runs/                       # ignored run data
    ├── cache/                      # ignored cached data
    ├── worktrees/                  # ignored working copies
    └── state/                      # ignored receipts, observations and leases

The architecture distinguishes original checker output, normalized observations, persistent problem facts, and human-readable projections. These are not interchangeable authority sources. Empty directories may not appear in Git until populated.

work sync binds reports to a workspace/run and consumes matching reports idempotently. Repeated findings retain stable tasks; repeated observations should avoid tracked-file noise. A bad report does not justify discarding other valid reports. Multi-file updates are not claimed to be a fully atomic database transaction; recovery tests cover selected intermediate states and process exits.

The dot-prefix rule skips .codeguard/ during ordinary source discovery; Codeguard still validates its own records. User source such as codeguard/src remains in scope. An older codeguard/workspace.json causes a migration conflict; moving the entire directory could hide user source. Tracked records must still obey repository security checks; completing that security gate remains work. Deleting tasks does not supply evidence that the source is clean.

10. Execution, concurrency, and resource limits

ProcessSpec records an absolute executable, literal arguments, explicit cwd, a selected environment, stdin policy, common deadline and combined stdout/stderr limit. Process execution handles capture, termination and cleanup. Unix process-group control and filesystem calls use isolated unsafe code; the workspace does not promise zero unsafe.

Task scheduling runs a validated DAG with dependency and shared-resource exclusion. Failed dependencies do not start their children. Cancellation and deadline expiry distinguish queued from running tasks. Arbitrary Rust callbacks that ignore cancellation cannot be forcibly preempted by the scheduler.

Budget Current value / scope
Check timeout Default 30 minutes; accepted 1 ms–24 hours
Check jobs Default min(available parallelism, 4); explicit range 1–64
Check source snapshot Current aggregate path requests at most 4,096 files, 16 MiB/file, 256 MiB total
Process output Per-process specification; many current probes use 16 MiB combined capture
Task lease Local token/generation ownership and expiry; not cross-machine coordination

These limits are implementation budgets, not measured latency or throughput guarantees. Different probes may impose smaller limits. No end-to-end CPU, memory or network sandbox is certified. Build extensions and native tool behavior remain part of the threat model.

11. Task lifecycle and no-progress control

stateDiagram-v2
    [*] --> Open
    Open --> Claimed: valid local lease
    Claimed --> Attempt: record start
    Attempt --> Recheck: finish with change
    Attempt --> Decision: repeated failure or no change
    Recheck --> Open: still present / incomplete
    Recheck --> Candidate: absent but policy unresolved
    Candidate --> Open: current input changes
    Candidate --> Resolved: target - verified full conditions
    Resolved --> Open: target - recurrence
Loading

This is a conceptual lifecycle, not a claim that every named state is stored verbatim. Current local facts remain open while recheck events distinguish still_present, still_blocked, suppression/configuration review, and candidate absence. Attempts, leases and verification receipts are separate structures.

A lease cannot be replaced by an owner string alone: tokens, generation and expiry matter. Failed/no-change/abandoned attempts contribute to bounded no-progress handling. next reads structured facts and verified local observations instead of executing instructions embedded in task Markdown. Complete parent-event reconciliation, cross-machine coordination and reliable formal closure remain pending.

12. False-positive rules and trust boundaries

Boundary Required behavior Current limit
Native diagnostics → findings Preserve exact rule/tool/location and unsupported states Parsers implement selected protocols and rule subsets
Project text → agent context Escape data; no instructions promoted to policy General prompt-injection immunity is not claimed
Candidate → approved exception Match exact current identity, expiry and approval scope Public CLI has no complete approval/activation path
Native suppression → repair result Detect changed coverage before claiming a fix Counterchecks exist only for selected adapters
Report → current observation Verify workspace, run, input and tool bindings A digest establishes byte consistency, not independent trust
Task projection → source status Recheck with original tool Checkbox/delete operations cannot establish resolution

False-positive handling is an explicit product capability, not a broad skip switch. Exact matching and signature verification building blocks exist, but their existence is not proof that key distribution, approval governance, current clocks and gate integration are complete. See false-positive design.

13. Protocols and configuration

The CLI emits command-specific versioned JSON, human-readable projections and selected SARIF. Schemas include current and older protocol shapes. RunReport is a target/common contract alongside multiple current local observation protocols; integrations must not assume every command already emits one identical envelope.

Configuration layers have different authority:

  1. Native tool configuration selects native checks.
  2. Project runtime options select time/concurrency, not policy.
  3. Rulepack/tool-lock/policy candidates describe intended bindings but are not independently approved by their location.
  4. Approved policy and exception authority require an explicit trustworthy source; full integration remains pending.

The runtime precedence and exact schema are documented in README. Unknown fields and unsupported versions must be handled according to the relevant parser, not universally claimed to share one parser policy. Protocol compatibility and legacy exit semantics need explicit adapters.

14. Reliability and operational recovery

Failure Output and repair action
Missing JDK/tool/configuration Preparation blocker; restore the needed environment or configuration
Native timeout or output limit Incomplete; preserve independently parseable current findings
Truncated JSON/XML or unsupported protocol Concrete parse/protocol issue; do not invent a finding
Input changed during/after scan Observation becomes unusable for current resolution; rescan
Sync conflict or interrupted persistence Preserve original report, report sync state, retry/reconcile
Changed managed AGENTS.md Preserve human content and surface ownership conflict
Repeated no progress Stop the same repair action and provide a specific decision requirement
Advisory database unknown/stale Display available scoped observations and unresolved CVE completeness

A clean native result should not trigger endless identical rescans because an unrelated policy prerequisite remains unresolved. The target experience is to surface the missing prerequisite once as a stable actionable item. Current partial authority integration is a product gap, not a reason to claim a fix has failed.

There is no daemon uptime SLO, multi-region RPO/RTO, production metrics backend or proven benchmark in this repository. Diagnosis currently relies on structured feedback, run IDs, local observations, and acceptance evidence. Raw logs are local and potentially sensitive even when Git-ignored.

15. Deployment, upgrades, and integration

Current deployment is a locally built binary plus independently prepared native toolchains. The @partme.ai/codeguard@0.1.3 npm package bundles an Apple Silicon macOS binary behind a Node command entry; the Node layer only forwards arguments, cwd, environment, streams and exit status. Publication, a fresh-cache npx version check, and registry/local artifact byte comparison passed on that host. The binary reports a candidate source commit, but this does not establish signed provenance, a reproducible build, a multi-platform binary release, or completed quality gates. tools install public apply is blocked while internal package verification/download/install primitives have tests.

flowchart LR
    Build[Explicit Rust build] --> Verify[Check binary version and host target]
    Verify --> Wasm{WASM package requested?}
    Wasm -->|yes| Probe[Match 32 pinned identities and run Zig worker]
    Wasm -->|no, local private only| Pack[Local platform-tagged npm tarball]
    Probe --> Licenses[Verify pinned upstream licenses]
    Licenses --> Pack
    Pack --> Node[Node bin: codeguard]
    Node --> Rust[Bundled Rust executable]
    Rust --> Native[Selected native analyzers]
Loading

The default local package is marked private and contains no npm install hook. Its bin entry is npm/codeguard.cjs; scripts/pack-npm-local.mjs builds it from an existing binary. The --public packaging mode produced the published @partme.ai/codeguard@0.1.3, restricted to Apple Silicon macOS. Fresh-cache registry execution and matching package/binary hashes are recorded in npm 0.1.3 acceptance evidence. Broad registry distribution still needs approved platform coverage, a trusted artifact manifest, matching versions and hashes, and a release process. CodeGraph's Node entry and platform package layout informed this design; its optional network fallback is not part of Codeguard's current installation path.

For the published 0.1.3 candidate-WASM package, --require-wasm and --public both reject a binary lacking the worker. The packer compares its inventory against the 32 pinned manifest identities and executes a Zig worker probe before writing a tarball; local offline npm acceptance additionally runs Zig and Dart from the package. The packer also verifies and includes all pinned upstream licenses; the public 0.1.3 tarball matches the registry bytes. This does not retroactively add WASM to 0.1.2 or qualify any language for lint; see public candidate acceptance.

For upgrades: record binary/schema versions, preserve workbench data, preview managed changes, rerun a bounded check, and validate report consumption before adopting the new binary. Downgrade must respect supported schemas; never rewrite historical files into an older shape merely to make parsing pass.

Target plugin integration should map host invocation to the same CLI semantics, return result/next action to the conversation, and keep transport failure distinct from quality status. Host-specific fail-open policy must not erase unresolved findings. No MCP server or host binding is provided by this baseline's command dispatcher.

16. Architecture decisions

Decision Choice and rationale Revisit when
A01 Language Rust orchestration; preserve native analyzers to retain ecosystem semantics A measured platform constraint requires a bounded adapter change
A02 Result model Findings and completion are separate New category needs additional dimensions without erasing either channel
A03 Persistence Reviewable files and local receipts Measured scale/concurrency requires a store migration with compatible projections
A04 Agent boundary Deterministic checks and transitions; agent proposes repairs A model-assisted advisory feature has independent evaluation and cannot grant authority
A05 Exceptions Precise identity, approval and lifecycle instead of broad bypass Valid project cases require richer identity without expanding unintended scope
A06 Architecture discovery Evidence-labelled unknowns and direct declarations Effective model/source graph resolution has controlled execution and tested provenance

These decisions document current intent and constraints, not retroactive approval of missing features. The technical design gives implementation detail, phase dependencies and observable acceptance criteria.

17. Acceptance and unresolved questions

Required acceptance dimensions are native semantic correctness, false-positive and false-negative measurement, fault handling, stable task identity, bounded retries, configuration/suppression changes, input freshness, platform behavior, and actual host delivery. Passing unit tests or having a schema file proves none of these in aggregate.

The dated local baseline is 990 passing tests with 101 ignored. No production false-positive rate, complete native matrix, MSRV matrix, full-platform support or remote CI result is inferred from it.

Open decisions for production include approval-source ownership, practical exception review UX, tool distribution/upgrade ownership, complete cross-platform process isolation, schema retention, private vulnerability reporting, and release packaging. They do not prevent using explicitly scoped local observations, but they do prevent declaring a completed production quality gate.


Document version: 1.2.0 · Created: 2026-09-28 · Updated: 2026-10-04 · Status: ready for review; implementation remains partial.

Source builds now provide native-first edit feedback through hook execute / hook claude post-tool-use: only explicit ordinary files are selected; Python uses Ruff and JS/TS uses module-local ESLint 10. Coherent same-byte native results avoid duplicate parsing. Uncovered files may use pinned WASM candidates; mixed scopes retain native results, unwired native scopes and failures. Recovery nodes require native-tool setup/repair and confirmation; complete zero-recovery candidates only recommend native lint, never full acceptance. One deadline bounds at most eight files and two WASM workers; builds without WASM report that gap. The outer feedback is 0.7.0 with local hook_fast_feedback 0.2.0. Candidate task synchronization is connected; default plugin Hooks, capability-matched closure and real-host acceptance remain incomplete. See edit-feedback acceptance.

Source edit feedback now imports recovery-bearing pinned WASM candidates into the existing .codeguard/ workbench. Confirmation identities remain stable per workspace/file/language; Python and JS/TS reuse existing confirmation/preparation identities. Reports bind the grammar, source SHA-256, known limitations and suspected byte positions; imports reject mismatched identities/coordinates and duplicate JSON keys. Task IDs appear only after successful synchronization. Complete zero-recovery observations create no new mandatory task; unlocated incomplete scans create check-recovery tasks. Neither closes existing tasks. Dialogue includes task show / task verify; missing native confirmation adapters report an explicit capability gap. Outer Hook feedback is 0.7.0, local feedback is 0.2.0, and generic next briefs use 0.3.0 while existing checkers retain 0.1.0. Default plugin Hooks, capability-matched closure and actual-host acceptance remain incomplete.

Native verification of a Zig confirmation task

Source builds can now verify a persisted Zig WASM confirmation task with codeguard task verify TASK_ID . --zig-tool /absolute/path/to/zig --format=json. The same explicit tool option is accepted by hook execute for repair_ready, using the existing lease and finished-attempt binding. lint zig can run the native tool without building the optional WASM feature; fallback without that feature reports its absence.

The pinned Zig 0.16.0 probe runs version and ast-check --color off against the exact source bytes under one deadline. A current native diagnostic changes the brief to source repair; missing tools, unsupported versions and execution failures retain environment/decision guidance. Fresh next briefs carry the unchanged tool path in their recheck argv. Changes to source or tool bytes invalidate old diagnostic guidance. Reports and attempts are retained under the existing workbench instead of a second task store.

The native observation is syntax_task_recheck 0.1.0, wrapped by task_verification_preview 0.12.0. Generic repair briefs are 0.3.0; old 0.2.0 briefs and 0.11.0 verification schemas remain available unchanged. Zero native AST diagnostics are candidate_absent_unverified_policy: they end the pending local verification step, but do not close the task or certify project lint, build or delivery. Erlang now has the same workbench integration through explicit OTP 28; Erlang task acceptance records its separate protocol versions. Swift also supports explicit Apple Swift 6.4 parse rechecks; see Swift acceptance. Generic confirmation adapters beyond Zig/Erlang/Swift remain absent. See the acceptance record.

Briefs also expose the latest native report reference/digest and current diagnostic positions; stale inputs suppress those positions. Only immutable grammars compiled into the binary reuse validated asset identities within a process; external manifests, source and native tools still require current-byte checks.

Verified closure and recurrence for one task (source SDK)

The source exposes verify_zig_task_resolution for a protected host to verify a Zig native syntax-confirmation task. The host independently pins its verification key, workspace, policy revision, code baseline, trusted time and rollback floor, and supplies the hash-bound original counterexample. Project-selected keys, policy candidates and task Markdown cannot provide that authority. The default plugin and public CLI still lack a trusted policy provider; this API is absent from published npm 0.1.3.

Under the existing task lease, the handler runs the same approved Zig 0.16.0 against the original bytes and current file. Both runs share the request deadline, capped by approval expiry. A code_fixed event requires original native diagnostics, changed current source with no diagnostics, and matching tool, host artifact, grammar, task and policy identities. A native-clean original becomes a false-positive investigation; environment failure or changing input requires verification. This proves syntax for the specified task, not full lint, types, security or CVE coverage.

Events replay through explicit parent links. Repeating the same verified result preserves its existing event. Ordinary task verify can append reopened when matching native diagnostics recur on current input, retaining the original fact and repair history and restoring native repair guidance. Missing parents, forks, duplicate identities, absent evidence or changed hashes require reconciliation. The handler also writes the existing native attempt receipt, clears matching awaiting_verification, and preserves a borrowed lease.

Sanitized events live in .codeguard/findings/<id>/events/lifecycle-*.json; comparison evidence is ignored under .codeguard/state/resolution_evidence/. The first finding.json is immutable. Local next/task show/status have no trusted policy context and cannot elevate historical claims into current closure or delivery approval. All host receipts retain delivery_decision=not_evaluated.

Other checker closures, environment/dependency/target/policy dispositions, actual host trust providers, cross-machine evidence recovery and the delivery gate remain open. See task lifecycle acceptance.

flowchart TD
    A[Protected host pins policy and trust context] --> B[Verify signature and original task identity]
    B --> C[Acquire or borrow existing lease]
    C --> D[Same Zig checks original counterexample]
    D --> E[Check current bytes and revalidate identities]
    E --> F{Native result and input}
    F -->|Original invalid and current repaired| G[Append resolution evidence and parent event]
    F -->|Original also native-clean| H[False-positive investigation]
    F -->|Tool failed or input changed| I[Preserve failed observation]
    G --> J[Ordinary task verify native recheck]
    J -->|Issue recurs| K[Reopen same task with history]
    G --> L[Independent complete delivery check]
    K --> J
Loading

Current public candidate: 0.1.4

@partme.ai/codeguard@0.1.4 is published for Apple Silicon macOS from clean source 1cd458f6e01a44a74388243e964e3f45290ac18e. It includes all 32 runnable, unqualified grammars, bounded edited-file checks, stable native-confirmation tasks, native rechecks and next guidance. Registry hashes, a fresh-cache npx invocation, the actual public-package repair loop with Zig 0.16.0, and the source commit's Linux CI passed. Ordinary CLI clean output cannot close a task without trusted policy. The protected Zig SDK is a source integration API; npm does not expose a self-approval command. Plugin activation, installed-host acceptance, full precision, other platforms and complete gates remain open. Earlier 0.1.3 evidence is historical. See 0.1.4 acceptance.

Erlang confirmation tasks and native repair guidance (current source)

codeguard task verify TASK_ID . --erl-tool /absolute/path/to/erl --format=json and the repair_ready event of hook execute . --erl-tool /absolute/path/to/erl now reuse the existing .codeguard/ task, lease, finished attempt and shared deadline. They call the same OTP 28 forms parser as lint erlang. Task language and tool options are checked before acquiring a lease or launching a tool; project source, macro expansion and parse transforms are not executed.

flowchart LR
    A[Suspected edited syntax] --> B[Stable workspace/file/language task]
    B --> C[task verify / repair_ready]
    C --> D[Explicit native OTP 28 parser]
    D -->|Current diagnostics| E[next positions and repair argv]
    E --> F[Repair and record attempt]
    F --> C
    D -->|Preprocessing or tool fault| G[next concrete blocking reason]
    G --> H[Restore project context or matched tool]
    H --> C
    D -->|Zero diagnostics| I[Retain evidence pending closure verification]
Loading

Erlang observations use syntax_task_recheck 0.2.0, verification feedback 0.13.0 and post-verification next briefs 0.4.0. Zig and historical schemas remain unchanged. native_confirmation_reason identifies missing tools or preprocessing gaps; guidance names OTP 28 preparation or project-native preprocessing/compilation. Source changes invalidate diagnostic guidance; changed tools lose their stored argv. Only a byte-current tool already observed as OTP 28 can be reused as ready.

Zero diagnostics remain candidate_absent_unverified_policy: they consume the linked pending verification, but cannot close the task or approve delivery. Two no-progress attempts use the existing decision budget. The protected closure API now includes a task-scoped Erlang source SDK; full Erlang project lint/preprocessing, native-finding lifecycle, automatic tool discovery and installed-host releases remain open. Public npm 0.1.4 does not include this extension. Acceptance and protocols.

Erlang repair_ready feedback uses Hook 0.8.0 / local summary 0.2.0 to include current native positions, the concrete unresolved reason, Unicode scalar column units and an existing report reference. Other Hook versions remain unchanged; installed-host delivery is not certified.

Aggregate Erlang native-first checking (current source)

codeguard check all . --format=json
codeguard check all . --erl-tool /absolute/path/to/erl --timeout 30s --jobs 2 --format=json

The erlang.lint task selects explicit Erlang or the first executable erl from absolute PATH directories, then uses the existing controlled OTP 28 scanner/parser. It observes at most 64 ordinary UTF-8 files, each at most 1 MiB, under the request deadline and scheduler concurrency. native_results.erlang_lint carries current source hashes, positions, tool selection, per-file next actions and original-tool recheck argv with an absolute source path, reusable outside the project directory. Files beyond the native budget are counted as unobserved.

Only complete, non-preprocessed forms observations for matching source and tool bytes skip duplicate WASM. Missing tools retain candidate observations; selected-tool failures stay visible alongside any supplementary candidate observation. Macro/preprocessor coverage remains unresolved. Source or tool changes withdraw affected positions and reusable argv. Project-scope changes set scope_stable: false and retain still-current single-file diagnostics; whole-scope completeness is withdrawn. SIGINT remains exit 130; JSON, human and conservative SARIF retain native findings without claiming project success.

Initialized workspaces now persist native-first observations directly, without a preceding WASM error: current check_feedback 0.38.0 embeds scan 0.2.0 with actual per-file task_id or task_sync_reason. lint erlang FILE binds the nearest existing workbench and emits 0.3.0. Repeated scans and historical WASM evidence reuse one task; missing tools and preprocessing produce environment tasks. Unbound aggregate checks also use 0.38.0 and historical protocols remain available; check_aborted remains 0.13.0, and prior schema bytes are unchanged. Default-host trusted closure and complete project checks remain open; the source SDK extension is described below. Public npm 0.1.4 does not contain this batch. See native repair workflow and acceptance.

flowchart TD
    A[check all: Erlang files] --> B{Explicit tool or PATH erl}
    B -->|Available| C[OTP 28 version and tool identity]
    C --> D[Bounded per-file forms parsing]
    D --> E{Current and complete without preprocessing?}
    E -->|Yes| F[Retain native diagnostics and recheck argv]
    F --> G[Skip duplicate WASM for matching bytes]
    E -->|No| H[Retain native blockers and any candidate observation]
    B -->|Absent| H
    G --> I[Project lint/build/tests remain incomplete]
    H --> I
    I --> J[Human / JSON / conservative SARIF]
Loading

All-grammar development evaluation boundary (2026-10-04)

The evaluate_grammars development entry reuses the same isolated Rust workers and Core statistics across all 32 grammars and 358 fixed cases. Protocol 0.2 separates repository, Dart upstream and provisional expectations into 35 language×source cohorts; mixed-source summaries sum counts without pooling precision. The Rust importer preserves source bytes, upstream expectations and origins; legacy 0.1 corpora/reports remain unchanged. Manifest/source/program identities, unknowns and pending labels remain explicit. This provides neither a project quality gate nor independent holdout evidence. See unified grammar evaluation.

P3C single-file application service

Native file lint and aggregate checks share P3C persistence/synchronization, stable finding identity and original-tool verification. File lint reads ancestor POMs and limits execution to one selected source. See workflow. Full effective-model coverage and trusted closure remain pending.

Findings and execution completeness remain independent through native parsing, project projection, sync and verification. A validated P3C diagnostic survives abnormal termination as a stable finding; the failed file contributes zero completed observations and retains its execution blocker. Empty, invalid, out-of-scope or changed-input reports cannot establish absence. See partial-execution acceptance.

Erlang task resolution and recurrence (current source SDK)

verify_erlang_task_resolution reuses Zig's signed-policy verification, shared deadline, lease, attempt handoff and append-only parent chain. The protected host independently fixes the trust root, workspace, policy revision, baseline and trusted clock; project files cannot grant approval. OTP 28 scans/parses the original counterexample and current bytes separately. Only an original native diagnostic, changed source and a complete clean current result can record code_fixed. Macros/includes, empty forms, truncation and execution failures require verification; an originally valid sample requires false-positive investigation.

Both WASM-first and native-first tasks are supported. Erlang policy 1.1.0/evidence 0.2.0 stay separate from Zig 1.0.0/0.1.0. Native-first evidence requires grammar_sha256=null and the original tool identity. The internal rule identity uses the actual approved policy-byte digest instead of inventing a grammar digest. History checks bind the language, source and grammar to the first report; rehashing local files cannot switch languages. Ordinary task verify --erl-tool can append recurrence with the matching tool, but cannot close a task without trusted policy.

This remains a source SDK without the default plugin's trusted policy provider. Public npm 0.1.4 lacks this extension; syntax receipts do not certify complete lint, security or project delivery. The tool digest binds the launcher; the host must independently protect the OTP environment. See Erlang lifecycle acceptance for the execution path and actual results.

Cargo input and proxy boundaries (current source)

Normal Clippy scans and same-rule --force-warn comparisons use cargo clippy --locked --offline --all-targets --message-format=json. A missing root Cargo.lock returns cargo_lock_unavailable before native startup and does not create a lock. Source fingerprints come from a bounded pre-run snapshot. Changes to observed sources, the manifest, lock, root Clippy/Cargo/toolchain configuration or selected tool withdraw the current Clippy findings and retain preparation/recheck work. Valid partial diagnostics under stable inputs remain visible without claiming a complete report.

For Cargo proxies such as rustup that dispatch by entry-point name, Clippy, rustdoc and build checks execute the selected Cargo path while validating the resolved bytes and post-run target identity. A separate sequence prevents private Clippy directories from colliding at identical timestamps. This protects observed inputs only; it does not prove the complete effective Cargo model, every build combination or a process sandbox. Local zero diagnostics still cannot close tasks automatically. Tests, failures and actual output are in the Cargo input acceptance record. Public npm 0.1.4 does not include this batch.

After native aggregation, current source uses non-cached Clippy compiler-artifact records, the original root-manifest identity and pre-run source hashes to avoid duplicate WASM for byte-matching Rust target entry points. Coverage stays in the current process and cannot be restored from editable reports. Failures, changed inputs/tools, duplicate JSON keys or events after the finish record grant no coverage. all-targets does not establish that the entire directory was parsed: unproven modules and conditionally excluded files retain prechecks. Native warnings, stable tasks and complete delivery obligations remain. Diagnostics repeated across library/test targets at the same file/rule/line/column project one finding, preferring error over warning; distinct positions remain separate and historical duplicate tasks are not automatically closed. See Rust native-first acceptance. Public npm 0.1.4 does not include this batch.

Existing Cargo discovery (current source)

check all, comments rust, build rust and their Cargo task rechecks accept an optional --cargo-tool. Without it, they select the first regular executable cargo in an absolute invoking-PATH directory. Empty/relative directories and non-executable entries are skipped. An explicit invalid tool or selected native failure remains a concrete blocker; it never triggers a search for another Cargo. Aggregate Rust checks share the selected entry.

The final cargo entry name is retained for rustup proxy dispatch; resolved bytes and target identity still undergo the existing checks. The child inherits RUSTUP_TOOLCHAIN and always receives RUSTUP_AUTO_INSTALL=0, even if the caller set it to 1. Cargo --locked --offline alone does not prevent rustup from installing a missing toolchain; rustup documents the separate control. A missing toolchain stays an environment failure, without a source violation or automatic installation. This does not qualify the entire toolchain, effective Cargo configuration, complete project coverage or trusted task closure.

Controlled proxy/no-fallback cases and actual installed/missing-toolchain observations are recorded in Cargo discovery acceptance. Public npm 0.1.4 does not include this source change.

Project-root Ruff discovery (current source)

For a configured Python scan, lint python, check all, selected-edit Hook execution and same-root task rechecks select an explicit --ruff-tool first, then the checked root's .venv/bin/ruff, then an executable in an absolute invoking-PATH directory. They do not activate a shell environment, enumerate installed packages or install Ruff. A root-local entry is version-probed and byte-bound through the existing native scan. Missing local directories/entry permit PATH discovery; linked/non-directory parents, broken or non-executable entries produce ruff_local_tool_invalid instead of silently switching to global Ruff. A chosen tool's version/execution failure never tries a different tool.

An invalid local environment projects one stable preparation task with .venv/bin/ruff evidence, bounded environment repair, original Codeguard recheck, history and closure conditions. No applicable Ruff configuration means no tool startup. Ordinary local parents may contain an executable symlink: the resolved tool bytes are fixed and rechecked. Local success and repaired-source zero diagnostics still do not approve policy or close tasks automatically. This selection concerns the explicitly checked root; per-module virtual environments, uv/Poetry/Conda resolution, real host integration and complete coverage remain separate work. See root-local Ruff acceptance. Public npm 0.1.4 does not include this source change.

Recovery tasks for unlocated syntax observations (current source)

check all/java and confirmed-write Hooks share syntax-task synchronization. Visible recovery nodes require native confirmation. A tree error with an incomplete recovery scan and no locatable nodes creates a check-capability recovery task: it retains an empty recovery array and syntax_recovery_incomplete, without a confirmed source violation or invented edit position. Complete zero-recovery observations recommend native checking without creating this task.

The workspace/file/language identity remains stable across repeat checks, Hooks and later visible recoveries. next and task Markdown require restoring the checker, language version or grammar; source edits are forbidden before native confirmation. task verify records a missing native adapter while retaining the open task. Zero recoveries, installation and checkbox edits cannot close existing tasks. Persistence failures retain observations and per-file reasons without fabricated task IDs.

Aggregate feedback uses check_feedback 0.38.0 with syntax_tasks; unlocated local confirmation reports use 0.3.0. Existing located 0.1.0 and native-first Erlang 0.2.0 reports and their schemas remain unchanged. Claude Hook command replay distinguishes recovery-node counts from incomplete recovery scans; actual-host and full-language acceptance remain open. Public npm 0.1.4 does not contain this batch. See acceptance and actual reports.

flowchart TD
    A[Native checks then fixed WASM observation] --> B{Recovery scan}
    B -->|Visible nodes| C[Native confirmation task]
    B -->|Incomplete and no positions| D[Check capability recovery task]
    B -->|Complete and zero nodes| E[Recommend native checking]
    C --> F[Stable identity and evidence history]
    D --> F
    F --> G[next / task show / conversation guidance]
    G --> H[Original native task verification]
    H -->|Adapter or environment unavailable| I[Keep open and record the exact gap]
    H -->|Local zero diagnostics| J[Retain policy and coverage verification]
Loading

Automatic native Erlang discovery for task rechecks (current source)

codeguard task verify "$TASK_ID" . --format=json (with TASK_ID set to the actual task_id returned by next) reuses lint/check selection for existing Erlang syntax tasks: explicit --erl-tool takes priority; otherwise the first executable erl in an absolute invoking-PATH directory is fixed. Rechecks verify OTP 28, current source and tool bytes while retaining leases, budgets, events and existing report versions. Both candidate-origin and native-first tasks can be rechecked; repair-ready Hooks use the same entry.

Only an absent tool produces erlang_tool_not_found_on_path; empty/relative PATH entries and non-executable files are ignored. An invalid explicit tool, unsupported selected version or execution failure never selects a later tool or installs one. After a valid observation, next supplies explicit recheck argv for the actual tool so later PATH changes cannot replace that entry. Local zero diagnostics still do not close tasks automatically; preprocessing, trusted policy and complete project capability remain separate obligations. See recheck discovery acceptance. Public npm 0.1.4 does not contain this batch.

Native confirmation of unlocated Swift observations (current source)

An existing Swift confirmation task now accepts codeguard task verify "$TASK_ID" . --swift-tool /absolute/path/to/swiftc --format=json, where TASK_ID comes from actual next output. hook execute accepts the same option for repair_ready. The caller supplies an installed Apple Swift 6.4 compiler; this path does not install tools or execute editable paths from historical reports. Missing tools receive an existing-compiler recovery action; unsupported versions and execution failures retain the task.

Rust reads and rechecks bounded source bytes, then runs swiftc -frontend -parse -diagnostic-style llvm -no-color-diagnostics - with frozen stdin, / as cwd, a cleared environment and the shared deadline. Only native error rules and positions enter agent guidance; raw diagnostic text is not treated as an instruction. Columns are UTF-8 bytes and must fall on character boundaries. Unknown output, exit/diagnostic contradictions, timeout, invalid positions and tool changes remain incomplete. The tool digest binds the launcher, not the entire Swift installation.

Native errors make the same task actionable for source repair. Source or tool changes withdraw old positions. A clean parse records candidate_absent_unverified_policy without automatically closing the task or satisfying project lint, type checking, macro/conditional-compilation context, build, security or delivery obligations. Existing no-progress budgets still apply. Swift grammar qualification and the 32-language precision conclusions are unchanged; public npm 0.1.4 does not contain this extension.

New protocols are syntax_task_recheck 0.4.0, task_verification_preview 0.15.0, repair_brief_preview 0.6.0 and Hook feedback 0.9.0 (task summary 0.3.0). Aggregate check uses 0.39.0 when next contains a native Swift brief; other paths retain 0.38.0. Historical schemas remain unchanged. See Swift native-confirmation acceptance for actual reports and limits.

flowchart LR
    A[Swift WASM recovery task] --> B[task verify / repair_ready]
    B --> C{Apple Swift 6.4 available?}
    C -->|No| D[Restore checker environment]
    C -->|Yes| E[Frozen stdin frontend parse]
    E -->|Errors with valid byte positions| F[Same task: repair source]
    F --> B
    E -->|No diagnostics| G[Retain evidence: verify policy and coverage]
    E -->|Timeout or invalid output| D
    G --> H[Project lint / type check / build / delivery]
Loading

Actual Claude lifecycle acceptance and fresh-task guidance

Claude Code 2.1.273 now has actual session-local plugin-source evidence for confirmed saves, repeated saves, an execution-time filesystem write failure, native Zig 0.16.0 rechecks before/after repair, stable task identity and one Stop continuation followed by a reentry guard. The locked public runtime remains 0.1.4, independently of current development source. Native diagnostics changed from one to zero; the task stayed open and delivery remained not evaluated. Edit argument validation failed before execution and produced no failure Hook in this host; the separate EACCES write exercised PostToolUseFailure. This is not marketplace installation, trusted closure, complete native-first coverage or multi-host acceptance. See actual host evidence.

The actual session exposed incorrect first-task guidance claiming the Zig adapter was unavailable although its native recheck worked. Development next / task show now distinguish implemented Zig 0.16.0, OTP 28 and Apple Swift 6.4 adapters from unverified local tool readiness, using the bound original report and explicit tool arguments. Read-only guidance does not execute or install a checker, trust executable paths in editable task records, authorize source repair before native confirmation, or close a task. Unsupported languages retain a concrete capability decision; existing native history keeps precedence. This correction is not in the locked public 0.1.4.

Fresh native-confirmation guidance uses repair-brief-preview 0.7.0 to bind the language, supported tool version, tool-selection option, and tool_readiness: not_evaluated. Aggregate checks use check-feedback 0.40.0; task show preserves the same recheck arguments in its outer action. The agent must replace the placeholder with a verified installed tool path. Preparation does not establish readiness or native execution. Historical schema definitions remain unchanged.

Native-first Kotlin single-file checking (development source)

codeguard lint kotlin FILE.kt [--kotlinc-tool ABS_PATH] [--timeout 30s] --format=json selects an explicit tool first, otherwise the first kotlinc in absolute invoking PATH entries. The current adapter supports Kotlin/JVM 2.4.10. Only an absent tool uses bundled WASM; a selected native failure remains visible. Frozen ordinary .kt files are compiled privately, without .kts, project build scripts or compiler plugins.

Only [SYNTAX] becomes kotlin.syntax; other diagnostics retain project-context limitations. Verified UTF-16 columns are also mapped to UTF-8 byte columns. Unknown output, redirected launchers, changed input and interrupted budgets cannot produce success. Missing backends or incomplete native checks require further native confirmation; an observable, complete zero-recovery WASM scan recommends native installation without granting project approval. The feedback schema is kotlin-lint-feedback 0.1.0.

Existing stable tasks now support task verify and repair_ready; aggregate feedback projects their current guidance. Initial check/file_changed now selects Kotlin native compilation first and synchronizes stable tasks. Complete Kotlin lint/comments, compiler JAR/JDK identity, version coverage and release acceptance remain open. Public npm 0.1.4 excludes this increment. See single-file acceptance.

Kotlin stable-task rechecks and agent feedback (development source)

Existing Kotlin WASM confirmation tasks support codeguard task verify TASK_ID . --kotlinc-tool ABS_PATH --format=json; omission reuses the standalone PATH selection. repair_ready through hook execute --kotlinc-tool ABS_PATH retains the task, lease and attempt history. next and task show derive tool guidance from bound facts rather than executing editable task Markdown.

Mixed native syntax and project-context diagnostics retain current syntax positions for repair while exposing unresolved context. Source or tool changes withdraw old positions. Native zero diagnostics advances to policy/coverage verification without repeated editing or installation. Rechecks do not automatically close tasks; Kotlin trusted closure remains unwired. Aggregate check feedback carries the current brief; initial check/file_changed now invokes the Kotlin native adapter for ordinary .kt files.

Protocols are syntax recheck0.5.0, task preview0.16.0, historical brief0.8.0, initial preparation brief0.9.0, Hook feedback0.10.0 and aggregate feedback0.41.0. Previous schema bytes remain unchanged. See Kotlin task-recheck acceptance.

Kotlin first native observation (development source)

check all . --kotlinc-tool ABS_PATH and confirmed file_changed accept the same explicit tool; omission discovers invoking PATH. A selected native failure stays visible and does not switch to WASM. Only an absent compiler uses the existing candidate fallback. At most 64 ordinary .kt files share the request deadline; .kts is not compiled by this path. Repeated observations update one stable task, and native zero diagnostics does not automatically close it.

New reports use aggregate0.42.0, file-changed Hook0.11.0, scan0.1/0.2, native origin0.4.0, native-origin recheck0.6.0/task preview0.17.0 and first-native brief0.10.0. Existing WASM-origin rechecks retain their previous protocols. See first-native acceptance. Full project lint, compiler/JDK identity, trusted closure and public release remain open.

When the bound first report contains incomplete, unlocated recovery, later missing-tool or stale native history preserves the limitation in next / task show: do not edit source before native confirmation, and follow the concrete environment recovery steps. Current native syntax diagnostics remain actionable; current zero diagnostics still require policy and coverage verification. See native-history guidance regression.

Native-first Swift single-file feedback (development source)

codeguard lint swift FILE.swift [--swift-tool ABS_PATH] [--timeout 30s] --format=json selects an explicit compiler first, otherwise the first executable swiftc in absolute invoking PATH entries. The current adapter supports Apple Swift 6.4 frontend parsing of frozen stdin. Only tool absence enables the bundled WASM candidate; a selected compiler's failure stays visible. Verified positions use UTF-8 byte columns. Source changes or entry redirection withdraw diagnostics, and timeout/cancellation remain incomplete/cancelled rather than source violations.

The swift-lint-feedback0.1.0 report distinguishes a required native confirmation for incomplete or hidden recovery from a recommendation after complete zero recovery. It never grants full lint or delivery approval: SwiftLint, comments, type checking, dependencies/security and project builds remain obligations. Compiler identity covers the selected entry, not the entire toolchain. Project-wide Swift native observation is now connected as described below; full language/release qualification remains open; initialized-workspace task connection is described below. Public npm0.1.4 excludes this increment. See single-file acceptance.

Swift project native observation (development source)

check all . [--swift-tool ABS_PATH] --format=json parses at most 64 ordinary Swift files under one shared deadline and reports unobserved files. Selected native failure never changes into a WASM result; only tool absence keeps candidate fallback. check-feedback0.43.0 / swift-parse-scan0.1.0 preserve current byte locations, selection and recheck argv. Source/tool changes withdraw positions; zero diagnostics do not prove SwiftLint, types or builds. This historical protocol describes an uninitialized workspace with not_connected task references; initialized-workspace task connection is described below. See project observation acceptance.

Confirmed saves through hook execute . --swift-tool ABS_PATH reuse the Swift scanner for selected paths only. Missing tools keep candidates; selected failures do not switch. hook-execution-feedback0.12.0 / hook_fast_feedback0.4.0 expose current native positions and the unconnected task state. The CLI Claude adapter emits bounded counts/byte positions without tool diagnostic text; mixed candidate errors still require native confirmation. Actual installed-host acceptance, stable native tasks and the full repair loop remain open. See save feedback acceptance.

Swift native-first repair workbench (development source)

In an initialized .codeguard/ workspace, check all and a confirmed successful-save hook execute file_changed synchronize Swift native syntax findings or environment blockers into stable tasks. Repeated observations reuse the same task. next and task show expose evidence, rule basis, allowed scope, repair steps, recheck commands, history and closure conditions. An uninitialized workspace reports a disconnected workbench; synchronization failures remain blockers. Standalone lint swift does not create tasks yet.

codeguard task verify TASK_ID . [--swift-tool ABS_PATH] --format=json selects an explicit tool or discovers one in the invoking PATH for native-first tasks. Existing WASM-origin tasks retain their explicit-tool contract; editable historical paths are not executed. Diagnostics request source repair. Zero diagnostics records candidate_absent_unverified_policy; the same task stays open pending full lint, type, build and delivery checks.

Native-first protocols use observation 0.5, scan 0.2, check 0.44, initial brief 0.11, save Hook fast 0.5 / outer 0.13, and recheck inner 0.7 / outer 0.18. Existing verification briefs retain 0.6, and historical schemas remain unchanged. Actual Apple Swift 6.4 executions verified stable task references across repeated scans, saves and rechecks before and after repair. This is not installed-host or trusted-closure acceptance and is excluded from public npm 0.1.4.

Recover missing task projections

codeguard work sync . --format=json now restores missing Markdown for committed facts under the workspace sync lock, imports new reports, and rechecks missing projections. Recovery reads structured facts, the current RepairBrief, original report hashes and consumption markers. It does not run checkers. Existing regular task files, including notes and checkmarks, retain their exact bytes. Symlinks, directory conflicts, invalid facts, changed origin hashes and uncommitted origins remain incomplete. Recovery examines at most 1,000 facts.

The readable task contains evidence, rule basis, allowed scope, steps, recheck argv, history and closure conditions. Local absolute paths in recheck arguments become verification placeholders; use task show for current instructions. Recovery never closes findings, changes original facts/events/consumption markers or attempt history, or grants delivery approval. Reports use work_sync_preview 0.3.0 with a positive restored_task_projections count only when recovery occurs; other runs retain 0.2.0.

flowchart LR
 A[work sync workspace lock] --> B[Validate committed facts and origins]
 B --> C[Recover missing projections and keep existing notes]
 C --> D[Import new reports]
 D --> E[Check remaining missing projections]
 E --> F[task show / next current repair guidance]
 F --> G[Native recheck with closure still requiring acceptance]
Loading

Next steps for independent source findings

When the first source finding is waiting for its owner or has exhausted its retry budget, and no prerequisite blocker exists, next can select another actionable or verification-required finding on a proven independent physical source. next_actions and human output retain read-only task show references for deferred findings. Their facts, budgets, leases and gate effects remain unchanged. Overlapping targets, aliases, unknown scope, invalid facts and failed reports retain conservative handling. The complete module dependency graph remains incomplete; non-Unix keeps the original selection. See the actual acceptance evidence and full report example.

Scoped Swift syntax task lifecycle (development source)

A protected host can call verify_swift_task_resolution to compare the original counterexample and current source with Apple Swift 6.4. Policy 1.2.0 and evidence 0.3.0 remain separate from Zig/Erlang protocols; native-first tasks retain a null grammar identity. An original parse diagnostic, changed source, and a complete clean recheck with the same tool permit a scoped code_fixed event. Repeated verification is idempotent; an ordinary task verify --swift-tool recheck reopens the same parent chain on recurrence. A valid original sample requires false-positive review; tool failures or identity changes cannot close the task. The host supplies independent trust and signatures. Default plugin integration and public distribution remain incomplete, as do SwiftLint, type checking, project builds, and full delivery acceptance. See lifecycle acceptance.

Scoped Kotlin resolution and context blockers (development source)

verify_kotlin_task_resolution reuses the host SDK with kotlinc-jvm 2.4.10. Policy 1.3.0 and evidence 0.4.0 are language-specific; native-first tasks keep a null grammar identity. The original diagnostic must have coherent UTF-16 and UTF-8 coordinates. Changed source and a complete clean recheck permit a scoped code_fixed event. Context-only errors remain pending verification. Mixed syntax and context errors retain the known finding and allow ordinary task verify --kotlinc-tool recurrence to reopen the same parent chain even when completion is incomplete. The host supplies independent trust. Tool identity currently covers the launcher, with full JAR/JDK/project identity, default plugin closure, lint/type coverage, and publication still pending. See acceptance.

Development-source Zig native routing (2026-10-05): check all, check zig and selected-file editing now reuse the frozen Zig 0.16.0 AST probe. Explicit/PATH selection runs native first; selected-tool failures retain an incomplete observation without switching to WASM. Missing tools retain candidate fallback. Source or tool-entry changes withdraw old positions; at most 64 files are observed under the shared deadline, with remaining scope visible. Check feedback 0.46, aborted feedback 0.15 and Hook feedback 0.14 are separate protocols; reports without Zig keep previous versions. Claude feedback includes bounded native rule IDs, positions and the original recheck instruction. First-native Zig task creation is now connected as described below: native reports expose only actually synchronized task IDs, and clean AST observations do not close historical tasks or prove complete lint/build. Public npm 0.1.4 and the plugin lock are unchanged.

flowchart TD
    A[check all / check zig / confirmed edit] --> B{Explicit or PATH Zig selected?}
    B -->|Yes| C[Frozen native ast-check]
    B -->|No| D[Candidate WASM and setup guidance]
    C --> E{Current input and successful observation?}
    E -->|No| F[Keep incomplete; withdraw stale positions]
    E -->|Native diagnostics| G[Repair current source and recheck original tool]
    E -->|Zero diagnostics| H[Continue project lint and build]
    G --> I[Native-first task connection still pending]
Loading

Native-first Zig tasks (development source)

In initialized workspaces, check zig, check all, lint zig and edit Hooks synchronize one stable task per workspace/source scope. A newly clean file creates no repair task. Clean rechecks of existing tasks record candidate_absent_unverified_policy and retain the open task. next and task show expose bounded native positions and original-tool arguments; task verify TASK_ID . [--zig-tool ABS_PATH] --format=json and repair_ready record native rechecks. Native-first grammar identity is null; native diagnostics must not request grammar edits.

New protocols: observation 0.6, bound scan 0.2, aggregate 0.47, single-file 0.3, brief 0.12, task-show 0.2, recheck inner 0.8/outer 0.19, edit Hook 0.16 and recheck Hook 0.15. Historical schemas remain unchanged. Actual Zig 0.16.0 validated broken and repaired inputs. Trusted SDK closure for native-first Zig tasks is described below. Default installed-host integration, full lint/build and distribution remain incomplete. Public npm 0.1.4 is unchanged. See acceptance.

Trusted native-first Zig resolution (development SDK)

A protected host can call verify_zig_task_resolution with independently signed policy 1.4.0 for native-first observation 0.6.0. Grammar must be null; legacy WASM-origin policy 1.0.0 retains its scope. An original same-tool diagnostic, changed source and a complete clean same-tool recheck permit scoped code_fixed with evidence 0.5.0. Repeated verification is idempotent; ordinary task verify --zig-tool positive recurrence reopens the same parent chain. Valid original samples require false-positive review. Unexpected output, invalid positions, changed tools or missing trusted context cannot close the task. The host independently supplies trust. Default plugin/public npm integration of that provider remains incomplete; local task records do not authorize delivery. See acceptance.

Explicit native differential development replay

The Rust evaluate_native_grammars example selects samples for explicitly supplied Zig0.16.0, OTP28, Apple Swift6.4 and kotlinc-jvm2.4.10 from the same frozen 32-language corpus. It reuses native adapters and the existing WASM worker. All 32 languages remain in inventory; unselected tools, missing adapters, incomplete native observations and hidden WASM recovery stay unresolved. TP/FP/FN/TN include only jointly decidable syntax samples. Located Kotlin syntax diagnostics survive mixed context blockers while execution remains incomplete. Changed tools/entries or program bytes withdraw classifications. Reports remain incomplete with zero qualified grammars and create no tasks or whitelist approvals. Reused adapters, regression samples and entry-artifact hashes do not prove independent holdout or full toolchain identity. See native differential acceptance for commands and actual evidence.

Isolated Python native syntax comparison

Development replay now accepts explicit Ruff0.16.8 with the Python3.12 target. Frozen stdin, --isolated --select E9 --ignore-noqa --no-cache excludes project configuration and ordinary lint. Only consistent located invalid-syntax diagnostics classify syntax errors; F401, wrong paths/positions, changed versions or contradictory reports remain incomplete. Report0.2 preserves historical0.1 bytes and does not expand trusted task-closing authority. The18-case actual replay found two WASM false negatives: an empty function suite and incorrect indentation. Python remains unqualified; see Python native differential acceptance.

Python development differential 0.3 measures raw grammar separately from the parser-plus-structure candidate. Existing comparison and TP/FP/FN/TN stay intact; verified rule identity and source positions, combined_candidate_comparison and a separate denominator are added. Truncation, cancellation and program changes never become clean candidates; native identity changes withdraw both comparisons. Candidates still require native confirmation, historical 0.1/0.2 reports remain unchanged, and neither qualification nor delivery authority expands. See layered acceptance.

JavaScript development differential now uses fixed Node 24.18.0 with isolated --check --input-type=module, a cleared environment, frozen stdin, a shared deadline and entry/artifact checks before and after execution. Report 0.4 records the explicit module goal and only verified source-line locations; unknown output or tool changes remain incomplete. It neither infers project CommonJS/ESM settings nor replaces ESLint. Node has a separate 128 MiB artifact budget; other checker budgets stay at 64 MiB. See JavaScript native acceptance. The actual 18-case module comparison retains 5 TP / 0 FP / 2 FN / 11 TN: top-level return and duplicate bindings remain missed, with 0/32 qualified grammars.

Empty-block structural facts (integration pending)

Rust runtime now provides scan_wasm_empty_blocks, traversing the full tree for blocks with no non-comment named statement and retaining parent kinds, byte positions and exhausted budgets. These facts are distinct from raw ERROR/MISSING and cannot authorize a language violation: a legal empty Rust function also produces a fact. The fixed candidate Python required_suite rule now reaches the private worker, explicit probe and single-file lint/work sync confirmation task through separate versioned recovery and structure fields. Aggregate check now preserves structure evidence and the same task identity through feedback0.48 and generic confirmation0.7; trusted native closure remains incomplete; the two raw Python grammar false negatives remain open. See structure task integration. See structural-fact acceptance.

See aggregate structure acceptance; this does not certify grammar quality or the full delivery gate.

The isolated Python native probe now rechecks the requested entry and frozen bytes after version detection and before syntax execution; changed entries do not trigger a second invocation. It also verifies continuity afterwards. See native-entry acceptance. Trusted Python closure still requires stable task identity, original-report and approved target-version integration; the development py312 probe does not authorize project delivery.

Python candidate confirmation now rechecks only its original single-file scope through the existing project Ruff configuration and native execution chain. Feedback 0.18 and task preview 0.20 bind the consumed first report and current source; neither grants project coverage nor trusted task resolution. Missing or modified original receipts reject execution. See acceptance.

Python native syntax repair feedback (0.19 / 0.21)

Matching invalid-syntax diagnostics in Ruff normal and ignore-noqa runs remain native syntax errors instead of suppression-audit failures. An EOF diagnostic can use the preceding nonempty source as its stable task anchor without changing native coordinates. Single-file confirmation feedback 0.19 and task preview 0.21 distinguish remaining syntax errors as still_present and provide source-repair guidance. A complete recheck without syntax errors only yields candidate_absent_unverified_policy; it cannot close a task. Historical 0.18 reports retain their event semantics, and source or configuration changes withdraw current conclusions. See native syntax feedback acceptance.

Python resolution prerequisites: original source and target version

The read-only host API validate_python_task_original_source(root, task_id, source) checks both first-report families, consumed receipts, frozen bytes and recovery/structure positions. After repair, it still accepts the original bytes and rejects substituting current bytes. The isolated syntax probe can receive an explicit Python target and rejects invalid targets before tool resolution; the existing development differential retains py312. These prerequisites do not provide signed approval, project target provenance or trusted resolution. See acceptance.

Native Ruff lint target observation

RuffSettingsObservation::explicit_python_target() returns only an explicit lint target observed in the pinned Ruff settings. It requires one linter.unresolved_target_version and an empty linter.per_file_target_version; implicit none, missing/duplicate fields, unknown versions and unresolved per-file targets return specific reasons. Formatter/analyze targets are not substitutes. This internal observation shares the native tool/source/configuration checks, leaves the public settings shape unchanged and does not authorize resolution. See acceptance.

Shared event commit for scoped tasks

Native syntax services now separate rechecks from commit_resolution. Before committing, domain evidence must match the redacted native pair for identity, original/current source, tool, adapter, grammar/approved policy and native-pair digest. Language entry points still verify signatures and execute native rechecks. Shared commit logic retains idempotency, policy-change reconciliation, parent-chain conflicts and recurrence, without granting project delivery. This prepares Python integration; Python trusted resolution is not implemented yet. See acceptance.

Scoped Python native syntax resolution (policy 1.5 / evidence 0.6)

The host SDK verify_python_task_resolution binds an independently signed policy to the task, consumed first report, original source, grammar, Ruff artifact, adapter, explicit lint target and project configuration digest. Rust invokes native Ruff against original stdin and the current scoped file. The current scan retains normal/ignore-noqa comparison and effective settings. Closure requires native syntax diagnostics on the original source, changed current source with complete zero syntax diagnostics, and stable inputs and policy bindings. Native counterevidence on the original enters false-positive investigation. Missing tools, unresolved targets, changed configuration and incomplete runs cannot close a task; formatter targets and implicit defaults cannot supply the lint target.

Both first-report families retain one task and append-only lifecycle history. Closed evidence 0.6 leaves historical protocols unchanged. Repeated verification is idempotent; recurrence preserves the previous closure. Ordinary verification may reopen but cannot authorize a new closure using a historical policy. Independent signing fixtures do not certify production host trust integration, project delivery or grammar qualification. See the scoped acceptance record.

Python3.14 template strings provide real native counterevidence: the pinned WASM reports ERROR while Ruff accepts identical bytes under explicit py314 and rejects them under py313. After scoped SDK false-positive review, next now reads the same Python confirmation task lifecycle and guides grammar/version investigation. Current source/configuration invalidation takes precedence over historical counterevidence. This does not approve a whitelist, close the task or rewrite historical corpus statistics. See the native counterevidence acceptance.

Syntax confirmation actions and retry budgets

A Python syntax-confirmation task uses repair-source when its current native observation is still_present and source/configuration bindings remain valid. Missing tools, incomplete observations and stale inputs do not authorize source edits from historical positions. For the same syntax-confirmation task and unchanged input, restore-checker-environment and repair-source share the existing no-progress budget. Switching actions cannot erase failed attempts. Append-only events retain their original action and fingerprint; other task families keep their existing accounting. New inputs and verified progress follow existing reset rules. Exhaustion requires a concrete diagnosis or decision and grants neither closure nor gate acceptance.

Unified scope for TypeScript module sources

detect, check all / check typescript and file_changed hooks now include .mts/.cts and .d.mts/.d.cts in the existing TypeScript scope. They use the pinned TypeScript grammar, never TSX. Complete same-file native ESLint observations retain priority; files in another build root without native context keep independent candidate fallback. Repeated suspected results update the same confirmation task; valid declarations create no new syntax blocker. Edit hooks check only confirmed changed files. Extension recognition does not certify module resolution, type checking, grammar qualification or delivery. See module-extension acceptance.

Explicit R and C++ source suffixes

Project discovery and WASM candidate routing include .R/.r and C++ .C/.cp/.CPP/.c++/.cxx/.hxx, retaining existing suffixes. Case remains significant: .C uses C++, while shared .h gets no speculative C++ grammar route. Missing native tools still produce actual candidate observations and incomplete delivery; suffix coverage does not qualify a grammar or grant acceptance. See suffix acceptance.

Conversation projection of pinned limitations

Candidate reports, independent structural rules and native diagnostics retain distinct provenance. Terminal feedback exposes bounded specific limitations. Claude resolves them from the bundled manifest for observed candidate languages, deduplicates and limits text, and does not use external report messages or source. Summaries reserve the incomplete-qualification and unevaluated-delivery boundary. Known compatibility issues still need native confirmation and do not expand allowlists. See acceptance.

Go whole-file structural candidate lane

Source builds use a language-neutral runtime root-child observation and a Go adapter rule to supplement permissive fragment parsing. The rule is explicitly whole-file, versioned and unqualified. Raw recoveries remain separate; a candidate never authorizes a source violation, guessed package name or task closure.

flowchart LR
    A[Selected Go file] --> B[Existing native Go checks]
    B -->|Uncovered frozen bytes| C[Isolated WASM worker]
    C --> D[Raw ERROR / MISSING]
    C --> E[Bounded root-child facts]
    E --> F[Go whole-file package rule]
    D --> G[Versioned candidate feedback]
    F --> G
    G --> H[One stable confirmation task]
    H --> I[Restore applicable native checking]
    I --> J[Confirm source or environment repair]
    J --> K[Original-tool recheck and closure policy]
Loading

Probe, aggregate checking and save feedback now carry the Go candidate; the Go confirmation-task native recheck now uses an explicit SDK; trusted closure remains pending. Repair instructions preserve source until native confirmation and keep the task open after a zero-candidate rescan. See acceptance.

Go candidate-task rechecks now accept --go-tool /absolute/sdk/bin/go and invoke the pinned SDK companion gofmt -e /dev/stdin on frozen whole-file bytes. Recheck0.9 / task feedback0.22 retain native diagnostics, tool and companion identities, first-report receipts and failed attempts. The repaired source can be observed without invalidating the original candidate history. Native zero diagnostics retain an open task pending approved policy and coverage. See acceptance.

Native-first Go lint with missing-tool candidates

Source-built codeguard lint go . --format json prefers explicit --go-tool, then executable Go from absolute caller PATH entries. Selected tool/version/execution failures remain native failures. When no native tool exists, the built-in WASM produces bounded whole-file recovery and structure candidates. Candidates or incomplete prechecks require a project-appropriate native tool; zero candidates in the completely observed bounded scope only recommend preparation. Native obligations remain incomplete and exit3 is retained. Builds without WASM report that capability gap. Repeated lint/check reuse the confirmation task; adding a package declaration does not close it. Public npm0.1.4 is unchanged. See limited acceptance.

flowchart LR
  A[lint go] --> B{Explicit or absolute PATH Go}
  B -->|Selected| C[Native go vet]
  C --> D[Preserve native report and failures]
  B -->|Absent| E[Bounded whole-file WASM candidates]
  E --> F{Candidates or incomplete scope}
  F -->|Yes| G[Require native preparation and confirmation]
  F -->|No| H[Recommend native preparation]
  G --> I[Stable task and native task verify]
  H --> J[Native obligations remain incomplete]
  I --> J
Loading

Limited Go task resolution by a protected host

The Unix SDK exposes verify_go_task_resolution(&GoTaskResolutionRequest). Independently signed policy1.6.0 binds Go1.23.4, same-SDK gofmt bytes and canonical companion-path digest. Original native diagnostics, current zero diagnostics and stable inputs are all required to close the same task; an ordinary original-tool recheck records recurrence and reopens it. Companion changes, native counterevidence and missing/tampered history cannot close it. Evidence0.7.0 never grants project delivery. The real Go pair was locally verified using a test host trust fixture; default production host integration remains open. See acceptance.

Read-only current-source command support catalogue

codeguard help --format json queries C01–C36 and additional public entries. codeguard help task verify --format json selects an exact command prefix. The command_help0.3 report separates implemented/partial/planned/unavailable_build and executable; executable means an entry exists, not that checking or installation completed. Grammar probe is unavailable without the WASM feature and remains unqualified with it. Unimplemented standalone MCP and other operations are explicitly planned.

codeguard help --format json
codeguard help lint --format json
codeguard task verify --help

Help does not inspect projects or start tools. Exit0 means the query completed, with delivery_decision still not_evaluated. Exact-prefix trailing help is supported; full language/path/tool-argument contextual help and complete parameter generation remain open. See actual reports and acceptance. Public npm0.1.4 does not contain this source increment.

Native-first standalone Rust lint

The current source supports codeguard lint rust . --cargo-tool /absolute/cargo --format json. It reuses the aggregate check's locked/offline all-targets Clippy observation, input validation and workbench synchronization, executing only lint. Initialized workspaces retain one stable task per finding and return the next action. Recheck with codeguard task verify TASK_ID . --cargo-tool /absolute/cargo --format json; zero diagnostics still require rule/policy review and do not automatically close the task.

When no explicit Cargo is selected and no executable is found on absolute PATH entries, WASM builds provide bounded candidate prechecks. Candidates or incomplete observations require native tool preparation; zero candidates across the complete bounded scope recommend it. Explicit tool errors or native failures do not trigger fallback or installation. The JSON protocol is rust_lint_feedback 0.1 with delivery unevaluated; help 0.2 adds Rust while preserving historical 0.1 schemas. Source integration does not imply public npm availability or complete Rust qualification.

Ruby single-file native syntax and task rechecks

Source builds add codeguard lint ruby FILE.rb --ruby-tool /absolute/path/to/ruby --format=json. This only observes fixed Ruby2.6.10p210 ruby -c with gems disabled and frozen UTF-8 stdin; user source is never executed. Explicit tool failures and unsupported versions do not trigger WASM fallback. Missing native selection uses candidate prechecks in WASM builds; candidates/incomplete checks require native preparation, while zero candidates recommend it. The ruby_lint_feedback0.1 report preserves native line numbers without fabricated columns, leaves project-version compatibility unverified and requires RuboCop, documentation, security and full project checks. Help0.3 adds Ruby without changing historical help0.1/0.2 schemas. Initialized workspaces reuse one stable confirmation task across WASM candidates and native observations. next retains native line positions and the verified --ruby-tool recheck argument; task verify records attempts and leaves zero-diagnostic tasks open pending policy/coverage review. Ruby syntax feedback0.3, native history0.9, recheck0.10, task preview0.23 and repair brief0.15 preserve old protocol versions. codeguard check ruby ROOT --ruby-tool /absolute/path/to/ruby --format=json and check all now reuse the bounded native syntax scan and stable task connector; selected failures do not switch to WASM. The shared deadline and64-file cap retain incomplete scope; native observations withdraw positions when source/tool identity changes. Aggregate feedback0.51 supports Ruby scan0.1/0.2 and brief0.15 without modifying old schemas. Full RuboCop/project lint and trusted closure remain pending. Public npm0.1.4 is unchanged.

Ruby edit feedback: source builds of hook execute / hook claude post-tool-use accept --ruby-tool ABS_PATH or select Ruby from the caller's absolute PATH entries. Only confirmed edited files are parsed under the event deadline. Selected failures do not fall back; absence retains WASM candidates. Bounded dialogue carries current line positions and real stable tasks without source/tool-message echoes or invented columns, and asks agents to verify project Ruby compatibility first. repair_ready rechecks using the selected tool and retains real evidence references; zero diagnostics do not close tasks. New closed protocols are edit feedback 0.19 (inner 0.10) and recheck feedback 0.20 (inner 0.6); old schemas are preserved. Actual installed-host triggering, complete RuboCop coverage, and public npm release remain unverified.

Ruby version declaration guard: source builds read the nearest .ruby-version between the source and project root, bounded to 64 ancestor levels and 4096 bytes. Only 2.6.10, 2.6.10p210 and their ruby- forms match the fixed parser. Other explicit versions yield ruby_project_version_mismatch; aliases/ambiguity yield ruby_project_version_unresolved; unsafe links/read failures yield ruby_project_version_unreadable. None starts the old Ruby or falls back to WASM. Declaration bytes and nearer missing declarations are rechecked after parsing; changes withdraw diagnostics. Saved positions are also withdrawn when a new declaration is incompatible. Standalone lint locates a .codeguard workspace before a Git root or Gemfile, so nested Gemfiles cannot hide the workspace pin; the nearest module version declaration remains authoritative. Absence retains an unapproved preliminary observation. Gemfile constraints, JRuby/RVM, complete project profiling and release remain pending. See version guard acceptance.

The Ruby six-category candidate profile now records runtime dialects, project-lock version selection and conditional tool scopes. Native rules, full project coverage and platform qualification remain unverified. See profile acceptance.

Native ShellCheck single-file inspection (partial capability)

codeguard lint shell app.sh --dialect bash --shellcheck-tool /absolute/shellcheck --timeout 30s --format json invokes ShellCheck 0.11.0 json1 through Rust, preserving native SC rules, severities and ranges. Explicit sh/bash/dash/ksh/busybox are supported; zsh/fish declarations, shebangs and known filenames remain capability gaps. Missing tools produce setup guidance. No Shell WASM asset is available, so fallback remains explicitly unavailable.

An explicit absolute --shellcheck-config or the nearest ancestor rc is frozen in a private run directory (automatic discovery is bounded to 64 ancestors). HOME/XDG global configuration is not loaded. Project configuration status is independent of native execution with built-in rules. Frozen stdin avoids executing the inspected script; source, entry bytes, rc bytes and nearer missing rc witnesses are rechecked across phases. Linked rc, invalid encoding and external-sources enablement are rejected. No fix is applied. Tool dependency closure and full platform isolation remain open.

SC1071/1090/1091/1092/1134/1144/1145 represent environment/dependency blockers and may coexist with retained local SC2086 diagnostics. json1 columns count Unicode scalar characters, with each tab counting one character. Invalid/partial reports cannot claim completeness. Free-text native messages and replacement payloads are not forwarded into repair instructions.

Version 0.1.0 shell_lint_feedback includes seven-part repair guidance, original-tool recheck argv and official rule links. task_workflow_status=not_integrated and empty attempt history explicitly identify the missing persistence integration. Incomplete evidence yields investigation guidance without authorized source paths. Even native zero diagnostics leaves the overall command incomplete/exit 3 and delivery not evaluated. Project coverage, Dockerfile/IaC, security, trusted exceptions and task closure require independent implementation and acceptance. See the partial acceptance record.