diff --git a/content/news/2026-09-18-what-a-good-install-actually-is.adoc b/content/news/2026-09-18-what-a-good-install-actually-is.adoc new file mode 100644 index 0000000..51dd7bc --- /dev/null +++ b/content/news/2026-09-18-what-a-good-install-actually-is.adoc @@ -0,0 +1,131 @@ += What a good install actually is +:description: Installation norms as craft — why FHS cargo-cult breaks, why Windows honest writes are a requirement set, and how a dual-mode layout might survive connectome-fs. +:revdate: 2026-09-18 +:keywords: blog, installation, FHS, UIL, POSIX, Windows, connectome-fs, OpenShellOrg, Ibex, Install Coordinator, DevCentr + +You know the argument. +Someone pastes the FHS paragraph about `/usr/local` and declares victory. +Someone else points at `%ProgramFiles%` and mutters about MSI like it is a moral failing. +A third person lives in `~/.local/bin` and refuses to explain why that is different from the first two. +Everyone is half right. +Everyone is also performing a standard they never read end-to-end. + +I keep coming back to installs because they are where philosophy meets disk: what you claim to own, what you leave reversible, and what a shell—or a graph store five years from now—can still find without archaeology. + +This essay is not a shipping notice. +It is the craft frame behind an installation norms guide and a layout proposal (UIL) we are writing into general-knowledge. +Read those pages when you want checklists and diagrams. +Stay here if you want the *why*. + +== Layout theater vs an install contract + +A **bad** install, in the sense that keeps hurting users, is not always a buggy script. +Often it is an **unstated contract**: files copied because "that is where things go," global environment mutated without a ledger, uninstall that deletes a folder but not the PATH entry that outlived it, upgrade that assumes only one version may exist because the author never side-by-side'd anything. + +A **good** install **names its claims** before it writes. +Machine scope vs user scope is a design choice, not a default. +Side-by-side versions are a feature when your CLI promises semver. +Rollback is not magic—it is knowing which registry keys, which services, which well-known names you touched. + +That sounds obvious written down. +It is rarely how installer templates behave, because templates optimize for the demo machine where `/usr/local` was empty and PATH was short. + +The norms guide we are assembling tries to say the quiet part out loud: **separate "where files land" from "what the install promises to the rest of the system."** +Land files in a tree that matches your support story. +Promise the environment in a record something else can read—future you, a coordinator, a shell pin resolver. + +== FHS, SUS, and the cargo-cult trap + +The Filesystem Hierarchy Standard is useful the way a city map is useful: it orients newcomers. +It is not a runtime API. +Nothing in the kernel rejects your binary because you chose `opt/myvendor` instead of a wiki's favorite spelling. + +POSIX and the Single UNIX Specification are deeper—they stabilize behavior engineers can rely on across systems. +They still do **not** answer the question that burns CLI authors: *where does this tool live for one user on one laptop when the distro package manager, the language ecosystem, and the vendor tarball all disagree?* + +Cargo-cult FHS is the habit of quoting hierarchy documents without naming **claims**. +You see it in post-install scripts that `chmod +x` into system directories "because Linux," in Docker images that mimic a full FHS tree for a single static binary, in debates that treat `/usr/local` as sin or sacrament without asking who shares that prefix on the host. + +Craft means treating variance as input. +Fedora's packaging norms, Ubuntu's Snaps, a corporate golden image, and your own `~/.local` habit are different hosts. +A layout that works is one whose **assumptions are explicit**—and whose undo path does not require guessing which of three PATH edits was yours. + +== Windows: direct-to-disk is not cheating + +Linux people sometimes treat Windows "portable folder plus PATH" installs as immature. +That judgment skips the platform's requirement set. + +MSI is a transactional, serialized mutation engine with a global lock and shared component bookkeeping. +It exists because IT needed pessimistic safety more than parallel indie installs. +The `_MSIExecute` mutex is not stupidity; it is a coarse gate chosen before your package's file list is known. +We wrote about that feeling—double-click, silence, *Another installation is already in progress*—in link:https://devcentr.org/news/2026-08-29-when-unrelated-installers-still-queue[When unrelated installers still queue]. + +So Windows tools often **write where you point them** or **append PATH in place with a ledger** because the alternative is pretending every dev iteration is an enterprise MSI. +That is not avoiding adulthood. +It is matching the job: iterative CLI work wants reversibility and visibility, not a ref-count graph for a redistributable you never shared. + +Craft on Windows still means the same contract: declare claims, keep undo honest, export MSI/MSIX when the deployment story requires tables and GPO—not because MSI is the only moral installer. + +== Linux variance without pretending one `/usr` + +On Linux the pain is pluralism, not absence of standards. +XDG gives config and data homes; binaries still scatter. +Distro packages, language-specific shims, and vendor tarballs coexist on one `$PATH`, and tab completion breaks in proportion to how many silent mutators ran before login. + +Good craft here looks like **well-known entrypoint names**, **versioned install roots**, and **environment mutation you can enumerate**. +Bad craft looks like "we picked `/usr/local/bin` because the README said so" with no story for Nix users, container bind mounts, or a user who cannot sudo. + +The encyclopedia cluster under link:https://docs.devcentr.org/general-knowledge/explanation/architecture/installation/[installation architecture] names patterns and anti-patterns so authors stop re-deriving this thread from first principles on every new tool. + +== UIL: one layout, two futures + +The **Unity Install Layout (UIL)** proposal is the structural bet I want to be wrong about in the details but right about in shape. + +**Classic mode** is today: explicit roots, side-by-side versions, ledgers for PATH and registry, entrypoints a shell can see. + +**Connectome mode** is tomorrow's graph: the same install as **addressable content**—editions, dependencies, rollback as graph operations, not only `rm -rf` and hope. + +connectome-fs (link:https://connectome-fs.github.io/[connectome-fs.github.io]) is the sibling org exploring that substrate—content-addressed storage where dependency edges can be first-class. +I am not claiming your next laptop boots into a graph filesystem. +I am claiming that if your install story **only** maps to a directory tree, you will rewrite it when graph-native storage stops being a research slide. + +UIL is dual-mode so we do not fork the mental model: the manifest you author for classic paths should have a straight mapping to connectome editions. +If that mapping is painful, the manifest is lying about what an install *is*. + +Proposal write-up: link:https://docs.devcentr.org/general-knowledge/explanation/architecture/installation/unity-install-layout.html[Unity Install Layout (UIL)]. +Norms checklist: link:https://docs.devcentr.org/general-knowledge/explanation/architecture/installation/installation-norms.html[Installation norms]. + +== Shell visibility (why OpenShellOrg is in this essay) + +link:https://openshellorg.github.io/[OpenShellOrg] cares about entrypoint dispatch—pins, re-exec, refusing to let the wrong Node answer when the pin said otherwise. +That work only succeeds when installs are **honest on the shell boundary**: binaries and shims on `PATH`, registrations that match what landed on disk, undo that does not leave a stale shim pointing at a deleted tree. + +DevCentr's toolchain lifecycle story and OpenShellOrg's shell-boundary story are siblings, not duplicates. +We orchestrate pins and health; they stress-test whether the shell can trust what it launches. +An install layout that hides binaries deep in `%ProgramFiles%` without a stable entrypoint is not "more secure"—it is **invisible**, which makes dispatch guesses and user hacks more likely, not fewer. + +If you care about structured shells, treat **shell-visible installs** as a first-class layout requirement, not a packaging afterthought. + +== Tooling as hypothesis, not billboard + +Docs should lead; tools should falsify the docs. + +We are exploring link:https://github.com/dev-centr/install-coordinator[Install Coordinator] because orchestration—claims, queues, visible waits—is the gap behind pretty wizards and ugly mutex dialogs. +link:https://github.com/dev-centr/ibex-install-builder[Ibex] is the host we use to try in-place PATH with ledgers, file-manager actions, and `installer.kdl` backends without pretending every artifact is MSI. +Neither repo is the essay's punchline. +They are where we test whether the norms survive contact with Windows Explorer and CI emit. + +Ibex tool docs: link:https://docs.devcentr.org/tools/ibex/latest/index.html[Ibex]. +Pattern comparison: link:https://docs.devcentr.org/general-knowledge/explanation/architecture/installation/good-vs-bad-patterns.html[Good vs bad install patterns]. + +== What I want you to take away + +Stop asking "where does FHS say?" as the first question. +Ask **what this install claims**, **who shares those resources**, **how undo works**, and **whether a shell or a graph can find the entrypoint without spelunking**. + +If you maintain an installer, write those answers down before the next path flamewar. +If you are designing storage or dispatch, read UIL alongside connectome-fs and OpenShellOrg's essays—same human problem, different altitude. + +The guide will change when the field teaches us something new. +So will this page. +That is the point of inner-thought writing: the layout is a craft, not a press release. diff --git a/public/news/atom.xml b/public/news/atom.xml index e736ce8..3862259 100644 --- a/public/news/atom.xml +++ b/public/news/atom.xml @@ -4,8 +4,17 @@ https://devcentr.org/news - 2026-09-03T12:00:00Z + 2026-09-18T12:00:00Z News and engineering blog posts from Dev-Centr. + + What a good install actually is + + https://devcentr.org/news/2026-09-18-what-a-good-install-actually-is + 2026-09-18T12:00:00Z + Installation norms as craft — why FHS cargo-cult breaks, why Windows honest writes are a requirement set, and how a dual-mode layout might survive connectome-fs. + + + MarkView for reading Markdown on disk diff --git a/public/news/rss.xml b/public/news/rss.xml index a6eb8c0..6baf34d 100644 --- a/public/news/rss.xml +++ b/public/news/rss.xml @@ -5,7 +5,16 @@ https://devcentr.org/news News and engineering blog posts from Dev-Centr. en-us - Thu, 03 Sep 2026 12:00:00 GMT + Fri, 18 Sep 2026 12:00:00 GMT + + What a good install actually is + https://devcentr.org/news/2026-09-18-what-a-good-install-actually-is + https://devcentr.org/news/2026-09-18-what-a-good-install-actually-is + Fri, 18 Sep 2026 12:00:00 GMT + Installation norms as craft — why FHS cargo-cult breaks, why Windows honest writes are a requirement set, and how a dual-mode layout might survive connectome-fs. + blog + news + MarkView for reading Markdown on disk https://devcentr.org/news/2026-09-03-markview-for-reading-markdown-on-disk diff --git a/src/lib/news-posts.generated.json b/src/lib/news-posts.generated.json index a2252f6..d3a9f75 100644 --- a/src/lib/news-posts.generated.json +++ b/src/lib/news-posts.generated.json @@ -1,5 +1,27 @@ { "posts": [ + { + "slug": "2026-09-18-what-a-good-install-actually-is", + "title": "What a good install actually is", + "description": "Installation norms as craft — why FHS cargo-cult breaks, why Windows honest writes are a requirement set, and how a dual-mode layout might survive connectome-fs.", + "date": "2026-09-18", + "tags": [ + "blog", + "installation", + "FHS", + "UIL", + "POSIX", + "Windows", + "connectome-fs", + "OpenShellOrg", + "Ibex", + "Install Coordinator", + "DevCentr", + "news" + ], + "html": "
\n
\n
\n

