stemedb/applications/aphoria/docs/cli-reference.md
jml e95c978481 feat(aphoria): add inline claim markers and claim enrichment infrastructure
This commit implements Phase 17 of the Aphoria roadmap, adding:

**Inline Claim Markers (@aphoria:claim):**
- New extractor for detecting inline markers in comments
- Pending markers tracked in .aphoria/pending_markers.toml
- CLI commands: list-markers, formalize-marker, reject-marker
- Support for all major comment styles (Rust, Python, SQL, etc.)
- Auto-sync during scan (configurable)

**Claim Enrichment:**
- ClaimEnrichment type with source attribution (inline, extractor, manual)
- EnrichedClaimInfo with full enrichment metadata
- Extended AuthoredClaim with optional enrichment field
- API endpoints for enriched claim queries
- Dashboard UI components (enrichment badge, verdict badge)

**Enhanced Extractor Trait:**
- verifiable_predicates() method for declaring (tail_path, predicate) pairs
- 10 security extractors now implement verifiable_predicates
- Enables claim suggester skill to find unclaimed patterns

**Documentation:**
- Phase 17 summary with complete implementation details
- Gap fixes summary documenting 8 closed vision gaps
- Updated CLI reference with new commands
- New aphoria-docs skill for documentation maintenance
- Updated roadmap with Phase 17 completion

**Integration:**
- ClaimsFile support for claim enrichment persistence
- Pattern aggregate store support for enrichment queries
- Dashboard filters and display for enrichment metadata
- API handlers for list-markers and enrichment queries

**Tests:**
- New gap_fixes_integration test suite
- Corpus enricher module with best practices ingestion

Closes: VG-005, VG-017, VG-018, VG-019, VG-020, VG-021, VG-022, VG-023

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-08 20:18:20 +00:00

18 KiB

Aphoria CLI Reference

Complete reference for all Aphoria commands.


Core Commands

aphoria scan

Scan codebase for conflicts with authoritative sources.

# Quick ephemeral scan (fast, ~0.25s)
aphoria scan .

# Persistent scan (enables drift detection)
aphoria scan --persist

# Sync with hosted corpus
aphoria scan --persist --sync

# CI mode (exit code 1 on BLOCK)
aphoria scan --exit-code

# Pre-commit (staged files only)
aphoria scan --staged --exit-code

# Output formats
aphoria scan --format table      # Human-readable (default)
aphoria scan --format json       # Machine-readable
aphoria scan --format sarif      # GitHub Security tab
aphoria scan --format markdown   # Documentation

Options:

  • --persist - Use persistent mode with Episteme storage
  • --sync - Sync with hosted corpus (requires --persist)
  • --exit-code - Exit with code 1 if BLOCK verdicts found
  • --staged - Only scan git staged files
  • --format <FORMAT> - Output format: table, json, sarif, markdown
  • --show-observations - Include all observations in output (not just conflicts)

Note: Aphoria respects exclusion patterns from .aphoriaignore and aphoria.toml, plus inline ignore comments. See Ignoring Files and Findings below.


aphoria init

Initialize Aphoria in current directory.

aphoria init

Creates .aphoria/ directory with:

  • claims.toml - Human-authored claims
  • pending-markers.toml - Inline claim markers (if any)
  • config.toml - Project configuration

Note: Does NOT download the authoritative corpus anymore. Corpus is now embedded in the binary.


aphoria ack

Acknowledge a conflict as intentional.

aphoria ack "code://python/requests/tls/cert_verification" \
  --reason "Local dev environment with self-signed certs"

aphoria bless

Define a pattern as your authoritative standard.

aphoria bless "code://rust/crypto/algorithm" \
  --value "ChaCha20Poly1305" \
  --reason "Org standard cipher suite"

Claims Management

aphoria claims create

Create a new human-authored claim.

aphoria claims create \
  --id wallet-seqcst-001 \
  --concept-path maxwell/core/wallet/atomics/ordering \
  --predicate pattern \
  --value SeqCst \
  --comparison equals \
  --provenance "Security analysis: wallet atomics prevent double-spend" \
  --invariant "All wallet atomic operations MUST use SeqCst" \
  --consequence "Weakening to Relaxed creates race conditions" \
  --tier expert \
  --evidence "wallet.rs lock-free design" \
  --evidence "Rust Atomics and Locks Ch. 3" \
  --category safety \
  --by jml

