feat(remote-systems-administration): add cross-platform operations skill (#35)

This commit is contained in:
Magnus Hedemark
2026-07-13 11:33:27 -04:00
committed by GitHub
parent d85ed67cbc
commit 901fca5d8a
14 changed files with 646 additions and 0 deletions
+1
View File
@@ -136,6 +136,7 @@ When the user mentions these keywords, load the corresponding skill:
| "chief of staff", "CoS", "executive office", "gatekeeping", "triage", "decision memo", "executive briefing", "board materials", "force multiplication", "leader effectiveness", "organizational sensing", "organizational radar", "team health", "institutional memory", "leadership transition", "calendar triage", "meeting audit", "strategic time", "attention allocation" | [chief-of-staff-methodology](chief-of-staff-methodology/SKILL.md) | | "chief of staff", "CoS", "executive office", "gatekeeping", "triage", "decision memo", "executive briefing", "board materials", "force multiplication", "leader effectiveness", "organizational sensing", "organizational radar", "team health", "institutional memory", "leadership transition", "calendar triage", "meeting audit", "strategic time", "attention allocation" | [chief-of-staff-methodology](chief-of-staff-methodology/SKILL.md) |
| "site-reliability-engineering", "site reliability engineering" | [site-reliability-engineering](site-reliability-engineering/SKILL.md) | | "site-reliability-engineering", "site reliability engineering" | [site-reliability-engineering](site-reliability-engineering/SKILL.md) |
| "research-methodology", "research methodology" | [research-methodology](research-methodology/SKILL.md) | | "research-methodology", "research methodology" | [research-methodology](research-methodology/SKILL.md) |
| "remote system administration", "remote administration", "SSH", "Ansible", "Paramiko", "remote Linux", "remote FreeBSD", "remote NetBSD", "remote OpenBSD", "remote macOS", "remote service", "remote firewall", "remote package update", "fleet administration", "fleet rollout", "launchctl", "rcctl", "systemctl" | [remote-systems-administration](remote-systems-administration/SKILL.md) |
| "technical-documentation", "technical documentation" | [technical-documentation](technical-documentation/SKILL.md) | | "technical-documentation", "technical documentation" | [technical-documentation](technical-documentation/SKILL.md) |
| "secure software engineering", "build securely", "secure by design", "security requirements", "security acceptance criteria", "threat model this design", "secure code review", "secure defaults", "authorization design", "multi-tenant isolation", "release evidence", "SBOM", "software supply chain", "AI security", "LLM security", "prompt injection", "tool authorization", "RAG security" | [secure-software-engineering](secure-software-engineering/SKILL.md) | | "secure software engineering", "build securely", "secure by design", "security requirements", "security acceptance criteria", "threat model this design", "secure code review", "secure defaults", "authorization design", "multi-tenant isolation", "release evidence", "SBOM", "software supply chain", "AI security", "LLM security", "prompt injection", "tool authorization", "RAG security" | [secure-software-engineering](secure-software-engineering/SKILL.md) |
| "security-audit-methodology", "security audit methodology" | [security-audit-methodology](security-audit-methodology/SKILL.md) | | "security-audit-methodology", "security audit methodology" | [security-audit-methodology](security-audit-methodology/SKILL.md) |
+4
View File
@@ -223,6 +223,10 @@ Query, search, and download public datasets from the City of Raleigh Open Data p
Turn an open question into a bounded, evidence-led investigation rather than a plausible-sounding synthesis. Turn an open question into a bounded, evidence-led investigation rather than a plausible-sounding synthesis.
### [remote-systems-administration](remote-systems-administration/SKILL.md)
Administer and troubleshoot remote Linux, FreeBSD, NetBSD, OpenBSD, and macOS hosts safely, one system or a controlled fleet at a time. Covers SSH, Ansible, Paramiko, portable diagnostics, platform-specific services, packages, configuration, firewalls, rollback, and evidence-led verification.
### [secure-software-engineering](secure-software-engineering/SKILL.md) ### [secure-software-engineering](secure-software-engineering/SKILL.md)
Build security into software requirements, design, implementation, review, and release decisions. Covers threat modeling, authorization, data and secret handling, dependencies, tenant isolation, security evidence, incident learning, and AI boundaries without treating a checklist as proof of security. Build security into software requirements, design, implementation, review, and release decisions. Covers threat modeling, authorization, data and secret handling, dependencies, tenant isolation, security evidence, incident learning, and AI boundaries without treating a checklist as proof of security.
+49
View File
@@ -0,0 +1,49 @@
# Remote Systems Administration
Operate remote Linux, FreeBSD, NetBSD, OpenBSD, and macOS hosts safely, without pretending their service managers, packages, firewalls, and configuration systems are interchangeable.
## Why Install This Skill
Remote administration is where a plausible command can turn into an outage. This skill gives an agent a disciplined path from host discovery through scoped change and verification. It starts with native SSH for a single bounded job, moves to Ansible for repeatable fleet work, and reserves Paramiko for Python programs that actually need protocol-level control.
It is deliberately platform-aware. The agent learns to find the active control plane before touching a service, package, firewall, or configuration file, and to preserve a rollback path before changing anything that could strand remote access.
## What You Get
| Resource | What it provides |
|---|---|
| `SKILL.md` | Operating contract, routing, boundaries, and verification checklist |
| `references/portable-operations.md` | POSIX baseline, SSH, discovery, diagnostics, and bounded evidence |
| `references/fleet-automation.md` | Ansible, Paramiko, inventory, canary, and rollout guidance |
| `references/linux.md` | Linux init, packages, logs, and firewall routing |
| `references/freebsd.md` | FreeBSD rc, packages, jails, and firewall routing |
| `references/netbsd.md` | NetBSD rc.d, services, pkgsrc, and firewall routing |
| `references/openbsd.md` | OpenBSD rcctl, updates, packages, and PF routing |
| `references/macos.md` | launchd, updates, profiles, and macOS operational limits |
| `references/safety-and-verification.md` | Mutation gates, rollback, and verification evidence |
| `references/source-index.md` | Primary sources and freshness notes |
| `templates/remote-change-plan.md` | A compact plan for a remote change before it starts |
## Quick Start
Start with a read-only preflight. Replace the example target with a host you are authorized to inspect.
```sh
ssh admin@example-host 'uname -srm; command -v systemctl service rcctl launchctl; id'
```
Then load the matching platform reference before choosing a service manager, package tool, or firewall control plane. For fleet work, put targets in an Ansible inventory, run a canary with `--limit`, and use `--check --diff` only with its limitations understood.
## Triggers
Use this skill when you need to:
- diagnose or administer a remote Linux, FreeBSD, OpenBSD, or macOS host;
- manage services, packages, updates, configuration, logs, or firewalls;
- use SSH, a bastion, file transfer, Ansible, or Paramiko;
- make a controlled change across several Unix-like machines;
- plan rollback and verification for a remote operational change.
## Requirements
You need legitimate remote access and the authority to perform the requested operation. Native SSH is the baseline. Ansible is optional for fleet configuration, and Python plus Paramiko is optional for programmatic SSH workflows. The skill does not create credentials, bypass host-key validation, or authorize destructive operations.
+95
View File
@@ -0,0 +1,95 @@
---
name: remote-systems-administration
description: >-
Administer and troubleshoot remote Linux, FreeBSD, NetBSD, OpenBSD, and macOS systems
safely, one host or a fleet at a time. Use when a task requires SSH, Ansible,
Paramiko, POSIX diagnostics, service management, software updates, system
configuration, firewall changes, or evidence-led remote operations.
license: MIT
compatibility: Requires legitimate remote access. Native SSH is the baseline; Ansible or Python with Paramiko is optional for fleet automation.
---
# Remote Systems Administration
Use this as an operating decision layer, not a bag of remote commands. Unix-like systems share a vocabulary but not an implementation. Identify the target's platform and active control plane before choosing a command.
## Operating contract
1. **Discover before changing.** Record target identity, production status, OS and release, service manager, package manager, firewall, access route, privilege path, and current state. Do not infer them from hostname, memory, or inventory labels.
2. **Use the smallest valid control plane.** Native SSH for a bounded one-host task; Ansible for repeatable desired state across a fleet; Paramiko only when a Python program genuinely needs SSH protocol control that the first two cannot provide.
3. **Protect access first.** Before changing SSH, routing, DNS, a firewall, privilege escalation, or a network interface, establish a tested rollback and a second recovery path. Keep the current session alive until the new path works.
4. **Preview, constrain, verify.** Limit the target set; use native validation, dry-run, diff, or a canary when available; then verify the affected service and its user-visible boundary. A zero exit code proves only that command ran.
5. **Report evidence, not a story.** Preserve bounded per-host results: target, command category, before/after evidence, failures, rollback state, and the remaining uncertainty. Never paste secrets, keys, full configuration files, or unbounded logs into the response.
## First response: classify the job
| Situation | Default path | Do not do |
|---|---|---|
| Diagnose or make one bounded change on one host | Native `ssh` with a read-only preflight | Do not open an interactive shell and make unrecorded edits |
| Repeat the same desired state across hosts | Ansible inventory + playbook, canary/serial rollout | Do not loop `ssh` blindly across production hosts |
| Python must coordinate SSH channels, SFTP, or a custom protocol flow | Paramiko with strict host-key verification and explicit timeouts | Do not disable host-key checks or turn a script into ad hoc fleet control |
| The platform/control plane is unknown | Run bounded discovery from `references/portable-operations.md` | Do not use `systemctl`, `apt`, `pfctl`, or `launchctl` based on a guess |
| Change affects connectivity, firewall, authentication, reboot, storage, or deletion | Load `references/safety-and-verification.md` first | Do not mutate before a rollback and recovery path are explicit |
## Required preflight for every mutation
Before the first state-changing command, confirm:
- exact host(s), environment, and authorized scope;
- OS/release and applicable platform overlay;
- service manager, package manager, firewall implementation, and configuration owner;
- access identity, elevation method, and whether the connection traverses a bastion;
- intended state, expected blast radius, rollback command or artifact, and stop condition;
- validation at both the component layer and the relevant external boundary.
Read-only discovery may proceed without confirmation. Destructive actions, privilege changes, firewall/remote-access changes, package removals, storage operations, and reboot/shutdown require an explicit directive after this preflight.
## Routing references
| Need | Load | File |
|---|---|---|
| SSH, POSIX diagnostics, bounded output, file transfer, logs, and host discovery | Portable operations | `references/portable-operations.md` |
| Ansible, Paramiko, inventory design, canaries, serial rollout, and per-host results | Fleet automation | `references/fleet-automation.md` |
| Linux init systems, packages, journaling, configuration, and firewall routing | Linux overlay | `references/linux.md` |
| FreeBSD rc(8), rc.conf, pkg, jails, and pf/ipfw routing | FreeBSD overlay | `references/freebsd.md` |
| NetBSD rc.d, rc.conf, service, and pkgsrc routing | NetBSD overlay | `references/netbsd.md` |
| OpenBSD rcctl, rc.conf.local, pkg_add, syspatch, and pf | OpenBSD overlay | `references/openbsd.md` |
| launchd, softwareupdate, configuration profiles, pf, and macOS operational limits | macOS overlay | `references/macos.md` |
| Mutation gates, safety classes, rollback, and verification evidence | Safety and verification | `references/safety-and-verification.md` |
| Primary documentation and source freshness | Source index | `references/source-index.md` |
## Platform boundary
Do not flatten platform differences:
- `systemctl` is not a BSD or macOS service manager.
- `rcctl` is OpenBSD-specific; FreeBSD uses rc scripts and `service`.
- `launchctl` domains and labels are not systemd units.
- `apt`, `dnf`, `pacman`, `pkg`, `pkg_add`, `softwareupdate`, and `brew` have different update, rollback, and package-origin semantics.
- Linux nftables, BSD PF, and the macOS Application Firewall are separate control planes. Never translate rules mechanically.
## Scope boundaries
This skill covers host-level Unix operations. Route containers to `docker-compose`, clusters to `kubernetes`, encrypted tailnet policy to `tailscale`, detection/remediation components to `crowdsec`, and reliability process design to `site-reliability-engineering`.
It does not authorize credential recovery, security-boundary bypass, production deletion, provider-console operations, or an unreviewed operating-system upgrade.
## Common pitfalls
1. **Running the right command on the wrong platform.** Discover the service/package/firewall manager before acting.
2. **Treating an SSH connection as proof of authority.** Connection success does not confirm sudo policy, host identity, or authorization for the change.
3. **Using `StrictHostKeyChecking=no` or Paramiko `AutoAddPolicy`.** An unknown host key is an identity event, not a convenience prompt.
4. **Parallelizing first.** Establish the procedure on one canary, then roll out in bounded batches with a stop condition.
5. **Calling a service healthy because it started.** Check process/unit state, logs, listening endpoint, and the relevant dependent or external boundary.
6. **Confusing package upgrades with OS upgrades.** Platform release lifecycle, kernel/base-system updates, and third-party packages have different procedures.
7. **Repairing a remote host through an access-path change without a rollback.** Preserve a live session and independent recovery channel.
## Verification checklist
- [ ] Target and platform were discovered from the live host.
- [ ] Mutation had explicit scope, rollback, and recovery path.
- [ ] The control plane matched the target platform.
- [ ] Fleet work used an inventory, bounded concurrency, and a stop condition.
- [ ] Sensitive values and unbounded output were excluded from evidence.
- [ ] Verification covered the changed component and its relevant external boundary.
- [ ] Per-host success, failure, and rollback status are explicit.
@@ -0,0 +1,78 @@
# Fleet Automation: Ansible and Paramiko
## Choose the fleet control plane
| Work shape | Default | Why |
|---|---|---|
| Diagnose a few distinct hosts | Native SSH | The work is investigative, not desired-state management |
| Apply repeatable state to multiple hosts | Ansible | Inventory, idempotence, check/diff support, bounded rollout, and per-host results already exist |
| Python must manage SSH channels, SFTP, or a custom event loop | Paramiko | It supplies SSH protocol primitives, not fleet safety or desired-state semantics |
Do not build an SSH loop when an Ansible playbook expresses the desired state. Do not introduce Paramiko merely to avoid learning SSH configuration or Ansible inventory.
## Inventory and scope
Inventory is an authorization and blast-radius boundary, not a list of convenient addresses. Before a fleet mutation, identify groups, environment, maintenance constraints, platform differences, escalation method, and exclusion rules. Separate Linux, FreeBSD, NetBSD, OpenBSD, and macOS groups unless you have proved an action is portable.
Start with a canary host and a narrow limit. A fleet run must have:
- an explicit inventory or bounded host expression;
- a target count and maximum parallelism;
- a canary or serial batch strategy for nontrivial changes;
- a stop condition, such as failed health checks or unexpected diffs;
- a rollback or containment action per batch; and
- a per-host result record, including unreachable hosts.
## Ansible execution
Use Ansible for declared state, platform-specific modules, and structured results. Prefer modules over `shell`/`command`; use the latter only when no module accurately represents the job and then make `changed_when`, `failed_when`, and idempotence explicit.
The generic `ansible.builtin.package` module delegates to the package manager detected from target facts. It exposes only the common denominator, does not translate package names between distributions, and inherits check/diff support from the underlying manager. Use it only where that limited contract is enough. Split platform groups or use a specific module when package naming, repository policy, transaction preview, or service implications differ.
`ansible.builtin.systemd_service` applies only to hosts managed by systemd. Its `started` and `stopped` states are idempotent; `restarted` and `reloaded` are active lifecycle requests. Do not use a systemd-specific task against a generic POSIX group.
```sh
# Read-only reachability and facts for a limited group.
ansible unix_canary -m ansible.builtin.ping
ansible unix_canary -m ansible.builtin.setup -a 'filter=ansible_distribution*'
# Preview a single canary. --check is a simulation, not proof.
ansible-playbook site.yml --limit unix_canary --check --diff
# Apply in a deliberately bounded batch after review.
ansible-playbook site.yml --limit unix_canary
```
Ansible check mode runs without making remote changes only for modules that support it; unsupported modules can report nothing and do nothing. Diff output can reveal sensitive values. Treat both as previews with known gaps, not as completed validation. Redact or disable diffs for secrets.
Use `serial` for progressive batches and `max_fail_percentage` or explicit failure handling to stop a rollout. Avoid `strategy: free` for changes whose ordering, capacity, or error containment matters. `run_once` runs once per serial batch, not necessarily once for the entire play; use an explicit condition against the complete play host list when a task must execute globally exactly once.
## Paramiko
Paramiko's `SSHClient` and `Transport` provide SSH protocol access. The caller owns policy: host-key verification, timeouts, authentication source, concurrency limit, command allowlist, stdout/stderr limits, exit-status handling, cleanup, and result aggregation.
Minimum behavioral requirements for a Paramiko-based operation:
1. Load an approved host-key source and reject unknown or changed keys. Never use `AutoAddPolicy` for a managed fleet.
2. Set connection, banner, authentication, channel, and command timeouts.
3. Bound concurrent connections and collect a result for every target.
4. Read stderr and exit status; a channel that opened is not a successful command.
5. Close channels and clients deterministically, including failure paths.
6. Keep credentials out of source, command strings, and logs. Use an authorized credential provider.
7. Establish the procedure on a canary before concurrent execution.
A hand-written Paramiko tool must not silently erase Ansible's safety features. If it needs inventory parsing, host grouping, canary policy, retries, structured result files, privilege management, configuration idempotence, or secrets integration, the job likely belongs in Ansible or a deliberately designed automation system.
## Result and recovery contract
For each target, record only bounded operational metadata:
```text
target: host alias or approved inventory name
platform: detected family/release
operation: discovery | preview | apply | rollback
status: passed | failed | unreachable | skipped | rolled_back
evidence: command category plus bounded result reference
```
Do not mark a fleet run complete while “unreachable” or “skipped” targets are unaccounted for. A partial rollout is an outcome that needs an explicit decision, not an implicit success.
@@ -0,0 +1,39 @@
# FreeBSD Overlay
## FreeBSD is not Linux
FreeBSD uses its own base system, release engineering, rc framework, package toolchain, configuration conventions, and optional subsystems such as jails and ZFS. Do not transplant Linux systemd, APT/RPM, or nftables instructions.
Start by identifying the FreeBSD release, architecture, active services, package state, jail context, filesystem layout, and firewall implementation. When a host is inside a jail, distinguish a jail-level operation from a host-level operation before acting.
## Services and configuration
FreeBSD uses rc scripts and configuration conventions centered on files such as `/etc/rc.conf` and site-local `/etc/rc.conf.local`; `service` is the customary control interface for installed rc.d scripts. Inspect current configuration and the relevant rc script before enabling, restarting, or changing boot persistence.
```sh
service <name> status
service <name> onestatus
service <name> restart
```
The exact behavior belongs to the service's rc script. “Running” or a successful `service` exit does not prove that a daemon is listening or serving its dependency chain. Follow it with bounded logs/socket checks and the relevant external validation.
## Packages, ports, and base-system lifecycle
Use `pkg` for binary packages. The FreeBSD Handbook distinguishes packages from ports: packages are prebuilt artifacts, while ports automate source builds and permit compile-time choices. A package operation can affect dependencies and running services; plan the resulting restart/reload and validation.
Base-system updates and third-party packages are distinct lifecycles. Do not use package commands as a substitute for an OS release procedure. For release changes, kernel/base updates, boot-environment strategy, and ZFS rollback planning, follow the release-specific FreeBSD documentation.
Before a broad package operation, inventory installed packages, update candidates, held policy if applicable, application compatibility, disk space, backups/snapshots, and restart impact. `pkg audit -F` is an advisory/vulnerability check, not a change command.
## Firewalls and networking
FreeBSD may use PF, IPFW, or another installed system. Discover the active firewall and configuration owner. PF and IPFW have distinct grammars and persistence mechanisms. Do not copy OpenBSD PF assumptions without checking the FreeBSD documentation and installed version.
Firewall, route, DNS, interface, and remote-access changes require a retained session plus another recovery path. Validate syntax/configuration, make the smallest change, confirm that the administrator path remains open, then test the intended traffic flow.
## Jails and storage
Jails are an operating-system-level isolation mechanism with host/jail boundaries. Identify whether the target process, package database, network interface, and filesystem belong to a jail or its host. Do not administer a jail as if it controlled host services or firewall policy.
FreeBSD deployments often use ZFS. A snapshot can be a valuable rollback primitive, but it is not an authorization to use destructive rollback commands. Identify dataset scope, dependent services, replication/backup state, and recovery impact before snapshot, rollback, or dataset operations.
@@ -0,0 +1,61 @@
# Linux Overlay
## Discover the Linux control planes
“Linux” is a kernel family, not one operating model. Before a mutation, discover the distribution/release, init system, package manager, configuration owner, firewall implementation, and whether a higher-level system such as a configuration manager owns the setting.
Useful indicators include `/etc/os-release`, `ps -p 1`, `command -v systemctl`, and package-manager discovery. Treat these as observations, not a permission to overwrite files managed by another system.
## Services and logs
Most contemporary distributions use systemd, but do not assume it. When systemd is active, use `systemctl` for unit state and `journalctl` for bounded journal evidence. A unit becoming `active` is only component-level evidence; verify the listener, dependent service, and external boundary separately.
Other Linux systems may use OpenRC, SysV-style scripts, runit, s6, or a distribution-specific control interface. Discover the active manager and load its authoritative documentation before lifecycle or boot-persistence changes.
| Question | systemd-oriented evidence |
|---|---|
| What is running? | `systemctl status <unit>` and a bounded `journalctl -u <unit>` range |
| Will it start at boot? | `systemctl is-enabled <unit>` |
| Did configuration parse? | service-specific validation before `reload` or `restart` |
| Did it serve traffic? | endpoint/socket check plus relevant client/dependent check |
Do not blindly restart a service because configuration changed. Validate the configuration first where the service provides a check, then use reload only when documented as safe; otherwise plan the restart, effect, and rollback.
## Packages and updates
Discover the native package manager. Common families include APT/dpkg, DNF/RPM, zypper/RPM, pacman, and apk. Package-manager commands, repository configuration, update semantics, and reboot requirements are distribution-specific.
Before upgrades:
1. classify the change: one package, security updates, all packages, kernel, distribution release, or third-party repository change;
2. inspect candidates/transaction plan and held/excluded packages;
3. identify service restart and reboot implications;
4. preserve rollback or recovery strategy appropriate to the package system, filesystem, and workload; and
5. stage or canary before a fleet rollout.
Do not claim that a package update is rollback-safe merely because the manager supports downgrade. Availability, dependency graphs, database migrations, and configuration changes determine actual reversibility.
## Package-manager families and configuration collisions
Package manager discovery is not enough to choose a safe transaction. It must be paired with the distribution release, enabled repositories, package origin, held/excluded policy, and configuration-file behavior. A package transaction can leave a generated or conflict copy of an edited configuration rather than silently replacing it. Inspect and resolve that state deliberately before declaring a configuration change active.
- APT/dpkg, DNF/RPM, zypper/RPM, pacman, and apk have separate repository, solver, cache, and configuration semantics.
- Pacman tracks local package metadata and uses a separate sync operation for repository packages. Its removal and database bypass controls can have broad effects; do not turn off dependency/conflict checks to make a transaction proceed.
- Alpine `apk` can preserve proposed configuration as `.apk-new`; diskless/data-disk installations also require an explicit persistence step. Detect that deployment mode before treating a successful package command as durable across boot.
- A package manager's package name is not portable. `ansible.builtin.package` does not translate it between distributions.
## System configuration
Configuration files may be vendor-managed, package-conffiles, generated by cloud-init, NetworkManager, systemd-networkd, a configuration-management tool, or an application. Discover ownership before editing. Back up or version the existing state, make a minimal change, validate syntax, reload/restart only as required, and verify the active configuration rather than the file alone.
Changes to network configuration, DNS, SSH, sudo, PAM, routing, firewall state, mounts, kernel parameters, users, or storage are high-risk. Load `safety-and-verification.md` first and preserve access.
## Firewall routing
Linux firewall control planes include nftables and systems layered above it, such as firewalld or distribution tooling. Discover which system owns rules before changing anything. Do not mix direct nftables edits with a higher-level manager unless its documentation permits it, and never mechanically translate PF, iptables, or cloud firewall rules.
For nftables, inspect the existing ruleset and ownership before edits. Policy changes can sever the live SSH session. Validate rule syntax where available, retain a recovery path, apply a bounded change, and verify both expected traffic and retained administrative access.
## Reboot and lifecycle
A reboot is a state transition with dependencies. Identify the reason, pending work, required services, users, maintenance window, recovery access, and post-boot validation before issuing it. Verify boot completion, expected units, networking, time synchronization where relevant, and the affected application boundary. A reachable SSH daemon alone is not complete recovery.
@@ -0,0 +1,45 @@
# macOS Overlay
## Establish the management boundary
macOS is a Unix platform with Apple-owned system management layers. Before acting, identify the macOS version, whether the target is a user or system domain, device-management/profile ownership, FileVault or recovery implications, installed management tooling, and whether a setting belongs to macOS, a configuration profile, an MDM, or a third-party package manager.
Do not manage macOS as a lightly branded Linux host. `systemctl`, Linux package managers, and BSD rc tools are not macOS control planes.
## launchd and launchctl
launchd manages system and user services through domains and labels. `launchctl` operations are scoped to the relevant domain; a label alone is not a portable service identity. Discover the existing launchd job, its owner, program path, logs, and bootstrap configuration before changing it.
Use `launchctl` for inspection and lifecycle work only after identifying the correct system/user context. Do not unload or disable core services casually. Verify the job's state, process/listener behavior, relevant logs, and the application boundary after a change.
A Homebrew service, an application helper, a LaunchDaemon, and a LaunchAgent can have different ownership and persistence semantics. Follow the manager that owns the job rather than mixing control planes.
## Updates and software installation
`softwareupdate` addresses Apple-provided update workflows. Use Apple deployment documentation and the target release's supported management path before planning an update. An OS update can affect restarts, FileVault unlock, management enrollment, kernel/system extensions, application compatibility, and recovery behavior.
Homebrew is a separate third-party package manager. If it is present and authorized for the target, use its documented commands and respect formula/cask provenance, update behavior, service ownership, and user context. Do not install Homebrew merely to obtain a Unix package without an explicit directive.
Before any broad update:
1. distinguish Apple OS/security updates from Homebrew or other third-party packages;
2. establish maintenance window, power/network requirements, restart expectations, and recovery access;
3. inventory critical applications and management/profile constraints;
4. stage or canary where multiple hosts are involved; and
5. verify boot, login/management state, required launchd jobs, networking, and the affected application boundary.
## Configuration and profiles
Managed configuration profiles and MDM policy can reapply settings. Discover the source of truth before editing preferences or configuration files. A local change that is overwritten by management is not a successful operational fix.
System Integrity Protection, privacy controls, TCC, signed system volumes, and Apple platform security may make a direct Unix-style edit unsupported or ineffective. Do not attempt to weaken these controls or bypass authorization. Report the governing policy and the legitimate administration route.
## Networking and firewall
macOS has multiple security/networking layers, including PF and the Application Firewall. They serve different purposes. Discover which layer owns the requested policy before altering it. Never assume a PF rule changes application-level firewall behavior, or vice versa.
Network, PF, remote-login, VPN, DNS, routing, and firewall changes can strand a remote session. Preserve a current session and an independent authorized recovery path, validate candidate configuration, make the smallest change, and verify both retained administrative access and intended traffic behavior. Apple's Application Firewall is app/service admission control, whereas PF is a packet-filter control plane; identify which question is being asked before changing either.
## Logs and verification
Use bounded, relevant evidence. macOS unified logging can be extensive; scope by process, subsystem, predicate, or time range. A `launchctl` result or a successful command is component evidence only. Verify the actual listener, app behavior, dependent service, or user-visible workflow that motivated the change.
@@ -0,0 +1,32 @@
# NetBSD Overlay
## NetBSD is a separate platform
NetBSD uses its own rc.d system, base-system lifecycle, and pkgsrc package framework. Do not treat FreeBSD's release tooling, OpenBSD `rcctl`, or Linux systemd/package commands as NetBSD controls.
Discover the NetBSD release, architecture, active service configuration, package source, firewall implementation, and whether a setting belongs to the base system, pkgsrc, or another management layer.
## rc.d services
NetBSD's rc.d system uses `/etc/rc`, `/etc/rc.conf`, `/etc/rc.d`, `/etc/rc.local`, `/etc/rc.shutdown`, `/etc/rc.subr`, defaults under `/etc/defaults`, and optional overrides under `/etc/rc.conf.d`. Do not edit defaults to override a setting; use the documented configuration layer.
`service` is the normal alias for invoking rc.d scripts. Scripts support at least lifecycle actions such as `start`, `stop`, `restart`, and `status`; some support actions including `reload`. Verify the script and its configuration before relying on an action.
```sh
service <name> status
service <name> restart
```
A package can install an rc.d script, but that does not automatically make it an active boot service. Identify the script location, enablement/configuration, daemon process/listener, and dependent application boundary before declaring success.
## pkgsrc and packages
pkgsrc is the framework for third-party software. It can use prebuilt binary packages or build packages from source. `pkg_add` operates on binary packages; `pkgin` is a user-friendly frontend when installed. Package origins, repository branch, local prefix, dependencies, and source/binary policy matter before any upgrade.
Before an upgrade, inspect the repository configuration, installed set, compatibility implications, disk space, planned service effects, and rollback/recovery option. A pkgsrc quarterly branch or binary repository change is not an ordinary single-package update. Do not mix package locations or change `LOCALBASE` on an existing system without following the pkgsrc guidance.
Base-system maintenance is separate from pkgsrc. Use release-specific NetBSD documentation for base updates and release upgrades; do not substitute a package-manager operation for an OS lifecycle procedure.
## Firewalls, networking, and verification
Discover the active firewall and network configuration owner before changing rules, routes, interfaces, or DNS. Preserve remote access with a retained session and an independent authorized recovery channel. Validate candidate configuration where possible, apply the smallest scoped change, test the administration path and intended flow, then validate the application boundary.
@@ -0,0 +1,44 @@
# OpenBSD Overlay
## OpenBSD control planes
OpenBSD favors a coherent base system but still requires platform discovery. Identify release, architecture, base versus package ownership, active daemons, `/etc/rc.conf.local` state, PF state, and whether the host is a firewall/router before change.
Do not use Linux systemd commands or FreeBSD `service` conventions. OpenBSD's `rcctl` is the normal interface for inspecting, configuring, enabling, and controlling base and package daemons.
## Services with rcctl
`rcctl` can inspect configuration, enable/disable daemons, and invoke actions such as `check`, `configtest`, `reload`, `restart`, `start`, and `stop`. Prefer discovery and config validation before lifecycle changes.
```sh
rcctl ls all
rcctl get <daemon>
rcctl check <daemon>
rcctl configtest <daemon>
```
Enablement and daemon options are represented through rc configuration, including `/etc/rc.conf.local`. A successful restart is not the same as a healthy service. Inspect bounded logs, listening state, and the user-visible/dependent boundary.
## Packages and base updates
OpenBSD separates packages from system distribution files. `pkg_add` installs and updates packages; it is not the base-system updater. Packages are normally signed, and `pkg_add` rejects unsigned packages by default unless a policy override is explicitly used. Do not weaken signature validation to make an automation run pass.
`pkg_add -u` can update installed packages and their dependencies. Before a package update, inspect package origin, dependencies, service impact, disk space, and application compatibility. Use its non-mutating modes only as previews with the documented limitations understood.
For base-system errata and release lifecycle, use the appropriate OpenBSD mechanisms and release documentation, such as `syspatch` where applicable. Do not conflate package updates, syspatch, and a release upgrade.
## PF
PF is a security and availability boundary. Before any PF change:
1. capture the active ruleset and identify configuration ownership;
2. preserve the current SSH/admin session and create an independent authorized recovery path;
3. validate candidate rules before loading them, such as with `pfctl -n -f <file>`;
4. apply the smallest scoped change only after an explicit directive; and
5. verify retained administration access, expected allowed flow, expected denied flow, and relevant application health.
`pfctl -f` replaces a ruleset. `pfctl` options that enable/disable or flush PF state are not routine troubleshooting commands. Treat them as high-risk, scope them precisely, and never use them to “clean up” without explicit authorization and recovery planning.
## Operational character
OpenBSD's secure defaults and clear base/package split do not make remote changes safe by default. Preserve package signature policy, configuration provenance, and connectivity. Prefer documented base controls over improvised wrappers, and use the release-specific manuals before asserting a current lifecycle command or support status.
@@ -0,0 +1,68 @@
# Portable Remote Operations
## Start with bounded, read-only discovery
A remote hostname is not a platform classification. Establish identity and available control planes from the live host before selecting an overlay.
```sh
ssh -o BatchMode=yes -o ConnectTimeout=10 admin@example-host '
printf "host="; hostname
uname -srm
command -v systemctl service rcctl launchctl || true
command -v apt-get dnf yum zypper pacman pkg pkg_add softwareupdate brew || true
id
'
```
Use a known host alias and a managed `known_hosts` file. Keep `BatchMode=yes` for non-interactive automation so authentication failures stop rather than prompting or hanging. Do not use `StrictHostKeyChecking=no`; an unexpected host key must be investigated through an authorized identity channel.
## SSH access patterns
| Need | Prefer | Guardrail |
|---|---|---|
| One host, one bounded command | `ssh host -- command` | Quote the remote command deliberately; capture exit status and bounded output |
| Bastion/jump host | `ProxyJump` in SSH config or `ssh -J` | Validate the route and host keys for each hop |
| Repeated one-host sessions | SSH connection multiplexing | Use a private control socket path and bounded lifetime; do not share it across principals |
| Transfer a known file | `sftp` or `scp` with explicit source/destination | Verify checksum or content and owner/mode after transfer |
| Privileged command | `sudo -n` after checking authorization | Do not consume prompts or transmit passwords in command text |
`ssh` and `sftp` support `ProxyJump`; OpenSSH configuration also supports connection sharing through `ControlMaster` and `ControlPath`. These improve routing and performance, not authorization.
## POSIX baseline
Portable primitives are useful for discovery, not proof that every utility flag is portable. Prefer a small, bounded set:
| Question | Typical tools | Evidence to capture |
|---|---|---|
| Identity and OS | `hostname`, `uname`, `id` | hostname, kernel/system label, effective identity |
| Process/service clue | `ps`, `pgrep`, `kill -0` | process state only, not application health |
| Filesystem capacity | `df`, `du` | affected mount and available capacity |
| Memory/load | `uptime`, `vmstat` where available | bounded sample and platform caveat |
| Network/listener | `netstat`, `sockstat`, `ss`, `lsof` as discovered | listener and bound address, not merely process PID |
| Logs | `tail`, platform log reader | a bounded time/range and redaction |
| Config/file state | `test`, `stat`, `cmp`, checksums | path, ownership/mode, hash or minimal diff |
Do not write a “portable” command that assumes GNU `sed`, GNU `date`, `grep -P`, `xargs -r`, Bash, or Linux `/proc`. If a task needs those capabilities, classify the platform and use the appropriate overlay.
## Safe remote execution
1. Send one command category per SSH invocation: discovery, validation, or a single scoped mutation. Avoid opaque `&&` chains that blur the failed step.
2. Set client-side timeouts and use non-interactive mode for automation.
3. Do not emit secrets into the process list, shell history, logs, or command output. Use an authorized secret mechanism outside command arguments.
4. For a file edit, capture the original metadata/content hash, validate syntax before reload where the platform supports it, and retain a rollback artifact.
5. Preserve output bounds. Ask for the relevant unit, process, or time range instead of `journalctl`/`log show`/`dmesg` dumps.
## Privilege boundaries
`sudo` is a privilege boundary, not a convenient prefix. Confirm the intended account and command authorization using a read-only check appropriate to local policy. `sudo -n` is safer for automation because it fails instead of waiting for an unseen password prompt. Do not modify sudoers, SSH authorization, users, groups, or host keys without an explicit directive and recovery path.
## Verification boundary
A remote command's exit code is evidence about that command only. For a service change, gather:
1. service-manager or process state;
2. relevant logs/events after the change;
3. listener, local socket, or protocol check where applicable; and
4. the actual dependent or external boundary the change was meant to restore.
For platform-specific commands, load the corresponding overlay and `references/safety-and-verification.md`.
@@ -0,0 +1,60 @@
# Safety and Verification
## Classify the operation
| Class | Examples | Required posture |
|---|---|---|
| Read-only | inspect units, packages, logs, sockets, config metadata | Proceed with bounded output and redaction |
| Reversible bounded change | one service reload, add one package, edit one owned config | Confirm target/scope/rollback, validate, then verify |
| Connectivity or access change | SSH, firewall, routing, DNS, sudo/PAM, VPN, network interface | Explicit directive, retained session, independent recovery path, validated rollback, staged application |
| Lifecycle change | broad updates, reboot, storage/mount changes, release upgrade | Explicit directive, maintenance/impact plan, recovery and post-change verification |
| Destructive or security-boundary change | delete data/users, reset credentials, disable protections, flush firewall state | Explicit directive after non-destructive alternatives and exact scope are documented |
## Mutation gate
Before a state-changing operation, answer all of these from evidence:
1. **What exact target is affected?** Host aliases, platform, environment, and count.
2. **What owns the setting?** Native service/package/firewall manager, configuration management, profile/MDM, or application.
3. **What is the desired outcome and blast radius?** One component, one host, canary, batch, or fleet.
4. **What could break?** Access, service availability, data, compatibility, dependencies, boot, or policy.
5. **How is rollback performed?** Exact prior state/artifact and authority to use it.
6. **How is recovery reached if the new path fails?** Retained session, console, bastion, or other authorized channel.
7. **What would prove success?** Component condition plus relevant network/application/user boundary.
8. **When do we stop?** Failure threshold, unexpected diff, loss of canary health, or any loss of admin access.
If a question is unknown, treat it as a blocker, not permission to guess.
## Connectivity-preserving changes
For firewall, SSH, routing, DNS, and privilege-path changes:
- retain the current working session until the replacement path has been tested;
- use a time-bounded rollback where the platform and change process safely support it;
- test new configuration/rules before loading when the control plane supports a parse/validation mode;
- apply one host or a canary first;
- confirm both existing administrative access and the new intended flow; and
- leave evidence sufficient for a human to recover the host.
For an initial remote firewall configuration, an authorized local console is safer than SSH when it is available. If it is not available, the independent recovery path is a hard prerequisite, not a nice-to-have.
Never “solve” an access problem by changing a password, disabling a control, accepting an unknown host key, opening a broad firewall rule, or bypassing authorization without explicit authority.
## Verification levels
| Claim | Minimum evidence |
|---|---|
| Command completed | exit status plus bounded stdout/stderr |
| Service started/reloaded | manager/process state plus relevant logs |
| Service is usable | listener/local protocol check plus dependent or external boundary |
| Configuration is active | syntax/manager validation plus observed active state |
| Package change succeeded | package database state plus expected binary/service behavior |
| Firewall change succeeded | retained administration path, intended allow/deny behavior, and application health |
| Fleet rollout succeeded | accounted per-host results, batch/canary health, and stated external boundary |
| Reboot recovered | host reachable, expected boot/runtime services healthy, and application boundary restored |
Do not promote a lower-level result to a higher-level claim. “Unit active,” “SSH connected,” and “playbook exit 0” are not equivalent to service, system, or fleet health.
## Evidence hygiene
Keep results bounded and safe to share. Record command categories and small relevant excerpts rather than entire environment files, configuration files, secret values, private keys, tokens, customer data, or unrestricted logs. If validation needs sensitive information, perform it through the authorized system and report the non-sensitive verdict.
@@ -0,0 +1,35 @@
# Source Index
This skill is a routing and safety guide, not a frozen command reference. Re-check current primary documentation before asserting version-specific behavior, package availability, service defaults, or upgrade paths.
| Area | Primary source | What it grounds | Checked |
|---|---|---|---|
| OpenSSH client/configuration | [OpenBSD ssh(1)](https://man.openbsd.org/ssh.1), [ssh_config(5)](https://man.openbsd.org/ssh_config.5) | Host-key behavior, `ProxyJump`, connection multiplexing | 2026-07-13 |
| Ansible playbooks | [Check and diff mode](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_checkmode.html), [execution strategies](https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_strategies.html) | Simulation limits, diff sensitivity, serial rollout | 2026-07-13 |
| Ansible modules | [package](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/package_module.html), [systemd_service](https://docs.ansible.com/projects/ansible/latest/collections/ansible/builtin/systemd_service_module.html) | Generic-module limits, package-name variance, service-manager scope | 2026-07-13 |
| Paramiko | [Paramiko documentation](https://docs.paramiko.org/en/stable/) and [SSHClient API](https://docs.paramiko.org/en/stable/api/client.html) | Client, host-key, channel, and SFTP responsibilities | 2026-07-13 |
| systemd | [systemctl manual](https://www.freedesktop.org/software/systemd/man/latest/systemctl.html) | Unit lifecycle and state inspection | 2026-07-13 |
| Linux firewall | [nftables wiki](https://wiki.nftables.org/wiki-nftables/index.php/Main_Page) | nftables architecture and CLI concepts | 2026-07-13 |
| Arch packages | [pacman(8)](https://man.archlinux.org/man/pacman.8) | package database, transaction, cache, and dependency controls | 2026-07-13 |
| Alpine packages | [Alpine Package Keeper](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) | configuration conflict files, persistence modes, and package state | 2026-07-13 |
| FreeBSD | [FreeBSD Handbook: configuration](https://docs.freebsd.org/en/books/handbook/config/), [firewalls](https://docs.freebsd.org/en/books/handbook/firewalls/), [ports and packages](https://docs.freebsd.org/en/books/handbook/ports/) | rc framework, remote-firewall caution, base/package distinction, package/ports lifecycle | 2026-07-13 |
| NetBSD services | [NetBSD rc.d guide](https://www.netbsd.org/docs/guide/en/chap-rc.html) | rc.d configuration, service lifecycle, and `service` alias | 2026-07-13 |
| NetBSD packages | [pkgsrc guide](https://www.netbsd.org/docs/pkgsrc/using.html), [pkg_add(1)](https://man.netbsd.org/pkg_add.1) | pkgsrc package origins, binary packages, and pkg tools | 2026-07-13 |
| OpenBSD services | [rcctl(8)](https://man.openbsd.org/rcctl) | daemon configuration, enablement, and actions | 2026-07-13 |
| OpenBSD packages | [pkg_add(1)](https://man.openbsd.org/pkg_add) | package install/update, signatures, package/base distinction | 2026-07-13 |
| OpenBSD PF | [pfctl(8)](https://man.openbsd.org/pfctl), [pf.conf(5)](https://man.openbsd.org/pf.conf) | rule validation/loading and PF control scope | 2026-07-13 |
| Apple launchd | [Creating Launch Daemons and Agents](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html) | daemon/agent distinction, labels, and launchd ownership model | 2026-07-13 |
| Apple firewall | [Block connections to your Mac with a firewall](https://support.apple.com/guide/mac-help/change-firewall-settings-mh34041/mac) | application/service firewall behavior | 2026-07-13 |
| Apple deployment | [Apple Platform Deployment](https://support.apple.com/guide/deployment/welcome/web) | Apple-supported management and deployment posture | 2026-07-13 |
| Homebrew | [Homebrew manpage](https://docs.brew.sh/Manpage) | package-manager behavior and environment controls | 2026-07-13 |
## Research observations
- Ansible documents `--check` as a simulation with module support gaps and notes that `--diff` can expose sensitive information; the skill therefore treats both as previews, not proof.
- Paramiko documents that clients are responsible for authentication and checking server host keys; the skill therefore forbids automatic acceptance of unknown keys.
- OpenBSD documents `rcctl` actions and `pkg_add`'s signed-package behavior; the skill keeps OpenBSD service and package guidance separate from Linux and FreeBSD.
- The FreeBSD Handbook distinguishes prebuilt packages from ports; the skill does not present them as a single update mechanism.
## Refresh rules
Refresh this index before adding exact release support windows, package versions, security advisories, default firewall behavior, command flags that vary by release, or OS upgrade procedures. If a primary site is unavailable to a crawler, use the maintained canonical URL and state the retrieval limitation rather than replacing it with a plausible paraphrase.
@@ -0,0 +1,35 @@
# Remote Change Plan
## Intent
- **Requested outcome:**
- **Authorized by / change window:**
- **Target(s):**
- **Environment and criticality:**
## Live discovery evidence
- **OS and release:**
- **Service manager:**
- **Package manager / package origin:**
- **Firewall / network control plane:**
- **Access route and elevation method:**
- **Current component state:**
## Change
- **Desired state:**
- **Exact control plane and command class:**
- **Blast radius:** one host / canary / batch size / full fleet
- **Stop condition:**
## Recovery
- **Rollback procedure:**
- **Independent recovery path:** console, bastion, retained session, or other authorized path
- **State/artifact captured before change:**
## Validation
- **Component evidence:**
- **External or user-visible boundary:**
- **Per-host result record:** target, status, evidence, rollback status
## Completion
- **Outcome:** passed / failed / rolled back / blocked
- **Remaining uncertainty or follow-up:**