You know the argument.\nSomeone pastes the FHS paragraph about /usr/local and declares victory.\nSomeone else points at %ProgramFiles% and mutters about MSI like it is a moral failing.\nA third person lives in ~/.local/bin and refuses to explain why that is different from the first two.\nEveryone is half right.\nEveryone is also performing a standard they never read end-to-end.

\n
\n
\n

I keep coming back to installs because they are where philosophy meets disk: what you claim to own, what you leave reversible, and what a shell—or a graph store five years from now—can still find without archaeology.

\n
\n
\n

This essay is not a shipping notice.\nIt is the craft frame behind an installation norms guide and a layout proposal (UIL) we are writing into general-knowledge.\nRead those pages when you want checklists and diagrams.\nStay here if you want the why.

\n
\n
\n
\n
\n

Layout theater vs an install contract

\n
\n
\n

A bad install, in the sense that keeps hurting users, is not always a buggy script.\nOften it is an unstated contract: files copied because \"that is where things go,\" global environment mutated without a ledger, uninstall that deletes a folder but not the PATH entry that outlived it, upgrade that assumes only one version may exist because the author never side-by-side’d anything.

\n
\n
\n

A good install names its claims before it writes.\nMachine scope vs user scope is a design choice, not a default.\nSide-by-side versions are a feature when your CLI promises semver.\nRollback is not magic—it is knowing which registry keys, which services, which well-known names you touched.

