151 lines
4.9 KiB
Go
151 lines
4.9 KiB
Go
// Package policy modela la política de ejecución declarada en agent.md.
|
|
//
|
|
// La política decide qué puede hacer el agente. Su principio central es
|
|
// "fail closed": toda capacidad peligrosa que no esté declarada explícitamente
|
|
// se considera denegada, y el modo unrestricted solo se activa cuando
|
|
// agent.md lo pide literalmente.
|
|
package policy
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Mode es el nivel de autoridad general del agente.
|
|
type Mode string
|
|
|
|
const (
|
|
// ModeGuarded permite lectura, análisis y diagnóstico. Es el valor por defecto.
|
|
ModeGuarded Mode = "guarded"
|
|
// ModePrivileged permite administración activa dentro de las directivas.
|
|
ModePrivileged Mode = "privileged"
|
|
// ModeUnrestricted permite operaciones destructivas necesarias para la tarea.
|
|
ModeUnrestricted Mode = "unrestricted"
|
|
)
|
|
|
|
// Capability identifica una capacidad controlada por una directiva ALLOW_*.
|
|
type Capability string
|
|
|
|
const (
|
|
CapNetwork Capability = "ALLOW_NETWORK"
|
|
CapWebResearch Capability = "ALLOW_WEB_RESEARCH"
|
|
CapDownloads Capability = "ALLOW_DOWNLOADS"
|
|
CapPackageInstall Capability = "ALLOW_PACKAGE_INSTALL"
|
|
CapServiceRestart Capability = "ALLOW_SERVICE_RESTART"
|
|
CapOutsideRead Capability = "ALLOW_OUTSIDE_PROJECT_READ"
|
|
CapOutsideWrite Capability = "ALLOW_OUTSIDE_PROJECT_WRITE"
|
|
CapDelete Capability = "ALLOW_DELETE"
|
|
CapReboot Capability = "ALLOW_REBOOT"
|
|
CapSelfToolCreation Capability = "ALLOW_SELF_TOOL_CREATION"
|
|
)
|
|
|
|
// Directivas que no son capacidades booleanas ALLOW_*.
|
|
const (
|
|
directiveMode = "EXECUTION_MODE"
|
|
directiveBackup = "BACKUP_BEFORE_SYSTEM_EDIT"
|
|
directiveTimeout = "DEFAULT_COMMAND_TIMEOUT"
|
|
directiveTaskOrder = "TASK_ORDER"
|
|
directiveMaxSteps = "MAX_STEPS"
|
|
directiveMaxDL = "MAX_DOWNLOAD_SIZE"
|
|
)
|
|
|
|
const (
|
|
defaultCommandTimeout = 60 * time.Second
|
|
defaultMaxSteps = 40
|
|
defaultMaxDownload = 1 << 30 // 1 GiB (§68)
|
|
)
|
|
|
|
// AllCapabilities lista las capacidades en un orden estable para mostrarlas.
|
|
var AllCapabilities = []Capability{
|
|
CapNetwork, CapWebResearch, CapDownloads, CapPackageInstall,
|
|
CapServiceRestart, CapOutsideRead, CapOutsideWrite, CapDelete,
|
|
CapReboot, CapSelfToolCreation,
|
|
}
|
|
|
|
// Policy es la política efectiva tras interpretar agent.md.
|
|
type Policy struct {
|
|
Mode Mode
|
|
|
|
// caps contiene solo las capacidades concedidas explícitamente.
|
|
caps map[Capability]bool
|
|
|
|
// BackupBeforeSystemEdit es protector, no peligroso, por eso su valor por
|
|
// defecto es true: omitirlo nunca debe reducir la seguridad.
|
|
BackupBeforeSystemEdit bool
|
|
|
|
// DefaultCommandTimeout es el timeout de los comandos sin timeout propio.
|
|
DefaultCommandTimeout time.Duration
|
|
|
|
// MaxSteps limita las llamadas al modelo por tarea o por mensaje del CLI,
|
|
// para que un agente atascado no itere indefinidamente.
|
|
MaxSteps int
|
|
|
|
// MaxDownloadSize limita el tamaño de cada descarga en bytes (§68).
|
|
MaxDownloadSize int64
|
|
|
|
// TaskOrder es el orden explícito de tareas si agent.md lo define.
|
|
// Vacío significa orden lexicográfico.
|
|
TaskOrder []string
|
|
|
|
// Unknown son directivas no reconocidas; se reportan en el log.
|
|
Unknown []string
|
|
|
|
// Declared indica si agent.md contenía un bloque de política. Si es false,
|
|
// se aplicaron todos los valores por defecto.
|
|
Declared bool
|
|
}
|
|
|
|
// Default devuelve la política más restrictiva: guarded y sin capacidades.
|
|
func Default() *Policy {
|
|
return &Policy{
|
|
Mode: ModeGuarded,
|
|
caps: map[Capability]bool{},
|
|
BackupBeforeSystemEdit: true,
|
|
DefaultCommandTimeout: defaultCommandTimeout,
|
|
MaxSteps: defaultMaxSteps,
|
|
MaxDownloadSize: defaultMaxDownload,
|
|
}
|
|
}
|
|
|
|
// Allows informa si una capacidad fue concedida explícitamente.
|
|
func (p *Policy) Allows(c Capability) bool {
|
|
return p.caps[c]
|
|
}
|
|
|
|
// Summary produce una representación legible, estable y sin secretos,
|
|
// usada por /policy y en el prompt de sistema.
|
|
func (p *Policy) Summary() string {
|
|
var b strings.Builder
|
|
fmt.Fprintf(&b, "EXECUTION_MODE=%s\n", p.Mode)
|
|
for _, c := range AllCapabilities {
|
|
fmt.Fprintf(&b, "%s=%t\n", c, p.Allows(c))
|
|
}
|
|
fmt.Fprintf(&b, "%s=%t\n", directiveBackup, p.BackupBeforeSystemEdit)
|
|
fmt.Fprintf(&b, "%s=%d\n", directiveTimeout, int(p.DefaultCommandTimeout/time.Second))
|
|
fmt.Fprintf(&b, "%s=%d\n", directiveMaxSteps, p.MaxSteps)
|
|
fmt.Fprintf(&b, "%s=%d\n", directiveMaxDL, p.MaxDownloadSize)
|
|
if len(p.TaskOrder) > 0 {
|
|
fmt.Fprintf(&b, "%s=%s\n", directiveTaskOrder, strings.Join(p.TaskOrder, ","))
|
|
}
|
|
if !p.Declared {
|
|
b.WriteString("# no policy block found in agent.md: defaults applied\n")
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
// knownCapabilities permite validar nombres ALLOW_* rápidamente.
|
|
var knownCapabilities = func() map[Capability]bool {
|
|
m := make(map[Capability]bool, len(AllCapabilities))
|
|
for _, c := range AllCapabilities {
|
|
m[c] = true
|
|
}
|
|
return m
|
|
}()
|
|
|
|
// sortedUnknown ordena las directivas desconocidas para logs deterministas.
|
|
func (p *Policy) sortedUnknown() {
|
|
sort.Strings(p.Unknown)
|
|
}
|