security: add the capability and policy layer as the only path to action
Phase 12 (ADR-0005). Capabilities are registered in code with parameter schemas, risk classes and default effects; sudo_shell and delete_database are locked to DENY and cannot be relaxed. Policies are scoped globally or per mind with capability, target glob, action kind and optional hour window; evaluation is deterministic, most specific wins, and ties go to the stricter effect. Invoke is the single entry point: it refuses dreaming and replay contexts, validates parameters (unknown keys, non http URLs and path traversal rejected), evaluates policy and session grants, hashes the exact request and records a policy_decision event. ALLOW executes with timeout and panic isolation and turns textual output into a tool-trust observation; ASK creates an approval request bound to the hash with an alert notification; DENY is counted and recorded. Operators approve once, approve for a time-boxed session grant, deny with a note, or modify parameters (re-validated, re-hashed, original kept in the append-only decision log). The self-model's capability list is recomputed from effective policy on start and on every policy change. The act process maps fetch requests to http.fetch and the action handler invokes through the layer; replies report capabilities and outcomes. Policy matrix and approval centre pages, dashboard count, API, CLI (approvals, policy, invoke) and docs/capabilities.md.
This commit is contained in:
@@ -200,12 +200,24 @@ func (h Handlers) buildIntent(ctx context.Context, c *brain.Cycle, a conversatio
|
||||
}
|
||||
case "request":
|
||||
in.Kind = "decline"
|
||||
caps := c.State.SelfModel.Capabilities
|
||||
if len(caps) == 0 {
|
||||
var usable []string
|
||||
for _, cap := range c.State.SelfModel.Capabilities {
|
||||
if cap.Policy == "allow" || cap.Policy == "ask" {
|
||||
usable = append(usable, cap.Name+" ("+cap.Policy+")")
|
||||
}
|
||||
}
|
||||
if len(usable) == 0 {
|
||||
in.Summary = "Explain honestly that no external capabilities are granted, so the request cannot be carried out; offer what is known instead."
|
||||
in.Points = append(in.Points, "I have no capabilities granted to act on external systems.")
|
||||
} else {
|
||||
in.Summary = "Explain which capabilities exist and that actions require policy approval."
|
||||
in.Kind = "acknowledge"
|
||||
in.Summary = "Say which capabilities could apply and that any action goes through policy; if one was proposed this cycle its status is in working memory."
|
||||
in.Points = append(in.Points, "Capabilities I may use: "+strings.Join(usable, ", ")+".")
|
||||
for _, it := range c.Runtime.Workspace().WorkingMemory {
|
||||
if strings.HasPrefix(it.Key, "action:") {
|
||||
in.Points = append(in.Points, "Action status: "+it.Content)
|
||||
}
|
||||
}
|
||||
}
|
||||
h.addKnowledge(ctx, c, &in, topic)
|
||||
case "introspection":
|
||||
|
||||
Reference in New Issue
Block a user