\n
\n
\n

That sounds obvious written down.\nIt is rarely how installer templates behave, because templates optimize for the demo machine where /usr/local was empty and PATH was short.

\n
\n
\n

The norms guide we are assembling tries to say the quiet part out loud: separate \"where files land\" from \"what the install promises to the rest of the system.\"\nLand files in a tree that matches your support story.\nPromise the environment in a record something else can read—future you, a coordinator, a shell pin resolver.

\n
\n
\n
\n
\n

FHS, SUS, and the cargo-cult trap

\n
\n
\n

The Filesystem Hierarchy Standard is useful the way a city map is useful: it orients newcomers.\nIt is not a runtime API.\nNothing in the kernel rejects your binary because you chose opt/myvendor instead of a wiki’s favorite spelling.

\n
\n
\n

POSIX and the Single UNIX Specification are deeper—they stabilize behavior engineers can rely on across systems.\nThey still do not answer the question that burns CLI authors: where does this tool live for one user on one laptop when the distro package manager, the language ecosystem, and the vendor tarball all disagree?

\n
\n
\n

Cargo-cult FHS is the habit of quoting hierarchy documents without naming claims.\nYou see it in post-install scripts that chmod +x into system directories \"because Linux,\" in Docker images that mimic a full FHS tree for a single static binary, in debates that treat /usr/local as sin or sacrament without asking who shares that prefix on the host.

\n
\n
\n

