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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Entries are newest-first. Dates are UTC, ISO 8601 (§14). Versioning policy: bum
for upstream skill changes, registry updates (§2.1, §15.1), factual corrections
to normative content, and brand/identity changes.

- **v1.41 (2026-08-04):** **§3.1.1 added — TypeScript over JavaScript.** §3.1 named Rust as the preferred language and prescribed ASLR+CFI where Rust is not viable, but it had nothing to say about the one runtime where that framing does not apply: JavaScript is already memory-safe, so the memory-safety lever is inert, and the section fell silent exactly where a stability rule was still needed. §3.1.1 supplies it — **type safety is the Priority 1 lever on this runtime**. Where a memory-safe alternative exists (Rust to WebAssembly, Rust or Go on a server, Flutter/Dart for a UI) §3.1 still chooses it; where the JavaScript runtime is genuinely required — a browser page, a Node/Deno/Bun program, an Electron app, an npm-distributed tool, a VS Code extension — the **source language MUST be TypeScript**, and plain JavaScript source becomes a documented exemption rather than a default. Six requirements attach: `"strict": true` plus `noUncheckedIndexedAccess`, `noImplicitOverride`, and `exactOptionalPropertyTypes` (relaxing `strict` is a Priority 1 regression); no `any` and no non-null `!` in production paths (use `unknown` and narrow); `@ts-ignore` prohibited outright in favor of `@ts-expect-error` with a stated reason, which fails the build once the suppression stops being needed; **run-time validation at every trust boundary**, since a type annotation is a compile-time claim and asserting an unverified shape is the silent-failure mode §3.1 already forbids; **`tsc --noEmit` gating CI**, because esbuild, SWC, and Bun strip types without checking them, and a project that only transpiles has not satisfied this section; and loading `spacecraft-typescript-guidelines` before writing or reviewing TypeScript. Emitted `.js` and source maps in a build directory are derived artifacts and out of scope — the rule governs what is authored and committed. Three narrow cases need no filing: a tool's own configuration file that must be `.js` (e.g. `eslint.config.js` where no TypeScript loader exists), a vendored or upstream-derived file carried under §4.2, and generated output. Everything else — including "it is only a small script" — requires a documented technical exemption, on the same footing as the §3.1 memory-safe-language exemption. §16 gains a checklist bullet; the skill cross-reference table gains a TypeScript row.
- **v1.40 (2026-07-27):** **Two gaps closed: where work may be sent, and what must be measured before a skill is packed.** **§6.4 added — Authorized Contribution Targets (Non-Negotiable).** §6.3 has always said how a commit must be signed on "a Spacecraft Software-controlled Git remote" without ever defining that set, so nothing in the standard stopped a script, a CI job, or an assistant-driven session from pushing a branch or opening a pull request against a third-party repository. §6.4 names the authorized namespaces — `github.com/Spacecraft-Software` and `github.com/UnbreakableMJ`, with a future Spacecraft Software-controlled host (Gitway) inheriting the same standing — and makes every other destination **outbound** and **default-deny**: silence is a denial, not permission. **Automation never initiates** an outbound contribution, and authorization for one does not carry to the next task, session, or repository; only Mohamed Hammad, acting explicitly and per contribution, may authorize one (§5.4). The rule is not git-only — publishing to a package registry under a namespace Spacecraft Software does not control (`crates.io`, npm, PyPI, AUR, Nixpkgs, Guix, Flathub) and filing issues or patches on an external tracker or mailing list are outbound under the same rule. **Forks stay free**: a fork under an authorized namespace may be created and pushed to at will, because that is our namespace — turning a fork branch into an upstream PR is the gated act. Where an upstream change is needed, §4.2's carry-the-patch-in-tree route is preferred to upstreaming. The free-software/GNU posture (§1) yields the identity clauses (§2, §11–§12, §15) but **not** this one: sending anything to GNU, the FSF, or Savannah still needs explicit authorization. An unauthorized submission MUST be withdrawn as soon as it is discovered, and recorded. **§5.6 added — Skill Packaging Requirements.** Skills are software-class artifacts (§4.1.1) whose loader limits are only discovered at install time, after the packing work is done: a `SKILL.md` frontmatter `description` over **1024** characters is rejected on load. §5.6 caps it at **1000 rendered characters** — a deliberate 24-character margin — and pins down *rendered*: a YAML folded scalar (`description: >`) joins its wrapped lines with single spaces and keeps a trailing newline, so raw line lengths are not the measurement, and block (`>`/`|`) and single-line plain or quoted forms alike are counted after folding. The cap MUST be **machine-enforced** in two places — the skill repository's CI on every pull request and push to the default branch, *and* the command that produces the distributable bundle. A developer-installed git hook is a convenience, never the gate: hooks are opt-in per clone. An over-limit skill MUST NOT be packed, committed, or published; trim the description rather than raise the cap. §16 gains a checklist bullet for each section.
- **v1.39 (2026-07-26):** **Three external palettes registered, and a new class for the two that cannot conform.** **§11.3.5 added — Tokyo Night**, taken verbatim from the upstream editor theme (canvas Night `#1A1B26`, `surface` the documented Storm background `#24283B`, `surface-alt` the Night `bg_dark` `#16161E`, which sits darker than the canvas as §11.0.1 permits). It needed no Spacecraft-derived substitutes: every role token clears 4.5:1 on all three backgrounds — accent `#7AA2F7` 6.79:1, structure `#BB9AF7` 7.39:1, success `#9ECE6A` 9.35:1, error `#F7768E` 6.46:1, warning `#E0AF68` 8.55:1, focus `#7DCFFF` 9.96:1 — so it is registered as a conforming alternate, with `tokyonight-high-contrast` lifting the two tokens below 7:1 on the canvas (`accent` → `#97B6F9` 8.44:1, `error` → `#F998AA` 8.22:1). The upstream comment tone `#565F89` (2.76:1) is recorded as not bindable to any role token. **§11.5 added — Fidelity Palettes (registered, non-conforming):** a new class for palettes reproduced exactly from a widely used external theme so tooling can meet a user already working in it. **Solarized Dark (§11.5.1) and Solarized Light (§11.5.2)** are registered verbatim from Ethan Schoonover's Solarized — no token substituted, deepened, or lifted to make a number pass — and they **do not** satisfy §11's contrast guarantee. Solarized Dark: body text `base0` 4.75:1 on the canvas, twelve pairings below 4.5:1, and `structure`/`border` (2.97:1) and `error` (2.81:1) below 3:1 on `base02`. Solarized Light is worse: body text `base00` measures **4.13:1, under the AA floor**, and `success` (2.97:1), `warning` (2.98:1), and `focus` (2.93:1) fall below 3:1, so an interface built on it cannot signal status by color at all. §11.5 therefore bars adopting a fidelity palette as a project's §11.4 palette, keeps `steelbore-mono` as the accessible-mode path, and ships no `-high-contrast` sibling for them (lifting would change the values they exist to reproduce); † and ‡ mark the two failure bands throughout. Solarized defines one elevated tone per mode, so `surface-alt` shares `surface`. **§11.4.1 added — Reference Names:** every palette gains an additive reference name for prose (`steelbore-color-palette`, `steelboreclassic-color-palette`, `blue-color-palette`, `blackpinkpanther-color-palette`, `matrixgreen-color-palette`, `navywhite-color-palette`, `tokyonight-color-palette`, `solarizeddark-color-palette`, `solarizedlight-color-palette`). Slugs are unchanged and remain the machine identifier, so no consumer breaks. **§11.4** gains bullets for both additions.
- **v1.38 (2026-07-26):** **§4.3 corrected — the symlink runs the other way.** v1.36 required the root `LICENSE` to be a symlink into `LICENSES/`, on the premise that GitHub follows symlinks for license detection. It does not: GitHub's detector reads **git blobs**, and a symlink's blob is the target *path*, not the license text. Measured after v1.36 landed, both `Standard` and `Construct` reported `NOASSERTION` — no identified license — where sibling repos with a regular `LICENSE` file report `GPL-3.0`. The rule is inverted: the root `LICENSE` is now a **regular file** holding the verbatim primary license text, and `LICENSES/<SPDX-id>.txt` for that license is a **symlink back to it** (`ln -s ../LICENSE LICENSES/GPL-3.0-or-later.txt`). `reuse` reads the working tree through the filesystem, so it follows the link and lints clean; GitHub gets a real blob. The single-source-of-truth goal of v1.36 is preserved — the text still exists exactly once — and two independently maintained copies remain non-compliant. Added: the root text MUST be a **canonical, unmodified** copy as published (FSF text for the GPL family, Creative Commons text for CC-BY-SA-4.0, or the choosealicense.com copy) — reflowed or Markdown-formatted texts defeat detection even when the wording is intact. Secondary licenses in `LICENSES/` (§4.2 upstream texts, a differently-licensed tooling class per §4.1.1) stay regular files; only the primary license is linked. §5.2 `LICENSE` row and the §16 checklist bullet updated to match.
Expand Down
66 changes: 65 additions & 1 deletion The_Steelbore_Standard.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ repository](https://github.com/Spacecraft-Software/Standard), newest
entry first. It is kept out of this document so the standard reads as
the rules *in force* rather than the record of how they got there.

This document is **version 1.40**, updated 2026-07-27 (§14: UTC, ISO
This document is **version 1.41**, updated 2026-08-04 (§14: UTC, ISO
8601). The skill encoding of the standard keeps a parallel history in
`spacecraft-standard-constitution/references/CHANGELOG.md` in the
[Construct
Expand Down Expand Up @@ -182,6 +182,61 @@ means of achieving it — but it is not the whole of Priority 1.**
(unit, integration, and fuzz/property where applicable) gating CI, not
asserted by inspection alone.

### §3.1.1 — TypeScript over JavaScript

JavaScript is not a preferred language under §3.1: it is dynamically
typed, so whole classes of defect that a compiler would reject survive
into production and surface as run-time failures. The memory-safety
lever does not apply — the runtime is memory-safe either way — so **type
safety is the stability lever available here**, and the standard
requires it be pulled.

Where a memory-safe alternative exists (Rust compiled to WebAssembly,
Rust or Go for a server, Flutter/Dart for an application UI), it must be
chosen per §3.1. **Where the JavaScript runtime is genuinely required**
— a browser page, a Node/Deno/Bun program, an Electron application, an
npm-distributed tool, a VS Code extension — the source language MUST be
**TypeScript**. Plain JavaScript source is a documented exemption, not a
default.

- **Strict mode is mandatory.** `tsconfig.json` sets `"strict": true`,
and additionally `noUncheckedIndexedAccess`, `noImplicitOverride`, and
`exactOptionalPropertyTypes`. A configuration that relaxes `strict` is
a Priority 1 regression.

- **No silent escape hatches.** `any` and non-null assertions (`!`) are
prohibited in production paths; use `unknown` plus narrowing.
`@ts-ignore` is prohibited outright — where a suppression is
unavoidable, use `@ts-expect-error` with a comment naming the reason,
so the suppression fails the build once it becomes unnecessary.

- **Validate at the boundary.** Data crossing a trust boundary (network
responses, files, environment, IPC, user input) is `unknown` until
parsed by a run-time validator. A type annotation is a compile-time
claim, not a check — asserting a shape that was never verified is
exactly the silent-failure mode §3.1 forbids.

- **Compiled output is not source.** Emitted `.js` (and its source maps)
in a build directory is a *derived artifact* and is outside this rule.
The rule governs what is authored and committed.

- **The build must typecheck.** `tsc --noEmit` (or the equivalent
project-wide check) gates CI. A project that only transpiles —
stripping types without checking them, as esbuild, SWC, and Bun do by
default — has not satisfied this section.

- **Load the guidelines skill** — `spacecraft-typescript-guidelines` —
before writing or reviewing any TypeScript.

**Exemptions.** Plain JavaScript remains acceptable, without filing,
only where TypeScript cannot express the artifact: a tool’s own
configuration file that must be `.js` (e.g. `eslint.config.js` where no
TypeScript loader is available), a vendored or upstream-derived file
carried under §4.2, and generated output. Anything else — including "it
is only a small script" — requires a documented technical exemption in
the project’s README or architecture notes, in the same manner as the
§3.1 memory-safe-language exemption.

## §3.2 — Priority 2: Performance

Performance is the foremost priority after stability. Modern hardware
Expand Down Expand Up @@ -1899,6 +1954,14 @@ Before finalising **any** Spacecraft Software artifact, mentally verify:
- [ ] **§3.1** Stability: memory safety (Rust, or ASLR+CFI documented);
robust error handling, fault tolerance, and test-verified

- [ ] **§3.1.1** Where the JavaScript runtime is required, source is
**TypeScript** under `"strict": true` (plus
`noUncheckedIndexedAccess`, `noImplicitOverride`,
`exactOptionalPropertyTypes`); no `any` / `!` / `@ts-ignore` in
production paths; boundary data validated at run time; `tsc --noEmit`
gates CI; any plain-JavaScript source outside the listed exemptions is
documented — N/A for projects with no JavaScript runtime

- [ ] **§3.2** Performance: concurrency considered throughout
architecture design; adopted where it advances performance, abandoned
where it degrades performance or compromises Stability; serial
Expand Down Expand Up @@ -2018,6 +2081,7 @@ skipping it.
| Task | Load this skill |
|----|----|
| Writing any Rust code | `microsoft-rust-guidelines` |
| Writing any TypeScript (§3.1.1) | `spacecraft-typescript-guidelines` |
| Writing or reviewing shell scripts | `spacecraft-cli-shell` + `spacecraft-cli-preference` |
| Generating DOCX / ODT / PDF on demand | `spacecraft-document-format` |
| Authoring or building a Texinfo manual | `spacecraft-texinfo-document` |
Expand Down
84 changes: 81 additions & 3 deletions The_Steelbore_Standard.texi
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
@setfilename The_Steelbore_Standard.info
@documentencoding UTF-8
@documentlanguage en
@settitle The Steelbore Standard 1.40
@settitle The Steelbore Standard 1.41
@c %**end of header

@set VERSION 1.40
@set UPDATED 2026-07-27
@set VERSION 1.41
@set UPDATED 2026-08-04
@set SUBDOMAIN https://Standard.SpacecraftSoftware.org/

@copying
Expand Down Expand Up @@ -380,6 +380,72 @@ tests (unit, integration, and fuzz/property where applicable) gating CI,
not asserted by inspection alone.
@end itemize

@menu
* Typed JavaScript::
@end menu

@node Typed JavaScript
@subsection §3.1.1 — TypeScript over JavaScript

JavaScript is not a preferred language under §3.1: it is dynamically
typed, so whole classes of defect that a compiler would reject survive
into production and surface as run-time failures. The memory-safety
lever does not apply --- the runtime is memory-safe either way --- so
@strong{type safety is the stability lever available here}, and the
standard requires it be pulled.

Where a memory-safe alternative exists (Rust compiled to WebAssembly,
Rust or Go for a server, Flutter/Dart for an application UI), it must be
chosen per §3.1. @strong{Where the JavaScript runtime is genuinely
required} --- a browser page, a Node/Deno/Bun program, an Electron
application, an npm-distributed tool, a VS Code extension --- the source
language MUST be @strong{TypeScript}. Plain JavaScript source is a
documented exemption, not a default.

@itemize
@item
@strong{Strict mode is mandatory.} @code{tsconfig.json} sets
@code{"strict": true}, and additionally
@code{noUncheckedIndexedAccess}, @code{noImplicitOverride}, and
@code{exactOptionalPropertyTypes}. A configuration that relaxes
@code{strict} is a Priority 1 regression.
@item
@strong{No silent escape hatches.} @code{any} and non-null assertions
(@code{!}) are prohibited in production paths; use @code{unknown} plus
narrowing. @code{@@ts-ignore} is prohibited outright --- where a
suppression is unavoidable, use @code{@@ts-expect-error} with a comment
naming the reason, so the suppression fails the build once it becomes
unnecessary.
@item
@strong{Validate at the boundary.} Data crossing a trust boundary
(network responses, files, environment, IPC, user input) is
@code{unknown} until parsed by a run-time validator. A type annotation
is a compile-time claim, not a check --- asserting a shape that was
never verified is exactly the silent-failure mode §3.1 forbids.
@item
@strong{Compiled output is not source.} Emitted @file{.js} (and its
source maps) in a build directory is a @emph{derived artifact} and is
outside this rule. The rule governs what is authored and committed.
@item
@strong{The build must typecheck.} @code{tsc --noEmit} (or the
equivalent project-wide check) gates CI. A project that only transpiles
--- stripping types without checking them, as esbuild, SWC, and Bun do
by default --- has not satisfied this section.
@item
@strong{Load the guidelines skill} --- @code{spacecraft-typescript-guidelines}
--- before writing or reviewing any TypeScript.
@end itemize

@strong{Exemptions.} Plain JavaScript remains acceptable, without
filing, only where TypeScript cannot express the artifact: a tool's own
configuration file that must be @file{.js} (e.g.@:
@file{eslint.config.js} where no TypeScript loader is available), a
vendored or upstream-derived file carried under §4.2, and generated
output. Anything else --- including "it is only a small script" ---
requires a documented technical exemption in the project's README or
architecture notes, in the same manner as the §3.1 memory-safe-language
exemption.

@node Priority 2
@section §3.2 — Priority 2: Performance
Performance is the foremost priority after stability. Modern hardware
Expand Down Expand Up @@ -3485,6 +3551,15 @@ explicitly renamed
☐ @strong{§3.1} Stability: memory safety (Rust, or ASLR+CFI documented);
robust error handling, fault tolerance, and test-verified
@item
☐ @strong{§3.1.1} Where the JavaScript runtime is required, source is
@strong{TypeScript} under @code{"strict": true} (plus
@code{noUncheckedIndexedAccess}, @code{noImplicitOverride},
@code{exactOptionalPropertyTypes}); no @code{any} / @code{!} /
@code{@@ts-ignore} in production paths; boundary data validated at run
time; @code{tsc --noEmit} gates CI; any plain-JavaScript source outside
the listed exemptions is documented --- N/A for projects with no
JavaScript runtime
@item
☐ @strong{§3.2} Performance: concurrency considered throughout
architecture design; adopted where it advances performance, abandoned
where it degrades performance or compromises Stability; serial
Expand Down Expand Up @@ -3615,6 +3690,9 @@ Task
Writing any Rust code
@tab @code{microsoft-rust-guidelines}
@item
Writing any TypeScript (§3.1.1)
@tab @code{spacecraft-typescript-guidelines}
@item
Writing or reviewing shell scripts
@tab @code{spacecraft-cli-shell} + @code{spacecraft-cli-preference}
@item
Expand Down
Loading