Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions .github/check-palette-single-source.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@
* steelbore-color-palette/assets/** — the canonical TOML and its generated
mirrors (steelbore.scm is drift-gated by generate-steelbore-scm.py; the CSS
is a rendering of the same data)
* spacecraft-steelbore-standard/** — TEMPORARY. §11 of the Standard is the
normative palette specification and mirrors the published .texi, so values
cannot be removed from it inside this repository alone: that is a normative
change requiring the two-repo, two-PR flow at a matching version and date.
Remove this exemption when that pair lands.

The Standard skill was exempt until v2.03. §11 was the normative palette
specification and carried the values itself, so they could not be removed here
alone — that took a two-repo change at a matching version. v2.03 inverted §11.4:
the TOML now governs every value and §11 governs the contract around it, so the
exemption is gone and the skill is checked like everything else.
Comment on lines +64 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate the shipped CSS derivatives against the TOML

Once the TOML governs every value, this transition still leaves nine literal palette values in both steelbore-color-palette/assets/spacecraft.css and its shipped spacecraft-texinfo-document/assets/spacecraft.css derivative without a generator or comparison gate. The checker only scans .md files, so after a future TOML edit CI can report single-source OK while generated HTML continues using stale colors. Generate these stylesheets from the TOML or add a value/byte drift check covering both copies.

Useful? React with 👍 / 👎.


Usage:
check-palette-single-source.py [ROOT]
Expand All @@ -73,10 +74,17 @@

ALLOWED_PREFIXES = (
os.path.join("steelbore-color-palette", "assets"),
# See the module docstring: normative spec, removable only via a Standard change.
"spacecraft-steelbore-standard",
)

# CHANGELOG.md anywhere is exempt, and this one is not a convenience either. A
# changelog is a historical record: the v1.45 entry describing Tokyo Night's
# arrival quotes the canvas that version introduced, and that quotation is a
# statement about what was true then. Editing it to name a token instead would
# falsify the record — the entry would claim a wording the release never had.
# Those values are also inert: nothing reads a changelog to resolve a colour, so
# a stale one misleads no implementation. Live prose is what this gate is for.
EXEMPT_BASENAMES = {"CHANGELOG.md"}

# Third-party trees keep upstream's content verbatim under Standard §4.2, and
# construct-cli is code with its own fixtures rather than palette prose.
SKIP_DIRS = {".git", ".github", ".githooks", "android-skills", "orca-skills",
Expand All @@ -103,7 +111,7 @@ def main(argv):
continue
full = os.path.join(dirpath, fn)
rel = os.path.relpath(full, root)
if allowed(rel):
if allowed(rel) or fn in EXEMPT_BASENAMES:
continue
try:
text = open(full, encoding="utf-8").read()
Expand Down
Binary file modified spacecraft-steelbore-standard.skill
Binary file not shown.
Binary file modified spacecraft-steelbore-standard.zip
Binary file not shown.
4 changes: 2 additions & 2 deletions spacecraft-steelbore-standard/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: >
Spacecraft Software-umbrella project — even if the user doesn't explicitly mention the Standard.
If the user mentions "Spacecraft Software", a Spacecraft Software subproject name, or asks you to work on
anything in the Spacecraft Software ecosystem, consult this skill immediately. It encodes
The Steelbore Standard v2.02 (§19-§26 assurance + requirements + V&V; §13 design systems; §3.1.1 TypeScript; §5.7 AGENTS.md; §6.4 contribution targets; §5.6 skill packaging; §11 palettes + §11.6 system theme; §18 accessibility; §17 progress reporting; §3.3 security-by-design) so
The Steelbore Standard v2.03 (§19-§26 assurance + requirements + V&V; §13 design systems; §3.1.1 TypeScript; §5.7 AGENTS.md; §6.4 contribution targets; §5.6 skill packaging; §11 palettes + §11.6 system theme; §18 accessibility; §17 progress reporting; §3.3 security-by-design) so
you never need to ask for it or have it attached to a prompt again.
license: GPL-3.0-or-later
maintainer: Mohamed Hammad <Mohamed.Hammad@SpacecraftSoftware.org>
Expand All @@ -17,7 +17,7 @@ website: https://Construct.SpacecraftSoftware.org/

# The Steelbore Standard — Compliance Reference

**Version:** 2.02 | **Date:** 2026-09-12 | **Author:** Mohamed Hammad
**Version:** 2.03 | **Date:** 2026-09-14 | **Author:** Mohamed Hammad

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align the palette skill with the new authority order

After this version switch, steelbore-color-palette/SKILL.md:29-34 still says §11 was last amended in v1.45 and, critically, that the Standard wins disagreements, while assets/steelbore.toml also identifies v1.45 as its governing Standard. In the exact conflict this release is meant to resolve, an agent loading the required palette skill is therefore told the opposite precedence and may discard the authoritative TOML value. Update the palette skill and TOML authority metadata, then rebuild both palette bundles as part of the v2.03 sync.

AGENTS.md reference: AGENTS.md:L47-L52

Useful? React with 👍 / 👎.

**Maintainer:** Mohamed Hammad | **Contact:** [Mohamed.Hammad@SpacecraftSoftware.org](mailto:Mohamed.Hammad@SpacecraftSoftware.org)
**Copyright:** Copyright (C) 2026 Mohamed Hammad & Spacecraft Software | **License:** GPL-3.0-or-later
**Website:** [https://Construct.SpacecraftSoftware.org/](https://Construct.SpacecraftSoftware.org/)
Expand Down
2 changes: 2 additions & 0 deletions spacecraft-steelbore-standard/references/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ activation. The canonical record is the published Standard's own
`standard/CHANGELOG.md` (extracted from §1 of the document itself in v1.37); this
file mirrors it and must be synced to the same version and date.

- **v2.03 (2026-09-14):** **§11 stops restating colour values — `steelbore.toml` becomes the single source, and §11.4's tie-break clause is inverted.** §11 has always named `steelbore.toml` "the canonical machine-readable source" and instructed that **values are read, never retyped** — then printed all 157 of them itself, across eleven tables spanning §11.0 through §11.5. The instruction and the document disagreed, and §11.4 settled it in the document's favour: *"Where this document and that file disagree, this document governs and the file is corrected."* That clause was the cost of keeping two copies — something had to break the tie, and a specification is the natural winner. **v2.03 stops keeping two copies.** Every hex and RGB triple is removed from §11; each table names the token and the role it plays, with the value obtained from the file. Where dropping a value column would have destroyed meaning the column was converted rather than deleted: §11.1.1's "Variant hex" is now "Variant token" and reads `Plasma Orange Lift` where it read a hex, with unlifted rows saying `(unchanged)` rather than repeating their base; the seven per-palette "Color" headers became "Token"; and a §8.6 table carrying canvases by hex was converted the same way. **The normative heart is §11.4's inversion**: the file now governs every value and §11 governs the contract around it — which roles exist, which are mandatory, what the contrast guarantee covers, which palettes are adoptable. The two can no longer disagree about a colour because only one of them states one, and changing a colour is a single edit rather than an edit plus a search for every restatement. **The cost is written into §11.4 rather than left for a reader to find: §11 can no longer be implemented from the published document alone.** A reader of the PDF, HTML, or Info output gets role names, contracts, and palette membership, but needs `steelbore.toml` for any colour — a real reduction in self-sufficiency, accepted in exchange for values having exactly one definition. **Contrast ratios stay**, deliberately: a measured ratio and a WCAG threshold are textually identical (`15.09:1` is a measurement, `4.5:1` is the AA rule), so removing one class would have removed the other and taken §11.0.2's matrix with it; 168 ratios are preserved. **Unchanged:** every role name, the contrast guarantee, the palette family and its membership, §11.5's non-adoptable fidelity palettes, and §11.6's resolution order. No project conforming at v2.02 becomes non-conformant at v2.03. This is the skill-side sync of Standard PR #36. This skill's own frontmatter `description` measures 994 characters under the §5.6 cap — only the version number moved.

- **v2.02 (2026-09-12):** **§6.5's CI gate corrected — it reads the index, not the working tree.** v1.51 required CI to fail when "a tracked text file contains a CR byte" and left the implementation to the reader; the reference implementation grepped the working tree (`git grep -Il $'\r'`), and the accompanying note claimed `git grep` "honors `.gitattributes`, so a pinned exception is invisible to it and needs no exclusion list." **That claim is false, and it breaks the exception §6.5 itself grants.** A file pinned `*.bat text eol=crlf` is stored LF in the repository and *checked out CRLF by design* — that is the entire point of the pin. `git grep` reads the working tree, finds the CR the pin deliberately put there, and fails the build. The section granted an exception in one row and shipped a gate that punished it in the next, and the two rows only appeared to agree because no repository had yet needed a pinned exception. It was found the moment one did: `achernar` carries a `gradlew.bat`, which a Windows batch interpreter requires in CRLF. **The gate now reads what is stored.** `git ls-files --eol` reports each file's index line ending as `i/lf`, `i/crlf` or `i/mixed`, and any `i/crlf` or `i/mixed` is the violation — CRLF *in the repository*, which is what §6.5 was always about. A pinned `eol=crlf` file reports `i/lf` and passes, correctly; a path pinned `-text` is declared binary, is not a text file at all, and is skipped with its blob left exactly as it is — which is what a saved MIME archive or a binary git failed to auto-detect actually needs; and a file committed with CRLF before `.gitattributes` existed reports `i/crlf` and fails, which is exactly the case the section exists to catch. Validated against real repositories: `ironway` reports exactly 129 (matching an independent count), `bravais` 2, `achernar` 2, `standard` and `engram` 0. The row now specifies the mechanism rather than leaving it to the implementer, and states plainly that a working-tree grep is **not** a correct implementation. **A second fact the correction surfaced, worth recording because it changes what adoption costs:** `.gitattributes` does not retroactively normalize blobs already committed with CRLF. `bravais` has carried `* text=auto eol=lf` for months and still reports two `i/crlf` files; the attribute governs future writes and checkouts, and existing blobs stay as they are until `git add --renormalize` rewrites them. Adopting §6.5 in a repository that already carries CRLF is therefore two acts, not one — the config files, and a renormalization commit — and a rollout that ships only the first leaves the damage in place while reporting success. Nothing else in §6.5 changes. This is the skill-side sync of Standard PR #34. This skill's own frontmatter `description` measures 993 characters under the §5.6 cap — only the version number moved.

- **v2.01 (2026-09-12):** **§17.4 added — the Closing TL;DR.** §17 has governed the *progress report* since it was written, and v1.47 made that report thorough: one labelled row per track, its own bar, its own percentage, a specified cell count, normative column alignment. What it never governed is the last thing a reader actually reads. §17.3 has always required a summary "when summarizing the work done at the end of a turn/message" and said nothing whatsoever about its shape, so the end of a turn was whatever prose happened to trail off there — sometimes a paragraph, sometimes a list of everything touched, sometimes nothing at all, and frequently a completion claim buried three sentences into a recap of the method. It is the same failure §17 exists to catch, arriving one layer up: the numbers were made rigorous and the sentence a busy reader takes away from them was left unspecified. **§17.4 requires every turn that hands control back to the user — work finished, work stopped part-way, or a question that blocks further progress — to end with a two-line `TL;DR:` block**, placed last, after the prose and after any §17.1 progress block. Exactly two lines: long enough to say what happened and what it means, short enough that skipping it is not worth the effort. **The two closing shapes are the load-bearing part.** When the work is complete the second line ends with a plain statement of completion — `Job is done.` or an equivalent in the same register — and carries no question mark, because nothing is being asked. When the user's input is required the second line **ends with a question mark**, and the question is the actual decision they have to make: named, answerable, and specific enough to answer in one word or one sentence. "Let me know how you want to proceed?" names nothing and does not satisfy the rule. The punctuation is doing real work in both directions — a turn that ends without a question mark is *asserting* that nothing is blocked on the user, so a turn that needs an answer and closes on a period will simply not get one, and the work stalls while both sides believe it is the other's move. **Simplified English is a requirement rather than a preference.** Short, common words and short sentences; project jargon, unexplained abbreviations, section numbers, identifiers, and file paths stay in the prose above. The test is that a reader who skipped the entire turn still understands what happened from the two lines alone — which is the condition under which most end-of-turn text is genuinely read. **`Job is done` is a claim about the work, not a closing pleasantry.** It is written only when the work is actually finished and verified, on exactly the honesty rule §17.2 already applies to a saturated bar, which shows twenty filled cells only at 100% precisely because rounding 99% up reports work as finished that is not. Partly-done work says so and says what remains. A TL;DR asserting a completion the prose above it does not support is worse than no TL;DR at all, because it is the part the reader trusts and the part they will act on. **The block is additive and never substitutive**: it does not replace the detail, the file list, the caveats, or the §17.1 progress block. Two lines cannot carry a hand-off, and a turn that answers with a TL;DR alone has reported nothing. §17.4 is deliberately scoped wider than the chapter lede, which speaks of implementing from a PRD or project plan: the closing block binds every turn that returns control, including turns that wrote no code at all — a question is exactly the case where the reader most needs to know, in two lines, that they are the one being waited on. §16 gains a §17.4 bullet alongside the existing §17 one rather than lengthening it, since the two govern different artifacts. This is the skill-side sync of Standard PR #33. This skill's own frontmatter `description` measures 993 characters under the §5.6 cap — only the version number moved.
Expand Down
Loading
Loading