1
0
Fork 0
forked from lukas/nixos-config
nixos-config/hosts/blunix/localServices/secrets.nix
pijukka ba6d7b8512 agent-codex: wire up Builder handoff (test-stage relay), own XMPP identity
Agent -> Builder handoff pipeline, first cut:

- agents/agent.md: documents the ===BUILDER-HANDOFF=== marker format
  the Agent uses once the user explicitly wants an elaborated spec
  implemented.
- worker.py: extract_handoff() detects the marker, strips it from the
  user-facing reply, and enqueue_builder_job() writes the spec as a new
  job into a separate builder-inbox queue.
- builder.py (new): path-triggered oneshot worker for that queue. Test
  stage only -- runs Codex read-only against the same agents/ role dir
  and is told to relay the received spec back unchanged, to validate
  the pipeline before any real write capability is built. No execution,
  no filesystem changes.
- New Prosody account builder@bot.0ff.space (own XMPP identity, own
  secrets/builderXmpp.age, own go-sendxmpp config) so Builder replies
  are visibly distinct from Agent replies instead of reusing agent@'s
  identity with a text prefix.

Verified end to end against the live services: a real Agent job that
requests a test handoff produces the marker, gets detected, enqueues a
Builder job, and the Builder relays it back -- confirmed in Prosody's
log as a message from builder@bot.0ff.space to lukas@0ff.space.

Builder does not yet get real technical execution capability or a
"build with lukas's permission" dialog loop -- that needs its own
sandbox/approval design and is explicitly not built here.
2026-07-30 10:08:17 +02:00

35 lines
1.2 KiB
Nix

{ lib, ... }:
{
age.secrets.agentXmpp = {
file = ../../../secrets/agentXmpp.age;
owner = "drone";
};
age.secrets.builderXmpp = {
file = ../../../secrets/builderXmpp.age;
owner = "drone";
};
# These globally declared secrets belong to services that run only on pinix.
# Keep the unused blunix copies root-owned so agenix activation does not
# depend on service users that intentionally do not exist on this host.
age.secrets.bindPW.owner = lib.mkForce "root";
age.secrets.mailPW.owner = lib.mkForce "root";
age.secrets.oidcGTS.owner = lib.mkForce "root";
age.secrets.oidcGTSEnv.owner = lib.mkForce "root";
age.secrets.webdav.owner = lib.mkForce "root";
age.secrets.lldapAdmin.mode = lib.mkForce "400";
# Dex reads these files as root while preparing its runtime configuration.
age.secrets.oidcVikunja.file = ../../../secrets/oidcVikunja.age;
age.secrets.oidcAudiobookshelf.file = ../../../secrets/oidcAudiobookshelf.age;
age.secrets.oidcQuantum.file = ../../../secrets/oidcQuantum.age;
age.secrets.oauth2Cookie.file = ../../../secrets/oauth2Cookie.age;
age.secrets.traefikBasicAuth = {
file = ../../../secrets/traefikBasicAuth.age;
owner = "traefik";
};
}