@homeflare/alchemy 0.19.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/linux/index.js +140 -93
- package/dist/linux/index.js.map +11 -10
- package/dist/linux/region.d.ts +11 -0
- package/dist/linux/region.d.ts.map +1 -1
- package/dist/linux/remote-file-lifecycle.d.ts.map +1 -1
- package/dist/linux/remote-file-plan.d.ts +22 -0
- package/dist/linux/remote-file-plan.d.ts.map +1 -1
- package/dist/linux/remote-file.d.ts +4 -1
- package/dist/linux/remote-file.d.ts.map +1 -1
- package/dist/linux/unit-handlers.d.ts.map +1 -1
- package/dist/linux/unit-lifecycle.d.ts +1 -5
- package/dist/linux/unit-lifecycle.d.ts.map +1 -1
- package/dist/linux/unit-preflight.d.ts +50 -0
- package/dist/linux/unit-preflight.d.ts.map +1 -0
- package/dist/proxmox/index.d.ts +15 -3
- package/dist/proxmox/index.d.ts.map +1 -1
- package/dist/proxmox/index.js +4 -1
- package/dist/proxmox/index.js.map +1 -1
- package/docs/adopted-deploys.md +13 -0
- package/docs/linux-host.md +11 -1
- package/docs/provider-standard.md +138 -0
- package/docs/upstream-conformance.md +164 -0
- package/package.json +1 -1
- package/src/linux/region.ts +15 -0
- package/src/linux/remote-file-lifecycle.test.ts +0 -88
- package/src/linux/remote-file-lifecycle.ts +25 -7
- package/src/linux/remote-file-plan.ts +37 -1
- package/src/linux/remote-file-region.test.ts +181 -0
- package/src/linux/remote-file.ts +4 -1
- package/src/linux/unit-handlers.ts +12 -5
- package/src/linux/unit-lifecycle.ts +12 -30
- package/src/linux/unit-preflight.test.ts +128 -0
- package/src/linux/unit-preflight.ts +116 -0
- package/src/linux/unit-rename.test.ts +76 -0
- package/src/proxmox/ceph-adopt.test.ts +210 -0
- package/src/proxmox/constraints-forms.test.ts +14 -6
- package/src/proxmox/constraints-node-forms.test.ts +12 -3
- package/src/proxmox/index.test.ts +7 -4
- package/src/proxmox/index.ts +15 -3
package/dist/linux/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/linux/directory.ts", "../src/launchd/host-effect.ts", "../src/launchd/runner.ts", "../src/ownership/adopt.ts", "../src/ownership/resume.ts", "../src/ownership/rows.ts", "../src/ownership/whole.ts", "../src/launchd/secret-tripwire.ts", "../src/launchd/host-file-form.ts", "../src/linux/directory-lifecycle.ts", "../src/linux/providers.ts", "../src/linux/remote-file.ts", "../src/launchd/job-form.ts", "../src/launchd/plist.ts", "../src/linux/region.ts", "../src/linux/remote-file-form.ts", "../src/linux/remote-file-plan.ts", "../src/linux/remote-file-lifecycle.ts", "../src/linux/unit.ts", "../src/linux/unit-handlers.ts", "../src/linux/unit-form.ts", "../src/linux/
|
|
3
|
+
"sources": ["../src/linux/directory.ts", "../src/launchd/host-effect.ts", "../src/launchd/runner.ts", "../src/ownership/adopt.ts", "../src/ownership/resume.ts", "../src/ownership/rows.ts", "../src/ownership/whole.ts", "../src/launchd/secret-tripwire.ts", "../src/launchd/host-file-form.ts", "../src/linux/directory-lifecycle.ts", "../src/linux/providers.ts", "../src/linux/remote-file.ts", "../src/launchd/job-form.ts", "../src/launchd/plist.ts", "../src/linux/region.ts", "../src/linux/remote-file-form.ts", "../src/linux/remote-file-plan.ts", "../src/linux/remote-file-lifecycle.ts", "../src/linux/unit.ts", "../src/linux/unit-handlers.ts", "../src/linux/systemctl.ts", "../src/linux/unit-form.ts", "../src/linux/unit-settle.ts", "../src/linux/unit-preflight.ts", "../src/linux/unit-lifecycle.ts", "../src/linux/ssh-runner.ts", "../src/launchd/host-lookup.ts", "../src/linux/ssh-command.ts", "../src/linux/ssh-scripts.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * `Host.Directory` — one directory on the host, declared: path, mode, owner, group.\n *\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt`: a directory already at the path reads as `Unowned`, and\n * where the plan never asked, reconcile honours the same flag (docs/ownership.md).\n * ★ IT IS NOT LINUX-ONLY. `mkdir`, `chmod`, `chown` and `rmdir` are the same argv on macOS, so this\n * resource works through any HostRunner; it lives in the linux subpath because the gap it closes\n * was found there (a first deploy into a new tree, which every file resource refuses to create).\n */\nimport { Resource } from 'alchemy';\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport { isResolved } from 'alchemy/Diff';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { HostDirectoryAttributes, HostDirectoryProps } from './directory-lifecycle.ts';\nimport {\n deleteDirectory,\n diffDirectory,\n readDirectory,\n reconcileDirectory,\n} from './directory-lifecycle.ts';\n\nexport type { HostDirectoryAttributes, HostDirectoryProps } from './directory-lifecycle.ts';\n\nexport interface HostDirectory extends Resource<\n 'Host.Directory',\n HostDirectoryProps,\n HostDirectoryAttributes\n> {}\n\nexport const HostDirectory = Resource<HostDirectory>('Host.Directory');\n\nexport const HostDirectoryProvider = () =>\n Provider.effect(\n HostDirectory,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return HostDirectory.Provider.of({\n list: () => Effect.succeed([]),\n\n read: ({ olds, output }) =>\n lift(async () => {\n const found = await readDirectory(runner, olds.path);\n if (found === undefined) return undefined;\n return output === undefined ? Unowned(found) : found;\n }),\n\n diff: ({ instanceId, news, output }) => {\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffDirectory(runner, news, output));\n // ⛔ A new path is a replace even while the rest is unresolved: the engine's default\n // update would create the new directory and leave the old one behind forever.\n const path = resolvedString(news, 'path');\n return Effect.succeed(\n path !== undefined && path !== output.path ? { action: 'replace' as const } : undefined,\n );\n },\n\n reconcile: ({ fqn, instanceId, news, output }) =>\n Effect.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) =>\n lift(() => reconcileDirectory(runner, news, output, adopt)),\n ),\n\n delete: ({ output }) => lift(() => deleteDirectory(runner, output)),\n });\n }),\n );\n",
|
|
6
6
|
"/**\n * The one place a HostRunner's promises become Effects — plus the one probe of an unresolved\n * `news` both providers' diffs share. (The engine's adopt setting lives in ownership/adopt.ts.)\n *\n * ★ The lifecycle files are plain async functions over a HostRunner (see runner.ts for why the\n * runner is promise-based), so each provider handler is a single `lift(() => step(runner, …))`.\n * ⚠️ A thrown Error stays that Error — its message is the refusal a deploy prints. Anything else\n * thrown is wrapped, so the failure channel is always an Error with a readable message.\n */\nimport * as Effect from 'effect/Effect';\n\nexport const lift = <A>(step: () => Promise<A>): Effect.Effect<A, Error> =>\n Effect.tryPromise({\n catch: (cause) => (cause instanceof Error ? cause : new Error(String(cause))),\n try: step,\n });\n\n/**\n * A string prop of a diff's `news`, when that one prop is already resolved; `undefined` while it\n * is still an Output (a function-typed proxy), an Effect or a Config.\n * ★ For the identity props a diff must see even when the rest of `news` is unresolved — a plain\n * string is resolved by definition, so `typeof` is the whole test.\n */\nexport const resolvedString = (news: unknown, key: string): string | undefined => {\n if (typeof news !== 'object' || news === null) return undefined;\n const value = (news as Record<string, unknown>)[key];\n return typeof value === 'string' ? value : undefined;\n};\n",
|
|
@@ -13,25 +13,26 @@
|
|
|
13
13
|
"/**\n * HostFile's props, attributes and validation — the pure half of the provider.\n *\n * ⛔ `content` IS NEVER A SECRET. Alchemy stores props unencrypted, so the content of every HostFile\n * sits in the state store and in every plan diff. A secret file stays RENDERED BY A SECRET\n * RENDERER (openbao-agent templates, on this estate) that fetches it at run time; the stack\n * declares only non-secret config, and at most the PATH the renderer writes to.\n * secret-tripwire.ts refuses the obvious case (a PEM private key); nothing can catch all of them.\n */\nimport { fileSecretProblems } from './secret-tripwire.ts';\n\nexport interface HostFileProps {\n /** Absolute path. The parent directory must already exist. */\n path: string;\n /** UTF-8 text. ⛔ Never a secret — see the file header. */\n content: string;\n /** Permission bits. @default 0o644 */\n mode?: number;\n /** User name or numeric uid. Omitted: whoever the runner writes as (a rewrite keeps no owner). */\n owner?: string | number;\n /** Group name or numeric gid. Omitted: the directory's default group. */\n group?: string | number;\n}\n\nexport interface HostFileAttributes {\n path: string;\n /** SHA-256 of the bytes on disk. */\n sha256: string;\n mode: number;\n uid: number;\n gid: number;\n size: number;\n}\n\nexport const DEFAULT_MODE = 0o644;\n\nconst identityProblems = (name: string, value: string | number | undefined): string[] => {\n if (value === undefined) return [];\n if (typeof value === 'number') {\n return Number.isSafeInteger(value) && value >= 0\n ? []\n : [`${name} must be a non-negative integer id`];\n }\n return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) || /^\\d+$/.test(value)\n ? []\n : [`${name} ${JSON.stringify(value)} is not a valid user or group name`];\n};\n\n/**\n * An absolute, normalised path, or the reasons it is not. ★ Shared with sudo-allowlist.ts, so a\n * path the sudo runner may touch as root obeys exactly the rule a declared file does.\n */\nexport const pathProblems = (path: string): string[] => {\n const found: string[] = [];\n if (!path.startsWith('/')) found.push('path must be absolute');\n // ★ One spelling per file: `a/./b`, `a//b` and `a/../b` would each be a second resource for the\n // same inode, and `..` is how a derived path walks out of the directory it was meant for.\n if (\n path.endsWith('/') ||\n path\n .split('/')\n .slice(1)\n .some((part) => part === '' || part === '.' || part === '..')\n ) {\n found.push('path must be normalised (no trailing slash, no empty, \".\" or \"..\" segments)');\n }\n if (path.includes('\\x00')) found.push('path contains NUL');\n return found;\n};\n\nexport const fileProblems = (props: HostFileProps): string[] => {\n const found = pathProblems(props.path);\n const mode = props.mode ?? DEFAULT_MODE;\n if (!Number.isSafeInteger(mode) || mode < 0 || mode > 0o7777) found.push('mode must be 0–0o7777');\n found.push(...identityProblems('owner', props.owner));\n found.push(...identityProblems('group', props.group));\n found.push(...fileSecretProblems(props.content));\n return found;\n};\n",
|
|
14
14
|
"/**\n * HostDirectory's props, validation and lifecycle over a HostRunner.\n *\n * ★ WHY IT EXISTS AT ALL. `Host.File` and `Remote.File` both refuse to create a parent directory,\n * on purpose — creating one would invent an owner and a mode nobody declared. The consequence is\n * that a first deploy into a new tree fails on its first file. This resource is the declaration\n * that was missing, not a convenience flag on the file.\n * ⛔ ONE DIRECTORY, NEVER A CHAIN. A missing parent is a refusal that names it, so a tree is a\n * chain of declarations whose modes and owners are all visible in the plan. `mkdir -p` would\n * create the intermediate levels at whatever umask the deploy happened to run with.\n * ⛔ DELETE IS `rmdir`, NEVER RECURSIVE. A directory that still holds files is a refusal: removing\n * a declaration must not be able to remove data the declaration never mentioned.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport { pathProblems } from '../launchd/host-file-form.ts';\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\n\nexport interface HostDirectoryProps {\n /** Absolute path. ⚠️ Its parent must already exist — declare it as another HostDirectory. */\n path: string;\n /** Permission bits. @default 0o755 */\n mode?: number;\n /** User name or numeric uid. Omitted: whoever the runner writes as. */\n owner?: string | number;\n /** Group name or numeric gid. Omitted: the parent's default group. */\n group?: string | number;\n}\n\nexport interface HostDirectoryAttributes {\n path: string;\n mode: number;\n uid: number;\n gid: number;\n}\n\nexport const DEFAULT_DIR_MODE = 0o755;\n\nexport const refuse = (path: string, message: string): Error =>\n new Error(`Host.Directory ${path}: ${message}`);\n\nconst idProblems = (name: string, value: string | number | undefined): string[] => {\n if (value === undefined) return [];\n if (typeof value === 'number') {\n return Number.isSafeInteger(value) && value >= 0 ? [] : [`${name} must be a non-negative id`];\n }\n return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) || /^\\d+$/.test(value)\n ? []\n : [`${name} ${JSON.stringify(value)} is not a valid user or group name`];\n};\n\nexport const directoryProblems = (props: HostDirectoryProps): string[] => {\n const found = pathProblems(props.path);\n const mode = props.mode ?? DEFAULT_DIR_MODE;\n if (!Number.isSafeInteger(mode) || mode < 0 || mode > 0o7777) found.push('mode must be 0–0o7777');\n found.push(...idProblems('owner', props.owner), ...idProblems('group', props.group));\n return found;\n};\n\nconst numericId = (value: string | number): number | undefined =>\n typeof value === 'number' ? value : /^\\d+$/.test(value) ? Number(value) : undefined;\n\ntype Desired = { readonly mode: number; readonly uid?: number; readonly gid?: number };\n\nconst desired = async (runner: HostRunner, props: HostDirectoryProps): Promise<Desired> => {\n const found = directoryProblems(props);\n if (found.length > 0) throw refuse(props.path, found.join('; '));\n let uid: number | undefined;\n let gid: number | undefined;\n if (props.owner !== undefined) {\n uid = numericId(props.owner) ?? (await runner.lookupUser(String(props.owner)))?.uid;\n if (uid === undefined) throw refuse(props.path, `no user ${String(props.owner)} on this host`);\n }\n if (props.group !== undefined) {\n gid = numericId(props.group) ?? (await runner.lookupGroup(String(props.group)));\n if (gid === undefined) throw refuse(props.path, `no group ${String(props.group)} on this host`);\n }\n return {\n mode: props.mode ?? DEFAULT_DIR_MODE,\n ...(uid === undefined ? {} : { uid }),\n ...(gid === undefined ? {} : { gid }),\n };\n};\n\nexport const readDirectory = async (\n runner: HostRunner,\n path: string,\n): Promise<HostDirectoryAttributes | undefined> => {\n const stat = await runner.stat(path);\n if (stat === undefined || stat.kind !== 'directory') return undefined;\n return { gid: stat.gid, mode: stat.mode, path, uid: stat.uid };\n};\n\nconst octal = (mode: number) => mode.toString(8).padStart(3, '0');\n\n/** One program, checked: anything but exit 0 is an Error naming the argv and the host's words. */\nconst must = async (runner: HostRunner, path: string, argv: readonly string[]): Promise<void> => {\n const result = await runner.exec(argv);\n if (result.exitCode !== 0) {\n throw refuse(\n path,\n `${argv.join(' ')} -> ${String(result.exitCode)}: ${result.stderr.trim().slice(0, 300)}`,\n );\n }\n};\n\n/**\n * Create it when absent, then bring mode and ownership to the declaration and read back.\n * ⚠️ `mkdir -m` sets the mode with chmod(2) after mkdir(2), so it is exact — plain `mkdir` would\n * mask the declared bits through the deploying shell's umask and the drift would return forever.\n */\nexport const reconcileDirectory = async (\n runner: HostRunner,\n props: HostDirectoryProps,\n output?: HostDirectoryAttributes,\n adopt = false,\n): Promise<HostDirectoryAttributes> => {\n const want = await desired(runner, props);\n if (want.uid !== undefined && want.uid !== runner.effectiveUid() && !canActAsRoot(runner)) {\n throw refuse(\n props.path,\n `owner ${String(props.owner)} is not the deploying user; only root may chown. Deploy through ` +\n 'a root destination or a privileged HostRunner. This provider never calls sudo itself.',\n );\n }\n const stat = await runner.stat(props.path);\n if (stat !== undefined && stat.kind !== 'directory') {\n throw refuse(props.path, `is a ${stat.kind}, not a directory`);\n }\n /**\n * ⛔ A DIRECTORY THIS RESOURCE DOES NOT OWN IS NEVER RE-MODED. Where the engine's probe never\n * looked — a replace's new path, a create whose props were still an Output — an existing\n * directory with a different mode or owner is someone else's. ★ Adoption takes it over.\n */\n if (output === undefined && stat !== undefined && !adopt) {\n const drifted = stat.mode !== want.mode || (want.uid !== undefined && stat.uid !== want.uid);\n if (drifted) {\n throw refuse(\n props.path,\n 'already exists with another mode or owner and is not this resource. Remove it, or ' +\n 'declare it as a new resource and deploy with --adopt.',\n );\n }\n }\n if (stat === undefined) {\n const parent = props.path.slice(0, props.path.lastIndexOf('/')) || '/';\n const above = await runner.stat(parent);\n if (above === undefined || above.kind !== 'directory') {\n throw refuse(props.path, `its parent ${parent} does not exist; declare that directory too`);\n }\n await must(runner, props.path, ['mkdir', '-m', octal(want.mode), '--', props.path]);\n } else if (stat.mode !== want.mode) {\n await must(runner, props.path, ['chmod', octal(want.mode), '--', props.path]);\n }\n /**\n * ★ Only when it is actually wrong. A `chown` that changes nothing is still a write on the host\n * and a line in the deploy log, and \"a converged resource is not touched\" is the rule this\n * whole family is judged by.\n */\n const owner = ownerMatches(\n { gid: stat?.gid ?? -1, mode: 0, path: props.path, uid: stat?.uid ?? -1 },\n want,\n )\n ? undefined\n : ownerArg(want);\n if (owner !== undefined) await must(runner, props.path, ['chown', owner, '--', props.path]);\n const after = await readDirectory(runner, props.path);\n // ⚠️ READ BACK: a runner that ignored the mode shows up here, not as a forever-`update`.\n if (after === undefined || after.mode !== want.mode || !ownerMatches(after, want)) {\n throw refuse(props.path, 'the directory on the host does not match the declaration');\n }\n return after;\n};\n\n/** ⛔ Never `<uid>:` — GNU chown reads a trailing colon as that user's LOGIN group, undeclared. */\nconst ownerArg = (want: Desired): string | undefined => {\n if (want.uid === undefined) return want.gid === undefined ? undefined : `:${String(want.gid)}`;\n return want.gid === undefined ? String(want.uid) : `${String(want.uid)}:${String(want.gid)}`;\n};\n\nconst ownerMatches = (live: HostDirectoryAttributes, want: Desired): boolean =>\n (want.uid === undefined || live.uid === want.uid) &&\n (want.gid === undefined || live.gid === want.gid);\n\n/**\n * ★ A plan that will write asks the runner first (`checkWrite`, when it has one) — a directory is\n * created and chmod'd through `exec`, but a runner that refuses to touch the path at all should\n * say so at plan time rather than mid-apply.\n */\nexport const diffDirectory = async (\n runner: HostRunner,\n news: HostDirectoryProps,\n output: HostDirectoryAttributes,\n): Promise<Diff> => {\n const want = await desired(runner, news);\n if (news.path !== output.path) return { action: 'replace' };\n const live = await readDirectory(runner, news.path);\n // ⛔ BOTH: the live directory catches a hand chmod, the stored attributes catch a deploy that\n // died after the mkdir and before its commit.\n const converged =\n live !== undefined &&\n live.mode === want.mode &&\n ownerMatches(live, want) &&\n output.mode === want.mode &&\n ownerMatches(output, want);\n if (converged) return { action: 'noop' };\n await runner.checkWrite?.(news.path, want);\n return { action: 'update' };\n};\n\n/** Remove it. ⛔ `rmdir`: a directory that still holds anything is a refusal, never a recursion. */\nexport const deleteDirectory = async (\n runner: HostRunner,\n output: HostDirectoryAttributes,\n): Promise<void> => {\n const stat = await runner.stat(output.path);\n if (stat === undefined) return;\n if (stat.kind !== 'directory')\n throw refuse(output.path, `is now a ${stat.kind}; not removing it`);\n await must(runner, output.path, ['rmdir', '--', output.path]);\n};\n",
|
|
15
15
|
"/**\n * Every provider in this subpath with ONE HostRunner, as a single layer for a host stack.\n *\n * const runner = await sshRunner({ host: 'the-host' });\n * Layer.mergeAll(linuxProviders(runner), …the stack's other providers)\n *\n * ★ ONE RUNNER FOR ALL OF THEM, so a directory, the config file inside it and the unit that reads\n * that file are written by the same identity on the same host — a stack cannot create the\n * directory on one host and start the unit on another by accident.\n * ⛔ THERE IS NO DEFAULT. launchdProviders() defaults to localRunner() because a Mac stack runs on\n * the Mac it declares; a Linux host is somewhere else, and a silent default to \"this machine\"\n * would write the estate's `/etc/systemd/system` onto the laptop running the deploy.\n */\nimport * as Layer from 'effect/Layer';\nimport { type HostRunner, hostRunnerLayer } from '../launchd/runner.ts';\nimport { HostDirectoryProvider } from './directory.ts';\nimport { RemoteFileProvider } from './remote-file.ts';\nimport { SystemdTimerProvider, SystemdUnitProvider } from './unit.ts';\n\nexport const linuxProviders = (runner: HostRunner) =>\n Layer.mergeAll(\n HostDirectoryProvider(),\n RemoteFileProvider(),\n SystemdTimerProvider(),\n SystemdUnitProvider(),\n ).pipe(Layer.provide(hostRunnerLayer(runner)));\n",
|
|
16
|
-
"/**\n * `Remote.File` — one text file on a Linux host, declared: content, mode, owner, group — or one\n * MANAGED BLOCK inside a file this resource does not own.\n *\n * - create / update — atomic write (stage beside the target, chown, chmod, rename), skipped when\n * the host already says what we declare; then read back and compared.\n * - read — lstat plus the SHA-256 of the file and of the part this resource owns.\n * - diff — the declared digest against the stored AND the on-disk one, plus mode and owner.\n * - replace — only when `path` changes; create-before-delete.\n * - delete — removes the file, or in region mode only the block.\n *\n * ⛔ NEVER A SECRET — see remote-file-form.ts.\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt` (docs/ownership.md): a file already at the path, or a\n * block already carrying the markers, reads as `Unowned`.\n * ★ IT IS A SEPARATE RESOURCE FROM `Host.File`, not a flag on it: the two have different attributes\n * (a region name that a delete cannot work without) and different promises about the rest of the\n * file, and folding them together would make every existing Mac HostFile's state shape change.\n */\nimport { Resource } from 'alchemy';\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport { isResolved } from 'alchemy/Diff';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { RemoteFileAttributes, RemoteFileProps } from './remote-file-form.ts';\nimport {\n deleteFile,\n diffFile,\n readFileAttributes,\n reconcileFile,\n} from './remote-file-lifecycle.ts';\n\nexport type { RemoteFileAttributes, RemoteFileProps } from './remote-file-form.ts';\n\nexport interface RemoteFile extends Resource<\n 'Remote.File',\n RemoteFileProps,\n RemoteFileAttributes\n> {}\n\nexport const RemoteFile = Resource<RemoteFile>('Remote.File');\n\nexport const RemoteFileProvider = () =>\n Provider.effect(\n RemoteFile,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return RemoteFile.Provider.of({\n /** ⛔ A host's files are not a list of things this stack owns. */\n list: () => Effect.succeed([]),\n\n read: ({ olds, output }) =>\n lift(async () => {\n const found = await readFileAttributes(runner, olds.path, olds.region);\n if (found === undefined) return undefined;\n // ⛔ In region mode an existing file is NOT this resource: only the block is. A file\n // with no such block reads as nothing, so the create writes the block instead of\n // demanding --adopt for a file it was never claiming.\n if (olds.region !== undefined && found.contentSha256 === '') return undefined;\n return output === undefined ? Unowned(found) : found;\n }),\n\n diff: ({ instanceId, news, output }) => {\n // ★ An unfinished generation of our own: `--adopt` may resume it (ownership/resume.ts).\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffFile(runner, news, output));\n // ⛔ A new path is a replace even while `content` is unresolved (an Output templated in):\n // the engine's default would be an update, which writes the new path and never removes\n // the old one.\n const path = resolvedString(news, 'path');\n return Effect.succeed(\n path !== undefined && path !== output.path ? { action: 'replace' as const } : undefined,\n );\n },\n\n // ★ `--adopt` reaches the apply too: the probe never ran for a create with an Output prop.\n reconcile: ({ fqn, instanceId, news, output }) =>\n Effect.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) =>\n lift(() => reconcileFile(runner, news, output, adopt)),\n ),\n\n delete: ({ output }) => lift(() => deleteFile(runner, output)),\n });\n }),\n );\n",
|
|
16
|
+
"/**\n * `Remote.File` — one text file on a Linux host, declared: content, mode, owner, group — or one\n * MANAGED BLOCK inside a file this resource does not own.\n *\n * - create / update — atomic write (stage beside the target, chown, chmod, rename), skipped when\n * the host already says what we declare; then read back and compared.\n * - read — lstat plus the SHA-256 of the file and of the part this resource owns.\n * - diff — the declared digest against the stored AND the on-disk one, plus mode and owner.\n * - replace — only when `path` changes; create-before-delete. A region renamed inside one file\n * is an update that writes the new block, verifies it, then takes the old one out.\n * - delete — removes the file, or in region mode only the block.\n *\n * ⛔ NEVER A SECRET — see remote-file-form.ts.\n * ⛔ THE REGION IS PART OF THE IDENTITY. Renaming it, or changing its comment token, moves the block;\n * swapping between owning the whole file and owning a block is refused (remote-file-plan.ts).\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt` (docs/ownership.md): a file already at the path, or a\n * block already carrying the markers, reads as `Unowned`.\n * ★ IT IS A SEPARATE RESOURCE FROM `Host.File`, not a flag on it: the two have different attributes\n * (a region name that a delete cannot work without) and different promises about the rest of the\n * file, and folding them together would make every existing Mac HostFile's state shape change.\n */\nimport { Resource } from 'alchemy';\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport { isResolved } from 'alchemy/Diff';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { RemoteFileAttributes, RemoteFileProps } from './remote-file-form.ts';\nimport {\n deleteFile,\n diffFile,\n readFileAttributes,\n reconcileFile,\n} from './remote-file-lifecycle.ts';\n\nexport type { RemoteFileAttributes, RemoteFileProps } from './remote-file-form.ts';\n\nexport interface RemoteFile extends Resource<\n 'Remote.File',\n RemoteFileProps,\n RemoteFileAttributes\n> {}\n\nexport const RemoteFile = Resource<RemoteFile>('Remote.File');\n\nexport const RemoteFileProvider = () =>\n Provider.effect(\n RemoteFile,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return RemoteFile.Provider.of({\n /** ⛔ A host's files are not a list of things this stack owns. */\n list: () => Effect.succeed([]),\n\n read: ({ olds, output }) =>\n lift(async () => {\n const found = await readFileAttributes(runner, olds.path, olds.region);\n if (found === undefined) return undefined;\n // ⛔ In region mode an existing file is NOT this resource: only the block is. A file\n // with no such block reads as nothing, so the create writes the block instead of\n // demanding --adopt for a file it was never claiming.\n if (olds.region !== undefined && found.contentSha256 === '') return undefined;\n return output === undefined ? Unowned(found) : found;\n }),\n\n diff: ({ instanceId, news, output }) => {\n // ★ An unfinished generation of our own: `--adopt` may resume it (ownership/resume.ts).\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffFile(runner, news, output));\n // ⛔ A new path is a replace even while `content` is unresolved (an Output templated in):\n // the engine's default would be an update, which writes the new path and never removes\n // the old one.\n const path = resolvedString(news, 'path');\n return Effect.succeed(\n path !== undefined && path !== output.path ? { action: 'replace' as const } : undefined,\n );\n },\n\n // ★ `--adopt` reaches the apply too: the probe never ran for a create with an Output prop.\n reconcile: ({ fqn, instanceId, news, output }) =>\n Effect.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) =>\n lift(() => reconcileFile(runner, news, output, adopt)),\n ),\n\n delete: ({ output }) => lift(() => deleteFile(runner, output)),\n });\n }),\n );\n",
|
|
17
17
|
"/**\n * LaunchdJob's props, attributes and the pure half of the provider: domain parsing, the plist path,\n * and the props → plist mapping whose SHA-256 is the whole diff.\n *\n * ★ KEY NAMES AND MEANINGS FROM launchd.plist(5), checked against the 148 nix-darwin daemons on a\n * macOS 27.2 host on 2026-09-21 (read-only, from /nix/store): Label, ProgramArguments, RunAtLoad,\n * KeepAlive (boolean or {SuccessfulExit}), ThrottleInterval, StandardOutPath/StandardErrorPath,\n * EnvironmentVariables, UserName, StartInterval and StartCalendarInterval are the keys in real\n * use. Everything rarer goes through `extraKeys`.\n */\nimport { createHash } from 'node:crypto';\nimport { type PlistDict, type PlistValue, renderPlist } from './plist.ts';\n\n/** `system` (LaunchDaemons, root) or one user's login session, `gui/<uid>` (LaunchAgents). */\nexport type LaunchdDomain = 'system' | `gui/${number}`;\n\n/** One StartCalendarInterval entry. An omitted field is a wildcard, as in cron. */\nexport type CalendarInterval = {\n readonly minute?: number;\n readonly hour?: number;\n readonly day?: number;\n /** 0 and 7 are both Sunday. */\n readonly weekday?: number;\n readonly month?: number;\n};\n\n/** `true` = always restart; the object form restarts only on the named conditions. */\nexport type KeepAlive = boolean | { readonly successfulExit?: boolean; readonly crashed?: boolean };\n\nexport interface LaunchdJobProps {\n /** Reverse-DNS label. Unique per domain; also the plist's file name. */\n label: string;\n domain: LaunchdDomain;\n /** argv; the first element must be an absolute path. */\n programArguments: readonly string[];\n /**\n * ⛔ NON-SECRET VALUES ONLY. Props are stored unencrypted in Alchemy state, and these also land in\n * the plist on disk and in `launchctl print`. Pass a secret as a FILE PATH that a secret renderer\n * (openbao-agent) maintains — secret-tripwire.ts refuses the obvious mistakes.\n */\n environment?: Readonly<Record<string, string>>;\n runAtLoad?: boolean;\n keepAlive?: KeepAlive;\n /** Seconds between starts. */\n startInterval?: number;\n startCalendarInterval?: CalendarInterval | readonly CalendarInterval[];\n /** Minimum seconds between (re)starts; launchd's default is 10. */\n throttleInterval?: number;\n standardOutPath?: string;\n standardErrorPath?: string;\n workingDirectory?: string;\n /** Run as this user. ⚠️ System domain only — launchd ignores it for agents, so it is refused. */\n userName?: string;\n /** Run as this group. ⚠️ System domain only, like `userName`. */\n groupName?: string;\n /**\n * Any other launchd.plist(5) key, verbatim (`ProcessType`, `SoftResourceLimits`, …).\n * ⛔ A key the typed props own is refused, so one job can never say two things.\n */\n extraKeys?: PlistDict;\n}\n\nexport interface LaunchdJobAttributes {\n label: string;\n domain: LaunchdDomain;\n /** `<domain>/<label>` — what `launchctl print` / `bootout` take. */\n serviceTarget: string;\n plistPath: string;\n /** SHA-256 of the plist bytes last bootstrapped (reconcile) or found on disk (read). */\n plistSha256: string;\n /** Bootstrapped into the domain — not necessarily running. */\n loaded: boolean;\n /** launchd's own word: `running`, `not running`, … */\n state?: string;\n pid?: number;\n lastExitCode?: number;\n}\n\nexport type ParsedDomain =\n | { readonly kind: 'system' }\n | { readonly kind: 'gui'; readonly uid: number };\n\nexport const parseDomain = (domain: string): ParsedDomain | undefined => {\n if (domain === 'system') return { kind: 'system' };\n const match = /^gui\\/(\\d+)$/.exec(domain);\n return match?.[1] === undefined ? undefined : { kind: 'gui', uid: Number(match[1]) };\n};\n\nexport const serviceTarget = (label: string, domain: LaunchdDomain): string => `${domain}/${label}`;\n\n/**\n * Where launchd expects the job's plist. ★ Derived, never declared: a daemon's plist outside\n * /Library/LaunchDaemons is not bootstrapped at boot, so a free-form path would be a job that\n * silently stops existing after the next restart.\n */\nexport const plistPathFor = (\n label: string,\n domain: ParsedDomain,\n home: string | undefined,\n): string => {\n if (domain.kind === 'system') return `/Library/LaunchDaemons/${label}.plist`;\n // ⛔ No `~` fallback: the provider may run as root, whose `~` is not the agent owner's home.\n if (home === undefined || !home.startsWith('/')) {\n throw new Error(`gui/${String(domain.uid)}: no home directory for that uid on this host`);\n }\n return `${home}/Library/LaunchAgents/${label}.plist`;\n};\n\n/** Plist keys the typed props own — `extraKeys` may not name them. `Program` is refused too. */\nexport const OWNED_KEYS: readonly string[] = [\n 'EnvironmentVariables',\n 'GroupName',\n 'KeepAlive',\n 'Label',\n 'Program',\n 'ProgramArguments',\n 'RunAtLoad',\n 'StandardErrorPath',\n 'StandardOutPath',\n 'StartCalendarInterval',\n 'StartInterval',\n 'ThrottleInterval',\n 'UserName',\n 'WorkingDirectory',\n];\n\nconst calendarDict = (entry: CalendarInterval): PlistDict => {\n const dict: Record<string, PlistValue> = {};\n if (entry.minute !== undefined) dict['Minute'] = entry.minute;\n if (entry.hour !== undefined) dict['Hour'] = entry.hour;\n if (entry.day !== undefined) dict['Day'] = entry.day;\n if (entry.weekday !== undefined) dict['Weekday'] = entry.weekday;\n if (entry.month !== undefined) dict['Month'] = entry.month;\n return dict;\n};\n\nconst keepAliveValue = (keepAlive: KeepAlive): PlistValue => {\n if (typeof keepAlive === 'boolean') return keepAlive;\n const dict: Record<string, PlistValue> = {};\n if (keepAlive.successfulExit !== undefined) dict['SuccessfulExit'] = keepAlive.successfulExit;\n if (keepAlive.crashed !== undefined) dict['Crashed'] = keepAlive.crashed;\n return dict;\n};\n\n/** The plist dict for a job. ⚠️ Assumes jobProblems() came back empty. */\nexport const jobPlistDict = (props: LaunchdJobProps): PlistDict => {\n const dict: Record<string, PlistValue> = { ...props.extraKeys };\n dict['Label'] = props.label;\n dict['ProgramArguments'] = [...props.programArguments];\n const env = props.environment ?? {};\n if (Object.keys(env).length > 0) dict['EnvironmentVariables'] = { ...env };\n if (props.runAtLoad !== undefined) dict['RunAtLoad'] = props.runAtLoad;\n if (props.keepAlive !== undefined) dict['KeepAlive'] = keepAliveValue(props.keepAlive);\n if (props.startInterval !== undefined) dict['StartInterval'] = props.startInterval;\n const calendar = props.startCalendarInterval;\n if (calendar !== undefined) {\n dict['StartCalendarInterval'] = Array.isArray(calendar)\n ? (calendar as readonly CalendarInterval[]).map(calendarDict)\n : calendarDict(calendar as CalendarInterval);\n }\n if (props.throttleInterval !== undefined) dict['ThrottleInterval'] = props.throttleInterval;\n if (props.standardOutPath !== undefined) dict['StandardOutPath'] = props.standardOutPath;\n if (props.standardErrorPath !== undefined) dict['StandardErrorPath'] = props.standardErrorPath;\n if (props.workingDirectory !== undefined) dict['WorkingDirectory'] = props.workingDirectory;\n if (props.userName !== undefined) dict['UserName'] = props.userName;\n if (props.groupName !== undefined) dict['GroupName'] = props.groupName;\n return dict;\n};\n\nexport const sha256Hex = (bytes: Uint8Array | string): string =>\n createHash('sha256').update(bytes).digest('hex');\n\n/** The rendered plist and its digest — the only thing LaunchdJob compares. */\nexport const renderJob = (\n props: LaunchdJobProps,\n): { text: string; bytes: Uint8Array; sha256: string } => {\n const text = renderPlist(jobPlistDict(props));\n const bytes = new TextEncoder().encode(text);\n return { bytes, sha256: sha256Hex(bytes), text };\n};\n",
|
|
18
18
|
"/**\n * An XML property list serializer — the subset launchd.plist(5) reads, and nothing else.\n *\n * ★ WHY NOT AN npm LIBRARY. Nothing in this workspace depends on one (checked 2026-09-21: no\n * `plist`, `xmlbuilder` or `@xmldom/xmldom` anywhere under node_modules), and the common one pulls\n * an XML DOM in for PARSING, which a provider that only RENDERS never does. The subset a launchd\n * job needs is five node types, so this is ~100 lines plus exhaustive tests (plist.test.ts), which\n * also round-trip every case through Apple's own `plutil` when the tests run on macOS.\n *\n * ⛔ THE OUTPUT MUST BE DETERMINISTIC. LaunchdJob diffs by the SHA-256 of these bytes, so two\n * renders of one declaration must be byte-identical: dict keys are sorted, indentation is fixed,\n * and nothing depends on insertion order. A non-deterministic render is a forever-`update`.\n * ⚠️ AND A CHANGE TO THIS FILE'S OUTPUT RESTARTS EVERY JOB. A new header, indent or escape changes\n * every digest, so the next deploy after the kit upgrade updates — restarts — every declared\n * job at once. Treat any byte change here as a breaking change and say so in its changeset.\n *\n * ⛔ REFUSE, NEVER COERCE. `undefined`, `null`, a fraction, NaN, a class instance or a character XML\n * 1.0 cannot carry is a thrown PlistError naming the path, not a silently dropped key. A dropped\n * `KeepAlive` is a daemon that never restarts, and nothing downstream would say why.\n */\n\n/** Every value launchd reads. ⚠️ No `<real>`, `<date>` or `<data>`: no launchd key needs one. */\nexport type PlistValue =\n | string\n | number\n | boolean\n | readonly PlistValue[]\n | { readonly [key: string]: PlistValue };\n\nexport type PlistDict = { readonly [key: string]: PlistValue };\n\nexport class PlistError extends Error {\n constructor(\n readonly path: string,\n detail: string,\n ) {\n super(`plist ${path === '' ? '(root)' : path}: ${detail}`);\n this.name = 'PlistError';\n }\n}\n\nconst HEADER =\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n' +\n '<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" ' +\n '\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\\n' +\n '<plist version=\"1.0\">\\n';\n\n/** ⚠️ A cycle, or a runaway generator, would otherwise recurse until the stack dies. */\nconst MAX_DEPTH = 32;\n\n/**\n * ⛔ CHARACTERS XML 1.0 CANNOT CARRY AT ALL — not even escaped (XML 1.0 §2.2 `Char`). C0 controls\n * other than tab, LF and CR; U+FFFE / U+FFFF; and an unpaired surrogate, which has no UTF-8 form.\n */\n// ★ The `u` flag makes a VALID surrogate pair one code point above U+FFFF, outside this class, so\n// only an unpaired half matches the \\uD800-\\uDFFF range.\n// oxlint-disable-next-line no-control-regex -- matching control characters is the point\nconst FORBIDDEN = /[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\uD800-\\uDFFF\\uFFFE\\uFFFF]/u;\n\n/**\n * Escape text content.\n * ⚠️ CR IS A CHARACTER REFERENCE, NOT A LITERAL. An XML parser normalises a literal CR (and CRLF)\n * to LF before the application sees it (XML 1.0 §2.11), so `a\\r\\nb` would come back as `a\\nb` and\n * the argument launchd passes would differ from the one declared. ` ` survives normalisation.\n */\nexport const escapeText = (text: string, path: string): string => {\n const bad = FORBIDDEN.exec(text);\n if (bad !== null) {\n const code = bad[0].codePointAt(0) ?? 0;\n throw new PlistError(\n path,\n `U+${code.toString(16).toUpperCase().padStart(4, '0')} cannot appear in XML 1.0`,\n );\n }\n return text\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\\r', ' ');\n};\n\nconst isPlainObject = (value: object): boolean => {\n const proto = Object.getPrototypeOf(value) as unknown;\n return proto === Object.prototype || proto === null;\n};\n\nconst renderValue = (value: unknown, path: string, depth: number, out: string[]): void => {\n const pad = '\\t'.repeat(depth);\n if (depth > MAX_DEPTH) throw new PlistError(path, `nested deeper than ${String(MAX_DEPTH)}`);\n if (typeof value === 'string') {\n out.push(`${pad}<string>${escapeText(value, path)}</string>`);\n return;\n }\n if (typeof value === 'boolean') {\n out.push(`${pad}<${value ? 'true' : 'false'}/>`);\n return;\n }\n if (typeof value === 'number') {\n // ⛔ launchd reads every numeric key as an integer; 1.5 would be a silently different job.\n if (!Number.isSafeInteger(value)) {\n throw new PlistError(path, `${String(value)} is not a safe integer (no <real> support)`);\n }\n out.push(`${pad}<integer>${String(value === 0 ? 0 : value)}</integer>`);\n return;\n }\n if (Array.isArray(value)) {\n if (value.length === 0) {\n out.push(`${pad}<array/>`);\n return;\n }\n out.push(`${pad}<array>`);\n for (const [index, item] of (value as readonly unknown[]).entries()) {\n renderValue(item, `${path}[${String(index)}]`, depth + 1, out);\n }\n out.push(`${pad}</array>`);\n return;\n }\n if (typeof value === 'object' && value !== null && isPlainObject(value)) {\n renderDict(value as Record<string, unknown>, path, depth, out);\n return;\n }\n const kind = value === null ? 'null' : typeof value;\n throw new PlistError(path, `${kind} has no plist form — omit the key instead`);\n};\n\nconst renderDict = (\n dict: Record<string, unknown>,\n path: string,\n depth: number,\n out: string[],\n): void => {\n const pad = '\\t'.repeat(depth);\n // ★ Code-unit order, not localeCompare: the same bytes on every machine and every locale.\n const keys = Object.keys(dict).sort();\n if (keys.length === 0) {\n out.push(`${pad}<dict/>`);\n return;\n }\n out.push(`${pad}<dict>`);\n for (const key of keys) {\n const child = path === '' ? key : `${path}.${key}`;\n out.push(`${pad}\\t<key>${escapeText(key, child)}</key>`);\n renderValue(dict[key], child, depth + 1, out);\n }\n out.push(`${pad}</dict>`);\n};\n\n/** Render a top-level dict as a complete XML plist document, ending in a newline. */\nexport const renderPlist = (dict: PlistDict): string => {\n if (typeof dict !== 'object' || dict === null || Array.isArray(dict) || !isPlainObject(dict)) {\n throw new PlistError('', 'the top level of a launchd plist must be a dict');\n }\n const out: string[] = [];\n renderDict(dict as Record<string, unknown>, '', 0, out);\n return `${HEADER}${out.join('\\n')}\\n</plist>\\n`;\n};\n",
|
|
19
|
-
"/**\n * A MANAGED REGION: a block a resource owns inside a file it does not own.\n *\n * ★ WHY THIS EXISTS. Four files on this estate are owned by something else and still need one\n * declared block: a packet-filter anchor line inside the OS vendor's own ruleset, a host table,\n * a generated Nix module, and an operator's ssh config. Declaring the WHOLE file would mean\n * taking it from its owner — which puts it back, or refuses its next activation. So the resource\n * owns the lines between two markers and promises that every other byte is untouched.\n * ⛔ THE REST OF THE FILE IS BYTE-IDENTICAL. Not \"semantically the same\", not re-indented, not\n * re-terminated: the bytes before the BEGIN line and after the END line are copied through. That\n * is the property region.test.ts asserts, because it is the whole reason the other owner tolerates\n * this.\n * ⛔ AMBIGUITY IS A REFUSAL, NEVER A GUESS. Two BEGIN markers with the same name, an END before its\n * BEGIN, or a BEGIN with no END all mean someone edited inside the block. Picking one would\n * silently delete their edit, so each is an Error naming the line.\n * ★ THE MARKER IS A COMMENT IN THE HOST FILE'S OWN LANGUAGE, which is why the comment token is a\n * prop: `#` covers the four consumers above, and a file whose comments are `//` or `;` says so.\n */\n\nexport type RegionSpec = {\n /** Distinguishes this block from any other managed block in the same file. */\n readonly name: string;\n /** The file's comment token. @default '#' */\n readonly comment?: string;\n};\n\nexport const DEFAULT_COMMENT = '#';\n\nconst tokens = (spec: RegionSpec) => {\n const comment = spec.comment ?? DEFAULT_COMMENT;\n return {\n begin: `${comment} BEGIN ${spec.name}`,\n end: `${comment} END ${spec.name}`,\n };\n};\n\nexport const regionProblems = (spec: RegionSpec): string[] => {\n const found: string[] = [];\n const comment = spec.comment ?? DEFAULT_COMMENT;\n if (!/^\\S{1,4}$/.test(comment) || comment.includes('\\u0000')) {\n found.push('region comment must be 1–4 non-space characters');\n }\n // ⛔ A marker must be one line and must be findable verbatim; a name with a newline would split\n // it, and leading or trailing space would not match what we later search for.\n if (!/^[A-Za-z0-9][A-Za-z0-9 ._:@/-]{0,79}$/.test(spec.name)) {\n found.push('region name must be 1–80 printable characters and start alphanumeric');\n }\n return found;\n};\n\nconst refuse = (message: string): Error => new Error(`managed region: ${message}`);\n\nconst duplicate = (what: string, at: readonly number[], line: string): Error =>\n refuse(\n `${what} for ${JSON.stringify(line)} (lines ${at.map((index) => index + 1).join(', ')}). ` +\n 'Remove the duplicate; this resource will not choose between them.',\n );\n\n/** Where the block sits: the line indices of its markers, or `undefined` when it is not there. */\nconst locate = (lines: readonly string[], spec: RegionSpec) => {\n const { begin, end } = tokens(spec);\n const begins = lines.flatMap((line, index) => (line === begin ? [index] : []));\n const ends = lines.flatMap((line, index) => (line === end ? [index] : []));\n if (begins.length > 1) throw duplicate('two BEGIN markers', begins, begin);\n if (ends.length > 1) throw duplicate('two END markers', ends, end);\n const [from] = begins;\n const [to] = ends;\n if (from === undefined && to === undefined) return undefined;\n if (from === undefined || to === undefined) {\n throw refuse(\n `${JSON.stringify(spec.name)} has a ${from === undefined ? 'END' : 'BEGIN'} marker and no ` +\n 'match. Repair the file by hand — a half-marked block means an edit inside it.',\n );\n }\n if (to < from) throw refuse(`${JSON.stringify(spec.name)} has its END marker before its BEGIN`);\n return { from, to };\n};\n\n/**\n * The file's bytes with the block set to `body`, appended at the end when it is not there yet.\n * ⚠️ A file that does not end in a newline gets one before the block is appended — the ONLY byte\n * this function adds outside its own block, and without it the last existing line and the BEGIN\n * marker would become one line.\n */\nexport const spliceRegion = (file: string, spec: RegionSpec, body: string): string => {\n const { begin, end } = tokens(spec);\n // ★ A body is stored as whole lines: exactly one newline after the last one, none doubled.\n const block = [begin, ...(body === '' ? [] : body.replace(/\\n$/, '').split('\\n')), end];\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found !== undefined) {\n return [...lines.slice(0, found.from), ...block, ...lines.slice(found.to + 1)].join('\\n');\n }\n const prefix = file === '' || file.endsWith('\\n') ? file : `${file}\\n`;\n return `${prefix}${block.join('\\n')}\\n`;\n};\n\n/** The block's body, or `undefined` when the file has no such block. */\nexport const readRegion = (file: string, spec: RegionSpec): string | undefined => {\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found === undefined) return undefined;\n const body = lines.slice(found.from + 1, found.to);\n return body.length === 0 ? '' : `${body.join('\\n')}\\n`;\n};\n\n/**\n * The file with the block and both markers removed — what a delete leaves behind.\n * ★ Byte-for-byte the file as it was before the block was appended, with one exception already\n * named on `spliceRegion`: a file that had no final newline when the block was added keeps the\n * newline that adding it required. Nothing else is added or dropped.\n */\nexport const removeRegion = (file: string, spec: RegionSpec): string => {\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found === undefined) return file;\n return [...lines.slice(0, found.from), ...lines.slice(found.to + 1)].join('\\n');\n};\n",
|
|
19
|
+
"/**\n * A MANAGED REGION: a block a resource owns inside a file it does not own.\n *\n * ★ WHY THIS EXISTS. Four files on this estate are owned by something else and still need one\n * declared block: a packet-filter anchor line inside the OS vendor's own ruleset, a host table,\n * a generated Nix module, and an operator's ssh config. Declaring the WHOLE file would mean\n * taking it from its owner — which puts it back, or refuses its next activation. So the resource\n * owns the lines between two markers and promises that every other byte is untouched.\n * ⛔ THE REST OF THE FILE IS BYTE-IDENTICAL. Not \"semantically the same\", not re-indented, not\n * re-terminated: the bytes before the BEGIN line and after the END line are copied through. That\n * is the property region.test.ts asserts, because it is the whole reason the other owner tolerates\n * this.\n * ⛔ AMBIGUITY IS A REFUSAL, NEVER A GUESS. Two BEGIN markers with the same name, an END before its\n * BEGIN, or a BEGIN with no END all mean someone edited inside the block. Picking one would\n * silently delete their edit, so each is an Error naming the line.\n * ★ THE MARKER IS A COMMENT IN THE HOST FILE'S OWN LANGUAGE, which is why the comment token is a\n * prop: `#` covers the four consumers above, and a file whose comments are `//` or `;` says so.\n */\n\nexport type RegionSpec = {\n /** Distinguishes this block from any other managed block in the same file. */\n readonly name: string;\n /** The file's comment token. @default '#' */\n readonly comment?: string;\n};\n\nexport const DEFAULT_COMMENT = '#';\n\nconst tokens = (spec: RegionSpec) => {\n const comment = spec.comment ?? DEFAULT_COMMENT;\n return {\n begin: `${comment} BEGIN ${spec.name}`,\n end: `${comment} END ${spec.name}`,\n };\n};\n\n/**\n * Whether two declarations name the SAME block.\n *\n * ⛔ THE COMMENT TOKEN IS PART OF THE IDENTITY, not a formatting preference. The markers are\n * matched as literal whole lines, so `# BEGIN pf` and `// BEGIN pf` are two different blocks:\n * changing the token leaves the old block invisible to every later read, exactly as renaming\n * does. A resource that treated either as a mere content change would splice a second block in\n * and never be able to find the first one again.\n * ★ Whole-file mode is its own identity: `undefined` equals only `undefined`.\n */\nexport const sameRegion = (a: RegionSpec | undefined, b: RegionSpec | undefined): boolean =>\n a === undefined || b === undefined\n ? a === undefined && b === undefined\n : a.name === b.name && (a.comment ?? DEFAULT_COMMENT) === (b.comment ?? DEFAULT_COMMENT);\n\nexport const regionProblems = (spec: RegionSpec): string[] => {\n const found: string[] = [];\n const comment = spec.comment ?? DEFAULT_COMMENT;\n if (!/^\\S{1,4}$/.test(comment) || comment.includes('\\u0000')) {\n found.push('region comment must be 1–4 non-space characters');\n }\n // ⛔ A marker must be one line and must be findable verbatim; a name with a newline would split\n // it, and leading or trailing space would not match what we later search for.\n if (!/^[A-Za-z0-9][A-Za-z0-9 ._:@/-]{0,79}$/.test(spec.name)) {\n found.push('region name must be 1–80 printable characters and start alphanumeric');\n }\n return found;\n};\n\nconst refuse = (message: string): Error => new Error(`managed region: ${message}`);\n\nconst duplicate = (what: string, at: readonly number[], line: string): Error =>\n refuse(\n `${what} for ${JSON.stringify(line)} (lines ${at.map((index) => index + 1).join(', ')}). ` +\n 'Remove the duplicate; this resource will not choose between them.',\n );\n\n/** Where the block sits: the line indices of its markers, or `undefined` when it is not there. */\nconst locate = (lines: readonly string[], spec: RegionSpec) => {\n const { begin, end } = tokens(spec);\n const begins = lines.flatMap((line, index) => (line === begin ? [index] : []));\n const ends = lines.flatMap((line, index) => (line === end ? [index] : []));\n if (begins.length > 1) throw duplicate('two BEGIN markers', begins, begin);\n if (ends.length > 1) throw duplicate('two END markers', ends, end);\n const [from] = begins;\n const [to] = ends;\n if (from === undefined && to === undefined) return undefined;\n if (from === undefined || to === undefined) {\n throw refuse(\n `${JSON.stringify(spec.name)} has a ${from === undefined ? 'END' : 'BEGIN'} marker and no ` +\n 'match. Repair the file by hand — a half-marked block means an edit inside it.',\n );\n }\n if (to < from) throw refuse(`${JSON.stringify(spec.name)} has its END marker before its BEGIN`);\n return { from, to };\n};\n\n/**\n * The file's bytes with the block set to `body`, appended at the end when it is not there yet.\n * ⚠️ A file that does not end in a newline gets one before the block is appended — the ONLY byte\n * this function adds outside its own block, and without it the last existing line and the BEGIN\n * marker would become one line.\n */\nexport const spliceRegion = (file: string, spec: RegionSpec, body: string): string => {\n const { begin, end } = tokens(spec);\n // ★ A body is stored as whole lines: exactly one newline after the last one, none doubled.\n const block = [begin, ...(body === '' ? [] : body.replace(/\\n$/, '').split('\\n')), end];\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found !== undefined) {\n return [...lines.slice(0, found.from), ...block, ...lines.slice(found.to + 1)].join('\\n');\n }\n const prefix = file === '' || file.endsWith('\\n') ? file : `${file}\\n`;\n return `${prefix}${block.join('\\n')}\\n`;\n};\n\n/** The block's body, or `undefined` when the file has no such block. */\nexport const readRegion = (file: string, spec: RegionSpec): string | undefined => {\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found === undefined) return undefined;\n const body = lines.slice(found.from + 1, found.to);\n return body.length === 0 ? '' : `${body.join('\\n')}\\n`;\n};\n\n/**\n * The file with the block and both markers removed — what a delete leaves behind.\n * ★ Byte-for-byte the file as it was before the block was appended, with one exception already\n * named on `spliceRegion`: a file that had no final newline when the block was added keeps the\n * newline that adding it required. Nothing else is added or dropped.\n */\nexport const removeRegion = (file: string, spec: RegionSpec): string => {\n const lines = file.split('\\n');\n const found = locate(lines, spec);\n if (found === undefined) return file;\n return [...lines.slice(0, found.from), ...lines.slice(found.to + 1)].join('\\n');\n};\n",
|
|
20
20
|
"/**\n * RemoteFile's props, attributes and validation — the pure half of the provider.\n *\n * ⛔ `content` IS NEVER A SECRET, for the same reason it is not on HostFile: Alchemy stores props\n * unencrypted, so every byte here sits in the state store and in every plan diff. A secret file\n * stays rendered at run time by a secret renderer; a stack declares at most the PATH it writes to.\n * secret-tripwire.ts refuses the obvious case and catches nothing subtle.\n * ★ TWO MODES, ONE RESOURCE. Without `region` this owns the whole file, exactly as HostFile does on\n * a Mac. With `region` it owns only the lines between two markers and promises every other byte\n * is untouched (region.ts) — which is the only way to declare a block inside a file another tool,\n * a vendor package or a person owns.\n */\nimport { pathProblems } from '../launchd/host-file-form.ts';\nimport { fileSecretProblems } from '../launchd/secret-tripwire.ts';\nimport { type RegionSpec, regionProblems } from './region.ts';\n\nexport interface RemoteFileProps {\n /** Absolute path on the host. ⚠️ The parent directory must exist — declare a HostDirectory. */\n path: string;\n /** UTF-8 text: the whole file, or the region's body. ⛔ Never a secret — see the file header. */\n content: string;\n /**\n * Own a block inside a file this resource does not own, instead of the whole file.\n * ⛔ In region mode `mode`, `owner` and `group` apply ONLY to a file this resource creates: an\n * existing file keeps the mode and ownership its owner gave it, because changing them would be\n * a second, undeclared claim on a file we only borrowed four lines of.\n */\n region?: RegionSpec;\n /**\n * Create the file when it is absent. Region mode only; whole-file mode always creates.\n * ⛔ Default `false`: a region declared against a path that does not exist is far more often a\n * typo (a wrong `/etc` path) than an intention, and creating it would hide the typo.\n */\n create?: boolean;\n /** Permission bits. @default 0o644 */\n mode?: number;\n /** User name or numeric uid. Omitted: whoever the runner writes as. */\n owner?: string | number;\n /** Group name or numeric gid. Omitted: the directory's default group. */\n group?: string | number;\n}\n\nexport interface RemoteFileAttributes {\n path: string;\n /** SHA-256 of the WHOLE file on disk, in both modes. */\n sha256: string;\n /** SHA-256 of the part this resource owns — in region mode, of the region's body alone. */\n contentSha256: string;\n /**\n * The block this resource owns, when it owns only a block.\n * ⛔ IT IS IN THE ATTRIBUTES ON PURPOSE. Alchemy's `delete` handler is given the attributes and\n * nothing else, and without the marker name a delete could not find the block — it could only\n * delete the whole file, which belongs to someone else.\n */\n region?: RegionSpec;\n mode: number;\n uid: number;\n gid: number;\n size: number;\n}\n\nexport const DEFAULT_MODE = 0o644;\n\nconst identityProblems = (name: string, value: string | number | undefined): string[] => {\n if (value === undefined) return [];\n if (typeof value === 'number') {\n return Number.isSafeInteger(value) && value >= 0\n ? []\n : [`${name} must be a non-negative integer id`];\n }\n return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) || /^\\d+$/.test(value)\n ? []\n : [`${name} ${JSON.stringify(value)} is not a valid user or group name`];\n};\n\nexport const fileProblems = (props: RemoteFileProps): string[] => {\n const found = pathProblems(props.path);\n const mode = props.mode ?? DEFAULT_MODE;\n if (!Number.isSafeInteger(mode) || mode < 0 || mode > 0o7777) found.push('mode must be 0–0o7777');\n found.push(...identityProblems('owner', props.owner));\n found.push(...identityProblems('group', props.group));\n found.push(...fileSecretProblems(props.content));\n if (props.region !== undefined) {\n found.push(...regionProblems(props.region));\n // ⛔ Say it at plan time rather than let a deploy silently ignore the prop: in region mode\n // these describe a file we do not own, and they are honoured only for a `create`.\n if (props.create !== true && (props.mode !== undefined || props.owner !== undefined)) {\n found.push(\n 'mode and owner apply only to a file this resource creates; drop them, or set create: true',\n );\n }\n } else if (props.create === true) {\n found.push('create is for region mode only; a whole-file declaration always creates the file');\n }\n return found;\n};\n",
|
|
21
|
-
"/**\n * What RemoteFile would write, worked out from what is on the host right now — the half of the\n * lifecycle that reads and decides, with no write in it.\n *\n * ⛔ IN REGION MODE THE LIVE FILE IS AN INPUT, not merely something to compare against: the declared\n * block is spliced into the bytes that are there, so every surrounding line survives verbatim.\n * That is why this cannot be a pure function of the props the way a whole-file render is.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\nimport type { FileStat, HostRunner, WriteOptions } from '../launchd/runner.ts';\nimport { type RegionSpec, readRegion, spliceRegion } from './region.ts';\nimport {\n DEFAULT_MODE,\n type RemoteFileAttributes,\n type RemoteFileProps,\n fileProblems,\n} from './remote-file-form.ts';\n\nexport const decoder = new TextDecoder();\nexport const encoder = new TextEncoder();\n\nexport const refuse = (path: string, message: string): Error =>\n new Error(`Remote.File ${path}: ${message}`);\n\nconst numericId = (value: string | number): number | undefined =>\n typeof value === 'number' ? value : /^\\d+$/.test(value) ? Number(value) : undefined;\n\nexport type Identity = { readonly uid?: number; readonly gid?: number };\n\n/** Validate, then resolve owner and group names to ids through the runner. */\nexport const identity = async (runner: HostRunner, props: RemoteFileProps): Promise<Identity> => {\n const found = fileProblems(props);\n if (found.length > 0) throw refuse(props.path, found.join('; '));\n let uid: number | undefined;\n let gid: number | undefined;\n if (props.owner !== undefined) {\n uid = numericId(props.owner) ?? (await runner.lookupUser(String(props.owner)))?.uid;\n if (uid === undefined) throw refuse(props.path, `no user ${String(props.owner)} on this host`);\n }\n if (props.group !== undefined) {\n gid = numericId(props.group) ?? (await runner.lookupGroup(String(props.group)));\n if (gid === undefined) throw refuse(props.path, `no group ${String(props.group)} on this host`);\n }\n return { ...(uid === undefined ? {} : { uid }), ...(gid === undefined ? {} : { gid }) };\n};\n\nexport const digestOf = (text: string): string => sha256Hex(encoder.encode(text));\n\n/** The digest of the part this resource owns, or `undefined` when that part is not there. */\nexport const ownedDigest = (\n file: string | undefined,\n region: RegionSpec | undefined,\n): string | undefined => {\n if (file === undefined) return undefined;\n if (region === undefined) return digestOf(file);\n const body = readRegion(file, region);\n return body === undefined ? undefined : digestOf(body);\n};\n\n/** The file as it is now, plus the digest of the part this resource owns. */\nexport const readFileAttributes = async (\n runner: HostRunner,\n path: string,\n region: RegionSpec | undefined,\n): Promise<RemoteFileAttributes | undefined> => {\n const stat = await runner.stat(path);\n if (stat === undefined) return undefined;\n const bytes = stat.kind === 'file' ? await runner.readFile(path) : undefined;\n const text = bytes === undefined ? undefined : decoder.decode(bytes);\n return {\n contentSha256: ownedDigest(text, region) ?? '',\n gid: stat.gid,\n mode: stat.mode,\n path,\n ...(region === undefined ? {} : { region }),\n sha256: bytes === undefined ? '' : sha256Hex(bytes),\n size: stat.size,\n uid: stat.uid,\n };\n};\n\nconst matches = (stat: FileStat | undefined, write: WriteOptions): boolean =>\n stat !== undefined &&\n stat.mode === write.mode &&\n (write.uid === undefined || stat.uid === write.uid) &&\n (write.gid === undefined || stat.gid === write.gid);\n\nexport type Plan = {\n /** The whole file's new bytes, in both modes. */\n readonly bytes: Uint8Array;\n readonly write: WriteOptions;\n /** The bytes on disk right now, or `undefined` when nothing is there. */\n readonly before: string | undefined;\n /** Nothing to do: the file already says what we declare, with the mode and owner we declare. */\n readonly converged: boolean;\n};\n\n/**\n * ⛔ A SYMLINK OR A DIRECTORY IS REFUSED, NOT REPLACED. The write is a rename(2), which over a\n * symlink replaces the LINK — quietly taking the path from whatever put it there (a config\n * manager's `/etc` entries are symlinks, and so is `/etc/resolv.conf` on most Linux hosts).\n */\nexport const planWrite = async (\n runner: HostRunner,\n props: RemoteFileProps,\n want: Identity,\n): Promise<Plan> => {\n const stat = await runner.stat(props.path);\n if (stat !== undefined && stat.kind !== 'file') {\n throw refuse(\n props.path,\n `is a ${stat.kind}; remove it from whatever owns it before declaring it here`,\n );\n }\n const current = stat === undefined ? undefined : await runner.readFile(props.path);\n const before = current === undefined ? undefined : decoder.decode(current);\n const declaredMode = props.mode ?? DEFAULT_MODE;\n if (props.region === undefined) {\n const write: WriteOptions = { mode: declaredMode, ...want };\n return {\n before,\n bytes: encoder.encode(props.content),\n converged: before === props.content && matches(stat, write),\n write,\n };\n }\n if (before === undefined) {\n if (props.create !== true) {\n throw refuse(\n props.path,\n 'does not exist, and a managed region does not create the file it lives in. Check the ' +\n 'path, declare the file itself, or pass create: true.',\n );\n }\n return {\n before,\n bytes: encoder.encode(spliceRegion('', props.region, props.content)),\n converged: false,\n write: { mode: declaredMode, ...want },\n };\n }\n const next = spliceRegion(before, props.region, props.content);\n /**\n * ⛔ THE FILE'S OWN MODE AND OWNER ARE COPIED BACK, never re-declared. We borrowed a block; the\n * rename would otherwise hand a file someone else owns a mode and an owner this stack chose,\n * which is a second claim nobody made.\n */\n return {\n before,\n bytes: encoder.encode(next),\n converged: next === before,\n write: { gid: stat?.gid ?? 0, mode: stat?.mode ?? declaredMode, uid: stat?.uid ?? 0 },\n };\n};\n",
|
|
22
|
-
"/**\n * RemoteFile's diff / reconcile / delete over a HostRunner, so the whole lifecycle runs against a\n * fake host in tests with no ssh and no real write. What it would write is worked out next door\n * (remote-file-plan.ts); this file is the part that decides to act.\n *\n * ⛔ IN REGION MODE, DRIFT MEANS THE REGION AND NOTHING ELSE. Every byte outside the markers belongs\n * to another owner, so a change there must never plan an update — otherwise the two owners fight\n * on every deploy and this resource loses the right to be in that file at all.\n * ⚠️ THE WRITE REPLACES THE INODE, in both modes. A process holding the old file keeps reading it\n * until it reopens, and a hard link to the path stops tracking. That is the price of never\n * leaving a torn file, and it is the trade the launchd family already makes.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport { sha256Hex } from '../launchd/job-form.ts';\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\nimport { removeRegion } from './region.ts';\nimport {\n DEFAULT_MODE,\n type RemoteFileAttributes,\n type RemoteFileProps,\n} from './remote-file-form.ts';\nimport {\n decoder,\n digestOf,\n encoder,\n identity,\n ownedDigest,\n planWrite,\n readFileAttributes,\n refuse,\n} from './remote-file-plan.ts';\n\nexport { readFileAttributes } from './remote-file-plan.ts';\n\n/**\n * ★ A PLAN THAT WILL WRITE ASKS THE RUNNER FIRST (`checkWrite`, when it has one), so a runner's own\n * refusals fail the plan instead of arriving halfway through the apply.\n */\nexport const diffFile = async (\n runner: HostRunner,\n news: RemoteFileProps,\n output: RemoteFileAttributes,\n): Promise<Diff> => {\n const want = await identity(runner, news);\n if (news
|
|
21
|
+
"/**\n * What RemoteFile would write, worked out from what is on the host right now — the half of the\n * lifecycle that reads and decides, with no write in it.\n *\n * ⛔ IN REGION MODE THE LIVE FILE IS AN INPUT, not merely something to compare against: the declared\n * block is spliced into the bytes that are there, so every surrounding line survives verbatim.\n * That is why this cannot be a pure function of the props the way a whole-file render is.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\nimport type { FileStat, HostRunner, WriteOptions } from '../launchd/runner.ts';\nimport { type RegionSpec, readRegion, sameRegion, spliceRegion } from './region.ts';\nimport {\n DEFAULT_MODE,\n type RemoteFileAttributes,\n type RemoteFileProps,\n fileProblems,\n} from './remote-file-form.ts';\n\nexport const decoder = new TextDecoder();\nexport const encoder = new TextEncoder();\n\nexport const refuse = (path: string, message: string): Error =>\n new Error(`Remote.File ${path}: ${message}`);\n\nconst numericId = (value: string | number): number | undefined =>\n typeof value === 'number' ? value : /^\\d+$/.test(value) ? Number(value) : undefined;\n\nexport type Identity = { readonly uid?: number; readonly gid?: number };\n\n/** Validate, then resolve owner and group names to ids through the runner. */\nexport const identity = async (runner: HostRunner, props: RemoteFileProps): Promise<Identity> => {\n const found = fileProblems(props);\n if (found.length > 0) throw refuse(props.path, found.join('; '));\n let uid: number | undefined;\n let gid: number | undefined;\n if (props.owner !== undefined) {\n uid = numericId(props.owner) ?? (await runner.lookupUser(String(props.owner)))?.uid;\n if (uid === undefined) throw refuse(props.path, `no user ${String(props.owner)} on this host`);\n }\n if (props.group !== undefined) {\n gid = numericId(props.group) ?? (await runner.lookupGroup(String(props.group)));\n if (gid === undefined) throw refuse(props.path, `no group ${String(props.group)} on this host`);\n }\n return { ...(uid === undefined ? {} : { uid }), ...(gid === undefined ? {} : { gid }) };\n};\n\nexport const digestOf = (text: string): string => sha256Hex(encoder.encode(text));\n\n/** What this declaration now owns, compared with what the last deploy owned. */\nexport type Move = 'none' | 'path' | 'region';\n\n/**\n * Has the thing this resource owns MOVED since the last deploy — and if so, how?\n *\n * 🔴 WHY THIS EXISTS (found by review, reproduced against the fake host, 2026-09-22). Without it,\n * only `path` was identity and both of these read as a routine `update`:\n * - RENAMING THE REGION left the old block in the file FOREVER. The new markers were spliced in,\n * the old ones were never touched, and `delete` — which can only look for the name in state,\n * now the new one — could never remove them. Two `anchor` lines in a packet filter, two\n * entries in a host table, and nothing in the stack able to take either back.\n * - DROPPING `region` TOOK OVER THE WHOLE FILE. The plan said `update`; the apply replaced every\n * byte of a file belonging to a vendor package with this resource's four lines. That is the\n * one thing the managed-region design exists to make impossible.\n * ⛔ A FLIP BETWEEN THE TWO MODES IS A REFUSAL, NOT A MOVE. Neither order is safe: writing the\n * whole file first destroys the other owner's bytes before anything can be undone, and removing\n * the block first destroys our own claim and then refuses. The operator destroys the resource\n * and declares a new one, which is the only sequence with a reviewable diff at each step.\n * ★ A region-to-region rename IS safe as a move, because both blocks can exist at once: write the\n * new one, verify it, then take the old one out (remote-file-lifecycle.ts reconcileFile).\n */\nexport const relocation = (props: RemoteFileProps, output: RemoteFileAttributes): Move => {\n if (props.path !== output.path) return 'path';\n if (sameRegion(props.region, output.region)) return 'none';\n if (props.region === undefined || output.region === undefined) {\n throw refuse(\n props.path,\n `changes between owning the whole file and owning the managed region ` +\n `${JSON.stringify((props.region ?? output.region)?.name ?? '')} at the same path. Those ` +\n 'are two different claims on one file: destroy this resource and declare a new one.',\n );\n }\n return 'region';\n};\n\n/** The digest of the part this resource owns, or `undefined` when that part is not there. */\nexport const ownedDigest = (\n file: string | undefined,\n region: RegionSpec | undefined,\n): string | undefined => {\n if (file === undefined) return undefined;\n if (region === undefined) return digestOf(file);\n const body = readRegion(file, region);\n return body === undefined ? undefined : digestOf(body);\n};\n\n/** The file as it is now, plus the digest of the part this resource owns. */\nexport const readFileAttributes = async (\n runner: HostRunner,\n path: string,\n region: RegionSpec | undefined,\n): Promise<RemoteFileAttributes | undefined> => {\n const stat = await runner.stat(path);\n if (stat === undefined) return undefined;\n const bytes = stat.kind === 'file' ? await runner.readFile(path) : undefined;\n const text = bytes === undefined ? undefined : decoder.decode(bytes);\n return {\n contentSha256: ownedDigest(text, region) ?? '',\n gid: stat.gid,\n mode: stat.mode,\n path,\n ...(region === undefined ? {} : { region }),\n sha256: bytes === undefined ? '' : sha256Hex(bytes),\n size: stat.size,\n uid: stat.uid,\n };\n};\n\nconst matches = (stat: FileStat | undefined, write: WriteOptions): boolean =>\n stat !== undefined &&\n stat.mode === write.mode &&\n (write.uid === undefined || stat.uid === write.uid) &&\n (write.gid === undefined || stat.gid === write.gid);\n\nexport type Plan = {\n /** The whole file's new bytes, in both modes. */\n readonly bytes: Uint8Array;\n readonly write: WriteOptions;\n /** The bytes on disk right now, or `undefined` when nothing is there. */\n readonly before: string | undefined;\n /** Nothing to do: the file already says what we declare, with the mode and owner we declare. */\n readonly converged: boolean;\n};\n\n/**\n * ⛔ A SYMLINK OR A DIRECTORY IS REFUSED, NOT REPLACED. The write is a rename(2), which over a\n * symlink replaces the LINK — quietly taking the path from whatever put it there (a config\n * manager's `/etc` entries are symlinks, and so is `/etc/resolv.conf` on most Linux hosts).\n */\nexport const planWrite = async (\n runner: HostRunner,\n props: RemoteFileProps,\n want: Identity,\n): Promise<Plan> => {\n const stat = await runner.stat(props.path);\n if (stat !== undefined && stat.kind !== 'file') {\n throw refuse(\n props.path,\n `is a ${stat.kind}; remove it from whatever owns it before declaring it here`,\n );\n }\n const current = stat === undefined ? undefined : await runner.readFile(props.path);\n const before = current === undefined ? undefined : decoder.decode(current);\n const declaredMode = props.mode ?? DEFAULT_MODE;\n if (props.region === undefined) {\n const write: WriteOptions = { mode: declaredMode, ...want };\n return {\n before,\n bytes: encoder.encode(props.content),\n converged: before === props.content && matches(stat, write),\n write,\n };\n }\n if (before === undefined) {\n if (props.create !== true) {\n throw refuse(\n props.path,\n 'does not exist, and a managed region does not create the file it lives in. Check the ' +\n 'path, declare the file itself, or pass create: true.',\n );\n }\n return {\n before,\n bytes: encoder.encode(spliceRegion('', props.region, props.content)),\n converged: false,\n write: { mode: declaredMode, ...want },\n };\n }\n const next = spliceRegion(before, props.region, props.content);\n /**\n * ⛔ THE FILE'S OWN MODE AND OWNER ARE COPIED BACK, never re-declared. We borrowed a block; the\n * rename would otherwise hand a file someone else owns a mode and an owner this stack chose,\n * which is a second claim nobody made.\n */\n return {\n before,\n bytes: encoder.encode(next),\n converged: next === before,\n write: { gid: stat?.gid ?? 0, mode: stat?.mode ?? declaredMode, uid: stat?.uid ?? 0 },\n };\n};\n",
|
|
22
|
+
"/**\n * RemoteFile's diff / reconcile / delete over a HostRunner, so the whole lifecycle runs against a\n * fake host in tests with no ssh and no real write. What it would write is worked out next door\n * (remote-file-plan.ts); this file is the part that decides to act.\n *\n * ⛔ IN REGION MODE, DRIFT MEANS THE REGION AND NOTHING ELSE. Every byte outside the markers belongs\n * to another owner, so a change there must never plan an update — otherwise the two owners fight\n * on every deploy and this resource loses the right to be in that file at all.\n * ⚠️ THE WRITE REPLACES THE INODE, in both modes. A process holding the old file keeps reading it\n * until it reopens, and a hard link to the path stops tracking. That is the price of never\n * leaving a torn file, and it is the trade the launchd family already makes.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport { sha256Hex } from '../launchd/job-form.ts';\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\nimport { removeRegion } from './region.ts';\nimport {\n DEFAULT_MODE,\n type RemoteFileAttributes,\n type RemoteFileProps,\n} from './remote-file-form.ts';\nimport {\n decoder,\n digestOf,\n encoder,\n identity,\n ownedDigest,\n planWrite,\n readFileAttributes,\n refuse,\n relocation,\n} from './remote-file-plan.ts';\n\nexport { readFileAttributes } from './remote-file-plan.ts';\n\n/**\n * ★ A PLAN THAT WILL WRITE ASKS THE RUNNER FIRST (`checkWrite`, when it has one), so a runner's own\n * refusals fail the plan instead of arriving halfway through the apply.\n */\nexport const diffFile = async (\n runner: HostRunner,\n news: RemoteFileProps,\n output: RemoteFileAttributes,\n): Promise<Diff> => {\n const want = await identity(runner, news);\n // ⛔ A mode flip throws HERE, at plan time, before anything is written (remote-file-plan.ts).\n if (relocation(news, output) === 'path') {\n // ★ Create-before-delete: two paths hold two files at once, so nothing forces deleteFirst.\n await runner.checkWrite?.(news.path, { mode: news.mode ?? DEFAULT_MODE, ...want });\n return { action: 'replace' };\n }\n const planned = await planWrite(runner, news, want);\n // ⛔ BOTH digests: the live one catches a hand edit, the STORED one catches a write that landed\n // and whose deploy then died before committing. Either alone reports `noop` over a wrong file.\n if (planned.converged && output.contentSha256 === digestOf(news.content)) {\n return { action: 'noop' };\n }\n await runner.checkWrite?.(news.path, planned.write);\n return { action: 'update' };\n};\n\n/**\n * `adopt` is whether adoption is on AND this apply is a create or an unfinished generation of our\n * own (ownership/adopt.ts). It lets such a generation take over what is already at the path — the\n * takeover the plan's probe would have allowed, had it run.\n * ★ IN REGION MODE THE FILE BEING THERE IS NOT A TAKEOVER: it belongs to someone else by\n * definition. What this resource claims is the block, so only a block already present with other\n * content is the thing adoption is asked about.\n */\nexport const reconcileFile = async (\n runner: HostRunner,\n props: RemoteFileProps,\n output?: RemoteFileAttributes,\n adopt = false,\n): Promise<RemoteFileAttributes> => {\n const want = await identity(runner, props);\n // ⛔ NO SILENT SUDO: handing a file to another user is root's call (chown(2)), so say so up front.\n if (want.uid !== undefined && want.uid !== runner.effectiveUid() && !canActAsRoot(runner)) {\n throw refuse(\n props.path,\n `owner ${String(props.owner)} is not the deploying user; only root may chown. Deploy through ` +\n 'a root destination or a privileged HostRunner. This provider never calls sudo itself.',\n );\n }\n /**\n * ⛔ WHAT WE OWNED LAST TIME MAY NOT BE WHAT WE OWN NOW. A new path, or a new region name or\n * comment token, means the old block or file is still out there and must be taken back — and\n * a flip between the two modes is refused outright (remote-file-plan.ts relocation).\n */\n const move = output === undefined ? 'none' : relocation(props, output);\n const prior = move === 'none' ? output : undefined;\n const planned = await planWrite(runner, props, want);\n const live = ownedDigest(planned.before, props.region);\n const declared = digestOf(props.content);\n /**\n * ⛔ SOMETHING WE DO NOT OWN IS NEVER OVERWRITTEN. With no prior state the engine's probe has\n * already refused whatever it found — except where it never looked: a replace's new path, and a\n * create whose props still held an Output at plan time. A path typo there would otherwise\n * overwrite a system file. ★ With adoption on, a create takes it over, as the probe would have.\n */\n if (\n prior === undefined &&\n live !== undefined &&\n live !== declared &&\n !(adopt && output === undefined)\n ) {\n throw refuse(\n props.path,\n `${props.region === undefined ? 'already exists' : 'already carries that managed region'}` +\n ' and is not this resource. Remove it, or declare it as a new resource and deploy --adopt.',\n );\n }\n if (!planned.converged) await runner.writeFileAtomic(props.path, planned.bytes, planned.write);\n /**\n * ⚠️ READ BACK, never echo the declaration: a umask, an ACL or a runner that ignored `uid` shows\n * up here as a refusal instead of as a forever-`update`.\n */\n const after = await readFileAttributes(runner, props.path, props.region);\n if (\n after === undefined ||\n after.sha256 !== sha256Hex(planned.bytes) ||\n after.contentSha256 !== declared\n ) {\n /**\n * ⚠️ Roll back a CREATE only: left behind, the next plan's recovery read finds a file with no\n * state, reports it Unowned, and every later deploy demands --adopt for our own file.\n * ⛔ NEVER IN REGION MODE — the file was someone else's before this deploy and must survive it.\n */\n if (planned.before === undefined && props.region === undefined) {\n await runner.removeFile(props.path).catch(() => undefined);\n }\n throw refuse(\n props.path,\n 'the write returned but the file on disk does not match the declaration',\n );\n }\n // ★ Create-before-delete, as the replace would have been: the old path — or, for a rename inside\n // one file, the old block — goes once the new one is written and verified.\n if (move === 'none' || output === undefined) return after;\n await deleteFile(runner, output);\n if (move === 'path') return after;\n /**\n * ⛔ A REGION RENAME TOOK THE OLD BLOCK OUT OF THIS SAME FILE, so `after` — read before that\n * removal — describes bytes that no longer exist. Storing it would make the whole-file digest\n * wrong from the moment it was written and every later plan would read it as drift.\n */\n const settled = await readFileAttributes(runner, props.path, props.region);\n if (settled === undefined || settled.contentSha256 !== declared) {\n throw refuse(props.path, 'removing the previous managed block did not leave ours intact');\n }\n return settled;\n};\n\n/**\n * Whole-file mode removes the file. ⛔ REGION MODE REMOVES ONLY THE BLOCK, leaving every other byte\n * identical — removing the file would delete another owner's configuration. Idempotent both ways.\n */\nexport const deleteFile = async (\n runner: HostRunner,\n output: RemoteFileAttributes,\n): Promise<void> => {\n const stat = await runner.stat(output.path);\n if (stat === undefined) return;\n if (stat.kind !== 'file') throw refuse(output.path, `is now a ${stat.kind}; not touching it`);\n if (output.region === undefined) {\n await runner.removeFile(output.path);\n return;\n }\n const bytes = await runner.readFile(output.path);\n if (bytes === undefined) return;\n const before = decoder.decode(bytes);\n const next = removeRegion(before, output.region);\n if (next === before) return;\n await runner.writeFileAtomic(output.path, encoder.encode(next), {\n gid: stat.gid,\n mode: stat.mode,\n uid: stat.uid,\n });\n};\n",
|
|
23
23
|
"/**\n * `Systemd.Unit` and `Systemd.Timer` — one systemd unit file and systemd's view of it, declared.\n *\n * - create / update — write the unit file atomically, `daemon-reload`, enable or disable, then\n * start, stop, or RESTART ONLY when something actually changed (unit-lifecycle.ts settle).\n * - read — the unit file's SHA-256 plus `systemctl show` (load state, active state, enablement).\n * - diff — the rendered digest against the stored AND the on-disk one, the declared enablement and\n * running state against systemd's, and systemd's own `NeedDaemonReload`.\n * - replace — only when the unit's name or directory changes, and DELETE FIRST: two unit files for\n * one name cannot both be the one systemd reads.\n * - delete — stop, disable, remove the file, reload.\n *\n * ⛔ A DEPLOY NEVER MASS-RESTARTS — see the ⛔ at the top of unit-lifecycle.ts. It is the property\n * that lets this family reach a host holding a vault, a clock or a UPS handler.\n * ⛔ THE UNIT FILE IS NEVER A SECRET (unit-form.ts): it is 0644 and its props sit in state.\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt`. A unit already on the host reads as `Unowned`; adopting\n * one that already matches the declaration does not restart it.\n * ★ TWO RESOURCES, ONE LIFECYCLE. A timer is a unit whose file ends `.timer` and carries a\n * `[Timer]` section; splitting the TYPE rather than the code means a plan says which of the two\n * a row is, and a `.service` declared as a timer is a refusal instead of a puzzle.\n */\nimport { Resource } from 'alchemy';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport type { SystemdUnitAttributes, SystemdUnitProps } from './unit-form.ts';\nimport { deleteHandler, diffHandler, readHandler, reconcileHandler } from './unit-handlers.ts';\n\nexport type { SystemdUnitAttributes, SystemdUnitProps, UnitSection } from './unit-form.ts';\n\nexport interface SystemdUnit extends Resource<\n 'Systemd.Unit',\n SystemdUnitProps,\n SystemdUnitAttributes\n> {}\n\nexport interface SystemdTimer extends Resource<\n 'Systemd.Timer',\n SystemdUnitProps,\n SystemdUnitAttributes\n> {}\n\nexport const SystemdUnit = Resource<SystemdUnit>('Systemd.Unit');\nexport const SystemdTimer = Resource<SystemdTimer>('Systemd.Timer');\n\nexport const SystemdUnitProvider = () =>\n Provider.effect(\n SystemdUnit,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return SystemdUnit.Provider.of({\n /**\n * ⛔ systemd's unit list is not a list of things this stack owns — it is every vendor,\n * package and hand-written unit on the host. Returning them would invite a nuke to stop\n * services nothing here declared.\n */\n list: () => Effect.succeed([]),\n read: ({ olds, output }) => readHandler(runner, olds, output),\n diff: ({ instanceId, news, output }) => diffHandler(runner, instanceId, news, output),\n reconcile: (args) => reconcileHandler(runner, args),\n delete: ({ output }) => deleteHandler(runner, output),\n });\n }),\n );\n\nexport const SystemdTimerProvider = () =>\n Provider.effect(\n SystemdTimer,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return SystemdTimer.Provider.of({\n list: () => Effect.succeed([]),\n read: ({ olds, output }) => readHandler(runner, olds, output),\n // ★ `'timer'` is the whole difference: the same lifecycle, refusing a name that is not one.\n diff: ({ instanceId, news, output }) =>\n diffHandler(runner, instanceId, news, output, 'timer'),\n reconcile: (args) => reconcileHandler(runner, args, 'timer'),\n delete: ({ output }) => deleteHandler(runner, output),\n });\n }),\n );\n",
|
|
24
|
-
"/**\n * The four provider handlers `Systemd.Unit` and `Systemd.Timer` share, as plain functions over a\n * HostRunner — so the two Resources differ only in their TYPE and the unit suffix they insist on.\n *\n * ★ WHY NOT ONE SHARED HANDLER OBJECT. `Provider.of` is typed per Resource, so an object built once\n * and passed to both would have to be widened or cast; functions with their arguments spelled out\n * keep both call sites fully checked and still say each rule once.\n */\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport type { Diff } from 'alchemy/Diff';\nimport { isResolved } from 'alchemy/Diff';\nimport type { Input } from 'alchemy/Input';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport type { HostRunner } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { SystemdUnitAttributes, SystemdUnitProps } from './unit-form.ts';\nimport { deleteUnit, diffUnit, readUnit, reconcileUnit } from './unit-lifecycle.ts';\n\nexport const readHandler = (\n runner: HostRunner,\n olds: SystemdUnitProps,\n output: SystemdUnitAttributes | undefined,\n): Effect.Effect<SystemdUnitAttributes | undefined, Error> =>\n lift(async () => {\n const found = await readUnit(runner, olds);\n if (found === undefined) return undefined;\n return output === undefined ? Unowned(found) : found;\n });\n\nexport const diffHandler = (\n runner: HostRunner,\n instanceId: string,\n news: Input<SystemdUnitProps>,\n output: SystemdUnitAttributes | undefined,\n expect?: string,\n): Effect.Effect<Diff | undefined, Error> => {\n // ★ An unfinished generation of our own: `--adopt` may resume it (ownership/resume.ts).\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffUnit(runner, news, output, expect));\n /**\n * ⛔ A RENAME MUST BE SEEN EVEN WHILE OTHER PROPS ARE UNRESOLVED. The engine's default for a prop\n * change is `update`, and an update under a new name writes the new unit file and leaves the old\n * unit running with nothing in state to ever remove it. `content` is exactly what is unresolved\n * when a rendered config file's digest is templated into the same deploy.\n */\n const name = resolvedString(news, 'name');\n return Effect.succeed(\n
|
|
25
|
-
"/**\n * Systemd.Unit / Systemd.Timer props, attributes, the unit-file renderer and the validation — the\n * pure half of the family.\n *\n * ⛔ THE DIRECTIVE SET IS SYSTEMD'S, NOT THIS FILE'S. There is no machine-readable schema of\n * `systemd.unit(5)` / `systemd.service(5)` directives to generate from, so this renders SECTIONS\n * AND LINES VERBATIM and claims to know nothing about what the keys mean. What it validates is\n * only what an INI file must be true of — a section name, a key shape, no embedded newline —\n * plus the two structural rules systemd's own output proves (see `unitProblems`). ★ That is the\n * honest boundary: invent no vendor shapes, and let `systemd-analyze verify` be the deep check a\n * host stack runs on the host.\n * ⛔ `content` IS NEVER A SECRET. Props sit unencrypted in Alchemy state and the unit file is\n * world-readable at 0644; a unit that needs a secret takes `EnvironmentFile=` pointing at a file\n * a secret renderer maintains.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\n\nexport type UnitSection = {\n /** `Unit`, `Service`, `Timer`, `Install`, … — verbatim, including its capitalisation. */\n readonly name: string;\n /**\n * The section's lines, in order. A repeated key is allowed and meaningful in systemd\n * (`ExecStartPre=` twice runs twice), so this is a list of pairs, never an object.\n */\n readonly lines: readonly (readonly [key: string, value: string])[];\n};\n\nexport type SystemdUnitProps = {\n /** Unit name WITH its suffix, e.g. `thing.service`. The unit file's name on disk. */\n name: string;\n /** The whole unit file, verbatim. Mutually exclusive with `sections`. */\n content?: string;\n /** The unit file as sections, rendered in the order given. Mutually exclusive with `content`. */\n sections?: readonly UnitSection[];\n /** Directory the unit file goes in. @default '/etc/systemd/system' */\n directory?: string;\n /** `systemctl enable` / `disable`. @default true */\n enabled?: boolean;\n /** `systemctl start` / `stop`. @default true */\n started?: boolean;\n /**\n * Digests of things this unit READS that live outside its unit file — a rendered config file's\n * `sha256` attribute, most often. A change here restarts the unit; nothing else does.\n * ⚠️ A hand edit of that file is NOT noticed: the digest in state still matches what the stack\n * declared, so the unit reads converged. That limit is the same one the Mac side records.\n */\n restartOn?: readonly string[];\n};\n\nexport type SystemdUnitAttributes = {\n name: string;\n unitPath: string;\n /** SHA-256 of the unit file this resource wrote. */\n unitSha256: string;\n /** SHA-256 of `restartOn`, so a config change is a diff. */\n configSha256: string;\n loadState: string;\n activeState: string;\n unitFileState?: string;\n enabled: boolean;\n active: boolean;\n};\n\n/** ★ systemd's admin drop-in directory, ahead of the vendor's in its search order (measured). */\nexport const DEFAULT_UNIT_DIRECTORY = '/etc/systemd/system';\n\n/**\n * Directories systemd looks in for a unit file it can enable.\n * ★ MEASURED 2026-09-22 with `systemd-analyze unit-paths` on Debian 13 / systemd 257, minus the\n * per-user and generator directories, which are not places a stack writes. `/lib/systemd/system`\n * is the same directory before the /usr merge, where the measured host has only the merged name.\n * ⛔ WHY IT IS ENFORCED. `systemctl enable <name>` looks the unit up BY NAME; a unit file outside\n * these directories is invisible to that lookup, so an enabled unit declared into, say, `/opt`\n * writes its file, reloads, and then fails at `enable` with the file already on disk.\n */\nexport const UNIT_SEARCH_DIRECTORIES = [\n '/etc/systemd/system',\n '/run/systemd/system',\n '/usr/local/lib/systemd/system',\n '/usr/lib/systemd/system',\n '/lib/systemd/system',\n] as const;\n\n/** ⛔ The unit file's mode and owner are systemd's rule, not a choice: readable, never writable. */\nexport const UNIT_WRITE = { gid: 0, mode: 0o644, uid: 0 } as const;\n\nexport const digestOf = (text: string): string => sha256Hex(new TextEncoder().encode(text));\n\n/** The digests of everything outside the unit file that should restart it, as one value. */\nexport const configDigest = (restartOn: readonly string[] | undefined): string =>\n digestOf((restartOn ?? []).join('\\n'));\n\n/** Sections → an INI unit file. ★ Keys and values pass through untouched; see the file header. */\nexport const renderUnit = (sections: readonly UnitSection[]): string =>\n `${sections\n .map((section) =>\n [`[${section.name}]`, ...section.lines.map(([key, value]) => `${key}=${value}`)].join('\\n'),\n )\n .join('\\n\\n')}\\n`;\n\nexport const unitText = (props: SystemdUnitProps): string =>\n props.content ?? renderUnit(props.sections ?? []);\n\nexport const unitPathFor = (props: SystemdUnitProps): string =>\n `${props.directory ?? DEFAULT_UNIT_DIRECTORY}/${props.name}`;\n\nconst NAME = /^[A-Za-z0-9][A-Za-z0-9_.@:-]*\\.([a-z]+)$/;\n/** systemd's own unit types. ★ Fixed vocabulary from `systemd.unit(5)`, not a guess at directives. */\nconst TYPES = new Set([\n 'automount',\n 'device',\n 'mount',\n 'path',\n 'scope',\n 'service',\n 'slice',\n 'socket',\n 'swap',\n 'target',\n 'timer',\n]);\n\nconst INSTALL_KEYS = new Set(['WantedBy', 'RequiredBy', 'UpsertedBy', 'Also', 'Alias']);\n\n/**\n * Every refusal at once, so one plan shows the whole list.\n * ⛔ THE TWO STRUCTURAL RULES, both proven by systemd's own output rather than assumed:\n * - `enabled: true` needs an `[Install]` section. `systemctl enable` has nothing to link without\n * one, and systemd's name for a unit file that has none is `UnitFileState=static` — measured on\n * a live host, where the journal daemon reads `static` and the ssh daemon reads `enabled`.\n * - A `.timer` needs a `[Timer]` section, and a timer's `[Install]` is what arms it at boot.\n */\nexport const unitProblems = (props: SystemdUnitProps, expect?: string): string[] => {\n const found: string[] = [];\n const type = NAME.exec(props.name)?.[1];\n if (type === undefined || !TYPES.has(type)) {\n found.push(\n `name must be <unit>.<type> with a systemd unit type, got ${JSON.stringify(props.name)}`,\n );\n } else if (expect !== undefined && type !== expect) {\n found.push(`this resource declares a .${expect} unit; ${props.name} is a .${type}`);\n }\n if ((props.content === undefined) === (props.sections === undefined)) {\n found.push('declare exactly one of content or sections');\n }\n const directory = props.directory ?? DEFAULT_UNIT_DIRECTORY;\n if (!directory.startsWith('/') || directory.endsWith('/') || directory.includes('/..')) {\n found.push('directory must be an absolute, normalised path with no trailing slash');\n }\n found.push(...textProblems(unitText(props)));\n if (props.enabled !== false && !UNIT_SEARCH_DIRECTORIES.includes(directory as never)) {\n found.push(\n `an enabled unit must live where systemd looks for it by name (${UNIT_SEARCH_DIRECTORIES.join(', ')}); ` +\n `${directory} is not one of them. Move it, or declare enabled: false.`,\n );\n }\n if (props.enabled !== false && !hasInstall(props)) {\n found.push(\n 'enabled units need an [Install] section with WantedBy/RequiredBy/Also/Alias; without one ' +\n 'systemd calls the unit \"static\" and `systemctl enable` has nothing to link. Add one, or ' +\n 'declare enabled: false and let something else pull it in.',\n );\n }\n if (type === 'timer' && !unitText(props).includes('[Timer]')) {\n found.push('a .timer needs a [Timer] section');\n }\n return found;\n};\n\nconst hasInstall = (props: SystemdUnitProps): boolean => {\n const text = unitText(props);\n if (!text.includes('[Install]')) return false;\n const after = text.slice(text.indexOf('[Install]'));\n return [...INSTALL_KEYS].some((key) => new RegExp(`^${key}=`, 'm').test(after));\n};\n\nconst textProblems = (text: string): string[] => {\n const found: string[] = [];\n if (text.trim() === '') found.push('the unit file is empty');\n if (text.includes('\\u0000')) found.push('the unit file contains NUL');\n if (!/^\\s*\\[[A-Za-z]+]/.test(text)) found.push('a unit file must begin with a [Section]');\n return found;\n};\n",
|
|
24
|
+
"/**\n * The four provider handlers `Systemd.Unit` and `Systemd.Timer` share, as plain functions over a\n * HostRunner — so the two Resources differ only in their TYPE and the unit suffix they insist on.\n *\n * ★ WHY NOT ONE SHARED HANDLER OBJECT. `Provider.of` is typed per Resource, so an object built once\n * and passed to both would have to be widened or cast; functions with their arguments spelled out\n * keep both call sites fully checked and still say each rule once.\n */\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport type { Diff } from 'alchemy/Diff';\nimport { isResolved } from 'alchemy/Diff';\nimport type { Input } from 'alchemy/Input';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport type { HostRunner } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { SystemdUnitAttributes, SystemdUnitProps } from './unit-form.ts';\nimport { deleteUnit, diffUnit, readUnit, reconcileUnit } from './unit-lifecycle.ts';\nimport { assertRenameTarget } from './unit-preflight.ts';\n\nexport const readHandler = (\n runner: HostRunner,\n olds: SystemdUnitProps,\n output: SystemdUnitAttributes | undefined,\n): Effect.Effect<SystemdUnitAttributes | undefined, Error> =>\n lift(async () => {\n const found = await readUnit(runner, olds);\n if (found === undefined) return undefined;\n return output === undefined ? Unowned(found) : found;\n });\n\nexport const diffHandler = (\n runner: HostRunner,\n instanceId: string,\n news: Input<SystemdUnitProps>,\n output: SystemdUnitAttributes | undefined,\n expect?: string,\n): Effect.Effect<Diff | undefined, Error> => {\n // ★ An unfinished generation of our own: `--adopt` may resume it (ownership/resume.ts).\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffUnit(runner, news, output, expect));\n /**\n * ⛔ A RENAME MUST BE SEEN EVEN WHILE OTHER PROPS ARE UNRESOLVED. The engine's default for a prop\n * change is `update`, and an update under a new name writes the new unit file and leaves the old\n * unit running with nothing in state to ever remove it. `content` is exactly what is unresolved\n * when a rendered config file's digest is templated into the same deploy.\n */\n const name = resolvedString(news, 'name');\n if (name === undefined || name === output.name) return Effect.succeed(undefined);\n /**\n * ⛔ THE NAME IS ENOUGH TO REFUSE A MASKED TARGET, and the refusal has to happen here: the old\n * unit is removed before the new one is reconciled. The unit file cannot be compared while\n * `content` is still an Output, so this is the name-only half of assertReplaceable\n * (unit-preflight.ts).\n */\n return lift(async () => {\n await assertRenameTarget(runner, output, name);\n return { action: 'replace' as const, deleteFirst: true };\n });\n};\n\nexport const reconcileHandler = (\n runner: HostRunner,\n args: {\n fqn: string;\n instanceId: string;\n news: SystemdUnitProps;\n output: SystemdUnitAttributes | undefined;\n },\n expect?: string,\n): Effect.Effect<SystemdUnitAttributes, Error> =>\n Effect.flatMap(adoptsAtApply(args), (adopt) =>\n lift(() => reconcileUnit(runner, args.news, args.output, adopt, expect)),\n );\n\nexport const deleteHandler = (\n runner: HostRunner,\n output: SystemdUnitAttributes,\n): Effect.Effect<void, Error> => lift(() => deleteUnit(runner, output));\n",
|
|
26
25
|
"/**\n * The `systemctl` subcommands the systemd family uses, over a HostRunner, plus the parser for the\n * one that returns data.\n *\n * ★ MEASURED 2026-09-22 on Debian 13, systemd 257 (257.13-1~deb13u1), read-only — nothing was\n * enabled, started or reloaded to write this:\n *\n * - `systemctl show -p <list> <unit>` EXITS 0 FOR A UNIT THAT DOES NOT EXIST, and answers with\n * the properties it would have had:\n * Id=hf-nonexistent-xyz.service LoadState=not-found\n * ActiveState=inactive SubState=dead\n * FragmentPath= UnitFileState=\n * ⛔ SO THE EXIT CODE IS NOT THE ANSWER — `LoadState` is. A provider that read exit 0 as \"the\n * unit is there\" would adopt a unit that does not exist and then never write its file.\n * - The properties come back in systemd's own order, not the order asked for, so the output is a\n * map and never positional.\n * - `systemctl is-enabled <unknown>` exits **4** and prints `not-found`; `is-active <unknown>`\n * exits **4** and prints `inactive`. Both are answers, not errors.\n * - `UnitFileState=static` is exactly systemd's name for a unit file with no `[Install]` section\n * (measured: the journal daemon is `static`, the ssh daemon is `enabled`).\n * - `/etc/systemd/system` is `root:root 0755` — the admin drop-in directory, ahead of the\n * vendor's `/usr/lib/systemd/system` in systemd's own search order.\n * ⚠️ REASONED, NOT MEASURED: the write subcommands. `daemon-reload`, `enable`, `disable`, `start`,\n * `stop` and `restart` were never run for this file, because running them would change a live\n * host. Each is therefore checked the same way: exit 0 or an Error carrying systemd's stderr, and\n * the state is read back with `show` afterwards rather than assumed.\n * ⛔ NEVER PUT `show` STDOUT WITH NO PROPERTY FILTER IN AN ERROR: the unfiltered property set\n * carries the unit's whole environment block.\n */\nimport type { HostRunner } from '../launchd/runner.ts';\n\nexport const SYSTEMCTL = 'systemctl';\n\n/** The properties every read asks for. ⛔ Never `Environment` — see the header. */\nexport const SHOW_PROPERTIES = [\n 'Id',\n 'LoadState',\n 'ActiveState',\n 'SubState',\n 'UnitFileState',\n 'FragmentPath',\n 'NeedDaemonReload',\n] as const;\n\nexport class SystemctlError extends Error {\n constructor(command: string, exitCode: number, stderr: string) {\n super(`systemctl ${command} -> ${String(exitCode)}: ${stderr.trim().slice(0, 300)}`);\n this.name = 'SystemctlError';\n }\n}\n\nexport type UnitStatus = {\n /** `loaded`, `not-found`, `masked`, `error`, `bad-setting`. ⛔ The authority on existence. */\n readonly loadState: string;\n /** systemd knows this unit: it has a unit file or is loaded. */\n readonly known: boolean;\n readonly activeState: string;\n readonly subState?: string;\n /** `enabled`, `disabled`, `static`, `masked`, … Empty for a unit with no unit file. */\n readonly unitFileState?: string;\n /** The unit file systemd would read. Empty when there is none. */\n readonly fragmentPath?: string;\n /** systemd's own view that its on-disk unit files are newer than what it has loaded. */\n readonly needDaemonReload: boolean;\n};\n\n/** `key=value` lines into a map. ⚠️ First wins: systemd never repeats a key, a truncated read might. */\nexport const parseShow = (stdout: string): Map<string, string> => {\n const fields = new Map<string, string>();\n for (const line of stdout.split('\\n')) {\n const at = line.indexOf('=');\n if (at <= 0) continue;\n const key = line.slice(0, at);\n if (!fields.has(key)) fields.set(key, line.slice(at + 1));\n }\n return fields;\n};\n\nexport const statusOf = (stdout: string): UnitStatus => {\n const fields = parseShow(stdout);\n const loadState = fields.get('LoadState') ?? 'not-found';\n const unitFileState = fields.get('UnitFileState') ?? '';\n const fragmentPath = fields.get('FragmentPath') ?? '';\n const subState = fields.get('SubState') ?? '';\n return {\n activeState: fields.get('ActiveState') ?? 'inactive',\n // ⛔ MEASURED: `show` answers for a unit that does not exist, so \"known\" is LoadState plus\n // whether systemd found a unit file at all — never the exit code.\n known: loadState !== 'not-found' || unitFileState !== '',\n loadState,\n needDaemonReload: fields.get('NeedDaemonReload') === 'yes',\n ...(subState === '' ? {} : { subState }),\n ...(unitFileState === '' ? {} : { unitFileState }),\n ...(fragmentPath === '' ? {} : { fragmentPath }),\n };\n};\n\nexport const showUnit = async (runner: HostRunner, name: string): Promise<UnitStatus> => {\n const result = await runner.exec([\n SYSTEMCTL,\n 'show',\n '--no-pager',\n '-p',\n SHOW_PROPERTIES.join(','),\n '--',\n name,\n ]);\n // ⚠️ A non-zero `show` means systemctl itself failed (no bus, a malformed name) — not a missing\n // unit, which exits 0. Failing closed here is what keeps a broken connection from reading as\n // \"the unit is gone\", which would make the next deploy write its file and restart it.\n if (result.exitCode !== 0)\n throw new SystemctlError(`show ${name}`, result.exitCode, result.stderr);\n return statusOf(result.stdout);\n};\n\n/** One write subcommand, checked. ⚠️ stderr only; `show` output never reaches an error. */\nconst run = async (runner: HostRunner, args: readonly string[]): Promise<void> => {\n const result = await runner.exec([SYSTEMCTL, ...args]);\n if (result.exitCode !== 0) {\n throw new SystemctlError(args.join(' '), result.exitCode, result.stderr);\n }\n};\n\n/** ⛔ After every unit-file write or removal, and before enable/start reads it. */\nexport const daemonReload = (runner: HostRunner): Promise<void> => run(runner, ['daemon-reload']);\n\nexport const enableUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['enable', '--', name]);\n\nexport const disableUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['disable', '--', name]);\n\nexport const startUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['start', '--', name]);\n\nexport const stopUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['stop', '--', name]);\n\n/**\n * ⛔ `restart`, NOT `reload-or-restart`. The reloading form asks the unit to re-read its config in\n * place when it declares `ExecReload=`, which means \"did the change take effect?\" has two\n * different answers depending on the unit — and a deploy cannot report a half-applied change.\n */\nexport const restartUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['restart', '--', name]);\n",
|
|
26
|
+
"/**\n * Systemd.Unit / Systemd.Timer props, attributes, the unit-file renderer and the validation — the\n * pure half of the family.\n *\n * ⛔ THE DIRECTIVE SET IS SYSTEMD'S, NOT THIS FILE'S. There is no machine-readable schema of\n * `systemd.unit(5)` / `systemd.service(5)` directives to generate from, so this renders SECTIONS\n * AND LINES VERBATIM and claims to know nothing about what the keys mean. What it validates is\n * only what an INI file must be true of — a section name, a key shape, no embedded newline —\n * plus the two structural rules systemd's own output proves (see `unitProblems`). ★ That is the\n * honest boundary: invent no vendor shapes, and let `systemd-analyze verify` be the deep check a\n * host stack runs on the host.\n * ⛔ `content` IS NEVER A SECRET. Props sit unencrypted in Alchemy state and the unit file is\n * world-readable at 0644; a unit that needs a secret takes `EnvironmentFile=` pointing at a file\n * a secret renderer maintains.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\n\nexport type UnitSection = {\n /** `Unit`, `Service`, `Timer`, `Install`, … — verbatim, including its capitalisation. */\n readonly name: string;\n /**\n * The section's lines, in order. A repeated key is allowed and meaningful in systemd\n * (`ExecStartPre=` twice runs twice), so this is a list of pairs, never an object.\n */\n readonly lines: readonly (readonly [key: string, value: string])[];\n};\n\nexport type SystemdUnitProps = {\n /** Unit name WITH its suffix, e.g. `thing.service`. The unit file's name on disk. */\n name: string;\n /** The whole unit file, verbatim. Mutually exclusive with `sections`. */\n content?: string;\n /** The unit file as sections, rendered in the order given. Mutually exclusive with `content`. */\n sections?: readonly UnitSection[];\n /** Directory the unit file goes in. @default '/etc/systemd/system' */\n directory?: string;\n /** `systemctl enable` / `disable`. @default true */\n enabled?: boolean;\n /** `systemctl start` / `stop`. @default true */\n started?: boolean;\n /**\n * Digests of things this unit READS that live outside its unit file — a rendered config file's\n * `sha256` attribute, most often. A change here restarts the unit; nothing else does.\n * ⚠️ A hand edit of that file is NOT noticed: the digest in state still matches what the stack\n * declared, so the unit reads converged. That limit is the same one the Mac side records.\n */\n restartOn?: readonly string[];\n};\n\nexport type SystemdUnitAttributes = {\n name: string;\n unitPath: string;\n /** SHA-256 of the unit file this resource wrote. */\n unitSha256: string;\n /** SHA-256 of `restartOn`, so a config change is a diff. */\n configSha256: string;\n loadState: string;\n activeState: string;\n unitFileState?: string;\n enabled: boolean;\n active: boolean;\n};\n\n/** ★ systemd's admin drop-in directory, ahead of the vendor's in its search order (measured). */\nexport const DEFAULT_UNIT_DIRECTORY = '/etc/systemd/system';\n\n/**\n * Directories systemd looks in for a unit file it can enable.\n * ★ MEASURED 2026-09-22 with `systemd-analyze unit-paths` on Debian 13 / systemd 257, minus the\n * per-user and generator directories, which are not places a stack writes. `/lib/systemd/system`\n * is the same directory before the /usr merge, where the measured host has only the merged name.\n * ⛔ WHY IT IS ENFORCED. `systemctl enable <name>` looks the unit up BY NAME; a unit file outside\n * these directories is invisible to that lookup, so an enabled unit declared into, say, `/opt`\n * writes its file, reloads, and then fails at `enable` with the file already on disk.\n */\nexport const UNIT_SEARCH_DIRECTORIES = [\n '/etc/systemd/system',\n '/run/systemd/system',\n '/usr/local/lib/systemd/system',\n '/usr/lib/systemd/system',\n '/lib/systemd/system',\n] as const;\n\n/** ⛔ The unit file's mode and owner are systemd's rule, not a choice: readable, never writable. */\nexport const UNIT_WRITE = { gid: 0, mode: 0o644, uid: 0 } as const;\n\nexport const digestOf = (text: string): string => sha256Hex(new TextEncoder().encode(text));\n\n/** The digests of everything outside the unit file that should restart it, as one value. */\nexport const configDigest = (restartOn: readonly string[] | undefined): string =>\n digestOf((restartOn ?? []).join('\\n'));\n\n/** Sections → an INI unit file. ★ Keys and values pass through untouched; see the file header. */\nexport const renderUnit = (sections: readonly UnitSection[]): string =>\n `${sections\n .map((section) =>\n [`[${section.name}]`, ...section.lines.map(([key, value]) => `${key}=${value}`)].join('\\n'),\n )\n .join('\\n\\n')}\\n`;\n\nexport const unitText = (props: SystemdUnitProps): string =>\n props.content ?? renderUnit(props.sections ?? []);\n\nexport const unitPathFor = (props: SystemdUnitProps): string =>\n `${props.directory ?? DEFAULT_UNIT_DIRECTORY}/${props.name}`;\n\nconst NAME = /^[A-Za-z0-9][A-Za-z0-9_.@:-]*\\.([a-z]+)$/;\n/** systemd's own unit types. ★ Fixed vocabulary from `systemd.unit(5)`, not a guess at directives. */\nconst TYPES = new Set([\n 'automount',\n 'device',\n 'mount',\n 'path',\n 'scope',\n 'service',\n 'slice',\n 'socket',\n 'swap',\n 'target',\n 'timer',\n]);\n\nconst INSTALL_KEYS = new Set(['WantedBy', 'RequiredBy', 'UpsertedBy', 'Also', 'Alias']);\n\n/**\n * Every refusal at once, so one plan shows the whole list.\n * ⛔ THE TWO STRUCTURAL RULES, both proven by systemd's own output rather than assumed:\n * - `enabled: true` needs an `[Install]` section. `systemctl enable` has nothing to link without\n * one, and systemd's name for a unit file that has none is `UnitFileState=static` — measured on\n * a live host, where the journal daemon reads `static` and the ssh daemon reads `enabled`.\n * - A `.timer` needs a `[Timer]` section, and a timer's `[Install]` is what arms it at boot.\n */\nexport const unitProblems = (props: SystemdUnitProps, expect?: string): string[] => {\n const found: string[] = [];\n const type = NAME.exec(props.name)?.[1];\n if (type === undefined || !TYPES.has(type)) {\n found.push(\n `name must be <unit>.<type> with a systemd unit type, got ${JSON.stringify(props.name)}`,\n );\n } else if (expect !== undefined && type !== expect) {\n found.push(`this resource declares a .${expect} unit; ${props.name} is a .${type}`);\n }\n if ((props.content === undefined) === (props.sections === undefined)) {\n found.push('declare exactly one of content or sections');\n }\n const directory = props.directory ?? DEFAULT_UNIT_DIRECTORY;\n if (!directory.startsWith('/') || directory.endsWith('/') || directory.includes('/..')) {\n found.push('directory must be an absolute, normalised path with no trailing slash');\n }\n found.push(...textProblems(unitText(props)));\n if (props.enabled !== false && !UNIT_SEARCH_DIRECTORIES.includes(directory as never)) {\n found.push(\n `an enabled unit must live where systemd looks for it by name (${UNIT_SEARCH_DIRECTORIES.join(', ')}); ` +\n `${directory} is not one of them. Move it, or declare enabled: false.`,\n );\n }\n if (props.enabled !== false && !hasInstall(props)) {\n found.push(\n 'enabled units need an [Install] section with WantedBy/RequiredBy/Also/Alias; without one ' +\n 'systemd calls the unit \"static\" and `systemctl enable` has nothing to link. Add one, or ' +\n 'declare enabled: false and let something else pull it in.',\n );\n }\n if (type === 'timer' && !unitText(props).includes('[Timer]')) {\n found.push('a .timer needs a [Timer] section');\n }\n return found;\n};\n\nconst hasInstall = (props: SystemdUnitProps): boolean => {\n const text = unitText(props);\n if (!text.includes('[Install]')) return false;\n const after = text.slice(text.indexOf('[Install]'));\n return [...INSTALL_KEYS].some((key) => new RegExp(`^${key}=`, 'm').test(after));\n};\n\nconst textProblems = (text: string): string[] => {\n const found: string[] = [];\n if (text.trim() === '') found.push('the unit file is empty');\n if (text.includes('\\u0000')) found.push('the unit file contains NUL');\n if (!/^\\s*\\[[A-Za-z]+]/.test(text)) found.push('a unit file must begin with a [Section]');\n return found;\n};\n",
|
|
27
27
|
"/**\n * The step that decides whether anything on the host actually moves: enablement, running state and\n * — only for a real change — a restart. Split from unit-lifecycle.ts because it is the rule the\n * whole family exists to keep, and it should be readable on its own.\n *\n * ⛔ THE RESTART CONDITION IS THE WHOLE CONTRACT. `changed` is set by the caller from the four\n * things that earn one (unit-lifecycle.ts reconcileUnit); `configChanged` is a digest the\n * DECLARATION itself listed. Nothing else restarts a unit — not a re-run, not an unrelated\n * resource in the same deploy, not `--adopt`.\n */\nimport type { HostRunner } from '../launchd/runner.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n configDigest,\n unitPathFor,\n} from './unit-form.ts';\nimport {\n type UnitStatus,\n daemonReload,\n disableUnit,\n enableUnit,\n restartUnit,\n showUnit,\n startUnit,\n stopUnit,\n} from './systemctl.ts';\n\nexport const refuse = (name: string, message: string): Error =>\n new Error(`Systemd.Unit ${name}: ${message}`);\n\nexport const attributesOf = (\n props: SystemdUnitProps,\n unitSha256: string,\n status: UnitStatus,\n): SystemdUnitAttributes => ({\n active: status.activeState === 'active' || status.activeState === 'activating',\n activeState: status.activeState,\n configSha256: configDigest(props.restartOn),\n enabled: status.unitFileState === 'enabled' || status.unitFileState === 'enabled-runtime',\n loadState: status.loadState,\n name: props.name,\n unitPath: unitPathFor(props),\n unitSha256,\n ...(status.unitFileState === undefined ? {} : { unitFileState: status.unitFileState }),\n});\n\nexport type Settle = {\n readonly before: Uint8Array | undefined;\n /** The unit file or systemd's view of it changed in a way that earns a restart. */\n readonly changed: boolean;\n readonly configChanged: boolean;\n readonly desired: string;\n readonly path: string;\n readonly status: UnitStatus;\n};\n\n/**\n * Bring enablement and running state to the declaration, restarting ONLY for a real change.\n * ⛔ THE RESTART CONDITION IS THE WHOLE CONTRACT: the unit file changed, or a digest the caller\n * listed changed. Nothing else — not a re-run, not an unrelated resource, not `--adopt`.\n */\nexport const settle = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n step: Settle,\n): Promise<SystemdUnitAttributes> => {\n const wantEnabled = props.enabled !== false;\n const wantStarted = props.started !== false;\n const isEnabled =\n step.status.unitFileState === 'enabled' || step.status.unitFileState === 'enabled-runtime';\n const undo = async (detail: string): Promise<never> => {\n // ⚠️ A create that never came up leaves nothing behind; an update keeps the new file and the\n // old stored digest, so the next deploy retries.\n if (step.before === undefined) {\n await runner.removeFile(step.path).catch(() => undefined);\n await daemonReload(runner).catch(() => undefined);\n }\n throw refuse(props.name, `${detail} The unit is NOT running.`);\n };\n try {\n if (wantEnabled && (!isEnabled || step.changed)) await enableUnit(runner, props.name);\n if (!wantEnabled && isEnabled) await disableUnit(runner, props.name);\n const active = step.status.activeState === 'active' || step.status.activeState === 'activating';\n if (!wantStarted) {\n if (active) await stopUnit(runner, props.name);\n } else if (!active) await startUnit(runner, props.name);\n else if (step.changed || step.configChanged) await restartUnit(runner, props.name);\n } catch (cause) {\n return undo(cause instanceof Error ? cause.message : String(cause));\n }\n /**\n * ⚠️ READ BACK, never echo the declaration. Returning `enabled: wantEnabled` because we called\n * `enable` would put a CLAIM in state instead of a reading, and the next plan would compare\n * the declaration against itself — so a link systemd did not actually make would never show up\n * as drift, in either direction.\n */\n const after = await showUnit(runner, props.name);\n if (wantStarted && after.activeState !== 'active' && after.activeState !== 'activating') {\n return undo(`systemctl reported success but the unit is ${after.activeState}.`);\n }\n const settled = attributesOf(props, step.desired, after);\n if (wantEnabled && !settled.enabled) {\n return undo(\n `systemctl enable reported success but systemd calls the unit ` +\n `${JSON.stringify(after.unitFileState ?? '')}, not enabled.`,\n );\n }\n return settled;\n};\n",
|
|
28
|
-
"/**\n * Systemd.Unit
|
|
28
|
+
"/**\n * Everything Systemd.Unit checks before it touches the host — split from unit-lifecycle.ts so that\n * a reconcile and a plan-time REPLACE run the very same checks.\n *\n * ★ WHY A REPLACE IS CHECKED AT PLAN TIME. A name or directory change is a delete-first replace,\n * and Alchemy runs `delete` on the old unit BEFORE `reconcile` on the new one (Apply.ts,\n * deleteOldGenerations under `node.deleteFirst`). A refusal that fired only in reconcile would\n * therefore arrive after the old unit was already stopped and its file removed: nothing running,\n * and a plan that had promised a clean swap.\n * ★ EVERY CHECK HERE IS READ-ONLY. systemd has no `print-disabled` equivalent in this family —\n * masking is `systemctl show`'s LoadState / UnitFileState, which `showUnit` already returns.\n * Validation, that show, a file read and `HostRunner.checkWrite` write nothing. `systemctl\n * enable` itself stays an apply step; the ways it is known to fail (no `[Install]`, a directory\n * systemd does not search) are `unitProblems`, checked here before the plan may promise a swap.\n */\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\nimport { type UnitStatus, showUnit } from './systemctl.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n UNIT_WRITE,\n digestOf,\n unitPathFor,\n unitProblems,\n unitText,\n} from './unit-form.ts';\nimport { refuse } from './unit-settle.ts';\n\nconst decoder = new TextDecoder();\n\n/** Throw every refusal at once, so one plan shows the whole list. */\nexport const assertValid = (props: SystemdUnitProps, expect?: string): void => {\n const found = unitProblems(props, expect);\n if (found.length > 0) throw refuse(props.name, found.join('; '));\n};\n\n/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */\nexport const assertMayWrite = (runner: HostRunner, name: string): void => {\n if (canActAsRoot(runner)) return;\n throw refuse(\n name,\n 'a systemd unit is root-owned and systemctl needs root. Point the runner at a destination ' +\n 'whose ssh user is root, or provide a privileged HostRunner. This provider never calls sudo.',\n );\n};\n\n/**\n * ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes\n * start fail; unmasking here would silently overrule whoever masked it.\n */\nexport const assertUsable = (props: Pick<SystemdUnitProps, 'name'>, status: UnitStatus): void => {\n if (status.loadState === 'masked' || status.unitFileState === 'masked') {\n throw refuse(\n props.name,\n 'is masked. If that is stale, `systemctl unmask` it deliberately, then redeploy. Nothing ' +\n 'was written.',\n );\n }\n};\n\n/**\n * ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Alchemy's adoption probe guards a\n * create, but NOT the new name of a replace — the engine reads nothing there — so a rename onto\n * a unit file someone else already has would stop the old unit and write ours over theirs.\n * ★ A file byte-identical to our render is exempt: it is this declaration's own leftover (a deploy\n * that died between write and reload), and rewriting it changes nothing.\n */\nexport const assertUnclaimed = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n): Promise<void> => {\n const path = unitPathFor(props);\n const bytes = await runner.readFile(path);\n const live = bytes === undefined ? undefined : digestOf(decoder.decode(bytes));\n if (live !== undefined && live !== digestOf(unitText(props))) {\n throw refuse(\n props.name,\n `${path} is already on this host and is not this resource. Remove it, or declare it as a ` +\n 'new resource and deploy with --adopt.',\n );\n }\n};\n\n/**\n * The half of a rename check that needs only the NEW NAME: the old unit deletable, the new one\n * writable and not masked.\n * ★ ON ITS OWN it is for the rename unit-handlers.ts `diffHandler` spots while `content` is still\n * an Output. That plan is a delete-first replace too, so a masked target refused only in\n * reconcile would again arrive after the old unit was stopped. The unit file itself cannot be\n * compared until `content` resolves, so `assertUnclaimed` stays reconcile's job there.\n */\nexport const assertRenameTarget = async (\n runner: HostRunner,\n old: SystemdUnitAttributes,\n name: string,\n): Promise<void> => {\n assertMayWrite(runner, old.name);\n assertMayWrite(runner, name);\n assertUsable({ name }, await showUnit(runner, name));\n};\n\n/**\n * A rename, checked at plan time: the new identity must be valid, writable, not masked and free,\n * and the old one deletable — before the plan may promise a delete-first replace.\n */\nexport const assertReplaceable = async (\n runner: HostRunner,\n next: SystemdUnitProps,\n old: SystemdUnitAttributes,\n expect?: string,\n): Promise<void> => {\n assertValid(next, expect);\n await assertRenameTarget(runner, old, next.name);\n await assertUnclaimed(runner, next);\n await runner.checkWrite?.(unitPathFor(next), UNIT_WRITE);\n};\n",
|
|
29
|
+
"/**\n * Systemd.Unit's read / diff / reconcile / delete as plain async functions over a HostRunner, so\n * the whole lifecycle runs against a fake host with no real systemd.\n *\n * ⛔ WHAT A DEPLOY DOES NOT DO — the rule this family was built around. It NEVER mass-restarts.\n * A unit is restarted only when THIS resource's unit file changed, or when a digest the\n * declaration itself listed in `restartOn` changed. A unit that is already running the content\n * we declare is left strictly alone: no restart, no reload, not even a `start`. An estate rebuild\n * must be able to reach a host that holds a vault, a UPS handler or a clock without bouncing\n * them, and \"the deploy ran\" must never be a reason anything went down.\n * ★ THE ORDER IS WRITE, RELOAD, ENABLE, THEN START OR RESTART. systemd reads the unit file at\n * `daemon-reload`, so writing it while the old unit runs changes nothing yet, and a write that\n * fails leaves the old unit running rather than leaving nothing running.\n * ⚠️ A FAILED START LEAVES THE UNIT DOWN. On an update the new unit file stays and state keeps the\n * previous digest, so the next deploy retries. On a CREATE the file this deploy wrote is removed\n * and systemd reloaded again: left behind, the next plan's recovery read finds a unit with no\n * state, reports it `Unowned`, and every later deploy demands `--adopt` for our own file.\n * ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes\n * start fail; unmasking here would silently overrule whoever masked it.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport type { HostRunner } from '../launchd/runner.ts';\nimport { daemonReload, disableUnit, showUnit, stopUnit } from './systemctl.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n UNIT_WRITE,\n configDigest,\n digestOf,\n unitPathFor,\n unitText,\n} from './unit-form.ts';\nimport { assertMayWrite, assertReplaceable, assertUsable, assertValid } from './unit-preflight.ts';\nimport { attributesOf, refuse, settle } from './unit-settle.ts';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** What is on the host now: the unit file's digest and systemd's view. `undefined` when neither. */\nexport const readUnit = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n): Promise<SystemdUnitAttributes | undefined> => {\n const bytes = await runner.readFile(unitPathFor(props));\n const status = await showUnit(runner, props.name);\n if (bytes === undefined && !status.known) return undefined;\n return attributesOf(props, bytes === undefined ? '' : digestOf(decoder.decode(bytes)), status);\n};\n\nexport const diffUnit = async (\n runner: HostRunner,\n news: SystemdUnitProps,\n output: SystemdUnitAttributes,\n expect?: string,\n): Promise<Diff> => {\n assertValid(news, expect);\n // ★ The unit's name or its directory is its identity on the host: a change is a replace, and\n // delete-first, because two unit files for one name cannot both be the one systemd reads.\n // ⛔ Which is why everything the new unit's reconcile would refuse is refused HERE, at plan\n // time (unit-preflight.ts): after the delete it would be too late.\n if (news.name !== output.name || unitPathFor(news) !== output.unitPath) {\n await assertReplaceable(runner, news, output, expect);\n return { action: 'replace', deleteFirst: true };\n }\n const desired = digestOf(unitText(news));\n const update = async (): Promise<Diff> => {\n assertMayWrite(runner, news.name);\n await runner.checkWrite?.(unitPathFor(news), UNIT_WRITE);\n return { action: 'update' };\n };\n // ⛔ BOTH digests: the stored one catches a start that failed after the write landed, the live\n // one catches a hand edit. Either alone reports `noop` over a unit that is not what we say.\n if (desired !== output.unitSha256) return update();\n if (configDigest(news.restartOn) !== output.configSha256) return update();\n const live = await readUnit(runner, news);\n if (live === undefined || live.unitSha256 !== desired) return update();\n if (live.enabled !== (news.enabled !== false)) return update();\n if (live.active !== (news.started !== false)) return update();\n // ⚠️ systemd's own word for \"the file on disk is newer than what I loaded\" — a write that landed\n // without its reload. It is drift that neither digest can see.\n const status = await showUnit(runner, news.name);\n return status.needDaemonReload ? update() : { action: 'noop' };\n};\n\n/**\n * `adopt` is whether adoption is on AND this apply is a create or an unfinished generation of our\n * own (ownership/adopt.ts): it lets such a generation take over a unit already on the host.\n * ★ AN ADOPTED UNIT THAT ALREADY MATCHES IS NOT RESTARTED. That is the whole point of adopting one:\n * the estate's live services come under declaration without a single bounce.\n */\nexport const reconcileUnit = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n output: SystemdUnitAttributes | undefined,\n adopt = false,\n expect?: string,\n): Promise<SystemdUnitAttributes> => {\n assertValid(props, expect);\n assertMayWrite(runner, props.name);\n const path = unitPathFor(props);\n const status = await showUnit(runner, props.name);\n assertUsable(props, status);\n const text = unitText(props);\n const desired = digestOf(text);\n const before = await runner.readFile(path);\n const liveSha = before === undefined ? undefined : digestOf(decoder.decode(before));\n const moved = output !== undefined && (output.name !== props.name || output.unitPath !== path);\n /**\n * ★ A rename the diff could not see — a name that was still an unresolved Output at plan time\n * (unit-handlers.ts diffHandler) — arrives here as an update. Run the same read-only checks a\n * plan-time replace runs, BEFORE deleteUnit, or the old unit is already gone when we refuse.\n */\n if (moved && output !== undefined) await assertReplaceable(runner, props, output, expect);\n const prior = moved ? undefined : output;\n /**\n * ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Where the engine's probe never\n * looked — a replace's new name, a create whose props were still an Output at plan time — a\n * unit file already there with other content belongs to someone else, and writing ours over it\n * would take their service. ★ A byte-identical file is this declaration's own leftover.\n */\n if (\n prior === undefined &&\n !(adopt && output === undefined) &&\n liveSha !== undefined &&\n liveSha !== desired\n ) {\n throw refuse(\n props.name,\n `${path} is already on this host and is not this resource. Remove it, or declare it as a ` +\n 'new resource and deploy with --adopt.',\n );\n }\n if (moved && output !== undefined) await deleteUnit(runner, output);\n const wrote = liveSha !== desired;\n /**\n * ⛔ THE THREE THINGS THAT EARN A RESTART, and nothing else:\n * - the unit file's bytes changed (`wrote`);\n * - state holds an older digest than the file does — a previous deploy's write landed and its\n * reload or restart never ran, so systemd is still running the old content;\n * - systemd itself says its loaded unit is older than the file (`NeedDaemonReload`, measured);\n * - a digest the declaration listed in `restartOn` changed.\n * ★ An adopted, converged unit hits none of them, which is why adoption never bounces a service.\n */\n const stale = prior !== undefined && prior.unitSha256 !== desired;\n const configChanged = prior !== undefined && prior.configSha256 !== configDigest(props.restartOn);\n if (wrote) await runner.writeFileAtomic(path, encoder.encode(text), UNIT_WRITE);\n if (wrote || status.needDaemonReload) await daemonReload(runner);\n const changed = wrote || stale || status.needDaemonReload;\n return settle(runner, props, { before, changed, configChanged, desired, path, status });\n};\n\n/**\n * Stop, disable, remove the unit file, reload. Idempotent.\n * ⛔ DELETING THE DECLARATION STOPS THE SERVICE. That is what removing it from the stack means, and\n * it is why a unit that must outlive its declaration is adopted rather than deleted.\n */\nexport const deleteUnit = async (\n runner: HostRunner,\n output: SystemdUnitAttributes,\n): Promise<void> => {\n assertMayWrite(runner, output.name);\n const status = await showUnit(runner, output.name);\n if (status.activeState === 'active' || status.activeState === 'activating') {\n await stopUnit(runner, output.name);\n }\n if (status.unitFileState === 'enabled' || status.unitFileState === 'enabled-runtime') {\n await disableUnit(runner, output.name);\n }\n const stat = await runner.stat(output.unitPath);\n if (stat !== undefined) {\n if (stat.kind !== 'file') throw refuse(output.name, `${output.unitPath} is a ${stat.kind}`);\n await runner.removeFile(output.unitPath);\n }\n await daemonReload(runner);\n};\n",
|
|
29
30
|
"/**\n * `sshRunner()` — the estate's Linux hosts behind the SAME HostRunner seam the launchd family\n * already drives a Mac through (launchd/runner.ts). Every provider in this directory reaches its\n * host only through it, so the whole Linux lifecycle runs against a fake in tests.\n *\n * ★ WHY THE SAME SEAM AND NOT A SECOND ONE. HostRunner is nine promise-returning methods with no\n * macOS in them; what was Mac-specific was launchctl and the plist, not the seam. Reusing it\n * means HostFile, the ownership rules and `checkWrite` already work on Linux, and a stack can\n * hand the same runner to a file, a directory and a unit.\n * ⛔ NO PASSWORDS AND NO SILENT SUDO. Every connection is `BatchMode=yes` (ssh-command.ts), and\n * `privileged` is false: this runner never calls sudo. A root-owned path therefore needs a\n * destination whose ssh user IS root — which is how the estate already reaches its hypervisors —\n * or a privileged runner of the caller's own. See docs/linux-host.md; the Linux twin of\n * sudoRunner is deliberately a later, separate change with its own allowlist.\n * ⛔ FAIL CLOSED. A connection that drops, a host key that changed, a shell that cannot parse the\n * script: none of them produces a \"not found\". Without the framing marker the result is an\n * Error, never data (ssh-command.ts parseFramed).\n * ★ EXERCISED READ-ONLY AGAINST A LIVE HOST, 2026-09-22 (Debian 13, systemd 257, ssh user uid\n * 1001): `stat` of a file, of a missing path and of a symlink (reported `symlink`, so the lstat\n * contract holds over the wire); `readFile` of a file and of a missing path; `getent` user and\n * group; a failing `exec`; and an argument of `a b '$HOME` + backtick + ` ;rm` arriving verbatim,\n * which is the quoting proven rather than argued. Nothing was written.\n * ⚠️ ONE CONNECTION PER CALL. No multiplexing is configured here: a deploy over a slow link pays a\n * handshake per read. Pass `sshArgs: ['-o', 'ControlMaster=auto', …]` to opt into your own\n * ControlPersist socket — the kit does not create one behind your back, because a stale socket\n * outliving the deploy is a surprise nobody declared.\n */\nimport { spawn } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { groupQuery, parseGroup, parseUser, userQuery } from '../launchd/host-lookup.ts';\nimport type { ExecResult, HostRunner } from '../launchd/runner.ts';\nimport { ABSENT, frameScript, parseFramed, sshArgv } from './ssh-command.ts';\nimport {\n execScript,\n parseStat,\n readScript,\n removeScript,\n statScript,\n writeScript,\n} from './ssh-scripts.ts';\n\nexport type SshRunnerOptions = {\n /** The destination exactly as the operator's own ssh config names it (`Host` block or user@host). */\n readonly host: string;\n /** Extra ssh options, after the fixed safety set and before the destination. */\n readonly sshArgs?: readonly string[];\n /** Kill a connection after this long. @default 120_000 */\n readonly execTimeoutMs?: number;\n /** ssh's own `ConnectTimeout`. @default 10 */\n readonly connectTimeoutSec?: number;\n};\n\ntype Raw = { exitCode: number; stdout: string; stderr: string; signal: string | null };\n\nconst spawnSsh = (argv: readonly string[], timeoutMs: number, stdin?: Uint8Array): Promise<Raw> =>\n new Promise((resolve, reject) => {\n const [program, ...args] = argv as [string, ...string[]];\n const child = spawn(program, args, {\n shell: false,\n stdio: [stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],\n timeout: timeoutMs,\n });\n const out: Buffer[] = [];\n const err: Buffer[] = [];\n child.stdout?.on('data', (chunk: Buffer) => out.push(chunk));\n child.stderr?.on('data', (chunk: Buffer) => err.push(chunk));\n child.on('error', (cause) => {\n reject(new Error(`ssh: ${cause.message}`));\n });\n if (stdin !== undefined && child.stdin !== null) {\n // ⚠️ EPIPE is normal here: the remote `cat` can die before we finish writing, and the real\n // failure is the exit code we are about to read — not a crash in this process.\n child.stdin.on('error', () => undefined);\n child.stdin.end(stdin);\n }\n child.on('close', (exitCode, signal) => {\n resolve({\n exitCode: exitCode ?? -1,\n signal,\n stderr: Buffer.concat(err).toString('utf8'),\n stdout: Buffer.concat(out).toString('utf8'),\n });\n });\n });\n\n/** What the process on the far end did — or an Error, when we cannot say that it ran at all. */\nexport const runRemote = async (\n options: Required<Pick<SshRunnerOptions, 'host' | 'connectTimeoutSec' | 'execTimeoutMs'>> &\n Pick<SshRunnerOptions, 'sshArgs'>,\n nonce: string,\n script: string,\n stdin?: Uint8Array,\n): Promise<ExecResult> => {\n const argv = sshArgv(options.host, frameScript(script, nonce), {\n connectTimeoutSec: options.connectTimeoutSec,\n ...(options.sshArgs === undefined ? {} : { sshArgs: options.sshArgs }),\n });\n const raw = await spawnSsh(argv, options.execTimeoutMs, stdin);\n const framed = parseFramed(raw.stderr, nonce);\n if (framed === undefined) {\n // ⛔ The command may or may not have run. Saying \"absent\" here is how a dropped link becomes a\n // deleted config, so it is an error with ssh's own words (truncated, never the stdout).\n throw new Error(\n `ssh ${options.host}: the remote command did not report a status (ssh exit ` +\n `${String(raw.exitCode)}${raw.signal === null ? '' : `, killed by ${raw.signal}`}): ` +\n `${raw.stderr.trim().slice(0, 300)}`,\n );\n }\n return { exitCode: framed.exitCode, stderr: framed.stderr, stdout: raw.stdout };\n};\n\nconst decodeBase64 = (text: string): Uint8Array =>\n new Uint8Array(Buffer.from(text.replaceAll('\\n', ''), 'base64'));\n\nconst failed = (host: string, what: string, result: ExecResult): Error =>\n new Error(\n `ssh ${host}: ${what} -> ${String(result.exitCode)}: ${result.stderr.trim().slice(0, 300)}`,\n );\n\n/**\n * Connect once to learn who we are, then hand back the runner.\n * ⛔ THE PROBE IS THE FAIL-CLOSED GATE. `effectiveUid()` is synchronous on HostRunner, so the uid\n * must be known before the first provider call; and `uname -s` refuses a host whose `stat -c`,\n * `base64` and `mv -f` are not the Linux spellings this runner sends. A host that cannot answer\n * both is a thrown Error at construction, not a stack that half-deploys.\n */\nexport const sshRunner = async (options: SshRunnerOptions): Promise<HostRunner> => {\n const settings = {\n connectTimeoutSec: options.connectTimeoutSec ?? 10,\n execTimeoutMs: options.execTimeoutMs ?? 120_000,\n host: options.host,\n ...(options.sshArgs === undefined ? {} : { sshArgs: options.sshArgs }),\n };\n const nonce = randomBytes(8).toString('hex');\n const run = (script: string, stdin?: Uint8Array) => runRemote(settings, nonce, script, stdin);\n const probe = await run('uname -s; id -u');\n if (probe.exitCode !== 0) throw failed(options.host, 'uname -s; id -u', probe);\n const [system, uid] = probe.stdout.trim().split('\\n');\n if (system !== 'Linux' || uid === undefined || !/^\\d+$/.test(uid)) {\n throw new Error(\n `ssh ${options.host}: expected a Linux host, got ${JSON.stringify(probe.stdout.trim())}. ` +\n 'sshRunner() sends GNU/BusyBox argv (stat -c, base64, mv -f); for a Mac use localRunner().',\n );\n }\n const euid = Number(uid);\n return {\n effectiveUid: () => euid,\n exec: (argv) => run(execScript(argv)),\n lookupGroup: async (nameOrId) => {\n const result = await run(execScript(groupQuery('linux', nameOrId)));\n return result.exitCode === 0 ? parseGroup('linux', result.stdout) : undefined;\n },\n lookupUser: async (nameOrId) => {\n const result = await run(execScript(userQuery('linux', nameOrId)));\n return result.exitCode === 0 ? parseUser('linux', result.stdout) : undefined;\n },\n privileged: false,\n readFile: async (path) => {\n const result = await run(readScript(path));\n if (result.exitCode === ABSENT) return undefined;\n if (result.exitCode !== 0) throw failed(options.host, `read ${path}`, result);\n return decodeBase64(result.stdout);\n },\n removeFile: async (path) => {\n const result = await run(removeScript(path));\n if (result.exitCode !== 0) throw failed(options.host, `remove ${path}`, result);\n },\n sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n stat: async (path) => {\n const result = await run(statScript(path));\n if (result.exitCode === ABSENT) return undefined;\n if (result.exitCode !== 0) throw failed(options.host, `stat ${path}`, result);\n const parsed = parseStat(result.stdout);\n // ⛔ Unparseable is an error, not \"nothing there\": a `stat` that printed something we do not\n // understand is a host this runner does not know, and guessing would write over a file.\n if (parsed === undefined) {\n throw new Error(`ssh ${options.host}: stat ${path} printed an unexpected shape`);\n }\n return parsed;\n },\n writeFileAtomic: async (path, bytes, write) => {\n const at = path.lastIndexOf('/');\n const temp = `${path.slice(0, at)}/.${path.slice(at + 1)}.${randomBytes(6).toString('hex')}.tmp`;\n const result = await run(writeScript(path, temp, write), bytes);\n if (result.exitCode !== 0) throw failed(options.host, `write ${path}`, result);\n },\n };\n};\n",
|
|
30
31
|
"/**\n * User and group lookups, as argv plus a parser — split out so the parsing is tested against the\n * real output shapes without running anything.\n *\n * ★ macOS FIRST, getent ELSEWHERE. macOS has no `getent`; its directory service answers through\n * `dscacheutil`. Shape MEASURED 2026-09-21 on macOS 27.2 (read-only query):\n *\n * name: someone\n * password: ********\n * uid: 501\n * gid: 20\n * dir: /Users/someone\n * shell: /bin/zsh\n *\n * An unknown uid printed NOTHING and exited 0 — so \"no record\" is an empty parse, never an\n * exit code. `getent` exits 2 for an unknown key; that also parses as no record.\n * ⛔ NEVER PARSE OR KEEP THE `password:` LINE. It is a placeholder on macOS, but a parser that\n * copies every field would carry a hash from any host where it is not.\n */\nimport type { HostUser } from './runner.ts';\n\nconst NUMERIC = /^\\d+$/;\n\n/** argv for looking up a user, by name or numeric id. */\nexport const userQuery = (platform: string, nameOrId: string): readonly string[] =>\n platform === 'darwin'\n ? [\n '/usr/bin/dscacheutil',\n '-q',\n 'user',\n '-a',\n NUMERIC.test(nameOrId) ? 'uid' : 'name',\n nameOrId,\n ]\n : ['getent', 'passwd', nameOrId];\n\n/** argv for looking up a group, by name or numeric id. */\nexport const groupQuery = (platform: string, nameOrId: string): readonly string[] =>\n platform === 'darwin'\n ? [\n '/usr/bin/dscacheutil',\n '-q',\n 'group',\n '-a',\n NUMERIC.test(nameOrId) ? 'gid' : 'name',\n nameOrId,\n ]\n : ['getent', 'group', nameOrId];\n\n/** The first `key: value` record in dscacheutil output, minus any password field. */\nconst firstRecord = (stdout: string): Map<string, string> => {\n const fields = new Map<string, string>();\n for (const line of stdout.split('\\n')) {\n if (line.trim() === '') {\n if (fields.size > 0) break; // ⚠️ records are blank-line separated; keep the first only\n continue;\n }\n const at = line.indexOf(': ');\n if (at <= 0) continue;\n const key = line.slice(0, at);\n if (key === 'password') continue;\n fields.set(key, line.slice(at + 2).trim());\n }\n return fields;\n};\n\nconst toId = (text: string | undefined): number | undefined =>\n text !== undefined && NUMERIC.test(text) ? Number(text) : undefined;\n\nexport const parseUser = (platform: string, stdout: string): HostUser | undefined => {\n if (platform === 'darwin') {\n const record = firstRecord(stdout);\n const uid = toId(record.get('uid'));\n const gid = toId(record.get('gid'));\n const home = record.get('dir');\n return uid === undefined || gid === undefined || home === undefined\n ? undefined\n : { gid, home, uid };\n }\n // getent passwd: name:x:uid:gid:gecos:home:shell\n const fields = (stdout.split('\\n')[0] ?? '').split(':');\n const uid = toId(fields[2]);\n const gid = toId(fields[3]);\n const home = fields[5];\n return uid === undefined || gid === undefined || home === undefined || home === ''\n ? undefined\n : { gid, home, uid };\n};\n\nexport const parseGroup = (platform: string, stdout: string): number | undefined => {\n if (platform === 'darwin') return toId(firstRecord(stdout).get('gid'));\n // getent group: name:x:gid:members\n return toId((stdout.split('\\n')[0] ?? '').split(':')[2]);\n};\n",
|
|
31
32
|
"/**\n * The wire format the ssh runner speaks: how an argv becomes one remote `sh` script, and how that\n * script's real exit code comes back. Pure functions, so every quoting and framing rule is tested\n * without opening a connection.\n *\n * ⛔ `ssh host <words>` IS NOT AN EXECVE. ssh joins its trailing arguments with spaces and the\n * REMOTE LOGIN SHELL parses the result, so an unquoted path with a space, a `$`, a backtick or a\n * `;` is re-parsed as shell syntax on the other side. Everything therefore goes through\n * `shellQuote`, and the remote command is always `/bin/sh -c '<script>'` — a POSIX shell named\n * explicitly, so a csh or fish login shell only ever execs it.\n * ⛔ AN EXIT CODE FROM ssh IS AMBIGUOUS. ssh exits 255 for its own failures (connection refused,\n * host key changed, auth) and otherwise passes the remote exit code through — and a remote\n * command may itself exit 255. A runner that read the code alone would report \"the file is not\n * there\" for a dropped connection, which is the exact \"never infer success from an empty result\"\n * failure. So every script ends by printing its own status on stderr behind a PER-RUNNER NONCE,\n * and a result without that line is a transport failure, never data.\n * ⚠️ THE NONCE IS NOT DECORATION. Without it a remote program that happens to print the marker on\n * stderr could claim any exit code it liked; with a fresh random nonce per runner, the only thing\n * that can produce the line is the script we sent.\n */\n\n/** A script whose work found nothing at the path. ★ Chosen from the 64–113 range sh leaves free. */\nexport const ABSENT = 66;\n\n/**\n * One argument, safe for a POSIX shell. ⛔ Single quotes, because they quote EVERYTHING; the\n * `'\\''` dance is how a literal quote gets through.\n */\nexport const shellQuote = (arg: string): string => {\n if (arg.includes('\\x00')) throw new Error('ssh: an argument contains NUL');\n return `'${arg.replaceAll(\"'\", `'\\\\''`)}'`;\n};\n\n/** An argv as one shell command line. */\nexport const quoteArgv = (argv: readonly string[]): string => argv.map(shellQuote).join(' ');\n\nconst marker = (nonce: string) => `__HF_RC_${nonce}=`;\n\n/**\n * Wrap a script so its status comes back unambiguously.\n *\n * ⛔ THE SCRIPT RUNS IN A SUBSHELL, AND THAT IS NOT COSMETIC. Several of the scripts end a branch\n * with `exit <code>` to say \"nothing was there\"; at the top level that exit leaves the shell\n * immediately and the marker line NEVER PRINTS — so the caller sees a framed result missing its\n * frame and, correctly, calls it a transport failure. 🔴 MEASURED 2026-09-22 against a live\n * Debian 13 host: `stat` of a missing path came back as \"the remote command did not report a\n * status (ssh exit 66)\" instead of \"nothing is at this path\". Inside `( … )` the exit leaves only\n * the subshell, `$?` carries the code out, and the frame always runs.\n * ⚠️ The leading `\\n` matters too: a program whose last stderr line has no newline would otherwise\n * glue itself to the marker and the marker would not be found.\n */\nexport const frameScript = (script: string, nonce: string): string =>\n `(\\n${script}\\n)\\n__hf=$?\\nprintf '\\\\n${marker(nonce)}%s\\\\n' \"$__hf\" >&2\\nexit \"$__hf\"`;\n\nexport type Framed = { readonly exitCode: number; readonly stderr: string };\n\n/**\n * The remote exit code and the stderr that belongs to the command, or `undefined` when the marker\n * is absent — which means the script never ran to its end: ssh failed, the connection dropped, or\n * the remote shell could not parse what we sent. ⛔ The caller must treat `undefined` as an error,\n * never as an answer.\n */\nexport const parseFramed = (stderr: string, nonce: string): Framed | undefined => {\n const at = stderr.lastIndexOf(`\\n${marker(nonce)}`);\n if (at < 0) return undefined;\n const digits = /^(\\d+)\\s*$/.exec(stderr.slice(at + marker(nonce).length + 1));\n if (digits?.[1] === undefined) return undefined;\n return { exitCode: Number(digits[1]), stderr: stderr.slice(0, at) };\n};\n\n/**\n * The fixed ssh options, in front of anything a caller adds.\n * ⛔ `BatchMode=yes` — a deploy that stops to ask for a passphrase is the failure \"no password\n * prompts\" names, and with BatchMode ssh fails at once instead.\n * ⛔ NOTHING HERE WEAKENS HOST VERIFICATION. No `StrictHostKeyChecking`, no `UserKnownHostsFile`:\n * the operator's own ssh config and known_hosts decide who the host is, and a changed key stays\n * a refusal. A runner that turned that off would make a man-in-the-middle a deploy target.\n * ★ `-T`: no pseudo-terminal, so the remote shell's stdout stays the bytes the program wrote.\n */\nexport const sshArgv = (\n host: string,\n script: string,\n options: { readonly connectTimeoutSec: number; readonly sshArgs?: readonly string[] },\n): readonly string[] => {\n if (host === '' || host.startsWith('-')) {\n throw new Error(`ssh: ${JSON.stringify(host)} is not a usable destination`);\n }\n return [\n 'ssh',\n '-T',\n '-o',\n 'BatchMode=yes',\n '-o',\n `ConnectTimeout=${String(options.connectTimeoutSec)}`,\n ...(options.sshArgs ?? []),\n host,\n `/bin/sh -c ${shellQuote(script)}`,\n ];\n};\n",
|
|
32
33
|
"/**\n * The four remote scripts a HostRunner needs, and the parser for the one that returns data.\n * Pure: every shape here is asserted in ssh-scripts.test.ts without a connection.\n *\n * ★ MEASURED 2026-09-22 on Debian 13 (systemd 257, kernel 7.0.14-pve), read-only over ssh:\n * $ stat -c '%f %a %u %g %s' /etc/hostname → 81a4 644 0 0 4 (exit 0)\n * $ stat -c '%f %a %u %g %s' /nonexistent → \"cannot statx\" (exit 1)\n * `%f` is the RAW mode in hex, so the file type is in it (0x8000 regular, 0x4000 directory,\n * 0xa000 symlink) and `%a` is the permission bits alone. ⛔ GNU `stat` does NOT follow symlinks\n * without `-L`, which is what makes this an lstat — the FileStat contract (runner.ts) requires it,\n * because writing through a symlink changes a file the resource never named.\n * ⚠️ COREUTILS, NOT POSIX. `stat -c`, `base64` and `mv -f` are GNU/BusyBox spellings, not POSIX\n * ones; this runner is for Linux hosts and refuses anything else at the probe (ssh-runner.ts).\n */\nimport { ABSENT, quoteArgv, shellQuote } from './ssh-command.ts';\nimport type { FileStat, WriteOptions } from '../launchd/runner.ts';\n\n/** ★ `-e` is false for a dangling symlink and `-L` is true for it, so both tests together mean\n * \"something is at this path\" — the question stat(2) answers and `-e` alone does not. */\nconst IF_PRESENT = (path: string) => `if [ -e ${path} ] || [ -L ${path} ]; then`;\n\nexport const statScript = (path: string): string => {\n const quoted = shellQuote(path);\n return `${IF_PRESENT(quoted)} stat -c '%f %a %u %g %s' -- ${quoted}; else exit ${String(ABSENT)}; fi`;\n};\n\n/** ★ base64 on the wire: stdout then carries no byte that a shell, a pty or a locale can alter. */\nexport const readScript = (path: string): string => {\n const quoted = shellQuote(path);\n return `${IF_PRESENT(quoted)} base64 -- ${quoted}; else exit ${String(ABSENT)}; fi`;\n};\n\n/** ⛔ `rm -f` is idempotent for an absent path and still FAILS for a directory, which is what keeps\n * HostRunner.removeFile from quietly removing something that is not a file. */\nexport const removeScript = (path: string): string => `rm -f -- ${shellQuote(path)}`;\n\nexport const execScript = (argv: readonly string[]): string => quoteArgv(argv);\n\n/**\n * Write bytes (fed on stdin) so `path` holds the old file or the new one and never a torn mix.\n *\n * ⛔ NOT `install`. GNU coreutils `install` opens the destination and writes THROUGH it — unlike\n * macOS's, which stages and renames — so a deploy interrupted mid-write would leave a truncated\n * config where a whole one used to be. Staging beside the target and `mv` (rename(2), same\n * directory so never EXDEV) is the only atomic spelling available over a shell.\n * ⛔ `set -C` and `umask 077`: the staged file is created O_EXCL, so a symlink or a file planted at\n * the temp name is a refusal rather than a write through it, and it is unreadable by anyone else\n * in the moment before its mode is set.\n * ⚠️ chown BEFORE chmod: chown by root clears setuid/setgid, so the other order silently drops a\n * declared 4755 — the same ordering localRunner keeps for the same reason.\n * ⚠️ Each step removes the staged file before it fails, so a failed write leaves no litter beside\n * a file someone else owns.\n */\nexport const writeScript = (path: string, temp: string, options: WriteOptions): string => {\n const target = shellQuote(path);\n const staged = shellQuote(temp);\n const bail = `{ rm -f -- ${staged}; exit`;\n /**\n * ⛔ NEVER `chown <uid>:` — GNU chown reads a trailing colon as \"and that user's LOGIN GROUP\",\n * which is a gid nobody declared. Each half is spelled only when it was asked for.\n */\n const owner =\n options.uid === undefined\n ? options.gid === undefined\n ? undefined\n : `:${String(options.gid)}`\n : options.gid === undefined\n ? String(options.uid)\n : `${String(options.uid)}:${String(options.gid)}`;\n const chown = owner === undefined ? [] : [`chown ${owner} -- ${staged} || ${bail} 72; }`];\n return [\n 'set -C',\n 'umask 077',\n `cat > ${staged} || ${bail} 71; }`,\n ...chown,\n `chmod ${options.mode.toString(8).padStart(3, '0')} -- ${staged} || ${bail} 73; }`,\n `mv -f -- ${staged} ${target} || ${bail} 74; }`,\n ].join('\\n');\n};\n\nconst TYPE_BITS = 0xf000;\nconst KINDS = new Map<number, FileStat['kind']>([\n [0x8000, 'file'],\n [0x4000, 'directory'],\n [0xa000, 'symlink'],\n]);\n\n/** `stat -c '%f %a %u %g %s'` output → a FileStat, or `undefined` when it is not that shape. */\nexport const parseStat = (stdout: string): FileStat | undefined => {\n const fields = stdout.trim().split(/\\s+/);\n if (fields.length !== 5) return undefined;\n const [rawMode, perms, uid, gid, size] = fields as [string, string, string, string, string];\n const raw = Number.parseInt(rawMode, 16);\n const mode = Number.parseInt(perms, 8);\n const numbers = [raw, mode, Number(uid), Number(gid), Number(size)];\n if (numbers.some((value) => !Number.isSafeInteger(value) || value < 0)) return undefined;\n return {\n gid: Number(gid),\n kind: KINDS.get(raw & TYPE_BITS) ?? 'other',\n // ⚠️ `%a` alone, never `%f & 0o7777`: they agree, and the permission field is the documented one.\n mode,\n size: Number(size),\n uid: Number(uid),\n };\n};\n"
|
|
33
34
|
],
|
|
34
|
-
"mappings": "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",
|
|
35
|
-
"debugId": "
|
|
35
|
+
"mappings": "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",
|
|
36
|
+
"debugId": "999A0F25FFF74BEF64756E2164756E21",
|
|
36
37
|
"names": []
|
|
37
38
|
}
|