fix(workspace): permissive-by-default git mutation gates#43
Merged
Conversation
The `datamachine_workspace_git_policies` option gates git mutation ops (pull / add / commit / push) and git_add's path allowlist. Before this change, unconfigured repos (the default state — no option row, no CLI to populate it, no docs describing it) would fail every git mutation with `git_write_disabled` / `no_allowed_paths`, making the workspace wrapper's git-family subcommands unusable out of the box and forcing callers back to plain `git -C <path>` shells. Root cause: the policy check treated "no entry" the same as "explicitly disabled". Combined with the lack of any way to configure the option (no CLI subcommand, no admin UI, no docs), this was effectively a hidden hard gate. Change: - `ensure_git_mutation_allowed()`: null entry → permissive (true). Entry present → honor explicit flags, with `write_enabled` / `push_enabled` defaulting to true when the flag itself is missing (so a partial config e.g. only `allowed_paths` doesn't accidentally lock out writes). - `git_add()`: empty allowlist → no restriction (sensitive-path and traversal checks still enforced unconditionally). - Error messages clarified to point at the policy option. - New `datamachine_workspace_git_policies` filter for runtime policy injection alongside the existing option. - `get_workspace_git_policies()` docblock documents schema + defaults. The primary-vs-worktree gate (`ensure_primary_mutation_allowed` + `--allow-primary-mutation` override) is the documented default safety mechanism (per AGENTS.md) and is unchanged. That's the intended protection layer. To restrict a repo explicitly: add an entry under `datamachine_workspace_git_policies.repos[<name>]` with `write_enabled: false` / `push_enabled: false` / an `allowed_paths` list / a `fixed_branch` constraint.
chubes4
added a commit
that referenced
this pull request
Apr 21, 2026
Fold all unreleased work (GitSync Phases 1-3, WorktreeCleanupTask, workspace git policy fix, AGENTS.md changes) under a single [0.7.0] heading so homeboy's release pipeline can promote it. Previous fix PR (#43) manually labeled the changelog [0.6.3] which didn't match homeboy's auto-detected minor bump from the accumulated feat: commits since v0.6.2. No functional code change — just changelog labeling + version constant alignment. Going forward: use 'homeboy changelog add -m ... -t ...' to append unreleased entries and let 'homeboy release' assign the version.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
datamachine_workspace_git_policiesWordPress option gates git mutation ops (pull/add/commit/push) andgit_add's path allowlist in the workspace wrapper. Before this change, every unconfigured repo failed every git mutation withgit_write_disabledorno_allowed_paths, making the wrapper's git-family subcommands unusable out of the box.Repro
On a fresh install (no
datamachine_workspace_git_policiesoption set):The
--allow-primary-mutationflag (the override documented in AGENTS.md) never gets evaluated because an earlier, undocumented gate fires first. The error message doesn't reference the option key or suggest a fix.Workaround before this PR:
git -C /var/lib/datamachine/workspace/<repo> pull— bypassing the wrapper entirely.Root cause
ensure_git_mutation_allowed()treated "no entry in policy array" identically to "explicitly disabled":Combined with:
workspace --helphas no policy subcommands)…this was a hidden hard gate with no configuration surface.
A second, analogous gate lived in
git_add(): theallowed_pathscheck returnedno_allowed_pathswhen the list was empty, which it always is by default.Fix
Permissive-by-default. The policy option becomes an opt-in restriction layer instead of a hidden requirement:
ensure_git_mutation_allowed()—nullentry → allow. Entry present → honor explicit flags.write_enabled/push_enableddefault totruewhen the flag itself is missing, so a partial config (e.g. only settingallowed_paths) doesn't accidentally disable writes.git_add()— emptyallowed_paths→ no restriction. When configured, the allowlist still gates. Sensitive-path + traversal checks are always enforced regardless of policy.Error messages now reference the policy option by name, so if someone does hit a deny, they know what to look at.
New filter
datamachine_workspace_git_policiesfor runtime injection of policy (e.g. env-specific, or driven by site config managed elsewhere) without writing to the option.get_workspace_git_policies()docblock documents the schema (write_enabled,push_enabled,allowed_paths,fixed_branch) and the permissive defaults.What doesn't change
The primary-vs-worktree gate (
ensure_primary_mutation_allowed+--allow-primary-mutationoverride) is the documented default safety mechanism per AGENTS.md:That gate is untouched. It's the intended protection layer — the one users read about and expect.
To explicitly deny a repo
Set an option entry:
Or via the filter:
Files
inc/Workspace/Workspace.php— gate logic + filter + docblockdata-machine-code.php— version bump 0.6.2 → 0.6.3docs/CHANGELOG.md— entry addedTesting
No existing unit tests cover the workspace git mutation gates (only
tests/smoke-gitsync.phpcovers the separate GitSync subsystem, which uses its own policy storage viaGitSync::updatePolicy()and is unaffected by this change).Manual verification: with this PR applied,
workspace git pull <repo> --allow-primary-mutationandworkspace git commit/push <repo>@<branch>succeed on an unconfigured workspace, matching AGENTS.md's documented contract.Related
Not blocking but discovered during a data-machine release cascade that involves pulling
mainvia the workspace wrapper. With this fix, the wrapper becomes usable for its intended workflows without requiring manual option configuration first.