Complete autonomous recovery controls

This commit is contained in:
kami
2026-07-30 14:57:25 +04:00
parent 8174400b1a
commit e8fadfc998
18 changed files with 364 additions and 77 deletions
+12
View File
@@ -29,6 +29,11 @@ type Project struct {
Repo string `json:"repo,omitempty"`
WorktreeRoot string `json:"worktree_root,omitempty"`
QualityGate string `json:"quality_gate,omitempty"`
// SafeOperations is an audited, deliberately small allow-list for work
// inside this project's task worktree. It documents what workers may
// perform without an operator grant; network, secrets, destructive Git,
// and paths outside the worktree are never represented here.
SafeOperations []string `json:"safe_operations,omitempty"`
}
type Machine struct {
ID string `json:"id"`
@@ -131,6 +136,13 @@ func New(c Config) (Registry, error) {
if len(p.MachineAffinity) == 0 {
return Registry{}, fmt.Errorf("project %q: %w", p.ID, ErrNoAffinity)
}
for _, op := range p.SafeOperations {
switch op {
case "read", "edit", "test", "git":
default:
return Registry{}, fmt.Errorf("project %q: unsafe operation %q is not policy-configurable", p.ID, op)
}
}
r.projects[p.ID] = p
}
for _, m := range c.Machines {
+10
View File
@@ -34,3 +34,13 @@ func TestNewRejectsBrokenReferences(t *testing.T) {
t.Fatalf("err=%v", err)
}
}
func TestProjectSafeOperationsAreNarrowAndAudited(t *testing.T) {
_, err := New(Config{Projects: []Project{{ID: "p", MachineAffinity: []string{"m"}, SafeOperations: []string{"read", "network"}}}, Machines: []Machine{{ID: "m", Address: "m:1"}}})
if err == nil {
t.Fatal("network operation was accepted into no-grant policy")
}
if _, err := New(Config{Projects: []Project{{ID: "p", MachineAffinity: []string{"m"}, SafeOperations: []string{"read", "edit", "test", "git"}}}, Machines: []Machine{{ID: "m", Address: "m:1"}}}); err != nil {
t.Fatalf("safe policy rejected: %v", err)
}
}