internals/skills/local-infra/SKILL.md
Go file map for the target:local execution surface. Files: local_spec.go, deploy_target_local.go, unified_targets_local.go, ssh_managed_config.go, hostdistro.go, install_ledger.go, builder_run.go, shell_profile.go, reverse_ops.go, service_render.go, deploy_ref.go. MUST be invoked before reading or modifying any of those files, or when debugging target:local deploy behaviour (ledger state, sudo batching, managed-block insertion, glibc preflight, ssh-config fragment, ref resolution).
npx skillsauth add overthinkos/overthink-plugins local-infraInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The InstallPlan IR (see /ov-internals:install-plan) is the central data type. LocalDeployTarget (the executor) consumes the IR and invokes a handful of supporting files for each concrete concern: distro detection, ledger I/O, builder-container invocation, shell profile writes, ReverseOp execution, service rendering, ref resolution, and the managed ssh-config fragment that VMs publish on create.
| File | Purpose | Key exports |
|---|---|---|
| ov/local_spec.go | LocalSpec struct + findLocalSpec lookup | LocalSpec, findLocalSpec |
| ov/deploy_target_local.go | LocalDeployTarget.Emit IR consumer | LocalDeployTarget |
| ov/unified_targets_local.go | LocalUnifiedTarget adapter (Add/Del/Test/Update/Status/Shell/Rebuild) | LocalUnifiedTarget |
| ov/ssh_managed_config.go | ~/.config/ov/ssh_config fragment writer (managed-block protocol) | WriteVmSshStanza, RemoveVmSshStanza, ListVmSshAliases, EnsureSshConfigInclude, RemoveSshConfigInclude, VmSshAlias, SshFragmentPath, SshConfigPath |
| ov/deploy_executor_ssh.go | Credential-free SSHExecutor (no -i, no host-key overrides) | SSHExecutor |
| ov/deploy_executor.go | ShellExecutor — local shell venue | ShellExecutor |
| ov/hostdistro.go | Detect host distro from /etc/os-release; glibc preflight | HostDistro, DetectHostDistro, DetectHostGlibc, CompareGlibc, distroIDAliases |
| ov/install_ledger.go | Flock-serialized JSON ledger at ~/.config/overthink/installed/ | LedgerPaths, LedgerLock, DeployRecord, LayerRecord, StepRecord, AcquireLedgerLock, AddLayerDeployment, RemoveLayerDeployment |
| ov/builder_run.go | podman run <builder> wrapper for compile-needing layers | BuilderRun, BuilderRunOpts, UserScopeBindMounts, UserScopeEnv |
| ov/shell_profile.go | bash/zsh/fish detection + managed-block fencing + env.d I/O | ShellKind, DetectLoginShell, EnvdDir, WriteEnvdFile, RemoveEnvdFile, EnsureManagedBlockVia, EnsureManagedBlock, RemoveManagedBlock, ShellInitFilePath |
| ov/reverse_ops.go | Execute ReverseOp slices in LIFO order via per-kind handlers | runReverseOps, ReverseExecutor interface, 15 reverse handlers |
Managed block is executor-based. EnsureManagedBlockVia(ctx, exec, shell, home, opts) is the single writer for the env.d-sourcing block: GetFile the existing rc, merge the fenced block, PutFile it back. LocalDeployTarget calls it with a ShellExecutor (host fs); VmDeployTarget with an SSHExecutor (guest fs) — so the block lands in the right user's rc on local AND vm deploys (R3, one path). EnsureManagedBlock(shell, home) is a thin wrapper over it with a local ShellExecutor. home is the DESTINATION user's home — the guest home for a VM deploy (see /ov-internals:vm-deploy-target).
| ov/service_render.go | Render ServiceEntry → systemd unit / supervisord INI | ServiceEntry, ServiceOverrides, RenderService, RenderedService |
| ov/deploy_ref.go | Unified 4-form ref resolver | DeployRef, RefKind, RefSource, ResolveDeployRef, classifyYAMLFile |
SSHExecutor carries User, Host, Port, Args, ConnectTimeout — no KeyPath, no KnownHostsFile, no host-key overrides. sshBaseArgs emits only -o LogLevel=ERROR + -o ConnectTimeout=… plus optional -p <port> plus the deployment's pass-through Args plus the destination. ssh(1) reads ~/.ssh/config + ssh-agent for everything else.
For VM destinations the Host field is the managed alias ov-<vmname>, written into ~/.config/ov/ssh_config by ov vm create. Both User and Port are left empty — the alias's Host stanza supplies them.
Pattern mirrors ov/shell_profile.go (the env.d managed block in ~/.profile / ~/.zshenv / ~/.config/fish/conf.d/overthink.fish):
# overthink:begin (managed by ov; do not edit inside this block) … # overthink:end.WriteVmSshStanza writes/replaces a Host stanza inside the managed block at ~/.config/ov/ssh_config. Multiple stanzas coexist, sorted by alias for deterministic output.EnsureSshConfigInclude ensures Include ~/.config/ov/ssh_config is present in ~/.ssh/config (also fenced).RemoveVmSshStanza returns the count of remaining stanzas; when zero the fragment file is deleted.RemoveSshConfigInclude strips the Include line; when ~/.ssh/config becomes empty after stripping, the file is deleted.VmSshAlias("eval-arch-vm") → "ov-eval-arch-vm". Unique within the managed fragment.~/.config/overthink/installed/Every target:local deploy writes a DeployRecord and per-layer LayerRecords with deployed_by: refcount semantics. See the file map above for the JSON shapes.
/ov-internals:install-plan — the IR these files support; full step-kind catalogue./ov-internals:go — overall Go code map; Kong framework; mode-purity invariant./ov-local:local-deploy — user-facing target:local surface./ov-core:deploy — command family overview./ov-image:layer — unified service: schema authored by layer authors.MUST be invoked when reading or modifying any of the listed files; when debugging target:local ledger state or ssh-config fragment behavior; when adding a new ReverseOpKind handler, a new shell to the detection map, or a new distro ID alias; or when extending the ref resolver to accept a new ref form.
development
Claude Code multi-agent support in Overthink — sub-agents, dynamic workflows, and agent teams, and how each drives the existing `ov eval` disposable beds to test and verify. MUST be invoked before authoring or invoking an ov sub-agent / dynamic workflow / agent team, wiring agent-lifecycle hooks, or asking "which primitive should drive the R10 beds?".
tools
Mounts a virtiofs share tagged `workspace` at /workspace inside a VM guest via a systemd .mount unit. Use when a kind:vm entity shares a host directory into the guest and you need it auto-mounted (and re-mounted at every boot).
development
MUST be invoked before any work involving: the `kind: android` schema kind, a `target: android` deploy, the `apk:` layer package format (installing Android apps declaratively), AndroidDeployTarget, an in-pod emulator OR a remote/physical adb-endpoint device, or nested `pod → android` deployment. The first-class Android device + app surface that sits above `ov eval adb`/`appium`.
tools
Use when committing, branching, pushing, merging, tagging, creating PRs, or approving/merging PRs with gh — the feat/-branch, R10-gated, never-force-push landing workflow across the main repo + the plugins submodule + image/<distro> submodules. Covers sync-to-upstream, branch/worktree pruning, the fork+PR path for contributors without write access, and cross-repo @github landing order.