Skip to content

Decisions: 0205 and 0204 addenda — one rollout technology for three paths, per-run gateway access, tailnet-only Organizations, freeze and waves - #567

Merged
immakermatty merged 4 commits into
mainfrom
agent/DEV-6671-gitops-environment-rollout
Oct 17, 2026
Merged

immakermatty merged 4 commits into
mainfrom
agent/DEV-6671-gitops-environment-rollout

Conversation

@immakermatty

@immakermatty immakermatty commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Why

Decision 0205 (#560, merged 2026-10-16) made a pull request to an Organization's Deployment Repo the only change path for its Machines and Environments, with apply after merge through a gateway. It did not yet say how the three rollout paths relate, how a run gets access, how personal Environments are approved, or what happens until the gateway exists. Meanwhile rollouts kept running from one laptop: in four days, 41 % of the Permit-consuming applies run from it failed, each followed by manual recovery. On 2026-10-17, after reviewing the live rollout state, Matěj (Organization Admin) decided the next layer of plan DEV-6671, including a follow-up for the reference Organization (0204). This PR records those decisions as dated addenda.

What changes

Only manual/decision-register.md. Two dated **Dodatek z 2026-10-17** blocks are appended to the ends of rows 0205 and 0204 (Czech, register style). Each row stays one table line; no earlier text of any row is edited.

0205 addendum, points (a)–(k):

  • (a) One technology, three paths. The reference Organization, other Organizations with a Conglomerate Host, and personal Environments share Machines, the workflow, the gateway program and the evidence format. They differ only in their deployment-domain settings (source of truth, gateway placement, path to the servers, approvals). No path gets its own code branch.

  • (b) Gateway. One program, running on the Conglomerate Host. The reference Organization runs it on its own small Conglomerate Host, and Lazurio operates the personal pool's gateway. A gateway belongs to the server its Environments run on. This closes the 0205 open question about where the reference Organization's gateway sits.

  • (c) Per-run access. Each run gets a short-lived SSH certificate signed by the gateway's CA (servers trust it after a one-time setup) and custody for that lane only; tailnet lanes also get an ephemeral tagged node. The long-lived key never leaves the gateway and the Operator's personal token is not used. The gateway holds the Machine's lock and queue. After a failure proven to precede the first mutation, it releases the lock and confirms the run ended. Refines points 4 and 9.

  • (d) Runner. A GitHub Actions workflow. The GitHub-hosted runner is the default for every domain; Blacksmith is only a development aid. The Operator's computer only dispatches reference-Organization runs, optionally with a local build as candidate.

  • (e) Approvals.

    • Organizations: persona or colleague review, a named person's merge, and one click in a GitHub Environment. This closes the 0205 open question about fully automatic apply.
    • Reference Organization: no persona and no click. The Agent acts on the Operator's instruction within the Operator's rights (0204 point 7), including unreleased candidates.
    • Personal Environments: a standard update every night at 02:00 Europe/Prague without approval, but only to a release that already passed wave 1 (including the operator's personal Environment) and browser acceptance. Candidates and not-yet-accepted releases reach only the operator's personal Environment, and the personal-pool gateway refuses any other release. The owner can opt in to approving in advance.
  • (f) Personal pool. One pool gateway reconciles personal Environments through the pool's server, without the owner's tailnet. The Conglomerate Host whose tailnet the Environment is in decides only the network. Refines point 7.

  • (g) Versions. Manual fleet rollouts are frozen from 2026-10-17. Exceptions: finishing in-flight recoveries, the one-time gateway bootstrap, and urgent fixes with the Operator's explicit consent. LazurioPlatform 0.1.9 is the first automated rollout; 0.2.0 is the milestone "all three paths without the Operator's computer".

  • (h) Waves. 0 reference Organization → browser acceptance (0178) → 1 the operator's own Organization, including its personal Environment → 2 Organizations on the same Conglomerate Host → 3 other Organizations once their gateway exists. Failures in what only the reference Organization has do not stop later waves (refines 0204 point 7). Other personal Environments receive a release only through the nightly run after wave 1 (point e).

  • (i) Progress in the Dashboard. The runner writes run state to the Dashboard database. An Organization Admin sees it in the Organization overview through their Lazurio account, and an owner sees their personal Environment. It is a mirror, not authority (refines point 3).

  • (j) Security promise of Organizations (every Organization except the reference one).

    • Their servers and Environments are reachable only over the tailnet. That covers management and SSH of every Proxmox host and the Conglomerate Host, the workshops, the vault, and every gateway call after admission.
    • No public SSH in normal operation; provider rescue is the break-glass path.
    • Exactly three public endpoints:
      1. tailnet sign-in (Headscale);
      2. the rollout gateway's admission. It answers only GitHub-OIDC-verified runs from the Organization's Deployment Repo merged to main, and grants only a temporary tagged node;
      3. production applications the Organization deliberately publishes, behind its fail-closed production gateway with Lazurio account sign-in. 0146 point 2 stays unchanged.
    • The central Lazurio Auth issuer is shared control plane (0204 point 7), not an Organization endpoint.
    • The reference Organization is managed the same way over its own tailnet, but people and visitors enter its Environments publicly.
  • (k) New Environments and Organizations use the same technology with another trigger.

    • Personal Environments are assigned instantly from a warm pool of ownerless, pre-provisioned Environments. Assignment is a Lazurio-account record, an assigned Environment is never handed to another person, and the pool is replenished in the background.
    • Organizations are made to measure from Dashboard onboarding: a Deployment Repo generated with declarations, a Conglomerate Host and server from operator stock, and progress shown in the Dashboard. Until then operators create them by hand.
  • Open:

    • the warm-pool size and how many of its Environments run;
    • the personal address at the moment of assignment;
    • who owns the operator's stock servers.

    The other 0205 open questions remain.

  • Today: decided, not deployed; the Operator's Mac remains the only runner until the gateway is deployed.

0204 addendum:

  • The reference Organization gets its own small Conglomerate Host with three parts:

    • Headscale, for managing all its servers over its tailnet;
    • its own Lazurio Vaultwarden, for testing Vaultwarden changes and migrations (no important secrets);
    • the rollout gateway.

    That makes it technologically the same as other Organizations. People and visitors still enter its Environments publicly, without a tailnet.

  • Its Deployment Repo becomes the private infra, renamed from the private machines. The public documentation repo infra is renamed to infra-example.

  • Its rollouts use the same pipeline, without a persona and without a click; the other conditions of point 7 stay.

  • The addendum names what it changes:

    • in point 2, the sentence that none of its Machines is in any tailnet;
    • in point 9, the sentences that it has no Headscale and, per 0203, no Conglomerate Host and therefore no Lazurio Vaultwarden. 0203's text is not edited, and point 4 (no vault for visitor Environments) still holds;
    • the repository names in point 8;
    • the reference-Organization exception in 0205 point 2.

Commits: aa80efb4 (first draft), 299dffb5 (Matěj's follow-up decisions: GitHub runner by default, the reference Organization's own Conglomerate Host, infra-example), f33b82ea (option A for the security promise; 0146 point 2 unchanged).

What does not change

  • Nothing is deployed, and no manual, schema or runtime changes. Until the gateway exists, the Mac stays the only runner and the freeze in (g) applies.
  • These stay as they are:
    • access authority (GitHub and Auth per 0192);
    • the Machines release process and Machines lifecycle gates (Permit);
    • forward repair (0166);
    • the shared control plane's own gates (0204 point 7).
  • Decisions 0146 and 0203 are not edited; 0146 point 2 explicitly stays valid. Personal-Environment networking per 0154 is unchanged: the Conglomerate Host still decides the network.
  • Personal Environments still have no Deployment Repo (0205 point 7).

Verification

  • A script compared the file with origin/main. The change is a pure append on lines 140 and 141: each old row is an exact prefix of the new one, each row keeps two cells, and the trailing newline is kept. git diff --name-only origin/main..HEAD lists only manual/decision-register.md.
  • I read both addenda against the full text of 0146, 0153, 0154, 0184, 0192, 0203, 0204 and 0205. Each addendum says which earlier points it refines or changes.
  • Public safety: the addenda name no client Organization, no person other than the deciding Admin (already named in the register), no host or address and no client repository.
  • GitHub CI on f33b82ea: all six jobs pass (bun run check on ubuntu and windows, guide app build, npm package gate on macOS, ubuntu and windows).
  • Local bun run check:
    • On aa80efb4 and 299dffb5, every suite passes except 13 cases in launchpad/src/macos-launcher-installer.test.mjs. They fail with lipo: -verify_arch requires exactly one input file, which is the known host issue macOS Launchpad installer check fails at lipo verify_arch on clean main #398 on clean main.
    • On f33b82ea, run while two applies were running from the same Mac, the same 13 macOS Launchpad installer check fails at lipo verify_arch on clean main #398 cases fail. In addition, 19 Doctor and update-CLI tests hit the 10 s per-test timeout, and the Launchpad suite took 584 s instead of 308 s.
    • Control: on clean main (5f2d171d), under the same load and with the runner's 10 s timeout, launchpad/src/diagnostics-lib.test.mjs alone hits the same timeouts (4 of 66 at that moment; the count moves with load). No test reads the register, so the timeouts are environmental, not caused by this change.
    • resident:test needs a clean checkout and passes on the commits; doctor:agent-skills passes.
  • bun run check:docs: pass on aa80efb4.
  • bun run pr:preflight: ok on f33b82ea against origin/main 5f2d171d. One earlier attempt failed: its git fetch exceeded the 20 s limit while the link was congested.

Risks and open questions

  • (j) is a security promise. It holds only once the gateway and tailnet-only management are deployed and public SSH is closed. Until then "Today: decided, not deployed" applies, so anyone citing (j) should check the deployment state.
  • Closing public SSH leaves provider rescue as the only way in when the tailnet or Headscale is down. That makes the Conglomerate Host critical for management.
  • Because of the freeze, non-urgent fixes for Organizations wait for the automated pipeline. Urgent fixes need the Operator's explicit consent.
  • Nightly unattended updates of personal Environments put the risk on the pipeline's quality. Owners can opt in to approval.
  • 0204 point 9 still says 0154 and 0184 do not extend to the reference Organization. Only the sentence about Headscale changes. How people join its management tailnet is left to implementation.

Follow-ups

  • The DEV-6671 roadmap in the owning Organization's Mission Control (separate PR).
  • Implementation in Machines (runner mode, gateway, CA trust) and the Dashboard (rollout progress), plus the repository renames and the small Conglomerate Host for the reference Organization.

🤖 Generated with Claude Code

immakermatty and others added 3 commits October 17, 2026 18:20
…teway-issued access, nightly personal updates, freeze and rings

Appends dated 2026-10-17 addenda to rows 0205 and 0204 of the decision
register (plan DEV-6671). The 0205 addendum adds points (a)-(k): one
technology for the reference Organization, Organizations with a
Conglomerate Host and personal Environments; one gateway program placed
with the server; per-run access issued by the gateway; GitHub Actions
runners; approvals per path, including the nightly personal update; the
freeze of manual fleet rollouts; rollout waves; run progress in the
Dashboard; tailnet-only server management; and new Environments and
Organizations from the same technology. It closes two of the open
questions of 0205. The 0204 addendum renames the reference
Organization's private Deployment Repo to infra and routes its rollouts
through the same pipeline without a persona or a click.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…all Conglomerate Host, real Organizations are tailnet-only, GitHub-hosted runner by default

Folds in decisions made after the first draft of the 2026-10-17
addenda (plan DEV-6671):

- 0205 (d): every deployment domain defaults to the GitHub-hosted
  runner; Blacksmith is only a development aid and leaves the open
  questions.
- 0205 (j): every Organization except the reference one is wrapped in
  its tailnet. Management, SSH, workshops, vault and the gateway's
  other calls are tailnet-only; the only public management doors are
  Headscale sign-in and the gateway admission for GitHub-verified runs
  from the Organization's Deployment Repo merged to main. The relation
  to the public production apps of 0146 point 2 is recorded as open;
  0146 is not changed.
- 0204: the reference Organization gets its own small Conglomerate
  Host with Headscale for managing its servers, its own Lazurio
  Vaultwarden for testing Vaultwarden changes and the rollout gateway.
  People and visitors still enter its Environments publicly. Its
  Deployment Repo becomes the private infra; the public documentation
  repo becomes infra-example. The addendum names the sentences of
  points 2, 8 and 9 it changes; the text of 0203 is not edited.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…blic endpoints; 0146 point 2 unchanged

Matěj chose option A for the tailnet promise of real Organizations
(every Organization except the reference one). Their servers and
Environments are reachable only over the tailnet: management and SSH of
every Proxmox host and the Conglomerate Host, workshops, the vault and
every gateway call after admission. There is no public SSH in normal
operation; provider rescue is the break-glass path. Exactly three
endpoints are public: tailnet sign-in (Headscale), the rollout
gateway's admission for GitHub-OIDC-verified runs from the
Organization's Deployment Repo merged to main (granting only a
temporary tagged node), and production applications the Organization
deliberately publishes behind its fail-closed production gateway with
Lazurio account sign-in, so 0146 point 2 stays unchanged. The 0146
item leaves the open questions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty marked this pull request as ready for review October 17, 2026 17:11

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your trial has ended. Reactivate Greptile to resume code reviews.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T17:16:56.580229Z f33b82e Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f33b82eae1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread manual/decision-register.md Resolved

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested on exact head f33b82eae15a876361354b3e345d1d5bba373ade.

Blocking contract gap in decision 0205(e)/(h): the nightly 02:00 update applies to every personal Environment, but the rollout waves place only the operator’s personal Environment in wave 1; waves 2–3 cover Organizations, not the rest of the personal pool. As written, the pool reconciler could move other owners to the new release before the staged acceptance is complete. Please specify when the remaining personal Environments become eligible (a separate wave or an explicit pin to the last release that passed the required gates), and how the nightly job enforces that rule. This is also the unresolved inline finding at discussion_r4303681667.

I verified that the diff only appends to rows 0204/0205, checked the relationships to 0146, 0153/0154, 0192 and 0203, and found no additional public-safety disclosure. The text labels the design “decided, not deployed”, rather than claiming the tailnet/gateway promise is live. CI is 6/6 green, local pr:preflight passed, and git diff --check is clean. No merge performed.

…s accepted in wave 1

Review found that point (e) scheduled every personal Environment for a nightly
update without approval, while point (h) put only the operator's personal
Environment into a wave, so nothing said when the rest of the personal pool may
receive a release. The nightly run now brings only a release that already passed
wave 1, including the operator's personal Environment, and browser acceptance.
Candidates and not-yet-accepted releases reach only the operator's personal
Environment, and the personal-pool gateway refuses any other release.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVED on exact head 41ffad3. The previous CHANGES_REQUESTED review on f33b82e is not reused. The new 0205(e) admits nightly personal-pool updates only for a release that has passed wave 1 (including the operator’s personal Environment) and browser acceptance; candidates/unaccepted releases remain operator-only, with a gateway exclusion. 0205(h) explicitly places other personal Environments after wave 1 at the nightly run. This closes the prior e/h gap, preserves the 0204(7) browser gate and operator instruction, and does not conflict with 0205(g) freeze or (i) status-as-mirror. 0204 is unchanged from the prior review. The addenda remain decision-only (“rozhodnuto, nenasazeno”), not a claim of live deployment. Local: focused two-row/prefix/semantic and added-line safety assertions passed; git diff --check and bun run pr:preflight passed. GitHub CI is 6/6 successful on this SHA; 0 unresolved threads and no competing review request. Fresh main 5f2d171 merges cleanly. No merge performed.

@immakermatty
immakermatty merged commit 7156831 into main Oct 17, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants