Right-size director/advisor container surface tiers after the 2026-07-10 permissions rollback #447
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/agentic-os#447
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
A permissions rollback on 2026-07-10 shrank the director/advisor container surface tiers well below what those roles operationally need (Kai: "I accidentally requested a permissions rollback much greater than the current operational needs"). Probed live from a running director surface during the infrastructure#538 recovery, the surface was missing capabilities its role is supposed to carry:
kubectl- theward ops kubectlguardfile is compiled in, but the binary is absent (/usr/local/bin/kubectlnot found) and there is no kubeconfig, so no cluster reach even thoughguardfile.kubectl.kdlexists.tailscaledis not running in the surface, sotailscale status/MagicDNS fail. Theadvisorrole is documented to carry the live-observe set (tailnet +~/.aws) by default, and the advisor dispatched for infra#538 produced a runbook-for-a-human rather than live findings - consistent with the same strip hitting the advisor role.~/.awsdir (SSM still authenticated via env, but the documented creds path is gone).generate-runner-tokennot surfaced -ward ops forgejo actionsexposed onlylogs, so the operator token-restore path (infrastructure#539) could not run from the surface.The net effect: the roster's stated role tiers (
engineer/director/advisor/qa/opsin.ward/roles.kdl, plus the ward-embedded role presets and the container image +WARD_CONTEXT_LEVELprovisioning) drifted from intent, and nothing flagged it.Do
director,advisor,engineer,qa,ops) state what it should carry: forgejo read/write, actions read, aws/ssm, kubectl, tailnet live-observe, admin verbs.advisorlive-observe set (tailnet +~/.aws) per its documented role, andward ops forgejo actions generate-runner-tokenon the operator/ops surface (its absence blocked the infra#539 token restore)..ward/roles.kdlguardfile bindings (dialect-1 surface), the ward-embedded role presets, and the container image /WARD_CONTEXT_LEVELprovisioning that decides which binaries (kubectl,tailscale) and creds land in a given surface. Note which layer owns each capability so a future rollback of one layer cannot silently disable a role.Acceptance
advisorsurface has tailnet +~/.aws; anops/director surface can mint a runner token).Context
Filed at Kai's request after the 2026-07-10 rollback surfaced during the infrastructure#538 recovery. This is the tier right-size half; the merge/status half splits into the ward-native foundational capability and agentic-os#446's specgen also-grant. Refs:
.ward/roles.kdl,.ward/guardfile.kubectl.kdl,.ward/guardfile.aws.kdl,.ward/guardfile.forgejo.admin.kdl,docker/dev-base/ops/Dockerfile(kubectl install), infrastructure#538, infrastructure#539, agentic-os#446.WARD-RESERVATION: held 🔒
reservation details
Holder: container
engineer-claude-agentic-os-447on hostkais-macbook-pro-2.local.Reserved by
ward agent --harness claude(reserved 2026-07-10T18:03:53Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (1h TTL).--forceoverrides.Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).
run seed context — what this run is carrying (ward#609)
coilyco-flight-deck/agentic-os#447· branchissue-447· harnessclaude· workflowpull-requests-and-mergeengineer-claude-agentic-os-447· wardv0.584.0· dispatched2026-07-10T18:03:53ZStatic container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.584.0).
— Claude (she/her), via
ward agentWARD-OUTCOME: merge-ready
details
workflow: pull-requests-and-merge; review summary: skipped - the in-container review gate was intentionally skipped by the
~/.ward/config.yamldefault.PR: #448 (branch
issue-447, head72727fd,ci / gategreen, mergeable). The director merges it and records the final done outcome.What landed
docs/role-surface-tiers.md- the deliberate per-role tier definition plus the per-layer capability ownership map (roles.kdl bindings / ward-embedded presets / dev-base image binaries / ward container bring-up).roles.kdlrebind - advisor regains its live-observe set (aws + new tailscale guardfile), director gains live-observe + kubectl + runner-token mint, ops gains runner-token mint.guardfile.forgejo.runnertoken.kdl+forgejo-runner-token.sh-ward ops forgejo actions generate-runner-token(global/org/repo scopes), the infrastructure#539 restore path, kept out of the fleet-wide readactions overlay.guardfile.tailscale.kdl- read-only tailnet observe surface (status/ping/netcheck/ip/whois/dns status/version), state-changing verbs denied.surface-check.sh+ward exec surface-check- bring-up self-check keyed onWARD_ROLE, exits non-zero listing every miss. Run as director from this engineer container it reproduced the exact drift this issue described (5 misses).release.ymltar list +check_ward_specs_bundledrift-guard extended so the four new bundle files ship in ward-specs and cannot silently drop.Verified -
ward doctorPASS (fleet + exec bundle) against the branch bundle viaWARD_CONFIG_REF, pre-commit all-files green, pytest 455 passed, CI green after the engineer merged main in and resolved the #437 ward-specs packaging conflicts.How it felt - the archaeology was the work: the rollback turned out to be layered (roles.kdl preset strip at 09:10, plus ward-side bring-up loss), and the shipped ward binary's strings were the only source for the ward#578 per-role guardfile-set behavior. The aos-side authoring was straightforward once the layer map existed.
Surprises
guardfile.forgejo.kdlmonolith forward ops forgejo(actions logsis ward-native Go), so the runnertoken overlay - like the existing readactions runs/tasks leaves - is authored intent until ward mounts role-bound overlays. Filed ward#1072 for that wiring plus invoking surface-check at bring-up.ward doctoron current main already fails its ops-bundle check with this ward version (#437 removed the committed swagger lock the shipped binary still wants). Pre-existing on main, not from this branch./gitcachedisk sits at 100%. Config-bundle clones failed mid-run until the agent removed its own cache dirs. Worth a look.Confidence - high on the aos-side definition, bindings, and self-check (all exercised live). Medium on how ward bring-up consumes the tailscale/aws bindings for daemon/creds provisioning - that half of the acceptance closes via ward#1072.
Follow-ups - ward#1072 (runtime overlay mounts, bring-up self-check, provisioning reconcile). Merge + commit-status stay deferred to the ward-native PR-workflow issue and #446, per this issue.
— Claude (she/her), via
ward agentWARD-RESERVATION: held 🔒
reservation details
Holder: container
engineer-codex-agentic-os-447on hostKAI-DESKTOP-TOWER.Reserved by
ward agent --harness codex(reserved 2026-07-10T23:05:51Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (1h TTL).--forceoverrides.Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).
run seed context — what this run is carrying (ward#609)
coilyco-flight-deck/agentic-os#447· branchissue-447· harnesscodex· workflowpull-requests-and-mergeengineer-codex-agentic-os-447· wardv0.605.0· dispatched2026-07-10T23:05:51ZStatic container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.605.0).
— Codex, via
ward agentWARD-OUTCOME: submitted
details
workflow: pull-request-and-merge; review summary: skipped - the in-container review gate was intentionally skipped by the temporary ward default pending brokered QA.
PR #448 is green and mergeable after the branch refresh.
What landed felt layered, not broad. The merge had to preserve the existing merge overlay from main while refreshing the director/advisor surface-tier fix and updating the bundle contract tests.
confidence: high
surprises: the flattened ward bundle had to keep the merge overlay in the packaged set once the role binding stayed on director.
follow-ups: merge PR #448 when the director lane takes it.