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
1 change: 1 addition & 0 deletions .github/workflows/bridge-gate.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/build-gossamer-gui.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Build the Hypatia GUI wasm artifact from the Ephapax/Gossamer sources.
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci-health-sweep.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Owner: Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Main CI workflow for hypatia
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/clusterfuzzlite.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
name: CodeQL Security Analysis
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/dependabot-automerge.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
#
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/dogfood-gate.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/estate-rescan.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Hypatia Estate Rescan — refresh verisimdb-data/scans with current truth
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/governance.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: PMPL-1.0-or-later
# This workflow is managed by gh actions-lock.
name: Governance
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/hypatia-remediation-sweep.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Hypatia Remediation Sweep — fleet-wide proactive scan
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/hypatia-scan.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: PMPL-1.0-or-later
# This workflow is managed by gh actions-lock.
name: Hypatia Security Scan
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/inbox-steward-intake.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Inbox Steward Intake — Process reports from gitbot-fleet inbox-steward
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/label-triage.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
name: Label Triage

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/labels.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
name: Labels

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/language-blockers.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/merge-orchestrate.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/mirror.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
name: Mirror to Git Forges
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
name: GitHub Pages (Ddraig SSG)
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/push-email-notify.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Dormant push-email notification. ARMED by setting the repo variable
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/roadmap-sync.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Centralized roadmap sweeper: adds recently-touched issues & PRs from every
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: PMPL-1.0-or-later
# This workflow is managed by gh actions-lock.
name: OSSF Scorecard
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/secret-scanner.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
name: Secret Scanner
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/security-policy.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/verify-proofs.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# This workflow is managed by gh actions-lock.
# SPDX-License-Identifier: MPL-2.0
# This workflow is managed by gh actions-lock.
# Consolidated workflow (behaviour-preserving merge).
Expand Down
16 changes: 16 additions & 0 deletions data/verisim/recipes/recipe-retired-descriptile-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": "recipe-retired-descriptile-policy",
"name": "Align CI descriptile checks with the canonical tree",
"description": "Repair the policy reference only after the canonical descriptile exists; never recreate retired copies.",
"triangle_tier": "eliminate",
"pattern_ids": ["SD024", "structural_drift/SD024"],
"target_categories": ["RetiredDescriptilePolicy"],
"languages": ["yaml", "shell", "bash", "just"],
"confidence": 0.95,
"auto_fixable": true,
"fix_script": "fix-retired-descriptile-policy.sh",
"action": "replace",
"formally_proven": false,
"successful_fixes": 0,
"failed_fixes": 0
}
1 change: 1 addition & 0 deletions lib/hypatia/cli.ex
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ defmodule Hypatia.CLI do
reason: f.reason,
action: to_string(f.action)
}
|> Map.merge(Map.take(f, [:line, :category, :recipe_id, :fix_script, :target]))
end)

results ++ normalized
Expand Down
70 changes: 69 additions & 1 deletion lib/rules/structural_drift.ex
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,8 @@ defmodule Hypatia.Rules.StructuralDrift do
sd013_path_specific_gitignore(repo_path) ++
sd014_safedom_example_dialect(repo_path) ++
sd022_stale_path_after_rename(repo_path) ++
sd023_state_a2ml_divergence(repo_path)
sd023_state_a2ml_divergence(repo_path) ++
sd024_retired_descriptile_policy(repo_path)

needs_intensive = Enum.any?(findings, & &1[:trigger_intensive])
needs_alert = Enum.any?(findings, & &1[:alert_user])
Expand All @@ -762,6 +763,73 @@ defmodule Hypatia.Rules.StructuralDrift do

# ─── Helpers ───────────────────────────────────────────────────────────

@doc """
SD024: Detect executable policy that requires descriptiles in retired paths.

A canonical tree can never satisfy such a check and SD004 simultaneously.
Report the policy file for reference repair; do not suggest recreating the
retired file. Documentation and commented examples are outside this rule.
"""
def sd024_retired_descriptile_policy(repo_path) do
files =
Path.wildcard(Path.join(repo_path, ".github/workflows/*.{yml,yaml}")) ++
Path.wildcard(Path.join(repo_path, "scripts/*.sh")) ++
Path.wildcard(Path.join(repo_path, ".githooks/*.sh")) ++
Enum.map(["Justfile", "justfile"], &Path.join(repo_path, &1))

