Commit Graph
3 Commits
Author SHA1 Message Date
Renn F 27e58f469f feat(runtime): stamp spawned containers with the stack's own compose-project labels
Agent spawns (all five provider paths), intake/secretary chats, and
sandbox sidecars now carry com.docker.compose.project/service/oneoff/
config-hash labels copied from the orchestrator's own compose project,
so a Docker UI (UGOS) groups them under the stack's project and they
die with the stack: bare compose stop/restart affects them, compose
down removes them (the config-hash label must be PRESENT for down to
even see the container — compose filters its API listing on that key
before the orphan predicate runs, verified live), and up -d deliberately
does not resurrect them since the orchestrator respawns its own agents.

Self-discovery reads the orchestrator's own container id from
/proc/self/mountinfo keyed on the root-independent /containers/<id>/
segment — the UGREEN NAS data-root is /volume1/@docker on btrfs, so its
mountinfo reads /@docker/containers/..., never the textbook
/var/lib/docker path (verified against the live NAS) — with a HOSTNAME
short-id fallback, then one docker inspect cached per process. Only
definitive outcomes cache; a transient inspect failure logs and retries
on the next spawn. Outside compose the helper yields nothing and every
spawn command is byte-for-byte unchanged.
2026-07-30 17:51:12 +02:00
Renzo FandGitHub d4b7e1e7b8 fix: post-finale completeness sweep — routing surface, provider config, budgets, compose env, interactive exemption (#661) 2026-07-23 09:41:27 +02:00
21d6730400 feat(providers): Gemini CLI provider — ModelProvider.GEMINI (#660)
* feat(providers): Gemini CLI provider — ModelProvider.GEMINI

Mirrors the grok blueprint with source-verified divergences (all facts
pinned against google-gemini/gemini-cli @ 9681621c): no refresher
daemon — Google's refresh tokens are reusable, so the RO host mount is
COPIED to a writable container-local ~/.gemini and each container
refreshes in-process independently (the write-back crash risk on RO
never triggers); settings.json renders security.auth.selectedType
'oauth-personal', experimental.enableAgents=false (subagent ban),
autoConfigureMemory=false with a bounded heap; tool scoping rides the
tiered TOML Policy Engine (deny-only rules that yolo mode structurally
cannot beat); gemini -p with --output-format stream-json; usage parsed
from the run's own stdout stats — the adversarial pass caught the
parser reading the json-mode nested shape while the entrypoint runs
stream-json's FLAT shape (every real run would have priced $0 forever,
hidden by fixtures sharing the assumption) — now flat-primary with the
nested shape as cited fallback; rate-limit classified from structured
error.type only (model-echo immune), native exit 41 auth passthrough;
per-model pricing for the three GA models; migrations 084 (enum) + 085
(seed) complete the 082-085 finale chain. V1 excludes interactive
intake/secretary. Stack-merge required two behavior-preserving
complexity refactors in the shared park/usage plumbing (a park-pair
loop; a usage-reader dispatch dict).

* fix(providers): route gemini usage read through the containment barrier

Mirrors the codex/grok fix — _gemini_usage_json now delegates to
_read_usage_json_contained, so CodeQL's path-injection alert on the
gemini read is resolved by the same resolve-and-contain guard.

---------

Co-authored-by: Renn F <rennf93@users.noreply.github.com>
2026-07-23 03:53:21 +02:00