feat(role-loader): CRD → file projection (proposal 010 PR-3) - #77
Merged
Merged
Conversation
Python mirror of PR-2's Go-side watcher. When role_sync.role_source is "crd" or "mirror", the new RoleCRDProjector polls the Kubernetes API for AgentCollective resources and writes their spec.roleDefinition to roles/<id>/role.yaml. The existing acc.role_loader file watcher then picks up the write naturally — no new hot-path code in agents. Design choices: * Optional kubernetes dep — never imported at module load. The KubernetesCRDClient lazy-imports kubernetes on first use; if the import fails (agents running role_source=files) the error path is explicit and recovery is a config flip. Agent containers stay slim by default. * Protocol-based CRDClient — production impl wraps CustomObjectsApi; tests inject FakeCRDClient. Keeps unit tests fast and cluster-free. * Atomic writes — file.tmp + os.replace so the agent's file watcher never reads a half-written file. * Idempotency in two layers: in-memory _last_written cache + on-disk content comparison (sentinel-stripped). Prevents mtime spam under steady state. Critical for mirror mode (PR-4) to not oscillate. * Sentinel header on every generated file points back at the source CRD + carries a UTC timestamp. Operators who cat the file see why it's there. Header is stripped before content comparison so timestamp updates don't trigger spurious rewrites. Test coverage: 19 unit tests in tests/test_role_crd_loader.py. Covers _strip_sentinel edge cases, project_one idempotency on in-memory + on-disk paths, atomic-write cleanup, empty-payload skip, namespace+name in header, project_once batch behaviour, exception swallowing on client errors, polling start/stop lifecycle (including no-start safety), and field-translation surface. KubernetesCRDClient itself is not unit-tested — it requires a live cluster and is covered by integration tests on acc1. Total: +675 LOC across 3 files (production ~330 + tests ~280 + docs). Well under PR-3's 600-LOC production budget. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 14, 2026
flg77
added a commit
that referenced
this pull request
Jun 14, 2026
…77) Brief-08: deliver the acc-pkg package toolchain as a UBI10 podman image with a thin host wrapper, so users run build/inspect/install/eval/list with zero local Python or `acc` install (mirrors Containerfile.cli/acc-cli). - container/production/Containerfile.acc-pkg: minimal UBI10 python-312 image; deps are pydantic+pyyaml only (catalog fetch is stdlib urllib); cosign v2.4.3 baked in for verify/install of signed packs; runs uid 1001. - acc-pkg (repo-root wrapper): podman run --rm, binds CWD at /work. Maps the image uid onto the caller (podman keep-id:uid=1001 / docker --user) so build artifacts + installs are owned by the user, not a subuid. Defaults ACC_PACKAGES_ROOT into ./.acc/packages so installs persist past the --rm container. - docs/CONTRIBUTING-ROLE.md: two-path "install the toolchain" section (container wrapper / Python editable). Verified on acc1 (podman 5.6.0): image builds (acc 0.3.34); full chain build -> inspect -> install --allow-unsigned -> eval runs offline against the capital-markets family source. Build tarball_sha256 reproduces the published @acc/capital-markets-roles@0.1.1 (49f43fcb...); eval surfaces 6 behavior + 5 safety + curated (the eval-autocopy bundle). quay push deferred — acc1 not logged into quay.io (folds into the brief-06 wave). Co-authored-by: flg <flg@acc1.ic3net.internal> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Third PR of proposal 010 — the Python mirror of PR-2's Go-side file watcher. When
role_sync.role_sourceiscrdormirror, the newacc.role_crd_loader.RoleCRDProjectorpolls the K8s API forAgentCollectiveresources and writes theirspec.roleDefinitiontoroles/<id>/role.yaml. The existingacc.role_loader.RoleLoaderfile watcher picks it up automatically — no new code path in the agent hot loop.Inert by default: runs only when
role_sourceiscrdormirror. Agents instandalonemode (the default) see no change and don't pay thekubernetesdependency cost.What's new
acc/role_crd_loader.py(~330 LOC):CRDClientProtocol so tests inject a fake without a live cluster.KubernetesCRDClientlazy-importskubernetesonly on first use. In-cluster config preferred; kubeconfig fallback for laptop dev.RoleCRDProjectorpolls everypoll_interval_s(default 30 s) and writes files atomically (*.tmp+os.replace). Two layers of idempotency: in-memory cache + on-disk sentinel-stripped content comparison.Test plan
tests/test_role_crd_loader.py— all green locally:_strip_sentineledge cases (4)project_oneidempotency on cache + disk + content paths (7)project_oncebatch behaviour + exception swallowing (4)AgentCollectiveCR, point an agent at it withACC_ROLE_SOURCE=crd, verifyroles/<name>/role.yamlappears within 1 poll interval and carries the sentinel header.Out of scope
Diff size
Production is under PR-3's 600-LOC budget; tests bring it over but are mostly fixture/setup code.
Proposal 010 reference
Vault path:
010 - Bi-directional file-CRD sync for role definitions.md. Status: Signed off 2026-05-14. PR-1 (#75) + PR-2 (#76) already merged.🤖 Generated with Claude Code