Enum.flat_map(files, fn file ->
case File.read(file) do
{:ok, content} ->
content
|> String.split("\n")
|> Enum.with_index(1)
|> Enum.flat_map(fn {line, number} ->
legacy =
~r/\.machine_readable\/(?:6a2\/)?(?:STATE|META|ECOSYSTEM|AGENTIC|NEUROSYM|PLAYBOOK|ANCHOR)\.a2ml/

# Quoted examples are prose, but quoted literal paths and shell
# command substitutions still participate in executable checks.
code =
Regex.replace(~r/"(?:\\.|[^"\\])*"|'[^']*'/, line, fn quoted ->
value = String.slice(quoted, 1, String.length(quoted) - 2)

if Regex.match?(~r/^#{legacy.source}$/, value) or
(String.starts_with?(quoted, "\"") and
(String.contains?(value, "$(") or String.contains?(value, "`"))) do
value
else
" "
end
end)

if not String.starts_with?(String.trim_leading(line), "#") and
Regex.match?(~r/(?:\s-f\s|\s-e\s|check_file\s)/, code) and
Regex.match?(legacy, code) do
[
%{
rule: "SD024",
file: Path.relative_to(file, repo_path),
line: number,
severity: :high,
reason:
"CI policy requires a retired descriptile path; align the check with .machine_readable/descriptiles/",
category: "RetiredDescriptilePolicy",
action: :update_reference,
recipe_id: "recipe-retired-descriptile-policy",
fix_script: "fix-retired-descriptile-policy.sh"
}
]
else
[]
end
end)

{:error, _} ->
[]
end
end)
end

defp group_by_severity(findings) do
findings
|> Enum.group_by(& &1.severity)
Expand Down
55 changes: 55 additions & 0 deletions test/retired_descriptile_policy_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: MPL-2.0
defmodule Hypatia.RetiredDescriptilePolicyTest do
use ExUnit.Case, async: true
alias Hypatia.Rules.StructuralDrift

test "detects the contradictory check and routes reference repair" do
repo =
Path.join(System.tmp_dir!(), "descriptile-policy-#{System.unique_integer([:positive])}")

File.mkdir_p!(Path.join(repo, ".github/workflows"))
on_exit(fn -> File.rm_rf!(repo) end)
file = Path.join(repo, ".github/workflows/compliance.yml")
File.write!(file, "run: |\n if [ ! -f .machine_readable/STATE.a2ml ]; then exit 1; fi\n")
[finding] = StructuralDrift.sd024_retired_descriptile_policy(repo)
assert finding.rule == "SD024"
assert finding.line == 2
assert finding.action == :update_reference
assert finding.fix_script == "fix-retired-descriptile-policy.sh"

normalized =
Hypatia.CLI.collect_findings(repo, [:structural_drift])
|> Enum.find(&(&1.type == "SD024"))

assert normalized.category == "RetiredDescriptilePolicy"
assert normalized.recipe_id == "recipe-retired-descriptile-policy"
assert normalized.fix_script == "fix-retired-descriptile-policy.sh"
assert normalized.line == 2

File.write!(
file,
"run: |\n if [ ! -f .machine_readable/descriptiles/STATE.a2ml ]; then exit 1; fi\n"
)

assert StructuralDrift.sd024_retired_descriptile_policy(repo) == []
File.write!(file, "# if [ ! -f .machine_readable/6a2/STATE.a2ml ]; then exit 1; fi\n")
assert StructuralDrift.sd024_retired_descriptile_policy(repo) == []

for prose <- [
~s(echo "test -f .machine_readable/STATE.a2ml"),
~s(printf '%s' 'check_file .machine_readable/META.a2ml')
] do
File.write!(file, "run: |\n #{prose}\n")
assert StructuralDrift.sd024_retired_descriptile_policy(repo) == []
end

for command <- [
~s(test -f ".machine_readable/STATE.a2ml"),
~s(test -e '.machine_readable/6a2/META.a2ml'),
~s(check_file '.machine_readable/AGENTIC.a2ml')
] do
File.write!(file, "run: |\n #{command}\n")
assert [%{rule: "SD024"}] = StructuralDrift.sd024_retired_descriptile_policy(repo)
end
end
end
Loading