water park

The propose loop

TODO: prose

The parts

PartWhat it isMendRoundsdns-desk
targetThe thing under management. The agent does not control it and treats its contents as untrusted.A repo’s CI, Kubernetes, Docker and cloud config.The same, enrolled.The Cloudflare zones a token can see.
readA deterministic read of the target. An audit yields findings sorted by fix confidence (deterministic, judgement, report-only). A request yields the current state, re-read before any apply.An audit over ten catalogs. Silent catalogs are shown greyed.The same, on a schedule.dns-state, incremental per zone.
operatorAn agent on a toolkit environment with the tool on its PATH and a credential that can read the target and nothing more. One per target.One mender per repo. A per-repo read-only token in its own vault.The same, holding a grant it trades for a one-hour read-only token.One desk per token. The vault’s zone list is the blast radius.
planWhat the operator proposes per finding or per request. Applied means mechanical from the tool’s own diff. Proposed means a judgement call it was confident in. Skipped means it turns on intent it cannot see, with a note. Rendered as a diff.mend-plan plus one mend-fix block per fix, independently selectable.One cluster per file, with status.dns-plan, a diff against the last read.
verifyRe-run the read after the change and before proposing. Findings gone, merge-worthy count not up, files still parse. Or re-read the target and re-plan if it moved.Before the plan is shown.A failed verify opens nothing.Re-read the zone before apply. Re-plan instead of applying stale.
proposeThe only path that writes, held by something that is not the operator.The human’s browser with the human’s token. Every context line re-verified against the target right now.A server minting a one-target write token for one proposal, checking policy and history, rendering the PR body from the findings.The desk applies after an APPROVE plan-id message, with a token scoped before the conversation began.
rulesConstraints that hold when the prompt is ignored, enforced where the write happens.The browser refuses a stale patch.Never reopen what a human closed. Never a second PR for the same thing. Never outside the derived branch. At most N open. enabled: false means nothing happens.The token’s scope. Today the approve is convention and the audit trail, until fountain#643.
recordWhere the state lives. It is where the person who decides is already standing, with nothing to keep in sync.The conversation. Report, plan and patch are derived from turns and blocks.GitHub. Branch name and a marker in the PR body. The conversation holds the round report.The conversation. Plan status is always derived, never stored.
refusalAn outcome, not a failure, rendered as one.skipped, with the note.already-open, declined, deferred, clean. A decline sticks until rounds:reconsider.A request outside the token’s zones.
TODO: prose

The four forms

audit-drivenrequest-driven
interactiveMend. Point it at a target, watch, ask for changes, take the patch or open the PR yourself.dns-desk. Ask in words, read the plan as a diff, approve, done.
ambientRounds. Schedule, reconcile against its own past work, cap, server as propose, declines stick.A ticket webhook starting a desk conversation. No app yet.

The loop on IAM

TODO: prose
FormIAM instanceBuild or reuseLessons
interactive, request-drivenThe concierge, in the desk’s form. The estate on screen. “tickets-api needs read on the receipts bucket.” One deterministic file edit. The plan is the rendered access delta. The PR is opened with a PR-only token. CODEOWNERS approve. The gated job applies. Refusals name the enrollment or escalation path.Build.I12
ambient, audit-drivenThe watcher, in Rounds’ form. Unused-access findings and expiring grants on a schedule. One PR per finding, capped, declines stick. The drift reconcile runs under the same rules.Rounds as-is for what its catalogs cover. IAM projections added.I7, I13
interactive, audit-drivenMend the access repo. Point Mend at the access repo. Its aws catalog reads the declared Terraform.Mend as-is.I3
ambient, request-drivenA ticket that opens a desk conversation and tracks the PR as comments.Later.I12
TODO: prose
PartIAM on the water park estateLessons
targetThe access repo and the live estate it owns, plus one satellite repo.I1, I8
readThe guardrails, the drift watch, the Access Analyzer proofs, the unused-access and expiring-grant projections, and the estate view.I3, I6, I7, I11
operatorA teammate on the reference Environment with a checkout, SKILL.md and a code-host token that can open PRs and nothing else. No cloud credential.I12, F4
planThe access delta rendered by the deterministic renderer, never the model. A directed refusal for a boundary exception or an unmapped requester.I12, I14
verifyThe guardrails and a terraform plan against Floci on every PR with no credential. check-no-new-access where an untrusted author cannot trigger it. The digest re-checked at apply.I4, I6, I14
proposeThe PR. Merge then apply by a gated job on a protected branch. The watcher’s propose endpoint with cap and declined list.I6, I13
rulesGenerated CODEOWNERS and branch protection. The apply role’s own boundary. The satellite’s iam:PermissionsBoundary condition. Rounds’ rules on reconcile and watcher (decision 28).I5, I6, I7, I8
recordGit for blame, the PR and provenance by PR and sha. The conversation for the request. Reconcile state in the code host.I6, I7, I12
refusalThe guardrail in the editor. The double refusal. An unmapped identity with the enrollment path. A reconcile PR closed unmerged.I3, I8, I12, I7

What the loop asks of Fountain

TODO: prose