Skip to content

feat: add deterministic linter (tools/lint/)#23

Open
rawwerks wants to merge 1 commit intomainfrom
feat/add-linter
Open

feat: add deterministic linter (tools/lint/)#23
rawwerks wants to merge 1 commit intomainfrom
feat/add-linter

Conversation

@rawwerks
Copy link
Copy Markdown

@rawwerks rawwerks commented Mar 24, 2026

PR: Add deterministic linter (tools/lint/)

Summary

Adds openprose-lint, a Rust-based deterministic linter for OpenProse programs. Supports both legacy .prose files and .md programs.

What it does

The linter checks the static, spec-driven parts of OpenProse programs — the things that should be deterministic regardless of which model executes them:

Legacy (.prose files):

  • Line/block structure, string literals, indentation
  • Agent definitions and references (duplicates, undefined refs)
  • Property validation (model names, permissions, skills)
  • Escape sequence validation (E002)
  • Prompt hygiene (empty, whitespace-only, oversized)
  • Output validation (E023: empty output name)
  • Permission value validation (W009)
  • Legacy syntax detection (old import/session forms)

.md programs:

  • YAML frontmatter validation (required fields, known vocabulary, duplicates)
  • Component and contract section parsing
  • Heading classification (components vs state schemas vs documentation)
  • Cross-validation (frontmatter nodes vs body components)
  • Multi-file program directory auto-detection and validation
  • Contract completeness observations
  • Hedging language detection in ensures clauses

Spec discovery:

  • discover command analyzes a corpus and reports patterns not covered by the spec
  • Role ↔ delegation correlation, API/prohibited overlap detection, state coherence
  • Designed to make spec/implementation drift visible and quantifiable

Where it lives

tools/lint/
├── build.rs           # Extracts vocabulary from skills/open-prose/compiler.md at compile time
├── Cargo.toml
├── README.md
├── fixtures/          # Test fixtures
│   ├── valid/
│   └── invalid/
└── src/
    ├── main.rs        # CLI: lint, lint-md, discover
    ├── lib.rs         # Public API
    ├── lint.rs        # .md program engine
    ├── lint_legacy.rs # Legacy .prose engine
    ├── diag.rs        # Diagnostic types
    ├── profile.rs     # Lint profiles (strict/compat)
    ├── fs.rs          # File collection utilities
    └── wasm.rs        # WASM bindings for browser/plugin use

Why tools/lint/

The skills/ directory is what gets installed as a Claude Code plugin. A Rust crate with Cargo.toml, src/, and target/ inside a skill would bloat plugin installation. tools/ is the conventional home for language tooling that operates on the spec but isn't part of it.

Spec integration

build.rs reads skills/open-prose/compiler.md at compile time to extract vocabulary (model names, property names, permission types). The test suite validates against skills/open-prose/examples/. Both paths are repo-relative.

Test results

25 tests, 0 failures

Legacy: 0 errors on example corpus (profile: compat)
.md:    0 errors, 27 warnings across 76 Press corpus files (auto-detected program dirs)
       — detects contracts in all 3 corpus formats (bare top-level, ## sections, code blocks)

Usage

cd tools/lint
cargo build --release

# Lint legacy .prose examples
cargo run -- lint ../../skills/open-prose/examples/

# Lint .md programs (auto-detects multi-file program directories)
cargo run -- lint-md path/to/programs/

# Spec observation report
cargo run -- discover path/to/programs/

What's not included

  • LSP server — separate concern, can follow later
  • Conformance test runner — needs design discussion for where conformance cases should live in this repo
  • Release automation — not needed for an in-repo tool

Related

See #22 for spec observations from linting the Press corpus.

Rust-based linter for OpenProse programs. Supports both legacy .prose
files and .md programs.

Legacy (.prose):
- Structure, syntax, string literals, escape sequences (E002)
- Agent definitions and references
- Property, permission, skill validation
- Prompt hygiene, output validation (E023)
- Legacy syntax detection

.md programs:
- YAML frontmatter validation
- Component and contract section parsing
- Heading classification (components vs state schemas vs docs)
- Multi-file program directory auto-detection
- Contract completeness observations

Spec discovery:
- discover command reports corpus patterns not covered by spec
- Role/delegation correlation, API/prohibited overlap, state coherence

build.rs reads skills/open-prose/compiler.md for vocabulary extraction.
Tests validate against skills/open-prose/examples/.
22 tests, 0 failures.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant