mirror of
https://scm.tikali.ai/tikali/applications/monky/monky-deployd.git
synced 2026-09-18 02:56:15 +00:00
1c42e913a8
Stdlib-only Python 3.12 agent for docker VMs and laptops: flock → checkin
(bearer = the agent's OpenBao token, bootstrapped from the install kit's
jwt-tenancy deploy grant) → action apply|none|down → bundle (sha256
verified) → refusal checks (unresolved ${VAR} names only, manifest paths
pinned to monky/data/<env>/see/, privileged/host-network, rollback, disk
need×1.5+headroom) → lease → POST /v1/auth/jwt-tenancy/login → KV reads →
.env 0600 → promote → compose pull/up → wait healthy → report; finally
renew-self / re-lease before max TTL, scrub. Exit 0/75/78/1. Redactor log
filter. Transports sdk (openziti) / proxy (ziti tunnel proxy 18443/18200) /
system. Laptop mode.
Packaging: hardened oneshot + 60 s timer + proxy unit, nfpm .deb with
/opt/monky-deployd/venv, install.sh for Ubuntu 26.04 (Gitea release
download, enrol, ACLs, bootstrap from stdin), ansible role skeleton for
osg1-07. CI: lint/test on every change; wheel (openziti on ubuntu:26.04) and
package (nfpm) allow_failure until runner egress is proven; GitLab release +
release:gitea on v* tags. Docs: README, PROTOCOL, OPERATIONS, CHANGELOG,
CLAUDE/AGENTS.
Divergence noted: monky-tenancy main (MR !15) still ships the AppRole lease
and kit; this agent implements the plan's Gate 1 RESULT (login_jwt, no
unwrap) and refuses an AppRole lease loudly (LEASE_SHAPE).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KLB7jieMNRkTsJ2epr4Ds1
2.4 KiB
2.4 KiB
AGENTS.md — rules for AI agents working in monky-deployd
Read CLAUDE.md first; these are the non-negotiables.
- Stdlib only. No runtime dependency in
monky_deployd/;openzitiis optional and imported lazily intransport.SdkTransportonly. - Never a secret value in a log, a report,
state.json, an exception message or a test assertion output. Register every value/token/grant withREDACTOR.add()the moment it exists; name variables, never values.tests/test_agent.pyasserts the report tail is clean — keep it so. - Auth is the jwt-tenancy deploy grant (
login_jwt→POST /v1/auth/jwt-tenancy/login). No AppRole, no unwrap, no compatibility fallback; an AppRole-shaped lease isLEASE_SHAPE(failed). - Vocabulary: check-in
action apply|none|down; reportresult applied|failed|down.env_id, backend, bundle, deploy grant. Never "tenant". - Refuse before you lease, and refuse hard: a failed check is
Refusal(code, detail)→ reportfailed→ exit 1. No "apply anyway with a warning". - Exit codes 0 / 75 / 78 / 1 are a contract (timer
SuccessExitStatus=75; 78 stops the loop). - Prod never purges volumes, whatever tenancy sends.
- Config is the YAML subset
config.parse_yaml_subsetunderstands (maps, scalars, simple lists). If you add a key:Configdataclass +config.example.yaml+install.sh+ the ansible template. - Tests are hermetic (fake tenancy/OpenBao HTTP servers + the stub
docker). Every new refusal code or protocol field gets a test against the fakes, and the fakes track the tenancy shapes of record (monky-tenancyapp/schemas_backends.py, design doc 24 §3.3). - Quality gates, each its own statement:
ruff format --check .,ruff check .,pytest,bash -n packaging/install.sh,systemd-analyze verifywhere available. - Branching:
feat/*/fix/*/docs/*→ MR intomain→ tagvX.Y.Zonmain(protectedv*). The version lives inmonky_deployd/__init__.py,pyproject.toml,install.shDEFAULT_VERSION,CHANGELOG.md— bump all four. - YAML traps: single-quote every CI script line; never
": "in an unquoted scalar. - Never edit a
*.ru.md; edit English only, keep<!-- xlate:verbatim-fences -->on line 1. - ADR citations are
MONKY-ADR-NNNN(monky-design-docs); cite, don't restate.