Skip to content

fix(rsr): resolve the machine tree per repo, and accept real file locations - #725

Merged
hyperpolymath merged 1 commit into
mainfrom
chore/path-contract-machine-readable
Aug 26, 2026
Merged

fix(rsr): resolve the machine tree per repo, and accept real file locations#725
hyperpolymath merged 1 commit into
mainfrom
chore/path-contract-machine-readable

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Companion to hyperpolymath/rsr-template-repo#43 and hyperpolymath/standards#651.

The problem

The oracle could not score the estate's own spine. It hardcoded .machine_readable/ in eight places, and eleven criteria detectors named root paths that the April 2026 root cleanup had already moved.

Measured, against rsr-template-repo with the standards SSOT

stage result
before could not read the profile at all
after path fix tier=none · 74.29% · pass=31 · fail=14
after detector fix tier=silver · 92.77% · pass=42 · fail=3

Nothing stranded

A fabricated legacy-layout copy of the template (machine-readable/ renamed back to .machine_readable/) scores identicallytier=silver, 92.77%, profile=true. Both layouts, same verdict.

Hypatia.Paths.machine_tree/1 + machine_tree_join/2 resolve per repo at check time. Resolving to one name only would make whichever half of the estate had not migrated unscoreable — the same failure being fixed, in mirror image.

The three that still fail are real

Left failing because they are failing:

  • 4.1.3 sha-pinned — dogfood-gate.yml uses unpinned @main actions
  • 5.1.1 no-python — the template ships strip-instruction-blocks.py and prune-dependabot-ecosystems.py while the estate bans Python; it bans Python and ships Python, and every minted repo inherits both
  • 8.1.4 no-scaffold-stub

What this does NOT change

coverage stays 69% and provisional stays true, because 19 of 74 criteria are detect="manual". A provisional scorecard never satisfies --fail-under, so the dogfood gate's Gold requirement remains structurally unreachable until those detectors exist. Separate defect; not papered over here.

Scope

This fixes the scoring path. Ten other files under lib/ still construct .machine_readable paths directly (19 Path.join sites). They should move to the same resolver — left as a follow-up rather than half-done silently.

Compiles clean.

🤖 Generated with Claude Code

…ations

The oracle could not score the estate's own spine. It hardcoded
`.machine_readable/` in eight places, and eleven criteria detectors named root
paths that the April 2026 root cleanup had already moved.

MEASURED, against rsr-template-repo with the standards SSOT:

  before          could not read the profile at all
  after paths     tier=none    score=74.29%  pass=31  fail=14
  after detectors tier=silver  score=92.77%  pass=42  fail=3

The three that still fail are REAL defects, not path artefacts, and are left
failing because they are failing: 4.1.3 sha-pinned (dogfood-gate.yml uses
unpinned @main actions), 5.1.1 no-python (the template ships
strip-instruction-blocks.py and prune-dependabot-ecosystems.py while the estate
bans Python - it bans Python and ships Python, and every minted repo inherits
both), and 8.1.4 no-scaffold-stub.

Hypatia.Paths.machine_tree/1 + machine_tree_join/2 resolve a repo's machine tree
per repo at check time. The canonical name is `machine-readable/`; the dotted
`.machine_readable/` is legacy and still accepted, because the canon itself,
scaffoldia, the julia variant and ~300 minted repos still carry it. Resolving to
one name only would make whichever half of the estate had not migrated
unscoreable - which is precisely the failure being fixed, in mirror image.

VERIFIED no repo is stranded: a fabricated legacy-layout copy of the template
(machine-readable/ renamed back to .machine_readable/) scores IDENTICALLY -
tier=silver, 92.77%, profile=true. Both layouts, same verdict.

Eleven detectors now accept the locations their files legitimately occupy, via
the existing any_of/1 (and a new any_of_mr/1 for paths inside the machine tree):
SECURITY/CONTRIBUTING/CODE_OF_CONDUCT.md at root or .github/ - GitHub resolves
both, and .github/ is the estate's canonical location; MAINTAINERS/GOVERNANCE/
AFFIRMATION/AUDIT.adoc at root or docs/; CHANGELOG as .adoc or .md;
.pre-commit-config.yaml at root or ci/; ANCHOR.a2ml flat or under
descriptiles/anchors/, which is how the spine nests it.

