Skip to content

feat(epi): surface @epi(...) epistemic-grade annotation (ADR-0009 D2)#49

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/dazzling-albattani-ubS9r
Jun 18, 2026
Merged

feat(epi): surface @epi(...) epistemic-grade annotation (ADR-0009 D2)#49
hyperpolymath merged 1 commit into
mainfrom
claude/dazzling-albattani-ubS9r

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Mirrors the just-landed @echo surface for the epistemic axis, completing the ADR-0009 D1+D2 function-declaration effect surface — Echo + Epistemic, both first-class.

Syntax — @epi(Opaque|Partial|Transparent)

@epi(Partial) fn f(x: Int): Int { ... }
@echo(Neutral) @epi(Transparent) fn g(...) { ... }   // any order, alongside @pure

AST + cycle-break (same pattern as Echo)

FunctionDecl.epi_annotation: Option<Epistemic>. The Epistemic enum moves epistemic.rs → ast.rs with a pub use crate::ast::Epistemic re-export, so the astepistemic cycle is broken and every epistemic::Epistemic site is unchanged.

Check — both axes now

check_echo_annotationscheck_effect_annotations: verifies inferred ⊑ annotated for both echo and epi, against the carrier-aware, call-graph-composed resolved_effects (whose FunctionEffect already carries .echo + .epi). Same upper-bound policy; same modular, soundness-preserving guarantee (the reverse {} gate still uses the actual grade).

Round-trip

pretty.rs / formatter.rs emit @epi after @echo, pinned by a round-trip test.

Tests / quality

5 new tests (parse @epi; @echo+@epi together; epi upper-bound accept/reject; round-trip). 138 lib tests, cargo fmt + clippy clean.

Remaining on this axis

Carry the (echo, epi) row in TypeAnnotation::Function (function-valued params) — coming next; it has a function-type grade-syntax + variance design choice I'll settle with the user first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742


Generated by Claude Code

Mirrors the @echo surface for the epistemic axis, completing the ADR-0009
D1+D2 function-declaration effect surface (Echo + Epistemic, first-class).

- Syntax: `@epi(Opaque|Partial|Transparent)` before `fn`, order-independent
  with `@pure`/`@echo` (grammar `epi_marker`; parser marker loop extended).
- AST: `FunctionDecl.epi_annotation: Option<Epistemic>`. The `Epistemic` enum
  moves epistemic.rs -> ast.rs with a `pub use crate::ast::Epistemic` re-export
  (same ast <-> epistemic cycle-break as Echo); every `epistemic::Epistemic`
  site is unchanged.
- Check: `check_echo_annotations` -> `check_effect_annotations`, now verifying
  BOTH axes `inferred <= annotated` (echo and epi) against the composed
  `resolved_effects` (FunctionEffect carries .echo + .epi).
- Round-trip: pretty.rs + formatter.rs emit `@epi` after `@echo`.

5 new tests (parse @epi + echo&epi together; epi upper-bound accept/reject;
round-trip); 138 lib tests, cargo fmt + clippy clean.

Remaining on this axis: carry the (echo, epi) row in `TypeAnnotation::Function`
(function-valued params).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 55 issues detected

Severity Count
🔴 Critical 0
🟠 High 23
🟡 Medium 32
View findings
[
  {
    "reason": "No test directory or test files found",
    "type": "no_tests",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper",
    "action": "flag",
    "rule_module": "honest_completion",
    "severity": "high",
    "deduction": 20
  },
  {
    "reason": "Issue in secret-scanner.yml",
    "type": "missing_workflow",
    "file": "secret-scanner.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in scorecard.yml",
    "type": "scorecard_wrapper_missing_job_permissions",
    "file": "scorecard.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (10 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/crates/jtv-core/benches/interpreter_bench.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (6 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/crates/jtv-core/benches/parser_bench.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "Js.Array2 deprecated -- use Array (3 occurrences)",
    "type": "deprecated_api",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/vscode-extension/src/Extension.res",
    "action": "search_replace",
    "rule_module": "migration_rules",
    "severity": "high"
  },
  {
    "reason": "Js.Promise deprecated -- use Promise (2 occurrences)",
    "type": "deprecated_api",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/vscode-extension/src/Extension.res",
    "action": "module_replace",
    "rule_module": "migration_rules",
    "severity": "medium"
  },
  {
    "reason": "Belt.Array deprecated -- use Array (30 occurrences)",
    "type": "deprecated_api",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/packages/jtv-analyzer/src/Main.res",
    "action": "module_replace",
    "rule_module": "migration_rules",
    "severity": "high"
  },
  {
    "reason": "Belt.Option deprecated -- use Option (2 occurrences)",
    "type": "deprecated_api",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/packages/jtv-analyzer/src/Main.res",
    "action": "module_replace",
    "rule_module": "migration_rules",
    "severity": "medium"
  },
  {
    "reason": "Js.Array2 deprecated -- use Array (7 occurrences)",
    "type": "deprecated_api",
    "file": "/home/runner/work/julia-the-viper/julia-the-viper/packages/jtv-analyzer/src/Main.res",
    "action": "search_replace",
    "rule_module": "migration_rules",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath
hyperpolymath marked this pull request as ready for review June 18, 2026 16:11
@hyperpolymath
hyperpolymath merged commit 0909a70 into main Jun 18, 2026
32 checks passed
@hyperpolymath
hyperpolymath deleted the claude/dazzling-albattani-ubS9r branch June 18, 2026 16:11
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.

2 participants