check_managed_files¶
rhiza_hooks.check_managed_files
¶
Refuse to commit an edit to a file the rhiza template owns.
A rhiza-managed repo syncs its development infrastructure from a template repo,
and every such repo's CLAUDE.md opens with the same rule: do not edit the managed
files, because the next sync overwrites them. Until this hook there was nothing
enforcing it — make validate, the one drift check that existed, was removed
upstream after rhiza v1.1.3.
So the failure mode was silent and total: edit a managed file, watch it work, get it reviewed and merged, and lose it at the next sync with no error at any point. This hook makes that loud at the commit that causes it.
The check is path-based, because .rhiza/template.lock records paths and no
content hashes. That is the right signal anyway — the objection is not "your edit
is wrong" but "this file is not yours to edit".
Only a file that actually differs from HEAD is reported, not merely one that is
managed and present. pre-commit normally passes just the staged paths, but under
--all-files — which make fmt and CI use — it passes every tracked file, and
without this the hook would report all sixty-odd managed files on a clean tree.
When git cannot answer (no HEAD yet, or no git at all) the hook falls back to
trusting the paths it was given, which is pre-commit's normal contract.
Bypassing it
- a path listed under
exclude:in.rhiza/template.ymlis not synced, so it is not managed and never reported (see :mod:rhiza_hooks._managed); --allow PATHwaives one path for a deliberate, knowingly-temporary override;SKIP=check-managed-files git commitwaives the whole hook, which is what arhiza synccommit needs, since rewriting managed files wholesale is exactly its job.
Exit codes
0 - no managed file is being modified 1 - at least one managed file is being modified
check_managed_files(filenames, repo_root, allowed)
¶
Report each given path that the template owns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filenames
|
list[str]
|
Paths being committed, as passed by pre-commit. |
required |
repo_root
|
Path
|
Root directory of the repository. |
required |
allowed
|
set[str]
|
Paths waived via |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of error messages, one per offending path (empty when none is managed). |
Source code in rhiza_hooks/check_managed_files.py
main(argv=None)
¶
Run the hook and return a process exit code.
Source code in rhiza_hooks/check_managed_files.py
modified_paths(repo_root)
¶
Return the tracked paths that differ from HEAD, staged or not.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_root
|
Path
|
Root directory of the repository. |
required |
Returns:
| Type | Description |
|---|---|
set[str] | None
|
Repo-relative paths with changes, or None when git cannot answer — no git on |
set[str] | None
|
PATH, no commits yet, or not a work tree. The caller then trusts the paths it |
set[str] | None
|
was handed instead of narrowing them. |
Source code in rhiza_hooks/check_managed_files.py
repo_relative(filename, repo_root)
¶
Normalise a hook argument to a repo-relative POSIX path for comparison.
pre-commit already passes repo-relative paths, but a hand-run invocation may
pass absolute or ./-prefixed ones. A path outside the repository is
returned as-is: it cannot match a managed path, so it is reported by nobody.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
Path as given on the command line. |
required |
repo_root
|
Path
|
Root directory of the repository. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The path, relative to |