Craft means treating variance as input.\nFedora’s packaging norms, Ubuntu’s Snaps, a corporate golden image, and your own ~/.local habit are different hosts.\nA layout that works is one whose assumptions are explicit—and whose undo path does not require guessing which of three PATH edits was yours.

\n
\n
\n
\n
\n

Windows: direct-to-disk is not cheating

\n
\n
\n

Linux people sometimes treat Windows \"portable folder plus PATH\" installs as immature.\nThat judgment skips the platform’s requirement set.

\n
\n
\n

MSI is a transactional, serialized mutation engine with a global lock and shared component bookkeeping.\nIt exists because IT needed pessimistic safety more than parallel indie installs.\nThe _MSIExecute mutex is not stupidity; it is a coarse gate chosen before your package’s file list is known.\nWe wrote about that feeling—double-click, silence, Another installation is already in progress—in When unrelated installers still queue.

\n
\n
\n

So Windows tools often write where you point them or append PATH in place with a ledger because the alternative is pretending every dev iteration is an enterprise MSI.\nThat is not avoiding adulthood.\nIt is matching the job: iterative CLI work wants reversibility and visibility, not a ref-count graph for a redistributable you never shared.

\n
\n
\n

Craft on Windows still means the same contract: declare claims, keep undo honest, export MSI/MSIX when the deployment story requires tables and GPO—not because MSI is the only moral installer.

\n
\n
\n
\n
\n

Linux variance without pretending one /usr

\n
\n
\n

On Linux the pain is pluralism, not absence of standards.\nXDG gives config and data homes; binaries still scatter.\nDistro packages, language-specific shims, and vendor tarballs coexist on one $PATH, and tab completion breaks in proportion to how many silent mutators ran before login.

\n
\n
\n

Good craft here looks like well-known entrypoint names, versioned install roots, and environment mutation you can enumerate.\nBad craft looks like \"we picked /usr/local/bin because the README said so\" with no story for Nix users, container bind mounts, or a user who cannot sudo.

\n
\n
\n

The encyclopedia cluster under installation architecture names patterns and anti-patterns so authors stop re-deriving this thread from first principles on every new tool.

\n
\n
\n
\n
\n

UIL: one layout, two futures

\n
\n
\n

The Unity Install Layout (UIL) proposal is the structural bet I want to be wrong about in the details but right about in shape.

\n
\n
\n

Classic mode is today: explicit roots, side-by-side versions, ledgers for PATH and registry, entrypoints a shell can see.

\n
\n
\n

Connectome mode is tomorrow’s graph: the same install as addressable content—editions, dependencies, rollback as graph operations, not only rm -rf and hope.

\n
\n
\n

connectome-fs (connectome-fs.github.io) is the sibling org exploring that substrate—content-addressed storage where dependency edges can be first-class.\nI am not claiming your next laptop boots into a graph filesystem.\nI am claiming that if your install story only maps to a directory tree, you will rewrite it when graph-native storage stops being a research slide.

\n
\n
\n

UIL is dual-mode so we do not fork the mental model: the manifest you author for classic paths should have a straight mapping to connectome editions.\nIf that mapping is painful, the manifest is lying about what an install is.

\n
\n
\n

Proposal write-up: Unity Install Layout (UIL).\nNorms checklist: Installation norms.

\n
\n
\n
\n
\n

Shell visibility (why OpenShellOrg is in this essay)

\n
\n
\n

OpenShellOrg cares about entrypoint dispatch—pins, re-exec, refusing to let the wrong Node answer when the pin said otherwise.\nThat work only succeeds when installs are honest on the shell boundary: binaries and shims on PATH, registrations that match what landed on disk, undo that does not leave a stale shim pointing at a deleted tree.

\n
\n
\n

DevCentr’s toolchain lifecycle story and OpenShellOrg’s shell-boundary story are siblings, not duplicates.\nWe orchestrate pins and health; they stress-test whether the shell can trust what it launches.\nAn install layout that hides binaries deep in %ProgramFiles% without a stable entrypoint is not \"more secure\"—it is invisible, which makes dispatch guesses and user hacks more likely, not fewer.

\n
\n
\n

If you care about structured shells, treat shell-visible installs as a first-class layout requirement, not a packaging afterthought.

\n
\n
\n
\n
\n

Tooling as hypothesis, not billboard

\n
\n
\n

Docs should lead; tools should falsify the docs.

\n
\n
\n

We are exploring Install Coordinator because orchestration—claims, queues, visible waits—is the gap behind pretty wizards and ugly mutex dialogs.\nIbex is the host we use to try in-place PATH with ledgers, file-manager actions, and installer.kdl backends without pretending every artifact is MSI.\nNeither repo is the essay’s punchline.\nThey are where we test whether the norms survive contact with Windows Explorer and CI emit.