Note what this does NOT change: coverage stays 69% and provisional stays true,
because 19 of 74 criteria are detect="manual". A provisional scorecard never
satisfies --fail-under, so the dogfood gate's Gold requirement remains
structurally unreachable until those detectors exist. That is a separate defect
and is not papered over here.

Scope: this fixes the scoring path. Ten other files under lib/ still construct
`.machine_readable` paths directly (structural_drift, root_hygiene, code_safety,
honest_completion, kin/gate, merge_orchestration/kin_gate and the mix tasks) -
19 Path.join sites in total. They should move to the same resolver; left as a
follow-up rather than half-done silently.

Compiles clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2f604d74-3df9-49e3-9a4f-4305da3952e8

📥 Commits

Reviewing files that changed from the base of the PR and between 5886fcd and cddabaf.

📒 Files selected for processing (2)
  • lib/paths.ex
  • lib/rules/rsr_conformance.ex

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⏰ Context from checks skipped due to timeout. (17)
  • GitHub Check: Integration Tests
  • GitHub Check: Cargo test
  • GitHub Check: Rust Tests
  • GitHub Check: governance / Validate Hypatia Baseline
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: criterion + baseline gate
  • GitHub Check: stress-test
  • GitHub Check: E2E — Rust CLI Scan
  • GitHub Check: Test
  • GitHub Check: k9iser manifest + build
  • GitHub Check: Build AsciiDoc
  • GitHub Check: analyze (javascript-typescript, none)
  • GitHub Check: Build Rust - x86_64-unknown-linux-gnu
  • GitHub Check: Build Rust - x86_64-pc-windows-msvc
  • GitHub Check: Build Rust - aarch64-apple-darwin
  • GitHub Check: Build Rust - x86_64-apple-darwin
  • GitHub Check: Build AsciiDoc
🔇 Additional comments (9)
lib/paths.ex (2)

23-45: LGTM!


47-52: LGTM!

lib/rules/rsr_conformance.ex (7)

17-18: LGTM!


181-187: LGTM!


337-346: LGTM!


356-366: LGTM!


381-411: LGTM!


424-424: LGTM!


435-437: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for resolving repository machine-readable content from the canonical machine-readable/ directory.
    • Continued support for repositories using the legacy .machine_readable/ directory.
    • Added flexible path handling for individual files and nested paths.
  • Bug Fixes

    • Improved conformance checks for community, governance, profiles and related machine-readable files across both directory layouts.
    • Recognises documented alternative file locations during validation.

Walkthrough

The change adds canonical and legacy machine-tree resolution. RSR conformance checks, descriptile lookup, and profile parsing now use the resolved tree and support documented alternate file locations.

Changes

Machine-tree conformance support

Layer / File(s) Summary
Machine-tree path resolution
lib/paths.ex
Adds machine_tree/1 and machine_tree_join/2 helpers. The resolver prefers machine-readable, then .machine_readable, and otherwise returns the canonical path.
RSR conformance integration
lib/rules/rsr_conformance.ex
Uses the resolved machine tree for capability discovery, criteria checks, descriptile lookup, and profile parsing. Community and governance checks accept documented alternate locations.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to cddab

This change makes repository scoring resolve machine-readable files from either supported layout and updates detectors to accept current file locations; no actionable merge-blocking risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant RSRConformance
  participant Hypatia.Paths
  participant RepositoryFilesystem
  participant DescriptileParser
  RSRConformance->>Hypatia.Paths: resolve machine_tree(repo_path)
  Hypatia.Paths->>RepositoryFilesystem: locate canonical or legacy machine-tree files
  RepositoryFilesystem-->>Hypatia.Paths: return resolved paths
  Hypatia.Paths-->>RSRConformance: provide machine-tree files
  RSRConformance->>DescriptileParser: parse descriptile and rsr-profile.a2ml
  DescriptileParser-->>RSRConformance: return parsed conformance data
Loading

Poem

A rabbit hops through paths both old and new
machine-readable leads the queue
Legacy trees remain in sight
Profiles parse with paths set right
Conformance checks now follow through

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarises the main change: per-repository machine-tree resolution and support for valid file locations.
Description check ✅ Passed The description directly explains the machine-tree path problem, the scoring changes, test results, remaining failures, and intentional scope limits.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gitar-bot