Required:

  • --id - Unique claim ID (e.g., "wallet-seqcst-001")
  • --concept-path - Concept path (e.g., "project/module/concept")
  • --predicate - Predicate (e.g., "pattern", "imported", "value")
  • --value - Value to check (parsed as bool, number, or text)
  • --provenance - Where this claim came from
  • --invariant - What must stay true
  • --consequence - What breaks if violated
  • --tier - Authority tier: regulatory, clinical, observational, expert, community, anecdotal
  • --category - Category: safety, architecture, imports, constants, derives, etc.
  • --by - Author name

Optional:

  • --comparison - Comparison mode (default: equals)
    • equals - Exact match
    • not_equals - Must not equal
    • present - Must exist
    • absent - Must not exist
    • contains - Must contain substring/list element
    • not_contains - Must NOT contain substring/list element
  • --evidence - Supporting evidence (can specify multiple times)

See comparison-modes.md for detailed comparison mode guide.

Note: When claims are ingested, Aphoria automatically captures the current git commit hash (if in a git repository) and stores it in the assertion metadata. This provides temporal context linking claims to specific code versions without requiring manual tracking.


aphoria claims list

List all claims.

# List all claims
aphoria claims list

# Filter by category
aphoria claims list --category safety

# Filter by status
aphoria claims list --status active
aphoria claims list --status deprecated

# JSON output
aphoria claims list --format json

aphoria claims explain

Generate detailed explanation for claims.

# Explain all claims (markdown)
aphoria claims explain

# Explain specific claim
aphoria claims explain --claim wallet-seqcst-001

# Output to file
aphoria claims explain -o claims-explained.md

# JSON format
aphoria claims explain --format json

Creates a document with:

  • Claim ID and metadata
  • Provenance (where it came from)
  • Invariant (what must stay true)
  • Consequence (what breaks if violated)
  • Evidence chain
  • Authority tier

aphoria claims update

Update fields on an existing claim.

aphoria claims update wallet-seqcst-001 \
  --invariant "Updated invariant text" \
  --consequence "Updated consequence" \
  --tier regulatory

Options:

  • --provenance - Update provenance
  • --invariant - Update invariant
  • --consequence - Update consequence
  • --tier - Update authority tier
  • --evidence - Add evidence (can specify multiple)
  • --category - Update category
  • --value - Update value

aphoria claims supersede

Mark a claim as superseded by a new claim.

aphoria claims supersede wallet-seqcst-001 \
  --new-id wallet-seqcst-002 \
  --value AcqRel \
  --provenance "Updated after performance analysis" \
  --invariant "Relaxed to AcqRel for perf" \
  --consequence "Still safe for single-writer" \
  --tier expert \
  --by jml

Creates a new claim and marks the old one as superseded.


aphoria claims deprecate

Mark a claim as deprecated.

aphoria claims deprecate wallet-seqcst-001 \
  --reason "No longer relevant after refactor"

Deprecated claims are not verified but remain in the file for audit trail.


aphoria claims import

Import claims in batch from a TOML file.

# Preview import (dry-run)
aphoria claims import docs/guidelines.toml --dry-run

# Import with TeamPolicy tier
aphoria claims import docs/guidelines.toml \
  --authority-tier team_policy \
  --source-guide "hexagonal-arch"

# Import with merge strategy
aphoria claims import docs/guidelines.toml \
  --merge overwrite                    # Overwrite existing claims
aphoria claims import docs/guidelines.toml \
  --merge skip_existing                # Skip duplicates (default)
aphoria claims import docs/guidelines.toml \
  --merge fail_on_duplicate            # Fail if duplicate found

Options:

  • --authority-tier <TIER> - Override authority tier for all imported claims (team_policy, expert, etc.)
  • --source-guide <NAME> - Track the guideline name for compliance filtering (stored in .aphoria/ingested_guides.toml)
  • --dry-run - Preview changes without writing to file
  • --merge <STRATEGY> - Merge strategy: skip_existing (default), overwrite, fail_on_duplicate

TOML Format:

[[claim]]
id = "hex-arch-http-001"
concept_path = "myapp/adapters/http"
predicate = "layer"
value = "adapter"
comparison = "equals"
provenance = "Hexagonal Architecture Guidelines"
invariant = "HTTP handlers MUST be in adapters layer"
consequence = "Business logic leaks into infrastructure"
authority_tier = "team_policy"
category = "architecture"
evidence = ["docs/architecture/hexagonal.md"]
created_by = "architecture-team"
created_at = "2026-02-08T12:00:00Z"

[[claim]]
id = "hex-arch-domain-imports-001"
concept_path = "myapp/domain/imports"
predicate = "imported"
value = "http"
comparison = "absent"
provenance = "Hexagonal Architecture Guidelines"
invariant = "Domain layer MUST NOT import HTTP adapters"
consequence = "Circular dependency breaks architecture"
authority_tier = "team_policy"
category = "architecture"
evidence = ["docs/architecture/hexagonal.md"]
created_by = "architecture-team"
created_at = "2026-02-08T12:00:00Z"

