feat(dialect): ADR-0008 purity certificate (purist vs adulterated) — neg-impl slice 1#39
Merged
Merged
Conversation
First, non-breaking slice of the neg-dialect implementation: a read-only AST analysis that stamps a program `purist-jtv` or `adulterated-jtv` by counting expression-level `neg` sugar -- the accountability-without-prohibition piece of ADR-0008 D4. Changes no semantics; the invasive parts (feature-gating DataExpr::Negate, parse-error in purist mode, the discouragement lint) are later slices. - crates/jtv-core/src/dialect.rs: `Dialect`, `PurityCertificate`, `certify()`; recursive scan of the whole AST for DataExpr::Negate. - Reverse/reversible-block subtraction stays purist (only expression-level neg is sugar) -- pinned by a test. - 5 tests; clippy -D warnings clean. https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742
| @@ -0,0 +1,227 @@ | |||
| // SPDX-License-Identifier: MPL-2.0 | |||
🔍 Hypatia Security ScanFindings: 52 issues detected
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_or(0) with dangerous default (3 occurrences, CWE-754)",
"type": "unwrap_dangerous_default",
"file": "/home/runner/work/julia-the-viper/julia-the-viper/crates/jtv-core/src/dialect.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"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"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
…sum()) The three Option::map(...).unwrap_or(0) count accumulators tripped Hypatia's unwrap_dangerous_default (CWE-754, flagged critical). 0 is the correct count for an absent branch, but iterating the Option and summing avoids the unwrap_or pattern entirely and is cleaner. No behaviour change; 5 dialect tests + clippy -D warnings green. https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742
🔍 Hypatia Security ScanFindings: 51 issues detected
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
marked this pull request as ready for review
June 18, 2026 00:41
hyperpolymath
pushed a commit
that referenced
this pull request
Jun 18, 2026
… effects
Designs item (b): lift Echo from a block gate to a graded effect in the function
arrow, and add a parallel Epistemic (knowledge/observability) effect.
- D1: Echo grade {Safe<=Neutral<=Breaking} carried by the arrow; composition is
the existing idempotent join (echo.rs/JtvEcho); block-level classify_stmts
becomes the body-aggregate special case.
- D2: Epistemic = what a function reveals about its inputs
{Opaque<=Partial<=Transparent}, the dual axis to Echo (loss vs revelation),
composing by join. (knowledge/observability reading chosen; belief/certainty
recorded as the alternative.)
- D3: effect row = product of the two idempotent lattices, composed componentwise.
- D4: orthogonal to Purity and the ADR-0008 dialect certificate.
Decision record; implementation is slice-wise, Echo-effect first (mostly
additive). STATE.a2ml: artefact location + session-history (dialect cert #39 +
ADR-0009).
https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
neg-dialect implementation, slice 1 (the non-breaking one). Implements ADR-0008 D4 — the purity certificate.
A read-only AST analysis (
jtv_core::dialect) that stamps a programpurist-jtvoradulterated-jtvby counting expression-levelnegsugar. This is the accountability-without-prohibition piece: the build can carry a visible badge for whether it used the escape hatch — no semantics change.Dialect(Purist / Adulterated),PurityCertificate { dialect, neg_uses },certify(&Program).DataExpr::Negate.reverse { x += a }(subtraction via the reverse mechanism) stays purist — only expression-levelnegmakes a program adulterated. That's exactly the ADR-0008 thesis.clippy -D warningsclean;#[forbid(unsafe_code)]respected.The invasive later slices (feature-gating
DataExpr::Negate, making-a parse error in purist mode, the D3 discouragement lint) are deliberately deferred — this slice is intentionally additive so it can't destabilise the build.Next in your sequence after this: (b) echo + epistemic first-class, then number-system semantics, then license wave-2.
https://claude.ai/code/session_01BJmfoz1ZS1Pejy9LLMY742
Generated by Claude Code