fix(reconcile): --verify no longer crashes JSON-encoding its result#272
Open
hyperpolymath wants to merge 7 commits into
Open
fix(reconcile): --verify no longer crashes JSON-encoding its result#272hyperpolymath wants to merge 7 commits into
hyperpolymath wants to merge 7 commits into
Conversation
ScorecardReconciler.verify/2 returns {:ok, summary} | {:error, reason}
whereas reconcile/3 returns a bare map. The mix task fed the raw result
straight to Jason.encode!/2, which cannot encode a tuple, so
`mix hypatia.reconcile owner/repo --verify` crashed on output (the
verify logic itself ran correctly — recurrence_defects were computed,
just never printed). Surfaced by the live modshells reconcile run while
closing the Scorecard epic (hypatia#260).
Normalise verify to a bare map at the task boundary (matching
reconcile/3's convention): {:ok, summary} -> summary; {:error, reason}
-> %{repo, verified: false, error: reason}. Both the success and the
no-token error path now emit clean JSON. Task-wrapper only; no change
to verify/2 or any tested code path; reconciler suite green.
Refs #260 #263.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
🔍 Hypatia Security ScanFindings: 13 issues detected
View findings[
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in mirror.yml",
"type": "missing_workflow",
"file": "mirror.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "believe_me undermines formal verification (2 occurrences, CWE-704)",
"type": "believe_me",
"file": "/home/runner/work/hypatia/hypatia/src/abi/RuleEngine.idr",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "Nickel file missing SPDX-License-Identifier header (1 occurrences, CWE-1104)",
"type": "ncl_missing_spdx",
"file": "/home/runner/work/hypatia/hypatia/configs/config.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (22 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "as_ptr exposes raw pointer that may dangle or alias unsafely (10 occurrences, CWE-676)",
"type": "as_ptr",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/codeberg.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/radicle.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
…egrity) The taiki-e/install-action step installed 'just' unpinned, tripping the governance R1 tooling-version-integrity rule (estate-canonical pin is just@1.34.0, matching other estate workflows). Pre-existing on main; fixed here so #272 can clear governance / Security policy checks. The Language/anti-pattern (Python) red was a stale run against the pre-escape governance-reusable; the bench scripts already carry both .hypatia-ignore entries and inline hypatia:ignore pragmas, so it resolves on re-run against current standards/main. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eliminates the last org-policy Python carve-out: replaces
scripts/{check-bench-regression,update-bench-baselines}.py with a
standalone, zero-dependency Rust crate (scripts/bench-tools/, deliberately
outside the workspace so it never perturbs the main build / proof gates).
- Faithful 1:1 port: same criterion bencher parsing, same Markdown
summary + ::error:: annotations, same exit codes (0/1/2), and a
byte-identical baselines.json serializer (Python json.dumps indent=2,
sort_keys=False semantics; insertion order + int tokens preserved).
Behaviour verified across advisory / regression / no-regression /
empty-input / usage-error cases.
- tests.yml + benchmarks/README.md rewired to 'cargo run --manifest-path'.
- Removed the now-moot exemptions: .hypatia-ignore lines,
.hypatia-exemptions.md rows, and the stale .hypatia-baseline.json
banned_language_file entries — so the carve-out can't become drift.
Unblocks #272's governance / Language anti-pattern by eliminating the
Python rather than suppressing it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Completes human-facing docs for the #272 governance fixes so nothing is stale or undocumented: - CHANGELOG.adoc [Unreleased]: bench Python→Rust port + just@1.34.0 pin. - scripts/README.adoc: document the new scripts/bench-tools/ crate (previously an undocumented directory). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| @@ -0,0 +1,331 @@ | |||
| // SPDX-License-Identifier: PMPL-1.0-or-later | |||
🔍 Hypatia Security ScanFindings: 14 issues detected
View findings[
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in mirror.yml",
"type": "missing_workflow",
"file": "mirror.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "believe_me undermines formal verification (2 occurrences, CWE-704)",
"type": "believe_me",
"file": "/home/runner/work/hypatia/hypatia/src/abi/RuleEngine.idr",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "Nickel file missing SPDX-License-Identifier header (1 occurrences, CWE-1104)",
"type": "ncl_missing_spdx",
"file": "/home/runner/work/hypatia/hypatia/configs/config.ncl",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (22 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "as_ptr exposes raw pointer that may dangle or alias unsafely (10 occurrences, CWE-676)",
"type": "as_ptr",
"file": "/home/runner/work/hypatia/hypatia/clients/rust/hypatia-client/src/ffi.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/codeberg.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (1 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/hypatia/hypatia/adapters/src/radicle.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
…panic) Resolves the Hypatia code-scanning alert introduced by PR #272's Python->Rust port: lib.rs number() now propagates the (statically-unreachable, ASCII-only) UTF-8 error via ? instead of unwrap(), mirroring the existing \u handler. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
scripts/bench-tools/src/lib.rs used char::from_u32(cp).unwrap_or('\u{fffd}').
unwrap_or is infallible (cannot panic), but Hypatia's
code_safety/unwrap_without_check rule matches the `unwrap` substring inside
`unwrap_or` and raised a file-level (line 1, zero-width) DoS-via-panic / CWE-754
error, blocking this PR. map_or('\u{fffd}', |c| c) is behaviour-identical and
carries no `unwrap` token. Root cause is the scanner rule, not this code —
tracked separately; this is the minimal unblock for #272.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Tiny follow-up to the merged Scorecard epic (#260). Surfaced by the live
mix hypatia.reconcile hyperpolymath/modshells --verifyrun.Bug
ScorecardReconciler.verify/2returns{:ok, summary} | {:error, reason};reconcile/3returns a bare map. The mix task fed the raw result toJason.encode!/2, which cannot encode a tuple — so--verifycrashed on output. The verify logic ran correctly (recurrence-defects were computed); only the print failed.Fix
Normalise
verifyto a bare map at the task boundary, matchingreconcile/3's convention:{:ok, summary}→summary{:error, reason}→%{repo, verified: false, error: reason}Task-wrapper only — no change to
verify/2or any tested code path.Verification
--verifywith token → clean JSON ({"recurrence_defects": [], "repo": "hyperpolymath/modshells"})--verifywithout token (also previously crashed) → clean JSON ({"error": "GITHUB_TOKEN not set", ...})Refs #260 #263.
🤖 Generated with Claude Code