Skip to content

feat: add deployer host installer (#22) - #69

Open
Nickfost wants to merge 90 commits into
mainfrom
feat/issue-22-deployer-host-installer
Open

feat: add deployer host installer (#22)#69
Nickfost wants to merge 90 commits into
mainfrom
feat/issue-22-deployer-host-installer

Conversation

@Nickfost

@Nickfost Nickfost commented Aug 8, 2026

Copy link
Copy Markdown
Member

Summary

  • add a repository-owned Linux/Bash deployer-host installer with explicit --check, --install, --upgrade, --repair, --rollback, --drain, and --uninstall modes
  • install a small generic runtime plus hardened systemd deploy, health, scoped-cleanup, and drain units while leaving application deployment logic behind a pinned host-local adapter
  • enforce exact immutable source/image identities, fail-closed approval and checkpoint evidence, staging/production separation, host-role isolation, transactions, active-operation locking, shutdown inhibition, and conservative uninstall
  • document the complete operator flow and add deterministic temporary-root tests

Closes #22

Acceptance matrix

Issue responsibility Implementation Deterministic evidence
Explicit noninteractive lifecycle scripts/install-deployer.sh requires exactly one mode and --config scripts/test-install-deployer.sh: missing/duplicate mode, check/install/upgrade/repair/rollback/drain/uninstall
Linux, systemd, Docker, Compose, tools, time, disk, network require_host supports Debian 12/13 and Ubuntu 22.04/24.04; Compose is conditional unsupported OS and mocked missing/systemd/Docker/Compose/time/disk/DNS/HTTPS cases
Dedicated-host isolation rejects worker/controller units and every Docker container, custom network, or volume not carrying the exact deployer identity mixed-role, unrelated workload, wrong identity, and exact owned-identity cases
Strict secret-free config bounded non-executing KEY=value parser; unknown, duplicate, malformed, missing, and ambiguous fields fail parser, mode, path, permission, symlink, secret-canary, and report checks
Protected credential references accepts only mode-0600 host-local regular files or an external reference resolved by the pinned application adapter file/external provider cases; missing, broad-mode, and symlink rejection
Environment/target separation explicit environment, target, deployer identity, and matching credential scope; in-place cross-environment changes fail staging/production mismatch and no-default cases
Immutable provenance and approval full source/core commits, qualified image digest, exact evidence, approval/policy identities, checkpoint ID, and capability-aware GitHub evidence moving/malformed references, manual/external evidence, GitHub capability evidence, and GitHub-Free fallback cases
Candidate and atomic activation validates the pinned adapter before mutation, stages a hashed release, atomically exchanges it, then health-checks before transaction commit failed candidate and failed unit activation preserve current state; install/upgrade/rollback paths
Auditable service surface generic runtime and six hardened systemd units/timers for deploy, health, scoped cleanup, and drain scripts/test-deployer-units.sh runs real systemd-analyze verify in a temporary root
Active work, drain, reboot, stale recovery kernel lock, mode-0600 active marker, one-hour stale bound, drain marker, operation timeouts, and systemd-inhibit live/stale markers, lock contention, interrupted transaction recovery, drain refusal, consumed-request replay refusal
Scoped Docker behavior core never deletes Docker resources; the pinned adapter owns only its exact identity and must implement scoped cleanup repository policy validation plus unrelated-resource preservation checks
Idempotence and repair content/state/unit/timer comparisons converge; managed modes and drift are repaired without duplicate releases fresh install, second install, check, unit drift, stale staging, interrupted transaction, and repair
Conservative uninstall drains, refuses active work, removes only activation and owned units/timers, retains config/credentials/releases/state/logs; works without Docker or candidate evidence fresh/repeated uninstall, dependency-loss uninstall, active refusal, and retained/unrelated-file checks
Human/machine report one secret-free REPORT line carries action, result, environment, target, version, digest, health, changed, rollback, and next action CHANGED, NO_CHANGE, BLOCKED, FAILED, rollback-available, and canary checks

Trust boundaries

The deployer is a dedicated role. It never registers a runner and does not receive pull-request jobs. Ordinary workers/controllers receive no deployment credentials, deployer Docker socket, production authority, or deployment route. The installer rejects mixed-role hosts and unrelated Docker state instead of adopting it.

The systemd runtime runs as root because the Docker socket is root-equivalent. Units apply NoNewPrivileges, ProtectSystem=strict, private temporary storage, explicit writable paths, and bounded operation timeouts, but do not pretend Docker access is unprivileged. The application adapter is a root-owned mode-0700 regular file pinned by SHA-256. Core defines its operation/timeout/redaction contract; application-specific staging, deployment, health, rollback, credential resolution, and exact-label cleanup remain application-owned.

Secret values are never CLI fields. File references stay under the protected configuration tree; external references are resolved by the pinned adapter. Reports and audit logs contain only validated identities, commits, digests, and approval metadata. Network hosts are fed to DNS/HTTPS probes over standard input rather than command arguments.

GitHub-native Environment protection is optional. github-environment requires separate exact-head capability evidence. manual-exact-head and external-exact-head provide fail-closed alternatives for private repositories where the available GitHub plan does not supply the needed protection. A credential store by itself is never treated as approval.

Operator examples

On a prepared isolated Linux deployer host, after creating the fictional root-owned configuration/evidence/credential files described in docs/DEPLOYER-HOST.md:

sudo ./scripts/install-deployer.sh --check --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --install --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --upgrade --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --repair --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --drain --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --rollback --config /etc/ci-fleet-deployer/deployer.conf
sudo ./scripts/install-deployer.sh --uninstall --config /etc/ci-fleet-deployer/deployer.conf

Rollback restores the last-known-good active state but deliberately leaves operator-owned desired configuration/evidence untouched; its report names the required reconciliation step before check.

Validation

  • scripts/test-install-deployer.sh
  • scripts/test-deployer-units.sh
  • shellcheck scripts/install-deployer.sh scripts/deployer-runtime.sh scripts/test-install-deployer.sh scripts/test-deployer-units.sh
  • scripts/validate.sh
  • python3 scripts/scan_committed_secrets.py
  • git diff --check

No host installation, Docker/systemd mutation, runner registration, infrastructure change, credential access, or production deployment was performed. Tests use an explicit temporary-root seam and mocked host commands. A prepared isolated deployment host still needs an operator proof of host prerequisites, application-adapter correctness, target policy, approval evidence, credentials, checkpoint evidence, deployment health, and rollback behavior before use.

Rollback and compatibility

The installer retains hashed core releases, active and last-known-good policy/state, audit logs, and host-local credentials. Failed candidate validation or activation restores the previous units, timer state, policy, state, and release pointer. Uninstall removes only the activation pointer and owned units/timers; retained data requires a separate explicit operator decision.

The public contract is application-neutral and Linux/Bash-only. Existing CI worker/controller behavior is unchanged.

@Nickfost

Nickfost commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 73f45a1a10

ℹ️ 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 scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: ed8c5e6351

ℹ️ 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 scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 777f8c534c

ℹ️ 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 scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 19a0c4e200

ℹ️ 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 scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 37d29628fc

ℹ️ 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 scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 773c3ae74c

ℹ️ 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 scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 61b3d0eace

ℹ️ 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 scripts/install-deployer.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: 5ddea4d953

ℹ️ 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 scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh Outdated
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: deb781caef

ℹ️ 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 scripts/install-deployer.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
- Permit the conventional /var/lock -> /run/lock symlink layout instead of
  rejecting the canonical parent path
- Write a structured failed audit record through fd 8 for every failure
  after approval consumption, including post-adapter snapshot/publication
  failures, with the failing phase recorded
- Reject unknown approval provider values instead of silently skipping
  GitHub capability validation
- Validate the retained last-known-good state schema and cross-match it
  with the retained policy before rollback starts
- Allow --repair to restore a missing or drifted owned active policy by
  skipping only the untrusted old-policy health probe while retaining
  candidate validation and post-activation health gates
- Fix the repair transaction-failure fixture to fail the candidate health
  call under the new single-health-call sequence and assert the exact
  call count
@Nickfost

Nickfost commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

@codex review

@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: f0b62de8ee

ℹ️ 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 scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread deploy/deployer/ci-fleet-deployer.service Outdated
Nicks Hermes added 2 commits August 13, 2026 09:14
…ded stop

- The runtime retires the validated pre-adapter incumbent snapshot,
  never an adapter-writable pointer read after the adapter ran.
- The controller installer rejects hosts carrying deployer units or
  state, preserving the role boundary in both install orders.
- The deploy unit's stop timeout is 30s so a hung adapter cannot hold
  the lock and inhibitor past the 45-minute deployment bound.
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

@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: 886a95d4b2

ℹ️ 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 scripts/install-worker-controller.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
…ring, shortcut metadata, local Docker

- The controller rollback path also rejects deployer hosts.
- deploy_exit restores the incumbent snapshot's content, not only its
  pointer, when a failed adapter deleted the target directory.
- The terminal failure audit record is appended after restoring the
  audit log under its durable name.
- The identical-bytes publication shortcut now requires the incumbent
  snapshot directory and files to have safe owner, mode, and type.
- Installer and runtime force DOCKER_HOST to the local socket and unset
  DOCKER_CONTEXT before any Docker call.
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

@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: 16d5851cac

ℹ️ 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 scripts/install-worker-controller.sh
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
…-file incumbent restore, shortcut metadata, pre-adapter durability

- Both installers now flock a shared /run/ci-fleet-role-admission.lock
  for their whole mutating run, closing the concurrent-install race.
- require_maintenance_host applies the same local-Docker sanitization
  as require_host.
- deploy_exit validates and restores each incumbent snapshot file
  independently.
- The publication shortcut requires root 0600 policy and state files.
- perform_rollback syncs all rolled-back core boundaries before
  invoking the adapter that publishes the commit marker.
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

@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: 5c8302c8bf

ℹ️ 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 scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/deployer-runtime.sh
Nicks Hermes added 3 commits August 13, 2026 11:55
… preservation

- deploy_exit restores incumbent snapshot directory and file modes as
  well as contents, and repairs audit-log mode drift before appending
  the failure record.
- The runtime keeps a protected copy of the last-known-good pair across
  the adapter call and restores it before committing success or
  failure.
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

Focused exact-head review at ee99bfc. Apply this objective value gate: report only a reproducible documented-workflow failure, a real trust-boundary authorization/credential issue, plausible loss/corruption of deployment/approval/rollback state, or a concrete repository/CI/runtime/configuration-contract violation that prevents use, validation, deployment, or recovery. Treat duplicates, sibling variants covered by one root fix, style, speculative defense-in-depth, forbidden inputs, and out-of-contract durability as non-blocking.

@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: ee99bfc926

ℹ️ 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 scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

Focused exact-head confirmation at b58e8d2. Please verify only the two accepted root fixes: retained rollback state survives recursive adapter cleanup of its writable state root, and immutable versioned adapter paths provide a documented rollback-capable adapter upgrade. Apply the objective review-value gate; collapse duplicates and speculative variants.

@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: b58e8d2e66

ℹ️ 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 scripts/deployer-runtime.sh
@Nickfost

Copy link
Copy Markdown
Member Author

@codex review

Focused exact-head confirmation at 515b071. Please verify the accepted rollback-state root fix: after recursive adapter cleanup, the retained pair and completed-deployment marker remain exact and an actual rollback succeeds. Apply the objective review-value gate; collapse duplicates and speculative variants.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 515b071461

ℹ️ 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".

@Nickfost Nickfost left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

[lane-a:pr69:publish-pending-dispositions] Publishing 16 previously drafted accepted/fixed evidence replies. Each corresponding Codex finding already has Nickfost +1; current exact-head CI is green and Codex found no major issues at 515b071.

Comment thread deploy/deployer/ci-fleet-deployer.service Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-worker-controller.sh Outdated
Comment thread scripts/deployer-runtime.sh
Comment thread scripts/install-deployer.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh Outdated
Comment thread scripts/install-deployer.sh
Comment thread scripts/deployer-runtime.sh
@Nickfost

Copy link
Copy Markdown
Member Author

Prepared isolated deployer proof completed on exact head 2ad48c75c1412a146086b7a18fb3027f423515f1 using only credential-free local synthetic tiers demo-a and demo-b; no staging or production system was accessed or implied.

Real Debian 13/systemd/Docker-host lifecycle covered install and unchanged rerun, deploy, exact request/approval/checkpoint binding, application-adapter validate/health/deploy/cleanup/rollback operations, immutable source/artifact state, failed cross-tier request preservation, upgrade, drain/refusal/resume, rollback to the prior application/core state, repeated uninstall, independent demo-b deployment, and complete cleanup. The proof exposed Debian’s canonical /etc/os-release -> ../usr/lib/os-release layout as a repository-owned preflight defect; 668213b7b3180bea368a7c93068d7c06594eaa4b fixes it and 2ad48c75c1412a146086b7a18fb3027f423515f1 places the regression at the mutating install boundary. Exact-head CI is green. Final cleanup proves no service, process, runner, credential, container, image, volume, network, or ci-fleet deployer state remains.

@Nickfost
Nickfost marked this pull request as ready for review August 17, 2026 02:47

@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: 2ad48c75c1

ℹ️ 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".

# active-operation guard is durably cleared — but only when the new pointer
# was never published. After publication the new pointer is the truth: the
# application has changed and restoring the incumbent would falsify state.
if [[ ${audit_pending:-0} == 1 && -n ${incumbent_pointer:-} && ${snapshot_pointer:-} != "$deployed_current" ]]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve new state after every successful adapter call

When the adapter successfully changes the application but a pre-publication integrity check subsequently fails—for example, the adapter also replaces audit.log, causing the check at lines 527-529 to abort—snapshot_pointer is still unset, so this handler restores the incumbent pointer even though the application is already on the new version. Fresh evidence beyond the earlier post-publication finding is that successful-adapter failures can occur before publication as well, leaving the recorded deployed state older than the running application; either publish trustworthy new state or roll the application back before restoring the incumbent.

AGENTS.md reference: AGENTS.md:L64-L66

Useful? React with 👍 / 👎.

Comment on lines +520 to +521
incumbent_backup=$(mktemp -d "$state_root/.incumbent.XXXXXX")
install -m 0600 "$deployed_current/policy.conf" "$deployed_current/state.json" "$incumbent_backup/"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the incumbent backup outside the writable state root

When a failing adapter recursively removes /var/lib/ci-fleet-deployer, it also removes this .incumbent backup before deploy_exit can restore the deployed snapshot. On a first deployment, where no last-known-good pair exists yet, this leaves deployed/current, active policy, and install state gone with no supported rollback or repair path. Fresh evidence beyond the retained-pair cleanup thread is that only the last-known-good pair and completed-request marker moved into process memory; the incumbent backup remains under the deleted root, while the regression exercises cleanup only after an upgrade has supplied an alternate rollback pair.

AGENTS.md reference: AGENTS.md:L64-L66

Useful? React with 👍 / 👎.

Comment on lines +1243 to +1244
if ! policy_adapter_operation "$active_policy" rollback 'last-known-good policy' "$transaction_dir/application-rollback-committed" && [[ ! -f "$transaction_dir/application-rollback-committed" || -L "$transaction_dir/application-rollback-committed" ]]; then
die 'application adapter rollback failed'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Protect the rollback journal from the rollback adapter

When the rollback adapter recursively removes the deployer state root and returns nonzero, it deletes transaction_dir during this call after the installer has already selected the older core, units, policy, and state. The EXIT handler then calls restore_transaction, which treats the missing journal as a successful no-op, while the adapter's nonzero contract means the application has restored its newer pre-call state; the host is therefore left with an older core—or missing state—describing a newer application. Preserve the recovery journal outside adapter reach, such as in unexported process memory, until the rollback is committed.

AGENTS.md reference: AGENTS.md:L64-L66

Useful? React with 👍 / 👎.

fi
reject_mixed_role
credential_reference_safe "${cfg[CREDENTIAL_PROVIDER]}" "${cfg[CREDENTIAL_REF]}" 'candidate policy'
run_verified_adapter "$config" "${cfg[ADAPTER_PATH]}" "${cfg[ADAPTER_SHA256]}" validate >/dev/null || die 'candidate adapter validation failed'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Revalidate the candidate snapshot after adapter validation

When a candidate adapter writes to the CI_FLEET_DEPLOYER_CONFIG path during validate and returns zero, this call leaves the installer using attacker- or adapter-modified bytes: line 1172 later copies that same mutable snapshot into active-policy.conf, while write_state still uses the values parsed before the adapter ran. A change to fields that candidate health does not cross-check, such as CORE_REF or SOURCE_COMMIT, can therefore commit a policy/state pair that immediately fails runtime and installer consistency checks. Preserve an immutable copy or verify the snapshot digest after validation before activating it.

AGENTS.md reference: AGENTS.md:L64-L66

Useful? React with 👍 / 👎.

Comment on lines +414 to +415
for unit in ci-fleet-health.service ci-fleet-health.timer ci-fleet-reconcile.service ci-fleet-reconcile.timer ci-fleet-cleanup.service ci-fleet-cleanup.timer ci-fleet-drift.service ci-fleet-drift.timer actions.runner.service; do
[[ ! -e "$systemd_root/$unit" && ! -L "$systemd_root/multi-user.target.wants/$unit" && ! -L "$systemd_root/timers.target.wants/$unit" ]] || block 'ordinary CI controller or runner state is present'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject status-receiver hosts as a separate trust role

When ci-fleet-status-receiver.service and /etc/ci-fleet-status are already present on an otherwise Docker-clean host, this role check passes because it recognizes only ordinary-controller and runner artifacts. The receiver runbook defines a dedicated host and stores per-controller signing keys plus the read token there, all of which become readable to the root deployer adapter if installation proceeds. A repo-wide search also finds no reciprocal deployer check or shared role-admission lock in install-status-receiver.sh, so installing the receiver second has the same result; reject receiver state in both installers and serialize their role admission.

AGENTS.md reference: AGENTS.md:L34-L34

Useful? React with 👍 / 👎.

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.

Add an idempotent Bash installer for deployment hosts

1 participant