// Package caps: the deterministic drop-in renderer (spec §4a).
//
// RenderService and RenderSocket turn a manifest's Set, filtered through an
// operator's Grants, into the exact bytes of a systemd drop-in — nothing
// else touches disk here (that is Task 6's converge pass; this file is pure
// bytes-in-bytes-out). Directive order is FIXED and every list is sorted, so
// re-rendering an unchanged Set/Grants pair is byte-identical: the converge
// pass's "write only if it differs" check is what keeps an unchanged pass
// from triggering a daemon-reload or a restart.
package caps
import (
"fmt"
"sort"
"strings"
)
// execStartPath is the literal ExecStart target, byte-identical to
// internal/host/units/carlos-app@.service's own `ExecStart=%s serve` line.
// The template is not parameterised by CARLOS_OPT_DIR either — a drop-in
// that disagreed with the template about the path would be a silent split
// brain (spec §4a).
const execStartPath = "/opt/carlos/live/%i"
// docEngineMemoryMax and docEngineMemoryHigh are the resource band a
// document-conversion orchestrator gets, in place of the template's 512M and
// the children tier's 1G. Chromium and LibreOffice are not small: one
// Chromium instance is dozens of processes and hundreds of megabytes before
// it has rendered anything, and a LibreOffice conversion of a large document
// is comparable. The default tier OOM-kills an engine mid-render, which is
// the failure mode that would make this capability useless.
//
// High is 90% of Max, the same throttle-and-reclaim-before-the-kill band the
// children tier uses (1G/920M) and internal/cgroup's highOf applies. (The
// exec-backed path has no engine tier — internal/host's memtier knows only the
// default and children bands — and doc_engine is unit-backed only: an exec
// child that declared it would get these directives from no one. The grant
// door's unit-backed rail is what makes that unreachable.)
const (
docEngineMemoryMax = "4G"
docEngineMemoryHigh = "3680M"
docEngineTasksMax = "2048"
)
// docEngineEgressDeny is the private-network fence that pays for the
// resource headroom above, and the reason this capability is a trade rather
// than a gift.
//
// A conversion engine's entire job is fetching URLs a CALLER chose — every
//
,