docs(installer): the installer is invisible; entries own defaults, recovery and cleanup; one release authority - #18
Merged
Merged
Conversation
…pies its path A product installer built on this contract printed, on a machine whose ~/.local/bin/app was a hand-written launcher script: Downloading app-installer (7ac50823-f020-47bd-9aca-632d3ac83b50)... Not done: bin-not-standalone: ~/.local/bin/app is a launcher script; app-installer never replaces it (remove it, or set APP_INSTALL_DIR). Every part of that followed the contract's letter and missed its intent. The contract said the line is in the user's words, but it did not say that the installer itself is not something the person knows about, that a reason for people and a code for software are two different things, or what to do when the product's path holds something that is neither this product nor another manager's install. - Voice (new, first of the rules): everything a person reads is about the product; the installer's name, K's terms, ids, unchosen channels and codes are not. Outcomes carry a reason in the user's words and a stable code, kept apart in the receipt. An obstacle gets one runnable next step, and a decision that belongs to the person is asked (attended) or named as a command (unattended), never handed back as a chore. - Worlds: a fresh install can find the product's path occupied. It is the person's: attended, ask to replace it (default no), move it aside under a name the line gives, say how to put it back; unattended, hold unless the request carries --yes. It is never deleted. The five worlds and the entries figure are unchanged: occupied is an obstacle within fresh. - --yes, Presence, the outcome table and the closing paragraph follow. scripts/check-docs.py passes.
…rity Folds in how the owner framed this across earlier threads (2026-09-16, 09-17, 09-21): - Users only touch entries: the install script, the product's commands, the product's remote upgrade. The installer is an implementation detail; no line names it or asks a person to run it (Voice). - New "Entries" rules. An entry turns what the person asked for into a request with the consents that implies; the install script consents to replacing an occupant of the product's path, which is almost always an earlier way of running the product, so there is no question. An entry finishes what it can: settle first, recover and retry once on unresolved, a product recovers its own interrupted remote upgrade on its next start, and a request K never started is recorded as failed before any change. Cleanup is the installer's, retried silently, derived from receipts and K's state, never a reason to reinstall, restart or ask. - Worlds, Presence, --yes and the outcome table follow. Recovery unresolved now says to run the install command again, not "repair". - One release authority. The byte store with <version>/manifest.json (RELEASE_BASE, INSTALLER_RELEASE_BASE) is gone from the contract: the authority's answer names the release and the size and sha256 of every file it serves, and nothing else describes a release. The crate's StaticManifestSource stays for examples and tests (index.html). scripts/check-docs.py passes.
…staller and K The last two commits added Voice, Entries, the occupied path and one release authority in place, so the page said several things twice, kept traces of the old model, and was ordered by history. This pass orders it for a first-time reader and says each rule once. - "The model" now leads: entries (the only things people use), the request, the installer (an implementation detail of the entries), K, and the release authority. The reads, the grid and the interface follow, then the rules in the same order: Voice, Entries, Request, Presence and consent, Lock and settle, Worlds, The product's answer, Verify, Repair, Report, Cleanup. Then the outcome table. - Consent lives in one section. It was spread over Presence, Entries, Repair, --yes, the commands table and the outcome table, and still said "running the installer is the consent", "the repair consent rule" and "invocation consent". - Cleanup is its own section. It was in Entries and again in Repair, in Request (housekeeping on replay, receipt retention) and in the closing paragraph. - Entries keeps "finish what you can": retry once on unresolved, recover a remote upgrade on the next start, nothing else retried on its own (moved from Report). - The closing paragraph is folded into Voice. Restatements of the reads section are gone from the rules; a dead lock owner moved to Lock and settle; "no separate manifest to agree with" is gone (nothing else describes a release says it). - Outcome table: the presence columns hold only what presence changes. The occupied row's held case sat under "Unattended adds", a leftover of the --yes model; it is now a Held reason. "Another installer running" is "another install or upgrade in progress". Changed requirements: - Another manager's installation: the line names the manager and where it is, and no longer says how to remove it. A removal instruction is a chore, and the next step a person gets is always an entry. - The next step is given when there is something to do, as the table already said; Voice had it unconditional. - <PRODUCT>_INSTALLER_VERSION is marked as a setting for the product's developers, since people never see the installer. Outside the contract: - figures/entries-grid.html: "never retries on its own" became false when entries started retrying once on unresolved; it now reads "never retries a failed target". "seed from the running app" was false since adoption works running or stopped; it reads "seed its existing bytes". - guide.html: exit 3 was "never the user's"; the contract gives the person a line for it and keeps exit 3 until a repair succeeds. - prior-art.html: the verify rules taken from Raft Computer no longer include two sources that must agree. scripts/check-docs.py passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… update The editorial pass dropped the removal hint, rightly (a chore, not an entry), but left the person with nothing to do. The manager that owns the installation is its entry, so its update is the next step.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Ferry's installer is built on this contract. It printed this to its owner, whose
~/.local/bin/ferrywas a hand-written launcher script:Each piece followed the contract's letter. The spirit it missed is the one agreed in earlier threads (2026-09-16/17 in #proj-raft-computer, 2026-09-21 in #all-staff-plus):
What changes
docs/installer.html(and one sentence ofindex.html):<version>/manifest.jsonbyte store (RELEASE_BASE,INSTALLER_RELEASE_BASE) is gone from the contract. The authority's answer names the release and the size and sha256 of every file. The crate'sStaticManifestSourcestays for examples and tests. Retiring it from the integration guide's sample is a follow-up.--yes, the outcome table ("Fresh, path occupied"; "Recovery unresolved" now says to run the install command again) and the closing paragraph follow.python3 scripts/check-docs.pypasses.The Ferry side of the same fix: ferry-installer 0.1.1 (a botiverse/ferry PR, linked once opened).
🤖 Generated with Claude Code