\n
\n
\n

Ibex tool docs: Ibex.\nPattern comparison: Good vs bad install patterns.

\n
\n
\n
\n
\n

What I want you to take away

\n
\n
\n

Stop asking \"where does FHS say?\" as the first question.\nAsk what this install claims, who shares those resources, how undo works, and whether a shell or a graph can find the entrypoint without spelunking.

\n
\n
\n

If you maintain an installer, write those answers down before the next path flamewar.\nIf you are designing storage or dispatch, read UIL alongside connectome-fs and OpenShellOrg’s essays—same human problem, different altitude.

\n
\n
\n

The guide will change when the field teaches us something new.\nSo will this page.\nThat is the point of inner-thought writing: the layout is a craft, not a press release.

\n
\n
\n
", + "source": "authored" + }, { "slug": "2026-09-03-markview-for-reading-markdown-on-disk", "title": "MarkView for reading Markdown on disk", @@ -192,7 +214,7 @@ "dlang", "dlangui" ], - "html": "
\n

A text file can store a configuration. It cannot, by itself, tell an operator which other keys exist, what the enum is, or why a default is safe. That gap is now a Dev-Centr product: UniConfig Config Panel, a schema-driven desktop surface for config files that never grew their own settings UI.

\n
\n
\n

The first beat is deliberately ordinary. Point the app at a .gitconfig, a dub.sdl, an EditorConfig, or a Terraform .tfvars. The same panel widgets appear: labels, descriptions, drop-downs, include checkboxes for unset schema fields. Opened files register into a left-hand tree persisted as SDLang (registry.sdl). Headless dump and validate exist for the same merge.

\n
\n
\n

The engine is a separate D package, uniconfig-core, so the DevCentr suite can depend on the tree without dragging dlangui. Profiles that map filename globs onto JSON Schema ship as SDLang beside the exe. The optional Vello GPU path on the dlang-supplemental dlangui fork is documented, not required; default builds stay on dlangui’s stock backend.

\n
\n
\n

Docs: UniConfig ·\nReleases: uniconfig ·\nLibrary: uniconfig-core ·\nHCI companion: When config files withhold the vocabulary.

\n
\n
\n
\n\"Split\n
\n
Figure 1. File versus panel
\n
", + "html": "
\n

A text file can store a configuration. It cannot, by itself, tell an operator which other keys exist, what the enum is, or why a default is safe. That gap is now a Dev-Centr product: UniConfig Config Panel, a schema-driven desktop surface for config files that never grew their own settings UI.

\n
\n
\n

The first beat is deliberately ordinary. Point the app at a .gitconfig, a dub.sdl, an EditorConfig, or a Terraform .tfvars. The same panel widgets appear: labels, descriptions, drop-downs, include checkboxes for unset schema fields. Opened files register into a left-hand tree persisted as SDLang (registry.sdl). Headless dump and validate exist for the same merge.

\n
\n
\n

The engine is a separate D package, uniconfig-core, so the DevCentr suite can depend on the tree without dragging dlangui. Profiles that map filename globs onto JSON Schema ship as SDLang beside the exe. The optional Vello GPU path on the dlang-supplemental dlangui fork is documented, not required; default builds stay on dlangui’s stock backend.

\n
\n
\n

Docs: UniConfig ·\nReleases: uniconfig ·\nLibrary: uniconfig-core ·\nHCI companion: When config files withhold the vocabulary.

\n
\n
\n
\n\"Split\n
\n
Figure 1. File versus panel
\n
", "source": "authored" }, { @@ -247,7 +269,7 @@ "vocabulary", "security" ], - "html": "
\n
\n
\n

Open almost any developer console and you will find the same soft lie waiting under a friendly button: Generate your API access token.\nYou click it.\nYou get a long string that never expires unless you delete it, that identifies your project or account, and that you will paste into a .env file and forget until something leaks.\nThat string is not an access token in the OAuth sense.\nIt is an API key wearing a costume stitched from marketing and Bearer-header habits.

\n
\n
\n

We are done pretending the costume is the thing.\nDev-Centr’s docs and Secrets Manager now name credentials by what they do, not by what the vendor’s UI whispered while you were trying to ship.

\n
\n
\n

Practitioner lock (use this in reviews and agent prompts): API key vs token.\nProduct enforcement: Secrets Manager vocabulary.

\n
\n
\n
\n
\n

A scene from every onboarding

\n
\n
\n

Picture a Monday standup where someone says the integration is \"using a token.\"\nHalf the room hears short-lived OAuth bearer from a login flow.\nThe other half hears the string we copied from Settings → Developers last quarter.\nNobody notices the mismatch until a rotation runbook says \"revoke the key\" and an agent helpfully tries to refresh it like a session.

\n
\n
\n

