1
0
Fork 0
forked from lukas/nixos-config
nixos-config/secrets/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

39 lines
1.9 KiB
Nix

let
tnix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILrZETtzrSfkomL9H31SuyQJ8O39ujMIjsCkbjL4DgxM";
root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICb7MnxZch2IfxkFhKjGWkAVeAENJFEFaMk91UQTiQBf";
root2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ6v2CMRHS50Wq5cAqWenwkV8GNONFIDbKpW4ChfptUc";
users = [ tnix root root2 ];
blunix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBKr9V1HzAAFJ+6sjtrrkq8/qM9DFQq2gNUvbIB5Jn2C";
pinix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBTIBiB9JYYtViI1IKK96pH+x3D63BQQgmZstc8jPBNp";
systems = [ blunix pinix ];
in
{
"dns-challenge.age".publicKeys = users ++ systems;
"domain.age".publicKeys = users ++ systems;
"lldapAdmin.age".publicKeys = users ++ systems;
"bindPW.age".publicKeys = users ++ systems;
"oidcHeadscale.age".publicKeys = users ++ systems;
"webdav.age".publicKeys = users ++ systems;
"go-sendxmpp.age".publicKeys = users ++ systems;
"oidcForgejo.age".publicKeys = users ++ systems;
"oidcGTS.age".publicKeys = users ++ systems;
"oidcGTSEnv.age".publicKeys = users ++ systems;
"oidcVikunja.age".publicKeys = users ++ systems;
"oidcAudiobookshelf.age".publicKeys = users ++ systems;
"oidcQuantum.age".publicKeys = users ++ systems;
"oidcOauth2.age".publicKeys = users ++ systems;
"oauth2Cookie.age".publicKeys = users ++ systems;
"traefikBasicAuth.age".publicKeys = users ++ systems;
"traefikDashboardPassword.age".publicKeys = users;
"mailPW.age".publicKeys = users ++ systems;
"ipv4.age".publicKeys = users ++ systems;
"ipv6.age".publicKeys = users ++ systems;
"motd.age".publicKeys = users ++ systems;
"wirelessSecretsFile.age".publicKeys = users ++ systems;
"resticPW.age".publicKeys = users ++ systems;
"headscalePreAuthKey.age".publicKeys = users ++ systems;
"agentXmpp.age".publicKeys = users ++ systems;
"builderXmpp.age".publicKeys = users ++ systems;
"forgejoToken.age".publicKeys = users ++ systems;
}