agentleFS
vmikhailovvmikhailov/code-explorer/.agents/skills/semantic-invariant-gates/SKILL.md

semantic-invariant-gates

Skill17 starsChanged 8 days agoMITView on GitHub

Use this skill when authoring, reviewing, testing, or updating Semantic Invariant Gates (SIG), defining architectural rules in OpenCypher, configuring ratchet baselines, or inspecting technical debt violations in CodeExplorer.

The file

Show its rules and text

We split this skill into the rules it gives an agent

18 rules. About 0 are common, 9 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when:

    line 14
  2. Very specific:

    Every invariant lives at a coordinate [Scope, Dimension] in the FOIM space:

    line 28
  3. Distinctive:

    Every invariant belongs to one of two categories:

    line 56
  4. Very specific:

    Instead of manually projecting scalar columns (AS file, AS line, AS symbol, AS target, AS message), return the matched graph nodes and …

    line 90
  5. Very specific:

    Multi-Call-Site Unrolling: When a single (File, Symbol, Target) pair occurs multiple times (either as multiple rows or unrolled from …

    line 121
  6. Very specific:

    Run your query interactively using ce query to test against the current workspace:

    line 139
  7. Distinctive:

    Test projects/files are appropriately excluded if not subject to the rule:

    line 146
  8. Distinctive:

    Place the YAML manifest in the appropriate categorized directory:

    line 152
  9. Distinctive:

    Run the gate evaluator (returns clean summary table only):

    line 181
  10. Distinctive:

    If the codebase already contains legacy violations that cannot be fixed immediately:

    line 206
  11. Very specific:

    When debt is fixed, ce gate ratchet --update lowers the ceiling (monotonic ratchet).

    line 214
  12. Distinctive:

    Ensure AST visitors and in-memory processors do not invoke filesystem or network IO:

    line 298
  13. Very specific:

    Don't put line numbers or timestamps into target.

    line 331
  14. Distinctive:

    Use stable identifiers like method names, package names, or typed constants so the SHA-256 fingerprint remains deterministic.

    line 332
  15. Very specific:

    Always add WHERE NOT (file CONTAINS 'test' OR file CONTAINS 'Test') unless the gate specifically targets testing practices.

    line 334
  16. Very specific:

    Every gate should include actionable instructions in the remediation field explaining *how* the developer or AI agent should fix the issue.

    line 336
  17. Distinctive:

    When introducing a new gate to an established repository, *never* break the build for existing debt.

    line 338
  18. Very specific:

    Always run ce gate ratchet --update -g <id> to record existing violations in the baseline.

    line 339

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Semantic Invariant Gates (SIG) Authoring Guide

This skill guides developers and AI agents in authoring, verifying, and maintaining Semantic Invariant Gates (SIG) in CodeExplorer.


When to Use This Skill

Use this skill when:

  • Defining new architectural invariants (e.g. boundary rules, layer purity, interface abstractions).
  • Writing and testing OpenCypher queries against the codebase property graph.
  • Creating gate manifests (.codeexplorer/gates/*.yaml) or adding built-in gates to BuiltInGateCatalog.cs.
  • Setting up baseline snapshots for legacy technical debt (ce gate ratchet --update).
  • Inspecting, filtering, or grouping gate violations (ce gate violations).
  • Reviewing code changes against architectural standards before merging.

Core Foundations

1. Fractal Orthogonal Invariant Matrix (FOIM)

Every invariant lives at a coordinate [Scope, Dimension] in the FOIM space:

CodeScopeGranularityExample Entities
ASystemEntire distributed topologyCross-service flows, external ingress/egress, cloud resources
SServiceExecutable / deployment unitService, App, Worker, CliTool, message topics, DBs
PModuleCompilation unit / ProjectProject, Library, package dependencies, layers
CClassType / Interface / StructType, inheritance trees, class dependencies, visitor purity
MMethodFunction / Procedure / EndpointFunction, Endpoint, CallLiteral, parameter rules
CodeDimensionArchitectural FocusQuestion Answered
CContractTyping, interfaces, API protocol fidelityAre contracts explicit, valid, and type-safe?
IRulesImplementation constraints & hygieneAre constants hardcoded? Are visitors IO-pure?
RResourcesResource & complexity control, metricsAre methods within complexity limits? Are resources bounded?
BBoundariesScope boundaries, encapsulation, layer isolationWho may talk to whom? (No direct DB calls from UI)

Identifier Convention: SIG-<ScopeCode>-<DimensionCode>-<Index3Digits> Examples:

  • SIG-P-B-001: Module Scope $\times$ Boundaries Dimension (Layer hierarchy)
  • SIG-M-I-001: Method Scope $\times$ Rules Dimension (Disallow hardcoded call arguments)
  • SIG-C-I-001: Class Scope $\times$ Rules Dimension (In-Memory AST Visitor IO Purity)

2. Architectural vs. Platform Categorization

Every invariant belongs to one of two categories:

  1. category: Architectural (platform: agnostic):
    • Universal structural rules and design principles applicable regardless of language or framework.
    • Examples: Unidirectional layer hierarchy, clean architecture transport purity, package acyclicity, in-memory AST visitor I/O purity.
    • Directory: .codeexplorer/gates/architectural/*.yaml
    • Cross-Language Best Practice: For general architectural rules (like I/O purity in AST visitors), design Cypher queries to match standard I/O abstractions across all supported ecosystems (.NET File/Directory, Node fs, Go os/ioutil, Python pathlib, Java Files).
  2. category: Platform (platform: <ecosystem>):
    • Runtime, framework, or technology-specific rules.
    • Examples: Prohibiting domain coupling to SQLite drivers (SqliteGraphClient, SqliteConnection) rather than IGraphClient (platform: dotnet).
    • Directory: .codeexplorer/gates/platform/<platform>/*.yaml (e.g. .codeexplorer/gates/platform/dotnet/).

Category & Platform Filtering:

# List only architectural gates
ce gate list --category architectural

# List only dotnet platform gates
ce gate list --platform dotnet

# Evaluate only platform gates
ce gate check --category platform

3. The Zero-Match Contract & v2 Node-First / Edge-Aware Extraction

A Semantic Invariant Gate operates on a strict Zero-Match Contract:

  • 0 rows returned $\implies$ PASS (Invariant holds across the codebase).
  • $\ge 1$ rows returned $\implies$ VIOLATION (Each row returned is a violation, evaluated against thresholds and ratchet).

Preferred v2 Contract — Node-First & Edge-Aware RETURN:

Instead of manually projecting scalar columns (AS file, AS line, AS symbol, AS target, AS message), return the matched graph nodes and relationship directly and declare message (and optional target) templates on the gate manifest:

target: "{target.name}" # optional override for single-node or aggregate queries
message: "Prohibited call from '{caller.name}' to '{target.name}' at {location}"
thresholds:
  warning: 1
  error: 5
query: |
  MATCH (caller:Function)-[r:CALLS]->(target:Function)
  WHERE caller.path CONTAINS 'Domain/' AND target.path CONTAINS 'Infrastructure/'
  RETURN caller, r, target

GateExecutionEngine automatically extracts:

  1. Source Node (caller, fn, src, p, c, t, etc.): extracts file (file_path / path), line (start_line), column (start_col), symbol (name), and nodeId (id).
  2. Relationship Edge (r, rel, edge, call): extracts exact call-site line and column (overriding the declaration line of the caller function) and automatically unrolls r.call_sites (["45:12", "88:9"]) when a function invokes a forbidden target multiple times!
  3. Target Node (target, tgt, pkg, d, ep, etc.): extracts target (name / full_name) and targetNodeId (id).
  4. Template Interpolation (message & target): supports {fn.name}, {r.line}, {node.label}, {node.id}, {location}, flat scalar columns ({loc}), and default fallback values ({d.engine|unknown}).

[!NOTE] Legacy v1 scalar projections (RETURN ... AS file, AS line, AS column, AS symbol, AS target, AS message) remain 100% supported as an explicit override.


4. Line-Shift Immune Fingerprinting

CodeExplorer calculates violation fingerprints without depending on volatile line numbers: $$\text{Fingerprint} = \text{SHA256}(\text{GateId} \parallel \text{FilePath} \parallel \text{Symbol} \parallel \text{Target} \parallel \text{Occurrence})$$

  • Why: Adding comments, reformatting, or inserting code above a violation shifts line numbers but must never invalidate the baseline snapshot.
  • Multi-Call-Site Unrolling: When a single (File, Symbol, Target) pair occurs multiple times (either as multiple rows or unrolled from r.call_sites), GateExecutionEngine assigns deterministic occurrence indices (#1, #2, ...), ensuring every call site gets its own unique fingerprint.

Step-by-Step Gate Creation Workflow

1. Formulate Rule ──> 2. Test in Cypher ──> 3. Create Manifest ──> 4. Run Check ──> 5. Ratchet Baseline
   (FOIM Coordinates)   (ce query "...")      (.codeexplorer/gates)   (ce gate check)   (ce gate ratchet)

Step 1: Formulate the Rule

  1. Clearly state what is forbidden.
  2. Select the FOIM Scope and Dimension.
  3. Determine category (Architectural vs Platform) and target platform (agnostic vs <platform>).
  4. Pick the next available ID: SIG-<Scope>-<Dimension>-NNN.

Step 2: Prototype and Test the Cypher Query

Run your query interactively using ce query to test against the current workspace:

ce query "MATCH (l:Library)-[r:DEPENDS_ON]->(pkg:Package) WHERE pkg.name = 'Microsoft.Data.Sqlite' RETURN l, r, pkg"

Verify that:

  • Clean code returns 0 rows.
  • Real violations are caught.
  • Test projects/files are appropriately excluded if not subject to the rule:
    WHERE NOT coalesce(fn.is_test, false)

Step 3: Create Gate Manifest YAML

Place the YAML manifest in the appropriate categorized directory:

  • Architectural gates: .codeexplorer/gates/architectural/<gate-id-in-kebab-case>.yaml
  • Platform-specific gates: .codeexplorer/gates/platform/<platform>/<gate-id-in-kebab-case>.yaml
id: SIG-P-B-004
category: Architectural
platform: agnostic
scope: Module
dimension: Boundaries
name: "Disallow Direct Database Packages in Domain Libraries"
severity: Error # Error | Warning
description: "Domain and Core libraries must remain storage-agnostic. Direct references to database drivers violate Clean Architecture."
remediation: "Move database drivers and EF Core dependencies to Infrastructure/Data layer projects."
message: "Core library '{l.name}' must not depend on database driver '{pkg.name}'"
thresholds:
  warning: 1
  error: 1
query: |
  MATCH (l:Library)-[r:DEPENDS_ON]->(pkg:Package)
  WHERE (l.name CONTAINS 'Core' OR l.name CONTAINS 'Domain')
    AND pkg.name IN ['Microsoft.Data.Sqlite', 'Npgsql', 'System.Data.SqlClient', 'MySqlConnector', 'better-sqlite3', 'pg', 'mysql2']
  RETURN l, r, pkg
ratchet:
  enabled: true
  baseline: baselines/SIG-P-B-004.json

Step 4: Verify Gate via CLI

Run the gate evaluator (returns clean summary table only):

# Check single gate (summary only)
ce gate check -g SIG-P-B-004

# Run all gates (summary only)
ce gate check

# Run only architectural gates
ce gate check --category architectural

# Run only platform gates for dotnet
ce gate check --platform dotnet

To view complete failure details, rules, remediations, and individual violation listings:

# View full failure details across evaluated gates
ce gate details

# View details and violations for a specific gate
ce gate details -g SIG-P-B-004

Step 5: Freeze Existing Debt into Baseline

If the codebase already contains legacy violations that cannot be fixed immediately:

# Update baseline snapshot for this specific gate
ce gate ratchet --update -g SIG-P-B-004

This generates .codeexplorer/gates/baselines/SIG-P-B-004.json. From this point forward:

  • Legacy violations are tolerated ([TOLERATED]).
  • Any new violation introduced in a PR immediately fails the gate ([FAIL]).
  • When debt is fixed, ce gate ratchet --update lowers the ceiling (monotonic ratchet).

Step 6: Inspect and Group Violations

# Aggregated summary by file
ce gate violations -g SIG-P-B-004 --group-by file

# Filter by specific file
ce gate violations -g SIG-P-B-004 --file Core/Analysis

# Export to JSON
ce gate violations -g SIG-P-B-004 -f json

Ontology Reference Cheatsheet

1. High-Level Architecture Nodes

LabelDescriptionKey Properties
ServiceBackend microservice or APIname, path, project_type
AppFrontend or client applicationname, path, project_type
WorkerBackground queue consumer / daemonname, path
LibraryShared package or class libraryname, path
CliToolCommand-line tool executablename, path
DatabaseLogical database or storage instancename, db_type
TopicMessage queue or pub/sub topicname, broker_type

2. Code-Level Nodes

LabelDescriptionKey Properties
TypeClass, interface, struct, enumname, symbol, file_path, line
FunctionMethod, constructor, functionname, symbol, file_path, line
CallLiteralHardcoded literal argument in method callvalue, callee, arg_index, file_path, line
EndpointHTTP route / REST handlerpath, method, route
QuerySQL query extracted from ASTraw_sql, operation_type
PackageExternal dependency (NuGet, npm)name, version

3. Key Relationships

RelationshipFrom $\to$ ToMeaning
DEPENDS_ONProject/Library $\to$ PackageProject references external package
SERVICE_CALLService $\to$ Service/EndpointNetwork invocation (REST, gRPC)
PUBLISHES_TOService $\to$ TopicPublishes events to message queue
SUBSCRIBES_TOWorker $\to$ TopicConsumes events from message queue
USES_DBService $\to$ DatabaseService accesses database
CALLSFunction $\to$ FunctionAST call graph invocation
PASSES_LITERALFunction/Type $\to$ CallLiteralFunction passes literal string argument
CONTAINSParent $\to$ ChildStructural containment (Project $\to$ Type $\to$ Method)
IMPLEMENTSType $\to$ TypeInterface implementation

Catalog of Real-World Gate Patterns

Pattern A: Clean Architecture Layer Purity (Boundaries)

Prohibit Domain/Application layer from referencing UI or Infrastructure packages:

MATCH (p:Project)-[:DEPENDS_ON]->(pkg:Package)
WHERE p.path CONTAINS 'src/Domain'
  AND (pkg.name STARTS WITH 'Microsoft.AspNetCore' OR pkg.name STARTS WITH 'EntityFramework')
RETURN 
  p.path AS file,
  0 AS line,
  p.name AS symbol,
  pkg.name AS target,
  'Domain layer project ' + p.name + ' cannot reference infrastructure package ' + pkg.name AS message

Pattern B: Circular Package Dependencies (Topology)

Detect circular references between workspace projects:

MATCH (a:Project)-[:DEPENDS_ON]->(b:Project)-[:DEPENDS_ON]->(a)
WHERE a.name < b.name
RETURN 
  a.path AS file,
  0 AS line,
  a.name AS symbol,
  b.name AS target,
  'Circular dependency detected between projects ' + a.name + ' and ' + b.name AS message

Pattern C: In-Memory Visitor IO Purity (Implementation Rules)

Ensure AST visitors and in-memory processors do not invoke filesystem or network IO:

MATCH (cls:Type)-[:CONTAINS]->(fn:Function)-[:CALLS]->(ioTarget:Function)
WHERE cls.name CONTAINS 'Visitor'
  AND (ioTarget.name STARTS WITH 'File.' OR ioTarget.name STARTS WITH 'Directory.' OR ioTarget.name STARTS WITH 'HttpClient.')
RETURN 
  cls.file_path AS file,
  fn.line AS line,
  cls.name + '.' + fn.name AS symbol,
  ioTarget.name AS target,
  'AST Visitor method ' + fn.name + ' performs prohibited IO call ' + ioTarget.name AS message

Pattern D: Disallow Hardcoded Call Arguments (Implementation Rules)

Flag raw string literals passed into business methods:

MATCH (caller)-[:PASSES_LITERAL]->(lit:CallLiteral)
WHERE NOT (coalesce(caller.symbol, '') CONTAINS 'Test' 
       OR coalesce(caller.file_path, '') CONTAINS 'Test' 
       OR coalesce(caller.file_path, '') CONTAINS 'test')
RETURN 
  lit.file_path AS file,
  lit.line AS line,
  coalesce(caller.name, 'unknown') AS symbol,
  lit.callee + '(' + lit.value + ')' AS target,
  'Hardcoded string literal "' + lit.value + '" passed to ' + lit.callee AS message

Best Practices & Pitfalls

  1. Avoid Volatile Symbols in target:
    • Don't put line numbers or timestamps into target.
    • Use stable identifiers like method names, package names, or typed constants so the SHA-256 fingerprint remains deterministic.
  2. Exclude Test Code:
    • Always add WHERE NOT (file CONTAINS 'test' OR file CONTAINS 'Test') unless the gate specifically targets testing practices.
  3. Always Provide Remediation:
    • Every gate should include actionable instructions in the remediation field explaining how the developer or AI agent should fix the issue.
  4. Use Baselines to Avoid Blocking Existing Work:
    • When introducing a new gate to an established repository, never break the build for existing debt.
    • Always run ce gate ratchet --update -g <id> to record existing violations in the baseline.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.