That is not pedantry.\nWrong nouns pick the wrong playbook: dashboard rotate versus protocol refresh; project metering versus user consent; forever-secret versus fifteen-minute claim set.

\n
\n
\n
\n
\n

What the words actually mean

\n
\n
\n

An API key identifies the application or project making the request.\nIt is how a platform bills you, rates you, and attributes traffic to \"the Stripe integration\" or \"the mobile backend.\"\nIt does not prove which human is pressing the buttons inside that app.

\n
\n
\n

An access token—OAuth access token, JWT bearer, session token—identifies an authorized subject for a limited time.\nIt answers what this holder may do now, often with scopes and an expiry baked into the credential (or into the introspection service behind it).

\n
\n
\n

Hold the analogies for a second and you can feel the difference in your hands:

\n
\n
\n
    \n
  • \n

    The API key is the project’s driver’s license. The meter knows which fleet car pulled up.

    \n
  • \n
  • \n

    The access token is a hotel keycard. It opens these floors for this stay. Morning checkout is a feature, not a bug.

    \n
  • \n
\n
\n
\n
\n
\n

How \"token\" ate the dashboard

\n
\n
\n

OAuth taught a generation of engineers that scoped access arrives as an access token.\nCloud consoles borrowed the word for a different product: long-lived secrets you mint yourself, optionally with checkbox scopes, optionally revoked one-by-one without nuking the whole account.

\n
\n
\n

So the industry grew a middle creature—scoped API keys, often sold as personal access tokens (PATs)—and dressed it in token language because:

\n
\n
\n
    \n
  • \n

    scopes made it feel like OAuth,

    \n
  • \n
  • \n

    Bearer headers made it travel like OAuth,

    \n
  • \n
  • \n

    and \"token\" sounded newer and safer than the grim old \"API key\" that once meant a single immortal string for the entire account.

    \n
  • \n
\n
\n
\n

Useful product evolution.\nTerrible vocabulary.

\n
\n
\n

Under the hood you still have two architectures:

\n
\n
\n
    \n
  • \n

    Scoped key / PAT — long-lived, dashboard-born, manually revoked, project- or account-bound with capability limits.

    \n
  • \n
  • \n

    True access token — handshake-born, short TTL, subject-bound, refreshed by protocol rather than by a human with a clipboard.

    \n
  • \n
\n
\n
\n
\n
\n

The rule we are enforcing

\n
\n
\n

Ignore the button.\nAsk three questions:

\n
\n
\n
    \n
  1. \n

    Was this pasted from a settings page, or minted by a login / client-credentials handshake?

    \n
  2. \n
  3. \n

    Does it expire in minutes or hours by design, or only when someone deletes it?

    \n
  4. \n
  5. \n

    Does it authorize a user or session, or only identify a project for metering?

    \n
  6. \n
\n
\n
\n

Dashboard paste + manual revoke → API key (scoped or not).\nHandshake + TTL → access token (and keep refresh token for the minting secret, not for ordinary API calls).

\n
\n
\n

In Secrets Manager kinds we write that as api_key, scoped_api_key, access_token, and refresh_token.\nVendor aliases can live in notes for search.\nThey do not get to own the type field.

\n
\n
\n
\n
\n

Why Dev-Centr is picking this fight

\n
\n
\n

We distribute secrets for a living—vendor → vault → local env → hosting matrix—and agents already hallucinate env names when the nouns wobble.\nIf the UI says \"token\" and the architecture says \"key,\" the agent will under-rotate forever-strings or over-store live session material.\nSecurity reviews then argue about words instead of blast radius.

\n
\n
\n

So the docs tell the truth, the product forces the kinds, and this post is the public notice: stop calling keys tokens just because a dashboard did.

\n
\n
\n

The costume can stay on the marketing site.\nIt does not get into our registry.

\n
\n
\n
", + "html": "
\n
\n
\n

Open almost any developer console and you will find the same soft lie waiting under a friendly button: Generate your API access token.\nYou click it.\nYou get a long string that never expires unless you delete it, that identifies your project or account, and that you will paste into a .env file and forget until something leaks.\nThat string is not an access token in the OAuth sense.\nIt is an API key wearing a costume stitched from marketing and Bearer-header habits.

\n
\n
\n

We are done pretending the costume is the thing.\nDev-Centr’s docs and Secrets Manager now name credentials by what they do, not by what the vendor’s UI whispered while you were trying to ship.

\n
\n
\n

Practitioner lock (use this in reviews and agent prompts): API key vs token.\nProduct enforcement: Secrets Manager vocabulary.

\n
\n
\n
\n
\n

A scene from every onboarding

\n
\n
\n

