Skip to content

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

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

feat: add deployer host installer (#22)#69
Nickfost wants to merge 101 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

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

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
@Nickfost
Nickfost force-pushed the feat/issue-22-deployer-host-installer branch from 2ad48c7 to a07990f Compare August 28, 2026 01:02

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

ℹ️ 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 deploy/deployer/ci-fleet-deployer.service Outdated
Comment thread scripts/install-deployer.sh Outdated
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 30, 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-08-30T10:49:41.325996Z 48ddebe New commits
ℹ️ 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: 024614b803

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

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

ℹ️ 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/install-deployer.sh Outdated

@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: 08e89046df

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

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

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

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

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


reject_deployer_role() {
local path
for path in "$root/etc/systemd/system/ci-fleet-deployer.service" "$root/etc/ci-fleet-deployer" "$root/var/lib/ci-fleet-deployer"; do

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject every deployer unit before installing receiver

On a partially removed or drifted deployer host where only a secondary unit such as ci-fleet-deployer-cleanup.timer remains and the main service/state directories are absent, this check passes and the status receiver can be installed alongside deployer state. Check the complete ci-fleet-deployer* unit family, as the controller-side admission check does, so partial deployer state also fails closed and the host roles remain separable.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +1318 to +1320
perform_drain() {
if active_deployment; then block 'active deployment prevents drain'; fi
secure_directory "$state_root" 700 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require an installed deployer before creating drain state

When --drain is run on an uninstalled or ordinary-controller host that has a deployer config but no managed deployer state, this unconditional creation of state_root publishes a deployer role marker without first checking convergence or rejecting other roles. The host is then wedged in mixed-role state: controller convergence rejects /var/lib/ci-fleet-deployer, while deployer installation rejects the controller. Require an existing managed deployer installation and role isolation before creating the drain marker.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.


reject_deployer_host() {
# A deployer host is a separate role; never run controller mutations on it.
if compgen -G "$(root_path /etc/systemd/system)/ci-fleet-deployer*" >/dev/null || [[ -e "$(root_path /var/lib/ci-fleet-deployer)" || -e "$(root_path /etc/ci-fleet-deployer)" ]]; 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.

P2 Badge Reject dangling deployer role markers

If /var/lib/ci-fleet-deployer or /etc/ci-fleet-deployer is a dangling symlink—for example after an incomplete cleanup—-e is false, so this admission check allows controller convergence and creates a mixed-role host. Other role checks in this change explicitly test -L; do the same here so unsafe deployer markers fail closed before controller mutation.

AGENTS.md reference: AGENTS.md:L33-L35

Useful? React with 👍 / 👎.

Comment on lines +85 to +91
if [[ ${audit_pending:-0} == 1 && -n ${consumed_marker:-} && ! -e "$consumed_marker" ]]; then
if [[ -e "$consumed_root" || -L "$consumed_root" ]] && [[ ! -d "$consumed_root" || -L "$consumed_root" || $(stat -c '%u:%a' "$consumed_root" 2>/dev/null) != "$expected_uid:700" ]]; then
rm -rf -- "$consumed_root" 2>/dev/null || status=1
fi
[[ -e "$consumed_root" ]] || install -d -m 0700 "$consumed_root" 2>/dev/null || status=1
if [[ -d "$consumed_root" && ! -L "$consumed_root" ]]; then
install -m 0600 /dev/null "$consumed_marker" 2>/dev/null || status=1

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 all consumed request markers during recovery

When an adapter recursively removes consumed-requests or the writable state root after multiple deployment attempts, this recovery recreates only the marker for the request currently being processed. Every older consumption marker is lost, and because replay validation consults only these markers plus the single last-request.conf, an older non-last request can later be accepted again when its protected policy/evidence is restored. Preserve and restore the complete consumed-request set outside the adapter-writable boundary rather than reconstructing only the current marker.

Useful? React with 👍 / 👎.

Comment on lines +266 to +272
if [[ -z ${CI_FLEET_DEPLOYER_REEXEC:-} ]]; then
exec 9<"$lock_dir"
flock -n 9 || die 'another deployer operation is running'
else
# The re-executed process inherits the locked descriptor 9 from its parent;
# reopening it would drop the lock during the handoff.
:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify the inherited lock before skipping acquisition

When the runtime starts with any nonempty CI_FLEET_DEPLOYER_REEXEC value but without the intended inherited descriptor 9, this branch skips flock entirely and deploy, cleanup, health, or drain can overlap another operation. Validate that fd 9 resolves to the expected lock directory and still carries the lock before accepting the internal re-exec flag; otherwise reject the invocation or acquire the lock normally.

AGENTS.md reference: AGENTS.md:L35-L35

Useful? React with 👍 / 👎.

@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: 48ddebe7be

ℹ️ 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 on lines +903 to +904
publish_deployed_snapshot "$active_policy" "$state_file" || return
rm -f "$previous_state" "$previous_policy" || return

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 rolled-back core before retiring recovery state

When the root rollback adapter creates a safe commit marker but changes /opt/ci-fleet-deployer/current or any deployed unit before returning, finalize_committed_rollback validates only the active policy, state, adapter, and credential reference; it never verifies current_matches or units_match. These lines then publish the snapshot and remove the last-known-good pair before retiring the journal, permanently accepting a core that may not match the rolled-back application. Revalidate or restore the protected rolled-back pointer and units before finalization.

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

Useful? React with 👍 / 👎.

fi
if [[ -n "$retired_snapshot" && -d "$deployed_root/$retired_snapshot" && ! -L "$deployed_root/$retired_snapshot" ]]; then rm -rf -- "${deployed_root:?}/$retired_snapshot"; fi
sync -f "$deployed_root" 2>/dev/null || sync "$deployed_root" 2>/dev/null || die 'retired deployed snapshot is not durable'
audit_pending=0

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 Restore active core state before disarming deploy recovery

When a successful deployment adapter truncates or removes active-policy.conf or install-state.json while leaving the request and audit boundaries intact, no success-path check detects that mutation. Clearing audit_pending here prevents deploy_exit lines 172-175 from restoring the protected policy/state copies, so the service reports success with the new application and deployed snapshot but subsequent health and deployment operations reject the missing or corrupted active state. Restore and verify those protected files before disabling recovery.

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

Useful? React with 👍 / 👎.

[[ -z "$retired_snapshot" || "$retired_snapshot" =~ ^\.snapshot\.[A-Za-z0-9._-]+$ ]] || die 'current deployed snapshot pointer is unsafe'
[[ -z ${CI_FLEET_DEPLOYER_TEST_SIGNAL_SELF:-} || $testing != 1 ]] || kill -"$CI_FLEET_DEPLOYER_TEST_SIGNAL_SELF" $$
if [[ -f "$request" && ! -L "$request" ]] && cmp -s "$request_snapshot" "$request"; then rm -f "$request"; fi
mv -Tf "$request_snapshot" "$last_request"

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 Persist the completed-request marker before recording success

When the state and audit roots are on separate filesystems, a power loss after this rename and the success-audit fsync at line 612 but before the EXIT handler syncs state_root can discard last-request.conf even though the application change, deployed pointer, consumed marker, and success audit are already durable. On a first completed deployment this makes perform_rollback fail its mandatory completed-deployment gate, leaving the changed application without the supported rollback path. Fsync the marker and its parent directory before committing the success record or disarming recovery.

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

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.

feat: Add idempotent install-deployer.sh for the separate CI deployment control plane

1 participant