From 754117e3b4650e075a0497f68ae9e414da678e8a Mon Sep 17 00:00:00 2001 From: UnbreakableMJ Date: Tue, 4 Aug 2026 13:01:11 +0300 Subject: [PATCH] =?UTF-8?q?feat(standard):=20=C2=A73.1.1=20TypeScript=20ov?= =?UTF-8?q?er=20JavaScript=20=E2=80=94=20v1.41?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §3.1 named Rust as the preferred language and prescribed ASLR+CFI where Rust is not viable, but said nothing 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, §3.1 still chooses it; where the JavaScript runtime is genuinely required, the source language MUST be TypeScript, and plain JavaScript source becomes a documented exemption rather than a default. Requirements: strict mode plus noUncheckedIndexedAccess / noImplicitOverride / exactOptionalPropertyTypes; no `any` or non-null `!` in production paths; `@ts-expect-error` with a reason instead of `@ts-ignore`; run-time validation at every trust boundary; `tsc --noEmit` gating CI (transpile-only pipelines do not satisfy the section); and loading spacecraft-typescript-guidelines. Emitted .js is a derived artifact and out of scope. §16 gains a checklist bullet; the skill cross-reference table gains a TypeScript row. Version bumped to 1.41 (2026-08-04), .md regenerated. Co-Authored-By: Claude Opus 5 (1M context) --- CHANGELOG.md | 1 + The_Steelbore_Standard.md | 66 ++++++++++++++++++++++++++++- The_Steelbore_Standard.texi | 84 +++++++++++++++++++++++++++++++++++-- 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b405bf..7c6e9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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/.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. diff --git a/The_Steelbore_Standard.md b/The_Steelbore_Standard.md index 4ebb10d..853e5fa 100644 --- a/The_Steelbore_Standard.md +++ b/The_Steelbore_Standard.md @@ -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 @@ -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 @@ -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 @@ -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` | diff --git a/The_Steelbore_Standard.texi b/The_Steelbore_Standard.texi index a284ace..74191ae 100644 --- a/The_Steelbore_Standard.texi +++ b/The_Steelbore_Standard.texi @@ -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 @@ -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 @@ -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 @@ -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