Skip to content

feat(risk): promote control-plane paths to HIGH risk (Closes #179) - #185

Merged
ytnobody merged 1 commit into
developfrom
hermit/ytnobody/issue-179
Jul 28, 2026
Merged

feat(risk): promote control-plane paths to HIGH risk (Closes #179)#185
ytnobody merged 1 commit into
developfrom
hermit/ytnobody/issue-179

Conversation

@ytnobody

Copy link
Copy Markdown
Owner

Summary

DefaultConfig().HighPaths now includes HERMIT's own control-plane surfaces, so PRs touching only these paths are always HIGH (never auto-merged), regardless of file/line count:

  • internal/risk/
  • internal/permissions/
  • internal/readiness/
  • harness.toml
  • .claude/
  • CLAUDE.md

HighPaths is checked before MediumPaths and returns as soon as it matches, so a change confined to internal/risk/ is now HIGH instead of the previous MEDIUM (via the broader internal/ prefix).

The list intentionally includes itself: internal/risk/ (the evaluator's own source) and harness.toml (whose [risk] section can override high_paths) are both in the list, so a future PR that tries to remove a path from high_paths to weaken the guard is itself a change to internal/risk/ and/or harness.toml, and therefore always trips HIGH.

cmd/hermit/templates/CLAUDE.md.tmpl and cmd/hermit/templates/harness.toml.tmpl are unaffected — they remain excluded via the pre-existing ExcludePaths = ["cmd/hermit/templates/"] entry, since they are scaffold content shipped to user projects, not HERMIT's own control plane.

Assumption (Issue was otherwise unambiguous)

None needed — the Issue's required path list, exclusion behavior, and acceptance criteria were fully specified. New requirement was filed as REQUIREMENTS.md REQ-015 (next available REQ-ID after REQ-014) with a REQ-015-named test in internal/risk/req_test.go, following this repo's existing REQ-ID/test-naming convention.

Changes

  • internal/risk/evaluator.go: extended DefaultConfig().HighPaths with the six control-plane paths; documented the self-referential guard property in a comment.
  • internal/risk/req_test.go: added TestREQ015_ControlPlanePathsAreHighRisk covering all six new HIGH paths at 1 file / 1 line, HIGH-over-MEDIUM priority, a non-control-plane internal/ path staying MEDIUM, and the templates/-only diff staying LOW.
  • internal/risk/evaluator_test.go: updated TestDefaultConfig_MatchesLegacyHardcodedValues's hardcoded wantHighPaths list, since it directly encoded the old three-entry list this Issue deliberately expands (this is the intended behavior change, not a regression).
  • REQUIREMENTS.md: added REQ-015.
  • README.md: documented control-plane paths as HIGH by default in the Risk Evaluation Criteria table and the example [risk] config.
  • cmd/hermit/templates/harness.toml.tmpl: same documentation update for the template shipped to user projects.

Note on this PR's own risk classification

This PR itself modifies internal/risk/ and REQUIREMENTS.md/README.md/harness.toml.tmpl, so under the new rule it will (correctly) evaluate as HIGH risk and requires a human merge decision — this is expected and is the exact self-referential property the Issue asked for.

Test plan

  • go build ./...
  • go test ./... — all packages pass, including new REQ-015 test cases
  • go vet ./...

🤖 Generated with Claude Code

internal/risk/, internal/permissions/, internal/readiness/,
harness.toml, .claude/, and CLAUDE.md are the mechanisms that
constrain HERMIT itself. A PR that only touches one of them was
previously MEDIUM (via the internal/ prefix) or unclassified by path
at all, and so could auto-merge under its own judgment -- a
structurally invalid question. DefaultConfig().HighPaths now includes
these six control-plane paths alongside the existing cmd/, go.mod,
.github/ entries, and HighPaths is checked (and returns) before
MediumPaths, so a change confined to internal/risk/ is HIGH, not
MEDIUM, even at one file / one line.

The list intentionally names itself: internal/risk/ and harness.toml
(whose [risk] section can override HighPaths) are both included, so a
PR that tries to narrow this list to weaken the guard is itself HIGH.

cmd/hermit/templates/{CLAUDE.md,harness.toml}.tmpl remain covered by
the pre-existing ExcludePaths entry for cmd/hermit/templates/, since
they are scaffold content shipped to user projects, not HERMIT's own
control plane -- unaffected by this change.

Added REQUIREMENTS.md REQ-015 and TestREQ015_ControlPlanePathsAreHighRisk
covering all six new HIGH paths, the MEDIUM-vs-HIGH priority ordering,
a non-control-plane internal/ path staying MEDIUM, and the
templates/-only exclusion staying LOW. Also updated the pre-existing
TestDefaultConfig_MatchesLegacyHardcodedValues assertion, since it
directly encoded the old three-entry HighPaths list that this Issue
deliberately expands.

Updated README.md and cmd/hermit/templates/harness.toml.tmpl to
document that control-plane paths are HIGH by default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ytnobody

Copy link
Copy Markdown
Owner Author

Superintendentによるレビュー(PR #185, Issue #179)

evaluate_risk の判定は現状 MEDIUM(internal/risk/evaluator.go の変更が旧ルールの internal/ MEDIUM パスにのみ該当するため)ですが、これは自動マージしません。理由:

自己言及的なブートストラップ問題: このPRの目的そのものが「制御面(internal/risk/ を含む)への変更は自動マージすべきでない」という主張です。それを、まだこのPRがマージされていない=旧い(緩い)ルールで評価して自動マージしてしまうと、Issue #179が防ごうとしているまさにその抜け穴(「制御面を変更するPRが、その制御面自身の判定で通ってしまう」)を実演することになります。これは論理的に一貫しません。したがって、リスクレベルの数値に関わらず人間の判断を仰ぎます。

差分の内容確認

  • internal/risk/evaluator.go: DefaultConfig().HighPathsinternal/risk/, internal/permissions/, internal/readiness/, harness.toml, .claude/, CLAUDE.md を追加。EvaluateWithConfigHighPathsMediumPaths より先に判定するため、優先順位は正しく機能する
  • 自己参照性(internal/risk/ 自身・harness.toml 自身をリストに含める)が明示コメント付きで実装されており、Issue本文の「このリストは自分自身を含むこと」という要求を満たしている
  • cmd/hermit/templates/ のExcludePaths挙動は変更されていない(テストで確認済み)
  • テスト(TestREQ015_ControlPlanePathsAreHighRisk)は6つの制御面パス全てを1行diffでHIGH判定することを検証しており、要求された受け入れ条件を満たしている
  • README.md / harness.toml.tmpl の記載も追加されている
  • CIは全て成功(Test/Lint/Security Scan)

懸念点

推奨

コード自体の品質・テストカバレッジに問題はなく、実装内容はIssueの要求を満たしています。人間による承認後のマージを推奨します(上記のブートストラップ上の理由により、たとえMEDIUM判定であっても自動マージはスキップしました)。マージ順序を決める際はREQ-015番号衝突の解消も合わせてご検討ください。

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