Guideline Tracking:

When you use --source-guide, Aphoria tracks the guideline in .aphoria/ingested_guides.toml:

[[guide]]
id = "hexagonal-arch"
name = "hexagonal-arch"
source_path = "docs/guidelines.toml"
document_hash = "blake3:abc123..."
ingested_at = "2026-02-08T12:00:00Z"
claims_count = 26
authority_tier = "team_policy"
category = "imported"
claim_ids = ["hex-arch-http-001", "hex-arch-domain-imports-001", ...]

This enables:

  • Change detection (hash comparison)
  • Compliance filtering (future: aphoria scan --check-policy hexagonal-arch)
  • Audit trail (who imported what, when)

Inline Claim Markers

aphoria claims list-markers

List pending inline claim markers.

# List all markers
aphoria claims list-markers

# Filter by status
aphoria claims list-markers --status pending
aphoria claims list-markers --status formalized
aphoria claims list-markers --status rejected

# JSON output
aphoria claims list-markers --format json

Inline markers are special comments in code:

// @aphoria:claim[safety] Wallet MUST NOT derive Clone
#[derive(Debug)]
pub struct Wallet { ... }

aphoria claims formalize-marker

Convert an inline marker into a full claim.

aphoria claims formalize-marker marker-001 \
  --id wallet-no-clone-001 \
  --tier expert \
  --evidence "Wallet contains AtomicU64" \
  --by jml

This:

  1. Creates a full claim in claims.toml
  2. Marks the inline marker as formalized
  3. Links the marker to the claim ID

After formalizing, update the comment:

// @aphoria:claimed wallet-no-clone-001
#[derive(Debug)]
pub struct Wallet { ... }

aphoria claims reject-marker

Reject an inline marker.

aphoria claims reject-marker marker-001 \
  --reason "False positive - this Clone is safe"

Marks the inline marker as rejected so it won't be suggested again.


Verification Engine

aphoria verify run

Verify all authored claims against current codebase.

# Verify all claims
aphoria verify run

# Verify specific claims
aphoria verify run wallet-seqcst-001 wallet-no-clone-001

# Filter by category
aphoria verify run --category safety

# Output formats
aphoria verify run --format table
aphoria verify run --format json
aphoria verify run --format markdown

Verdicts:

  • PASS - Claim matches observations (green)
  • CONFLICT - Claim contradicts observations (red)
  • MISSING - No observations found for this claim (yellow)