Picture a Monday standup where someone says the integration is \"using a token.\"\nHalf the room hears short-lived OAuth bearer from a login flow.\nThe other half hears the string we copied from Settings → Developers last quarter.\nNobody notices the mismatch until a rotation runbook says \"revoke the key\" and an agent helpfully tries to refresh it like a session.

\n
\n
\n

That is not pedantry.\nWrong nouns pick the wrong playbook: dashboard rotate versus protocol refresh; project metering versus user consent; forever-secret versus fifteen-minute claim set.

\n
\n
\n
\n
\n

What the words actually mean

\n
\n
\n

An API key identifies the application or project making the request.\nIt is how a platform bills you, rates you, and attributes traffic to \"the Stripe integration\" or \"the mobile backend.\"\nIt does not prove which human is pressing the buttons inside that app.

\n
\n
\n

An access token—OAuth access token, JWT bearer, session token—identifies an authorized subject for a limited time.\nIt answers what this holder may do now, often with scopes and an expiry baked into the credential (or into the introspection service behind it).

\n
\n
\n

Hold the analogies for a second and you can feel the difference in your hands:

\n
\n
\n
    \n
  • \n

    The API key is the project’s driver’s license. The meter knows which fleet car pulled up.

    \n
  • \n
  • \n

    The access token is a hotel keycard. It opens these floors for this stay. Morning checkout is a feature, not a bug.

    \n
  • \n
\n
\n
\n
\n
\n

How \"token\" ate the dashboard

\n
\n
\n

OAuth taught a generation of engineers that scoped access arrives as an access token.\nCloud consoles borrowed the word for a different product: long-lived secrets you mint yourself, optionally with checkbox scopes, optionally revoked one-by-one without nuking the whole account.

\n
\n
\n

So the industry grew a middle creature—scoped API keys, often sold as personal access tokens (PATs)—and dressed it in token language because:

\n
\n
\n
    \n
  • \n

    scopes made it feel like OAuth,

    \n
  • \n
  • \n

    Bearer headers made it travel like OAuth,

    \n
  • \n
  • \n

    and \"token\" sounded newer and safer than the grim old \"API key\" that once meant a single immortal string for the entire account.

    \n
  • \n
\n
\n
\n

Useful product evolution.\nTerrible vocabulary.

\n
\n
\n

Under the hood you still have two architectures:

\n
\n
\n
    \n
  • \n

    Scoped key / PAT — long-lived, dashboard-born, manually revoked, project- or account-bound with capability limits.

    \n
  • \n
  • \n

    True access token — handshake-born, short TTL, subject-bound, refreshed by protocol rather than by a human with a clipboard.

    \n
  • \n
\n
\n
\n
\n
\n

The rule we are enforcing

\n
\n
\n

Ignore the button.\nAsk three questions:

\n
\n
\n
    \n
  1. \n

    Was this pasted from a settings page, or minted by a login / client-credentials handshake?

    \n
  2. \n
  3. \n

    Does it expire in minutes or hours by design, or only when someone deletes it?

    \n
  4. \n
  5. \n

    Does it authorize a user or session, or only identify a project for metering?

    \n
  6. \n
\n
\n
\n

Dashboard paste + manual revoke → API key (scoped or not).\nHandshake + TTL → access token (and keep refresh token for the minting secret, not for ordinary API calls).

\n
\n
\n

In Secrets Manager kinds we write that as api_key, scoped_api_key, access_token, and refresh_token.\nVendor aliases can live in notes for search.\nThey do not get to own the type field.

\n
\n
\n
\n
\n

Why Dev-Centr is picking this fight

\n
\n
\n

We distribute secrets for a living—vendor → vault → local env → hosting matrix—and agents already hallucinate env names when the nouns wobble.\nIf the UI says \"token\" and the architecture says \"key,\" the agent will under-rotate forever-strings or over-store live session material.\nSecurity reviews then argue about words instead of blast radius.

\n
\n
\n

So the docs tell the truth, the product forces the kinds, and this post is the public notice: stop calling keys tokens just because a dashboard did.

\n
\n
\n

The costume can stay on the marketing site.\nIt does not get into our registry.

\n
\n
\n
", "source": "authored" }, { @@ -282,7 +304,7 @@ "packaging", "DevCentr" ], - "html": "
\n

msi-generator crossed the line from \"skeleton that prints a message\" to \"file you can open in an OLE/MSI viewer.\"

\n
\n
\n

v0.2 writes a version-3 compound file, an uncompressed cabinet payload, and the core table set (Directory, Component, File, Feature, FeatureComponents, Property, Media, plus _Tables / _Columns and the string pool). MSIX gained multi-file payloads and placeholder assets so manifests stop lying about missing logos.

\n
\n
\n

This is the engine Ibex’s msi / msix plugins call. It is not WiX, and we are not pretending an unsigned sample MSI is Store-ready — but the binary formats are finally real enough to iterate on.

