Port up-to-date.py converger to coilysiren.fleet ansible collection (bootstrap slice + token allowlist) #153

Closed
opened 2026-06-04 07:03:39 +00:00 by coilysiren · 1 comment
Owner

What

First slice of porting the hand-rolled fleet converger (agentic-os-kai/scripts/up-to-date.py)
to an Ansible collection, coilysiren.fleet, living in this repo under ansible/.

Lands:

  • repo_registry dynamic inventory plugin — live repo layout (GitHub + Forgejo)
    as inventory, repos grouped repos_present / repos_missing / archived /
    forgejo_only / org_<name>. Ports the step-6 discovery logic.
  • module_utils/repos.py — shared, pure-stdlib discovery helpers.
  • bootstrap.yml — clones repos_missing from GitHub via ansible.builtin.git.
  • Collection scaffold: galaxy.yml, ansible.cfg, requirements.yml, README.

Security hardening (first instance of coilysiren/inbox#36)

The inventory plugin fetches the Forgejo PAT from SSM and sends it as an
Authorization header. To prevent a tampered config from exfiltrating it, the
token destination is pinned to the canonical host in code (not config):
token_destination_allowed() requires https + forgejo.coilysiren.me, checked
before the token is ever fetched. A swapped forgejo_api or forgejo_token_ssm
is refused loudly. This is remediation #1 from coilysiren/inbox#36; the other
call sites (up-to-date.py, infrastructure scripts) remain open there.

Verified

  • ansible-galaxy collection list shows coilysiren.fleet; ansible-doc renders.
  • ansible-inventory --graph populates off live gh/forgejo.
  • ansible-playbook bootstrap.yml --check is a clean no-op (converged).
  • Tampered forgejo_api is refused before any SSM read.

Follow-on (not in this slice)

Port the remaining 7 converger steps to roles + custom modules
(repo_mirror_drift, repo_reconcile, catalog_deptree), then the private
fleet host inventory + coily exec freshen verb in agentic-os-kai.

## What First slice of porting the hand-rolled fleet converger (`agentic-os-kai/scripts/up-to-date.py`) to an Ansible collection, `coilysiren.fleet`, living in this repo under `ansible/`. Lands: - `repo_registry` dynamic inventory plugin — live repo layout (GitHub + Forgejo) as inventory, repos grouped `repos_present` / `repos_missing` / `archived` / `forgejo_only` / `org_<name>`. Ports the step-6 discovery logic. - `module_utils/repos.py` — shared, pure-stdlib discovery helpers. - `bootstrap.yml` — clones `repos_missing` from GitHub via `ansible.builtin.git`. - Collection scaffold: `galaxy.yml`, `ansible.cfg`, `requirements.yml`, README. ## Security hardening (first instance of coilysiren/inbox#36) The inventory plugin fetches the Forgejo PAT from SSM and sends it as an `Authorization` header. To prevent a tampered config from exfiltrating it, the token destination is pinned to the canonical host **in code** (not config): `token_destination_allowed()` requires https + `forgejo.coilysiren.me`, checked before the token is ever fetched. A swapped `forgejo_api` or `forgejo_token_ssm` is refused loudly. This is remediation #1 from coilysiren/inbox#36; the other call sites (up-to-date.py, infrastructure scripts) remain open there. ## Verified - `ansible-galaxy collection list` shows `coilysiren.fleet`; `ansible-doc` renders. - `ansible-inventory --graph` populates off live gh/forgejo. - `ansible-playbook bootstrap.yml --check` is a clean no-op (converged). - Tampered `forgejo_api` is refused before any SSM read. ## Follow-on (not in this slice) Port the remaining 7 converger steps to roles + custom modules (`repo_mirror_drift`, `repo_reconcile`, `catalog_deptree`), then the private fleet host inventory + `coily exec freshen` verb in agentic-os-kai.
Author
Owner

Goose triage - 2026-06-17

  • Tier: P2 (score 85) - High priority backlog item, clearly next thing
  • Mode: headless - Self-contained ansible collection port with clear steps

Auto-generated by ward exec goose-triage (qwen3-coder:30b), edited in place on each run. Labels are the conclusion; this is the why.

<!-- goose-triage --> **Goose triage** - 2026-06-17 - **Tier:** `P2` (score 85) - High priority backlog item, clearly next thing - **Mode:** `headless` - Self-contained ansible collection port with clear steps <sub>Auto-generated by `ward exec goose-triage` (qwen3-coder:30b), edited in place on each run. Labels are the conclusion; this is the why.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agentic-os#153
No description provided.