Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build-gossamer-gui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ jobs:
if [ -z "$cli" ]; then
echo "::error::No ephapax CLI binary produced by 'cargo build --release --workspace'."
echo "Contents of $release_dir:"
ls -la "$release_dir" 2>/dev/null || true
# No mask: this branch fails either way, and a failing `ls`
# (missing dir) is itself the diagnosis, so let its error show.
ls -la "$release_dir"
exit 1
fi

Expand Down
78 changes: 28 additions & 50 deletions .github/workflows/inbox-steward-intake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ jobs:
env:
EVENT_JSON: ${{ toJson(github.event) }}
DRY_RUN: ${{ inputs.dry_run }}
GH_TOKEN: ${{ secrets.FARM_PAT }}
run: |
set -euo pipefail

Expand Down Expand Up @@ -101,13 +102,14 @@ jobs:
echo "validated_count=$VALIDATED" >> "$GITHUB_OUTPUT"
echo "merged_count=$MERGED" >> "$GITHUB_OUTPUT"

# Commit the report
if [ "$DRY_RUN" = "false" ]; then
# Publish the report through a PR. `inputs.dry_run` is empty on
# repository_dispatch, so only an explicit 'true' is a dry run.
if [ "$DRY_RUN" != "true" ]; then
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$REPORT_PATH"
git commit -m "inbox-steward: record from $SOURCE_REPO ($PR_COUNT PRs, $MERGED merged)" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push report"
bash scripts/open-data-pr.sh report \
"inbox-steward: record from $SOURCE_REPO ($PR_COUNT PRs, $MERGED merged)" \
"$REPORT_PATH"
else
echo "::notice::Dry run - not committing report"
fi
Expand Down Expand Up @@ -234,12 +236,10 @@ jobs:
id: update
env:
RULE_UPDATES: ${{ needs.analyze-patterns.outputs.rule_updates }}
GH_TOKEN: ${{ secrets.FARM_PAT }}
run: |
set -euo pipefail

# Load existing baseline
BASELINE_PATH=".hypatia-baseline.json"


# Create rule update file
UPDATES_DIR="data/ruleset-updates"
mkdir -p "$UPDATES_DIR"
Expand All @@ -256,39 +256,19 @@ jobs:

echo "Created rule updates: $UPDATE_FILE"

# Auto-apply critical/high priority updates
CRITICAL_UPDATES=$(echo "$RULE_UPDATES" | jq '[.[] | select(.priority == "critical" or .priority == "high")]')

if [ "$(echo "$CRITICAL_UPDATES" | jq length)" -gt 0 ]; then
echo "Applying critical/high priority updates..."

for UPDATE in $(echo "$CRITICAL_UPDATES" | jq -c '.[]'); do
UPDATE_TYPE=$(echo "$UPDATE" | jq -r '.type')
ACTION=$(echo "$UPDATE" | jq -r '.action')
REASON=$(echo "$UPDATE" | jq -r '.reason')
SUGGESTION=$(echo "$UPDATE" | jq -r '.suggestion')

echo " - $UPDATE_TYPE: $ACTION ($REASON)"

# Apply the update to baseline
# For now, append as a comment/todo - full automation needs more logic
echo " :: TODO: Apply rule update: $SUGGESTION" >> "$BASELINE_PATH"
done

# Commit updates
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$UPDATE_FILE" "$BASELINE_PATH"
git commit -m "inbox-steward: apply critical rule updates from steward reports" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push updates"
else
echo "No critical/high priority updates to apply"
git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
git add "$UPDATE_FILE"
git commit -m "inbox-steward: record rule update suggestions" 2>/dev/null || true
git push origin HEAD 2>/dev/null || echo "::warning::Could not push updates"
fi
# Critical/high suggestions are surfaced, not applied. This step used
# to append " :: TODO: …" text lines to .hypatia-baseline.json,
# which corrupts the JSON the Governance baseline gate reads. The
# suggestions live only in $UPDATE_FILE (`applied: false`).
echo "$RULE_UPDATES" \
| jq -r '.[] | select(.priority == "critical" or .priority == "high")
| "::notice title=Rule update suggested (\(.priority))::\(.type): \(.action) (\(.reason)) — \(.suggestion)"'

git config user.name "Inbox Steward Intake"
git config user.email "inbox-steward-intake@reposystem.dev"
bash scripts/open-data-pr.sh rule-updates \
"inbox-steward: record rule update suggestions" \
"$UPDATE_FILE"