Matching Capabilities:

  • Path Matching - Respects crate boundaries and module hierarchies
  • Predicate Filtering - Prevents cross-predicate matches (imports vs derives)
  • Value-Specific Checks - "absent" mode checks for specific forbidden values
  • Wildcard Patterns - Supports patterns like message/*/derives for flexible matching
  • Comparison Modes - Six modes: equals, not_equals, present, absent, contains, not_contains

Example output:

PASS     wallet-seqcst-001 | maxwell/core/wallet/atomics/ordering/pattern = SeqCst
         Matched: core/src/wallet.rs:62 (confidence 1.0)

CONFLICT wallet-no-clone-001 | maxwell/core/wallet/type/wallet/derives/traits = Clone
         Found: core/src/wallet.rs:28 (traits = Text("Clone,Debug"))
         Consequence: Clone on Wallet allows multiple instances...

Claims: 10 total | 9 pass | 1 conflict | 0 missing

aphoria verify map

Show which extractors can verify which claims.

aphoria verify map

Outputs a table showing:

  • Claim ID
  • Covering extractors (which extractors can verify this claim)
  • Status (✓ covered, ✗ uncovered)

Example:

Claim ID                    | Covering Extractors           | Status
----------------------------|-------------------------------|--------
wallet-seqcst-001          | atomic_ordering               | ✓
wallet-no-clone-001        | derive_pattern                | ✓
core-no-tokio-001          | import_graph                  | ✓
tls-cert-verification-001  | tls_verify, config_security   | ✓
unclaimed-concept-001      |                               | ✗

Use this to identify:

  • Claims that lack extractor support (need new extractors)
  • Claims covered by multiple extractors (redundancy)
  • Coverage gaps in verification

Policy Management

aphoria policy export

Export standards as a Trust Pack.

aphoria policy export trust-pack.json

aphoria policy import

Import a Trust Pack from security team.

aphoria policy import trust-pack.json

Governance (Enterprise)

aphoria governance pending

List approval requests (Phase 14).

aphoria governance pending

Audit Trail

aphoria audit export

Export audit trail for SOC 2 compliance.

aphoria audit export --since 2026-01-01

Configuration

Project Config (.aphoria/config.toml)

[project]
name = "maxwell"
description = "Compute daemon with entropy accounting"

[episteme]
wal_dir = ".aphoria/wal"
store_dir = ".aphoria/store"
signing_key_path = ".aphoria/signing.key"

[thresholds]
block_threshold = 0.85
flag_threshold = 0.70

Environment Variables

  • APHORIA_CONFIG - Path to config file (default: .aphoria/config.toml)
  • APHORIA_LOG - Log level: trace, debug, info, warn, error
  • APHORIA_HOSTED_URL - Hosted corpus URL (for --sync)

Exit Codes

  • 0 - Success (no BLOCK verdicts or all claims passed)
  • 1 - Failure (BLOCK verdicts found or claim conflicts)
  • 3 - Configuration error

Git Integration

Aphoria automatically integrates with git repositories to provide temporal context for claims and observations.

Automatic Commit Hash Tracking

When claims or observations are ingested into Episteme, Aphoria automatically captures the current git commit hash:

{
  "authored": true,
  "git_commit": "de7af7c1b9e7f6a5d4c3b2a1098765432100abcd",
  "claim_id": "wallet-no-clone-001",
  "provenance": "Wallet is singleton with atomic state",
  "invariant": "Wallet type MUST NOT derive Clone"
}

Benefits:

  • Temporal Context - Know exactly which code version a claim was authored against
  • Audit Trail - Trace architectural decisions through git history
  • No Manual Tracking - Hash captured automatically at ingestion time
  • Graceful Degradation - Works seamlessly in non-git environments (hash field simply omitted)

Important: The commit hash is captured when assertions are created, not when TOML files are edited. This avoids the "double-commit problem" where committing a file with a hash in it creates a new commit, invalidating the stored hash.

Staged File Scanning

Scan only git-staged files for pre-commit hooks:

aphoria scan --staged --exit-code

This is faster and more appropriate for pre-commit checks than scanning the entire codebase.


Ignoring Files and Findings

Aphoria provides multiple ways to exclude files and suppress findings to reduce noise and focus on relevant issues.

1. .aphoriaignore File

Create a .aphoriaignore file in your project root using gitignore-style syntax:

# Aphoria Ignore Patterns

# Test fixtures and demo code
tests/fixtures/
examples/

# Third-party code
vendor/
node_modules/

# Glob patterns work too
**/*.test.js
**/test_*.py

Syntax:

  • One pattern per line
  • # for comments
  • * matches any string (e.g., *.test.js)
  • ** matches directories recursively (e.g., **/vendor/)
  • / at end matches directories only
  • Whitespace is trimmed

2. Config File Excludes

Add patterns to .aphoria/config.toml:

[project]
name = "myproject"

[[excludes]]
path = "tests/vulnbank/"
reason = "Intentional vulnerabilities for testing"

[[excludes]]
path = "demo/"
reason = "Demo code with relaxed security"

[[excludes]]
path = "**/fixtures/**"
reason = "Test fixtures"

Glob patterns (*, **) are supported and recommended over legacy prefix matching.

3. Inline Ignore Comments

Suppress specific findings inline:

Single-line ignore:

let password = "test123"; // aphoria:ignore - Test credential

Next-line ignore:

# aphoria:ignore-next-line - Intentional for dev environment
requests.get(url, verify=False)

Block ignore:

// aphoria:ignore-block - Demo authentication
function unsafeAuth() {
  const token = "hardcoded";
  return validateToken(token);
}
// aphoria:end-ignore

Supported comment styles:

  • // - Rust, Go, C, C++, TypeScript, JavaScript
  • # - Python, Ruby, Shell, YAML
  • /* */ - CSS, C-style blocks
  • -- - SQL
  • <!-- --> - HTML, XML

4. Acknowledgments

Formally acknowledge conflicts for audit trails:

aphoria ack "code://python/requests/tls/cert_verification" \
  --reason "Dev environment uses self-signed certificates" \
  --expires 2026-12-31

Acknowledgments are stored in .aphoria/acks.toml and can be version controlled.

Precedence

When multiple ignore mechanisms apply:

  1. Inline ignore comments (highest priority)
  2. .aphoriaignore patterns
  3. Config file excludes
  4. Acknowledgments
  5. Default scan

Best Practices

  • Version control .aphoriaignore - Team-wide exclusions
  • Use inline ignores sparingly - Document the "why" in the comment
  • Acknowledge, don't suppress - Use aphoria ack for intentional violations that need audit trails
  • Review exclusions regularly - Ensure they're still necessary

See Also