Files
spinifex/docs
Ben Duncan 4fbde4a665 docs(oci): ship the credential installer, and rewrite both OCI guides in the house voice (#1166)
* docs(oci): rewrite both OCI guides in the house voice

Seventy-five em dashes across the two guides, with four of them in headings where GitHub and the docs site slugify them differently and a cross-link resolves on neither. Recast as commas, colons and separate sentences.

The silent-credential failure was stated five times as the same triple, "forms, passes every health check, and then refuses every launch". It now reads in full once, under Credentials, and the other four refer back to it instead of echoing the skeleton.

Also broken up: the parallel stack in "Why run Spinifex on OCI", several five-sentence paragraphs, and a handful of clauses that leaned on a dash where a full stop was clearer.

No technical content changed. Every inline-code token is byte-identical before and after, every fenced block is unchanged apart from one comment line, and the four reworded headings carry no inbound anchor links. The docs build reports zero warnings for either page and both render at the same size as before.

* docs(oci): open the install guide with what Spinifex is, as the other install guides do

* docs(oci): ship the credential installer instead of asking for a hook

The guide told the reader to write their own executable to put the OCI API key
on each node, which is work nobody should have to do to install a product, and
the step was unclear about where the scoping actually happens.

`scripts/terraform/oci-spx/spx-oci-config.sh` now does it. It takes
`validate-topology.sh`'s hook contract, `hook <ssh-key> <host>...`, so it drops
straight into `--credential-hook` and is also runnable on its own against an
existing cluster.

It resolves the credential in four steps and takes the first complete one: the
`OCI_SPX_*` environment variables, the `[spinifex]` profile in `~/.oci/config`,
`~/.oci/oci_api_key_spx.pem` with the Terraform profile's identifiers, then the
Terraform credential itself with a warning that it is wider than the allocator
needs. Steps 2 to 4 go through `scripts/oci_env.py`, the same resolver the apply
uses, so the credential on the nodes and the one that built the infrastructure
cannot come from different profiles. The fingerprint is checked against the key
before anything is written, because a mismatched pair is otherwise an OCI 401 at
the first allocation, long after the deploy has reported success.

The node's filename stays `oci_api_key.pem` while the workstation's is
`oci_api_key_spx.pem`: the suffix exists only to keep the Spinifex key off
whatever `[DEFAULT]` uses, and a node has no other OCI key. Nothing reads the
name anyway, since the daemon learns the path from `key_file` inside
`/etc/spinifex/oci/config`.

Key material reaches the nodes over SSH, in the remote shell's stdin rather than
its arguments where `ps` would expose it, and goes into neither user-data nor
Terraform state. `--credential-hook` still accepts any executable with that
argument shape, so a tenancy that keeps credentials in a vault can substitute
its own.

Also in the guide: the policy statements name the compartment by `compartment
id` rather than by name, which is the form that resolves from a compartment the
policy is not attached at; `$CID` is consistently a compartment OCID; and the
table of contents matches the headings again.
2026-10-05 16:18:00 -05:00
..
2026-09-17 13:28:30 +10:00
2026-09-28 16:27:01 +10:00

Spinifex Documentation

This directory contains the Spinifex documentation. This is available in individual markdown files, and a generated website to aid navigation and browsing documentation at: https://docs.mulgadc.com

The AWS API coverage pages are generated from Spinifex's dispatch tables and the pinned AWS API models, one page per service. Run make aws-model-coverage to regenerate them and print a summary. Only pages.json and the intro.md files under coverage/ are hand-written; every README.md there is generated and will be overwritten.

The same run writes coverage/coverage.json, a versioned machine-readable model-versus-dispatch inventory. It is generated and must not be edited. Its operation states are structural: implemented means a registered action has neither a stub nor an explicit refusal. It is not a behavioural compatibility claim; conformance evidence and capability profiles establish that separately.

A published page names the operations Spinifex serves, and nothing else. It carries no percentage, no unimplemented operation and no operation the platform will never offer: the same run writes those to coverage/internal-report.md, which no slug in the docs site's configuration points at, so it stays internal. A notApplicable declaration in pages.json therefore publishes nothing; it keeps a permanent absence out of the report's candidate work.

Frontmatter

Each published page lives at <category>/<slug>/README.md and carries YAML frontmatter that the docs site turns into page metadata. Three fields have length rules, because search engines flag a title tag or meta description that falls outside them:

Field Renders as Length
title Page heading, sidebar label, landing card Short — it is UI text
seoTitle The browser and search-result title 50-60 characters
description The search-result snippet, not shown on the page 150-160 characters

seoTitle is used exactly as written and must end with — Spinifex Docs. Leave it out and the title falls back to title plus that suffix, which is normally too short to satisfy the rule.

Keep the two titles distinct. title is navigation text in a narrow sidebar, so stretching it to reach 50 characters damages the layout to satisfy a rule that only applies to the title tag. Put the search-facing wording in seoTitle.

A new page is only published once its path is added to scripts/docs-config.json in the mulga-docs repo. That repo's scripts/build-docs.js warns about any field outside its range.