# Job 4: Dispatch to .git-private-farm for fleet-wide application
dispatch-to-farm:
Expand Down Expand Up @@ -333,14 +313,12 @@ jobs:

echo "Dispatching to .git-private-farm: $(echo "$PAYLOAD" | jq -c '.')"

# Send to .git-private-farm
if gh api -X POST \
"/repos/hyperpolymath/.git-private-farm/dispatches" \
--input - <<<"$PAYLOAD" >/dev/null 2>&1; then
echo "✅ Successfully dispatched to .git-private-farm"
else
echo "::warning::Failed to dispatch to .git-private-farm"
fi
# Send to .git-private-farm. A refused dispatch fails the job; it
# used to be swallowed into a warning with stderr discarded.
gh api -X POST \
"/repos/hyperpolymath/.git-private-farm/dispatches" \
--input - <<<"$PAYLOAD" >/dev/null
echo "✅ Successfully dispatched to .git-private-farm"

# Job 5: Summary
summary:
Expand Down
18 changes: 14 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,20 @@ jobs:
# legitimately mention these tokens as documentation
# ("Zero believe_me." in src/Hypatia/ABI/RuleEngine.idr is the canonical
# example).
DANGEROUS=$(find lib src \( -name '*.idr' -o -name '*.v' -o -name '*.lean' -o -name '*.hs' \) \
-not -path 'lib/rules/*' \
-exec grep -Hn 'believe_me\|assert_total\|\bsorry\b\|\bAdmitted\b\|unsafeCoerce' {} + 2>/dev/null \
| grep -v ':[[:space:]]*--' || true)
#
# grep exits 1 when nothing matches, which is the PASS case, and 2
# on a real error. Test the status rather than masking both with
# `|| true` (`lib/rules` is the only `rules` directory under lib/src).
set -euo pipefail
status=0
HITS=$(grep -rHn --include='*.idr' --include='*.v' --include='*.lean' --include='*.hs' \
--exclude-dir=rules \
'believe_me\|assert_total\|\bsorry\b\|\bAdmitted\b\|unsafeCoerce' lib src) || status=$?
if [ "$status" -gt 1 ]; then
echo "FAIL: grep error (exit $status)"
exit "$status"
fi
DANGEROUS=$(printf '%s' "$HITS" | sed '/:[[:space:]]*--/d')
if [ -n "$DANGEROUS" ]; then
echo "FAIL: Dangerous patterns found"
echo "$DANGEROUS"
Expand Down
12 changes: 11 additions & 1 deletion lib/rules/research_extensions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ defmodule Hypatia.Rules.ResearchExtensions do
suite goes green while real failures pile up. Provenance: Datadog
CI Visibility flake-masking patterns.

`|| true` on a `trap …` line is not counted: the handler runs after the
step's status is decided and cannot mask it.

Severity: `:warn`. Action: `:report`.
"""
def re005_test_swallows_exit(repo_path) do
Expand Down Expand Up @@ -619,7 +622,14 @@ defmodule Hypatia.Rules.ResearchExtensions do

has_continue_on_error? = Regex.match?(~r/continue-on-error:\s*true\b/, stripped_body)

has_or_true? = Regex.match?(~r/\|\|\s*true\b/, stripped_body)
# A `trap` handler's `|| true` is not a swallow. The step's exit status
# is decided before the EXIT trap runs, and a failing handler command
# under `set -e` (e.g. `kill` of an already-exited PID) would itself
# turn a PASSING step red, so the `|| true` is what keeps it honest.
has_or_true? =
stripped_body
|> String.replace(~r/^[ \t]*trap[ \t].*$/m, "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve commands after trap registrations

For a multiline run block containing a valid same-line sequence such as trap 'cleanup' EXIT; cargo test || true, this replacement deletes the entire physical line rather than only the trap handler, so RE005 returns no finding even though the test failure is swallowed. Strip only the quoted trap command, or retain and scan commands following the trap registration.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #947 (this PR has merged). Only the quoted trap handler is dropped now, so trap '…' EXIT; cargo test || true is reported. There's a test for it.


Generated by Claude Code

|> then(&Regex.match?(~r/\|\|\s*true\b/, &1))

# A step carrying `hypatia:ignore RE005 -- <reason>` (or the
# `hypatia: allow research_extensions/RE005` spelling) is reviewed —
Expand Down
Loading
Loading