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
Binary file modified spacecraft-steelbore-standard.skill
Binary file not shown.
Binary file modified spacecraft-steelbore-standard.zip
Binary file not shown.
41 changes: 37 additions & 4 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 v1.49 (§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.2 compiler flags; concurrency; §3.3 security-by-design) so
The Steelbore Standard v1.50 (§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.2 compiler flags; concurrency; §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:** 1.49 | **Date:** 2026-08-16 | **Author:** Mohamed Hammad
**Version:** 1.50 | **Date:** 2026-08-22 | **Author:** Mohamed Hammad
**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 Expand Up @@ -345,6 +345,26 @@ and the correct comment syntax for the file type.)
Two independently maintained copies of the same license text are **non-compliant**:
they drift, and a stale root `LICENSE` misreports the project's license to every
GitHub visitor.
- **License file naming.** The canonical filename is `LICENSE` — **no extension**.
`LICENSE.md` and `LICENSE.txt` are non-compliant. GitHub's detector ranks an
extensionless `LICENSE` above every extended form, and a canonical plain-text copy
matches on that detector's exact matcher rather than falling through to a fuzzy one;
a Markdown-formatted copy is in any case already excluded by the verbatimness rule
above.

`COPYING` MAY additionally be provided at the project root, as a **symbolic link** to
`LICENSE`, by projects that want the GNU convention alongside the GitHub-detected
name. It MUST NOT be a second regular copy of the text. It MUST NOT appear inside a
distributable sub-unit: archivers dereference symbolic links by default, so a linked
`COPYING` inside a bundle ships the whole license text a second time.

**More than one license.** Where an artifact is offered under more than one license —
a dual-licensed §4.2 upstream import, for example — each license text gets its own
file, named `LICENSE.<TAG>` (`LICENSE.GPL`, `LICENSE.MIT`), after GNU's
`COPYING.LESSER` and `COPYING.RUNTIME` convention. License texts are never
concatenated into one file. The authoritative statement of *which* licenses apply, and
of their exact versions, remains the SPDX expression in the file header or the
repo-root `REUSE.toml`; the filename tag is a human-facing label, not a version claim.
- **CI gate:** `reuse lint` MUST pass before shipping.

When writing or reviewing any file, confirm REUSE coverage; when generating a new file,
Expand Down Expand Up @@ -451,6 +471,19 @@ limits are therefore enforced **before packing**, not after a failure.
| Machine-enforced | The cap MUST be checked by an automated gate that runs both in the skill repository's CI on every pull request and push to the default branch, and in whatever command produces the distributable bundle. A developer-installed git hook is a convenience, never the gate — hooks are opt-in per clone and cannot be relied on. |
| Over-limit skills do not ship | A skill whose description exceeds the cap MUST NOT be packed, committed, or published. Trim the description; do not raise the cap. |

**License carriage.** A bundle is a distribution in its own right. Consumers install
the `.zip` or `.skill` without ever seeing the source repository, so the repo-root
`LICENSE` never reaches them. A copyleft license obliges the distributor to give every
recipient a copy of the license along with the work; the bundle is where that
obligation lands.

| Rule | Detail |
|------|--------|
| `LICENSE` in every skill | Each skill directory MUST contain a `LICENSE` file named per §4.3, and every bundle built from that directory MUST include it. A bundle carrying no license text does not satisfy the distribution terms of any copyleft license the skill is under. |

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 Define license carriage for vendored skill trees

For vendored Android skills, this unconditional source-directory requirement cannot be satisfied without violating the repository's upstream-preservation invariant: each android-skills/<name>/ leaf lacks a license, while mkSkillPackage publishes only that leaf and therefore omits the group-level android-skills/LICENSE.txt. Adding LICENSE to every leaf would make the vendored tree non-verbatim, so §5.6 needs a vendored-skill exception or a packaging-time license-injection rule before these per-skill packages can comply.

AGENTS.md reference: AGENTS.md:L244-L253

Useful? React with 👍 / 👎.

| Byte-identical to the root | Where the skill and the repository name the same license, the skill's `LICENSE` MUST be byte-identical to the repo-root `LICENSE`, and an automated gate MUST verify it. §4.3 forbids two independently maintained copies of a license text; enforced equality is what keeps these one maintained text rather than two. |
| Regular file, never a link | The skill's `LICENSE` MUST be a regular file. A parent-relative symbolic link (`../LICENSE`) dangles the moment the directory is packaged on its own — which is precisely what bundling and per-skill Nix packaging do — and a within-directory link is dereferenced by the archiver, duplicating the payload instead of saving it. |
| Multi-licensed skills | A skill offered under more than one license carries one `LICENSE.<TAG>` file per license (§4.3) in place of a single `LICENSE`, and every one of them ships in the bundle. |