\n
\n
\n

Release: v0.2.0 · docs: component.

\n
", + "html": "
\n

msi-generator crossed the line from \"skeleton that prints a message\" to \"file you can open in an OLE/MSI viewer.\"

\n
\n
\n

v0.2 writes a version-3 compound file, an uncompressed cabinet payload, and the core table set (Directory, Component, File, Feature, FeatureComponents, Property, Media, plus _Tables / _Columns and the string pool). MSIX gained multi-file payloads and placeholder assets so manifests stop lying about missing logos.

\n
\n
\n

This is the engine Ibex’s msi / msix plugins call. It is not WiX, and we are not pretending an unsigned sample MSI is Store-ready — but the binary formats are finally real enough to iterate on.

\n
\n
\n

Release: v0.2.0 · docs: component.

\n
", "source": "authored" }, { @@ -300,7 +322,7 @@ "CI", "DevCentr" ], - "html": "
\n

DevCentr’s new install tool is out: Ibex (Install Builder EXtension). It turns \"put this folder on PATH\" and \"build an installer from this tree\" into something you can right-click or script. The CLI is ibex.

\n
\n
\n

The first beat is deliberately small. Install in-place (add to PATH) means what it says — append the folder to the user PATH, keep a ledger so you can undo, and skip the copy-into-Program-Files ritual when you are iterating on a CLI. File Explorer gets a menu for it (Win11 modern when the sparse package builds; classic cascade otherwise). Linux and macOS get file-manager actions too.

\n
\n
\n

The second beat is the project file. installer.kdl plus plugins: portable zip always works; NSIS and Inno emit scripts and call their compilers when present; MSI/MSIX call msi-generator; AppImage gets a stub path on Linux. Optional designer GUIs are discoverable (plugins install-gui) instead of reinvented inside our IDE.

\n
\n
\n

CI ships in the same cut. Edit ci-runner.sdl, run emit-ci, and get runner YAML plus CI-INSTALLER.adoc (how to enable pipelines, secrets, tags, and artifact downloads). Local build stays optional for smoke tests. Emitters in this release: GitHub Actions, GitLab CI, Azure Pipelines, Jenkins (Declarative), CircleCI, and Bitbucket Pipelines. DevCentr’s New Installer dialog can choose CI pipeline only; Explorer gets New Installer CI pipeline (--mode=emit-ci).

\n
\n
\n

DevCentr picks up the same verbs — New → Installer Project, toolbar Install in-place PATH, and CLI modes — so the OS menu and the app are not two products pretending to be one.

\n
\n
\n

Docs: Ibex · emit CI how-to · releases.

\n
\n
\n
\n\"Ibex\n
\n
Figure 1. Idealized Ibex project UI
\n
\n
\n
\n\"DevCentr\n
\n
Figure 2. DevCentr extension surface
\n
", + "html": "
\n

DevCentr’s new install tool is out: Ibex (Install Builder EXtension). It turns \"put this folder on PATH\" and \"build an installer from this tree\" into something you can right-click or script. The CLI is ibex.

\n
\n
\n

The first beat is deliberately small. Install in-place (add to PATH) means what it says — append the folder to the user PATH, keep a ledger so you can undo, and skip the copy-into-Program-Files ritual when you are iterating on a CLI. File Explorer gets a menu for it (Win11 modern when the sparse package builds; classic cascade otherwise). Linux and macOS get file-manager actions too.

\n
\n
\n

The second beat is the project file. installer.kdl plus plugins: portable zip always works; NSIS and Inno emit scripts and call their compilers when present; MSI/MSIX call msi-generator; AppImage gets a stub path on Linux. Optional designer GUIs are discoverable (plugins install-gui) instead of reinvented inside our IDE.

\n
\n
\n

CI ships in the same cut. Edit ci-runner.sdl, run emit-ci, and get runner YAML plus CI-INSTALLER.adoc (how to enable pipelines, secrets, tags, and artifact downloads). Local build stays optional for smoke tests. Emitters in this release: GitHub Actions, GitLab CI, Azure Pipelines, Jenkins (Declarative), CircleCI, and Bitbucket Pipelines. DevCentr’s New Installer dialog can choose CI pipeline only; Explorer gets New Installer CI pipeline (--mode=emit-ci).

\n
\n
\n

DevCentr picks up the same verbs — New → Installer Project, toolbar Install in-place PATH, and CLI modes — so the OS menu and the app are not two products pretending to be one.

\n
\n
\n

Docs: Ibex · emit CI how-to · releases.

\n
\n
\n
\n\"Ibex\n
\n
Figure 1. Idealized Ibex project UI
\n
\n
\n
\n\"DevCentr\n
\n
Figure 2. DevCentr extension surface
\n
", "source": "authored" }, {