// 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) }