### §5.7 — Agent Context Files

Coding agents load a project's root context file into their window at the start
Expand Down Expand Up @@ -1724,10 +1757,10 @@ Before finalising **any** Spacecraft Software artifact, mentally verify:
- [ ] **§3.3** Hardened security; PQC readiness addressed
- [ ] **§4.1** License is `GPL-3.0-or-later` or `AGPL-3.0-or-later` (AGPL for network-facing; per §4.1)
- [ ] **§4.2** Upstream copyright notices, license texts, and `NOTICE`/`AUTHORS` preserved verbatim; upstream licenses shipped in `LICENSES/`
- [ ] **§4.3** REUSE-compliant: two-tag SPDX header (`SPDX-FileCopyrightText` + `SPDX-License-Identifier`) on every file (or `.license` sidecar / `REUSE.toml` entry); `LICENSES/` directory present; root `LICENSE` carries the canonical license text and `LICENSES/<SPDX-id>.txt` symlinks to it (never two independent copies); `reuse lint` passes
- [ ] **§4.3** REUSE-compliant: two-tag SPDX header (`SPDX-FileCopyrightText` + `SPDX-License-Identifier`) on every file (or `.license` sidecar / `REUSE.toml` entry); `LICENSES/` directory present; root `LICENSE` carries the canonical license text and `LICENSES/<SPDX-id>.txt` symlinks to it (never two independent copies); license files named per §4.3 (`LICENSE` with no extension, `LICENSE.<TAG>` per license when more than one applies, `COPYING` only ever a symlink); `reuse lint` passes
- [ ] **§5** Project Posture: README/NOTICE/CONTRIBUTING present; default personal-hobby stance applied; general-use carve-outs declared in project README
- [ ] **§5.5** Package distribution: `packaging/guix.scm`, `packaging/default.nix`, and `packaging/PKGBUILD` present, buildable, and carrying correct version + SHA-256 checksum (in each package manager's native format) before any release tag is pushed
- [ ] **§5.6** Skill packaging: every `SKILL.md` `description` measures ≤ 1000 rendered characters (folded scalars counted as the loader sees them, not as raw lines); the cap is enforced by CI *and* by the command that produces the bundle, not only by a local git hook — N/A for projects that ship no skills
- [ ] **§5.6** Skill packaging: every `SKILL.md` `description` measures ≤ 1000 rendered characters (folded scalars counted as the loader sees them, not as raw lines); the cap is enforced by CI *and* by the command that produces the bundle, not only by a local git hook; every skill directory carries a `LICENSE` (§4.3 naming, byte-identical to the repo root, a regular file) and every bundle ships it — N/A for projects that ship no skills

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 Exempt multi-licensed skills in the audit row

For the existing dual-licensed microsoft-rust-guidelines, this audit row requires a regular LICENSE byte-identical to the repository root, but the new multi-license rule in §5.6 requires LICENSE.<TAG> files in place of a single LICENSE. The migration therefore cannot pass the authoritative §14 audit while following §5.6; make this row explicitly accept and validate the multi-license form.

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

Useful? React with 👍 / 👎.

- [ ] **§5.7** Agent context files: `AGENTS.md` and `CLAUDE.md` both present at the repository root and version-controlled; `CLAUDE.md` is an `@AGENTS.md` import plus Claude-only content and restates nothing; neither file is gitignored; no credentials, private hostnames, or personal filesystem paths in either; managed blocks rendered into `AGENTS.md` only
- [ ] **§6.1** POSIX-compliant CLI/system tools
- [ ] **§7** Shell scripts are POSIX-compatible; Nushell/Ion native variants provided where shell-native idioms are required; no Bashisms in shared scripts
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.

- **v1.50 (2026-08-22):** **§4.3 names the license file; §5.6 requires every bundle to carry it.** §4.3 already demanded a canonical, unmodified root license text but never named the file, and this repo had drifted into three spellings at once — `LICENSE`, `LICENSE.md`, `LICENSE-GPL` — one of which (`spacecraft-texinfo-document/LICENSE.md`) is a hand-written prose page containing no license text at all. The canonical name is now **`LICENSE`, with no extension**: GitHub's detector ranks an extensionless `LICENSE` above every extended form, and a canonical plain-text copy matches on its exact matcher rather than falling through to a fuzzy one — the Markdown-converted GPL currently in-tree drops to a fuzzy 99.24% and is, being reformatted, a modified license document the verbatimness rule already excluded. `COPYING` MAY be added at project root as a **symlink** to `LICENSE`, never a second regular copy, and never inside a distributable sub-unit: archivers dereference symlinks by default, so a linked `COPYING` in a bundle ships the text twice. Where more than one license applies, each gets its own **`LICENSE.<TAG>`** file (`LICENSE.GPL`, `LICENSE.MIT`) after GNU's `COPYING.LESSER` / `COPYING.RUNTIME` convention; texts are never concatenated, and the SPDX expression rather than the filename tag remains the version claim. §5.6 gains **License carriage** — a bundle is a distribution in its own right, installed without the consumer ever seeing this repository, so the repo-root `LICENSE` never reaches them and the copyleft obligation to supply the license with the work lands on the bundle. Every skill directory MUST carry a `LICENSE`, byte-identical to the repo root and verified by an automated gate (enforced equality is what keeps the copies one maintained text rather than the two independent copies §4.3 forbids), and it MUST be a regular file — a `../LICENSE` symlink dangles the moment a directory is packaged alone, which is exactly what bundling and the flake's per-skill `cp -r` do. REUSE is deliberately not invoked: `reuse lint` ignores files it recognizes as licenses by name and governs only `LICENSES/<SPDX-id>.<ext>`, so the rule rests on license verbatimness and GitHub detection instead. §14 checklist rows for §4.3 and §5.6 extended to match. This is the skill-side sync of Standard PR #29; the repo's own migration — renaming the in-directory license files, giving all 44 skills a `LICENSE`, repacking every bundle, and adding the equality gate — lands as its own PR.

- **v1.49 (2026-08-16):** **Skill renamed: `spacecraft-standard-constitution` → `spacecraft-steelbore-standard`.** The skill now carries the document's own canonical name — "The Steelbore Standard" has been the document's stable name since the v1.8 reinstatement, and the skill id now says so instead of the generic "constitution". Skill ids are §2.2 functional identifiers, so no codename rule is engaged. The rename touches the directory, the frontmatter `name:`, both bundles (rebuilt under the new filename; the old-name `.zip`/`.skill` are removed), the `README.md` §2 catalogue row and `nix build` example (the flake derives outputs from `readDir`, so no flake change), `AGENTS.md`, `CONTRIBUTING.md`, `REUSE.toml`, the CI cross-reference checker's version-pin exemption list (`check-skill-refs.py` — load-bearing: without it the renamed skill loses its exemption and CI fails), and every sibling skill that cross-references this one (fifteen skills plus the grok- and android-catalogue READMEs). Historical changelog entries keep the name that was current when they were written. The Standard-side rename (four in-document references, changelog header pointer, `AGENTS.md`) lands as its own PR at this same version and date — as v1.44 recorded, a cross-reference is normative content and renaming a skill is a two-repo edit. Same-day bump with different content, so it increments past v1.48 rather than sharing it. No rule changes. This skill's own frontmatter `description` measures 988 characters under the §5.6 cap, unchanged — only the version number moved.
- **v1.48 (2026-08-16):** **§17.2 simplified — the MVP row joins the single cell style.** v1.47 set the `MVP` row apart in `▰` (U+25B0) / `▱` (U+25B1) with one space inside each bracket, on the argument that the headline figure should be findable at a glance in a stack of otherwise identical bars. In practice the distinction bought less than it cost: the padded row needed its own label-field width (five characters where every other row uses six), its own bracket geometry, its own percentage-separator rule (one space where the others use two), and a documented edge case in which the two row types stop aligning at exactly 100% — four special cases carried by every emitter and checker of the format, to distinguish a row that its fixed position (always immediately after the last milestone) and its label already distinguish. **§17.2 now defines one cell style for every row** — milestones, `MVP`, `TODO`, `PLAN`, and `PRD` alike: `█` (U+2588) filled, `░` (U+2591) empty, tight brackets with no space inside either. The `▰`/`▱` pair, the whole of §17.2 from v1.32 until v1.47 narrowed it to the MVP row alone, is now retired entirely. The alignment rules collapse from five bullets to three, all universal: label and colon left-aligned in a six-character field followed by `[`; first bar cell in column 8, bars occupying columns 8–27, `]` in column 28; percentage right-aligned in a five-character field so `%` lands in column 33 whether the value is one, two, or three digits. The v1.47 misalignment-at-100% carve-out disappears rather than being restated — with tight brackets and a two-space separator, a 100% value consumes one separator space and the block stays aligned at every value. Unchanged: §17.1's row set, fixed order, and only-applicable-rows rule; the cell-count rounding and its two saturation rules; the prohibition on ASCII bars. §16's §17 bullet drops the two-style clause. `spacecraft-accessibility-support`'s `references/audit.md` reporting example is updated to the single style in the same pass. This skill's own frontmatter `description` measures 988 characters under the §5.6 cap, unchanged — only the version number moved.
- **v1.47 (2026-08-09):** **§17.1 and §17.2 rewritten — progress reports become a labelled-row block.** The format §17.1 has carried since the section was written packed every figure into three dense lines: a single unlabelled bar, then all milestones pipe-separated on one line, then MVP and PRD sharing a third. Only one of those numbers — the PRD total — ever got a bar, so the milestones and the MVP were reported as bare percentages while the least granular figure got the only visual. Reading it meant parsing a run-on line to find the milestone you cared about, and comparing two milestones meant comparing two integers rather than two bars. The replacement gives **every track its own row, its own 20-cell bar, and its own percentage**, in a fixed order: milestone rows `M0`…`Mn` ascending, then `MVP`, then `TODO`, then `PLAN`, then `PRD`. **`TODO` and `PLAN` are new tracks** — the old format had no way to report against a plan document or a task list at all, so work driven by either was reported against a PRD that did not exist. **Only applicable rows are emitted**, and this is a rule rather than a convenience: the milestone rows match the milestones the plan actually defines (`M0`–`M4` in the template is an illustration, not a required set), `TODO`/`PLAN`/`PRD` appear only when the task is driven by such an artifact, and `MVP` is always present. Padding the block out with fabricated 0% rows is forbidden — a track that does not exist reports progress against nothing, and a reader cannot tell a genuine zero from a placeholder. **§17.2 now defines two cell styles, and the distinction is normative.** Milestone, `TODO`, `PLAN` and `PRD` rows use `█` (U+2588) filled and `░` (U+2591) empty with tight brackets; the `MVP` row uses `▰` (U+25B0) and `▱` (U+25B1) with one space inside each bracket. MVP is the headline figure and the rows around it are the inputs that feed it, so it is set in a different glyph pair to stay findable at a glance in a stack of otherwise identical bars — the `▰`/`▱` pair that was the whole of §17.2 before this version is retained for exactly that one row rather than retired. **Column alignment is normative, and the bracket padding is what preserves it**: the MVP row is one character narrower in its label field and one character wider inside each bracket, so every bar cell and every percentage digit lands in the same column across the whole block. Stated as rules — label-plus-colon left-aligned in a six-character field on every row but MVP, five on MVP followed by `[` and a space; every bar in columns 8 through 27 on both; percentage right-aligned so its `%` lands in the same column on every row, which means two spaces after the closing bracket on the tight rows and one on `MVP`, with the separator never dropping below one space (so at 100% the `MVP` percentage sits one column right — the only value at which the two row types do not align, and preferable to a bracket abutting a digit). **Cell count is specified for the first time.** The old text said "20-character" and left the mapping from percentage to cells entirely unstated, so 43% could legitimately render as 8 cells or 9. It is now the percentage scaled to twenty cells and rounded to the nearest cell, with two saturation rules overriding the rounding: twenty filled cells **only** at exactly 100%, zero filled **only** at exactly 0%. Rounding 99% up to a visually complete bar reports work as finished that is not — precisely the drift §17 exists to catch. Unchanged: **§17.3's cadence** (baseline at task start, at each milestone completion, and in the end-of-turn summary), and the prohibition on legacy ASCII bars, now stated for `#`, `-` and `=` and binding on every row rather than on "the progress bar" singular. §16's §17 checklist bullet is rewritten from the old three-figure summary to the row-block form. `spacecraft-accessibility-support`'s `references/audit.md` reporting example is updated to the new block in the same pass. This skill's own frontmatter `description` measures 988 characters under the §5.6 cap, unchanged — only the version number moved.
Expand Down
Loading