gitar-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@codacy-production codacy-production Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements dynamic resolution for machine-readable directories and updates criteria detectors to support flexible file locations. While the code is reported as 'up to standards' by Codacy, there are several implementation gaps and performance concerns that should be addressed before merging.

The most significant gap is the total absence of automated tests for the new directory resolution logic and the updated criteria detectors. Furthermore, the machine tree resolution introduces redundant filesystem I/O that could impact performance during repository scans. Finally, there is a risk of inconsistent behavior as 10 other files in the 'lib/' directory still rely on hardcoded legacy paths.

About this PR

  • There are no automated tests included for the new path resolution logic or the updated criteria detectors. Given the criticality of path resolution for scoring, unit tests for the 'machine_tree/1' logic and integration tests for the file location updates are highly recommended.
  • The PR description identifies 10 other files in 'lib/' that still use hardcoded '.machine_readable' paths. To ensure system-wide consistency and avoid bugs where parts of the engine fail to find the directory, these should be updated to use the new resolution logic in this PR or a subsequent task should be explicitly tracked.

Test suggestions

  • Verify machine_tree/1 returns 'machine-readable' when the canonical directory exists.
  • Verify machine_tree/1 returns '.machine_readable' when only the legacy directory exists.
  • Verify machine_tree/1 defaults to 'machine-readable' when neither directory exists.
  • Verify criteria detection passes when files are located in subdirectories (e.g., .github/SECURITY.md or docs/MAINTAINERS.adoc).
  • Verify profile capabilities are correctly parsed from rsr-profile.a2ml regardless of which machine tree name is used.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Verify machine_tree/1 returns 'machine-readable' when the canonical directory exists.
2. Verify machine_tree/1 returns '.machine_readable' when only the legacy directory exists.
3. Verify machine_tree/1 defaults to 'machine-readable' when neither directory exists.
4. Verify criteria detection passes when files are located in subdirectories (e.g., .github/SECURITY.md or docs/MAINTAINERS.adoc).
5. Verify profile capabilities are correctly parsed from rsr-profile.a2ml regardless of which machine tree name is used.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread lib/paths.ex
Comment thread lib/rules/rsr_conformance.ex
hyperpolymath added a commit to hyperpolymath/a2ml-ecosystem that referenced this pull request Aug 26, 2026
…ecks (#44)

## What broke

`validate-a2ml.sh` exempts files under a repo's machine tree from the
in-file identity requirement — per RSR convention those carry identity
*structurally* (owning repo + path + filename), not via
`name`/`agent-id`.

That exemption matched `.machine_readable/` **only**.
`rsr-template-repo` has renamed its machine tree to `machine-readable/`
(un-hidden, 2026-08), so its 16 typed manifests fell out of the
exemption's reach and this action began reporting 16 spurious *"Missing
required identity field"* errors against a tree that hadn't changed in
any way relevant to identity.

## Measured, run as the action runs it

| form | files scanned | errors |
|---|---|---|
| old, single-path | 123 | **16** |
| new, dual-path | 123 | **0** |

## How this was missed — worth recording

The template vendors its own copy at `.githooks/validate-a2ml.sh`, which
*was* updated with the rename and reported 0 errors locally. **This
action is a separate implementation of the same rule, in a different
repo, invoked as a pinned action.** So the local run was green while CI
was red — the local checker simply wasn't the checker CI uses.

Two copies of one rule; only one updated. That is the actual defect
class, and it is worth knowing the estate has at least one more of
these.

## Both names, not a swap

The canon, scaffoldia, the julia variant and ~300 minted repos still
carry the dotted form. Matching only the *new* name would relocate the
same breakage onto them rather than fix it.

The new `case` matches a **strict superset** of the old pattern, so it
can only ever exempt more — a legacy repo cannot regress. Verified:
scaffoldia (legacy tree) still reports 0 errors.

Remove the legacy alternative once the estate migration completes.

Companion to hyperpolymath/rsr-template-repo#43,
hyperpolymath/standards#651, hyperpolymath/hypatia#725.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@hyperpolymath
hyperpolymath merged commit 31d809a into main Aug 26, 2026
66 of 81 checks passed
@hyperpolymath
hyperpolymath deleted the chore/path-contract-machine-readable branch August 26, 2026 23:17
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.

1 participant