Skip to content

About

Shared release-readiness guardrails for ReallyMe repositories, including CI policy checks, SPDX enforcement, Cargo/protobuf release invariants, and generated-code hardening validation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

29 Commits

Folders and files

Repository files navigation

ReallyMe Release Readiness

Shared release-readiness guardrails for ReallyMe repositories

Release Readiness License

This package contains a dependency-free Node.js core used by ReallyMe release scripts. Consumer repositories keep only their repository-specific checker and execute the immutable core supplied by a pinned package runner. This prevents policy fixes from remaining trapped in stale local copies.

What It Checks

  • Git-tracked release inputs and repository-contained paths.
  • GitHub Actions pinned to full commit SHAs, with Node jobs using explicit numeric versions of at least 24. This repository uses Node 24.
  • Workflow permissions matched structurally at the workflow and job scopes, and release-critical named steps matched as complete commands rather than loose substrings. Repeated step names can be scoped by job.
  • Latest stable registry requirements for ReallyMe Crypto, Codec, JOSE, and COSE dependencies when they appear in Cargo metadata.
  • Cargo workspace metadata, package surfaces, dependency sources, and publish policy.
  • Rust source structure: hard limits for module and implementation size, shrinking-only baselines for existing debt, thin facades, separate tests, typed error surfaces, no production panic shortcuts, and no wildcard imports or re-exports.
  • TypeScript, Swift, and Kotlin source structure: the same 500-line production and 800-line separate-test ceilings, shrinking-only baselines, thin declared facades, language-specific unsafe-operation checks, and mandatory native verification roles.
  • Opt-in repository-shape contracts with approved archetypes, declared root lanes and sublanes, explicit Cargo crate roles, canonical proto ownership, and typed exceptional roots. Organization-neutral runtime-composition and infrastructure profiles keep executable hosting separate from deployment intent and operational control. Application and application-collection profiles distinguish an independently released application from a repository containing several independently bounded applications, including collections with explicitly owned shared domain, event, or protocol packages. Product-workspace profiles cover several cooperating applications that jointly implement one product and share a release lifecycle. Facades are optional crate roles rather than separate repository archetypes. Taxonomy, conformance-suite, and documentation-site profiles separate canonical data, executable verification, evidence, and rendered documentation.
  • SPDX headers for tracked source files, with typed generated/vendored/ third-party exclusions that can be required to match current tracked files.
  • Protobuf schema contracts, generated output freshness, and adapter boundary checks.
  • Granular provider contracts with exact descriptor/request/result/error/response surfaces, unique operation parity, correlation, typed outcomes, service-separation, codec, runtime, and adapter checks.
  • Explicit retired-path enforcement so deprecated examples, trackers, and compatibility surfaces cannot remain present or tracked unnoticed.
  • Generated protobuf hardening checks for redacted Debug output, strict ProtoJSON, zeroizing temporary byte owners, recursive unknown-field wiping, final-owner zeroization, and closed-world sensitivity classification for every bytes and string schema field.
  • Command matrices for repository-specific release suites.

The package and Git release share one semantic version. Consumer checkers load the core supplied by the pinned runner rather than carrying a local copy. The current marker is:

assertContains(
  "core.mjs",
  'RELEASE_READINESS_VERSION = "0.6.7"',
);

Numeric core-contract identifiers are no longer supported. Consumer policy, the package version, and release tag must use the same semantic release version.

Usage

Run this repository's checks with:

npm run check

The GitHub Actions workflow runs the same command on Node 24.

Keeping Pins Current

This repository has no npm runtime dependencies. Its own workflow has two immutable action references (actions/checkout and actions/setup-node). The release checker verifies each named action's repository and its full commit SHA; a reviewed update to that SHA only changes the workflow. A repository may configure the github-actions Dependabot ecosystem to propose those workflow updates.

Other exact requirements are intentional toolchain and release contracts:

Requirement Declaration Update path
Buf CLI Exact workflow BUF_VERSION Update the workflow value; a consumer may separately opt into an exact policy override
Buffa generators Exact workflow BUFFA_VERSION Update the workflow value; a consumer may separately opt into an exact policy override
cargo-fuzz template Exact workflow CARGO_FUZZ_VERSION Update the workflow value; both install lanes use that variable
Node runtime 24 in this repository Review a runtime-major migration in this repository's workflow and checker
Release-readiness package 0.6.7 Publish a new package revision and update consumer pins

Dependabot does not update version literals embedded in checker source. The shared core therefore validates Buf, Buffa, and template cargo-fuzz versions declared in workflow environment values without duplicating their numbers. Keep action SHAs in workflow files and match action repositories in checker policy with assertWorkflowUsesStepPinnedTo or installBufAction. Declarative usesSteps policies can use { name, action: "owner/repository" } for the same rule; use { name, uses: "owner/repository@sha" } only when a specific reviewed revision is itself the contract.

Consumer repositories keep only their repository-specific checker. It loads the immutable core path supplied by the runner:

const coreUrl = process.env.RELEASE_READINESS_CORE_URL;
const { createReleaseReadinessContext } = await import(coreUrl);

Remote CI must pin this repository by a reviewed full commit SHA. Never use a mutable branch or tag in a credential-bearing workflow. Two invocation modes are supported.

An explicit checkout keeps the reviewed package visible in the job workspace:

- name: Checkout release-readiness runner
  uses: actions/checkout@FULL_ACTION_COMMIT_SHA
  with:
    repository: reallyme/release-readiness
    ref: FULL_RELEASE_READINESS_COMMIT_SHA
    path: .release-readiness
    persist-credentials: false

- name: Run release-readiness gates
  run: node .release-readiness/scripts/run-consumer-check.mjs

Alternatively, npm can execute the package directly from the same reviewed commit:

npm exec --yes --package=github:reallyme/release-readiness#FULL_COMMIT_SHA -- \
  reallyme-release-readiness

Both modes execute the same package runner. Arguments after reallyme-release-readiness in npm mode are passed to the consumer's scripts/check_release_readiness.mjs. The runner supplies its own immutable core through RELEASE_READINESS_CORE_URL; the consumer does not vendor or modify it. The runner also detects tracked Rust, TypeScript, Swift, and Kotlin source and requires the consumer checker to invoke the corresponding shared source policy. A repository cannot bypass the source rules by omitting a policy call.

For a new Rust/protobuf repository, start from templates/check_release_readiness.mjs and the companion templates/README.md. The template fails closed until every REPLACE_* marker has been replaced.

The protobuf release policy defaults to the explicit-checkout invocation at .release-readiness/scripts/run-consumer-check.mjs. Consumers using the npm invocation must configure generatedFreshnessStepRun with their complete, commit-pinned npm command. The policy references the consumer checker path for workflow-change coverage; it never expects a vendored core in new consumers. An unfiltered push, pull_request, or pull_request_target trigger covers every repository path. When a change trigger uses paths, its flat sequence must include the exact checker path and must not contain negated patterns. paths-ignore cannot prove coverage because its full glob semantics belong to GitHub, so configure an explicit paths entry for this policy instead.

Use the public archetype matrix to select a repository responsibility, then apply the exact lane and ownership rules in the repository-shape contract.

Generated protobuf freshness checks should snapshot generated outputs, run buf lint, buf generate, the repository hardening script such as harden-generated-example-proto.mjs, and cargo fmt, then compare the updated generated tree plus every tracked or non-ignored file outside the declared generated directories. Hardening scripts must also support --check-idempotent; repository checkers run that mode against checked-in output so a second pass cannot accumulate comments, derives, debug implementations, or drop implementations.

For authored Rust, configure assertRustSourcePolicy (or the aggregate rustSource policy) with the source roots and generated-source exclusions. Use roots: ["."] to govern every tracked Rust source throughout the repository. The non-configurable hard ceiling is 500 lines for authored production code and examples. Separate test files may contain up to 800 lines; test implementations inside production source are rejected. A production module may declare a separate test module with #[cfg(test)] mod tests;. The same ceilings apply to authored TypeScript, Swift, and Kotlin. Every tracked source file must be covered by the declared roots or an explicit generated-source prefix. Generated exclusions must identify a gen or generated path and match tracked source; they are not a general-purpose exception mechanism.

A repository may choose a lower target and record existing files between that target and the applicable hard ceiling in a tracked TSV as path<TAB>line-count. That allowance can only stay equal or decrease and never overrides the 500/800 ceilings. Remove the entry once the file reaches its target.

As a human-review convention, prefer action-named implementation files such as create.rs, evaluate.ts, sign.swift, and verify.kt. This is intentionally not enforced by the checker because whether a name expresses the repository's domain operation requires architectural judgment.

For authored TypeScript, use assertTypeScriptSourcePolicy. It governs .ts, .tsx, .mts, and .cts; requires explicit strict compiler settings in every declared tsconfig; rejects any, @ts-ignore, ESLint disable directives, wildcard imports or exports, production test bodies, non-null assertions, as any/as unknown/as never, generic thrown errors, and substantive index.* facades. @ts-expect-error is permitted only in separate test files and must include a reason. A non-empty static-analysis configuration policy must pin the repository's AST-aware lint rules. Verification commands must cover typecheck, lint, and test.

For authored Swift, use assertSwiftSourcePolicy. It rejects force unwraps, try!, as!, terminating shortcuts, embedded XCTest implementations, generic error surfaces, untyped throws, SwiftLint disable directives, and concurrency escape hatches. Facade files are explicit because Swift has no universal module facade filename. Its configuration text policy must prove repository-specific strict-concurrency and warnings-as-errors settings, while verification commands must cover format, lint, build, and test.

For authored Kotlin, use assertKotlinSourcePolicy. It rejects !!, unsafe casts, generic exceptions, terminating validation shortcuts, lateinit, @Suppress, wildcard imports, and embedded test implementations. Facade files are explicit. Its configuration text policy must prove settings such as explicit API mode and warnings-as-errors, while verification commands must cover format, static-analysis, compile, and test.

One verification command may satisfy multiple roles when a repository-native command performs all of them. Generated source must be excluded explicitly; authored examples remain production code. Semantic requirements that cannot be proved safely from source text—boundary-schema validation, correct branded-type selection, PII-safe error context, and effective secret zeroization—remain repository-specific compiler/linter rules and tests invoked by those mandatory verification commands.

Repository layout can be checked with assertRepositoryShapePolicy, either directly or through the optional aggregate repositoryShape field. The policy does not infer an archetype or require unused directories. See docs/repository-shapes.md for every accepted archetype, directory lane, invariant, crate role, and the architectural limits of automated proto-codec validation.

SPDX exceptions should use typed entries such as { path: "gen", reason: "generated" }. Enable both requireExclusionsMatched and requireExclusionReasons so deleted directories cannot leave silent, stale policy exceptions behind.

The default SPDX policy expects ReallyMe's MIT OR Apache-2.0 header on governed source and configuration files. Markdown and plain-text files are not header-governed by default. This policy does not choose or change a consumer repository's license. Repositories belonging to another organization, or ReallyMe repositories using different terms, must pass their own exact copyright and license values to assertSpdxHeaders and maintain the corresponding license files. Legacy consumers pinned to an earlier vendored-core release must preserve that core's original header and third-party notice while they migrate; new consumers must use the centrally versioned runner.

Protobuf Notes

Protobuf identifiers are ReallyMe wire identifiers, not provider registry values. assertProtoContract requires neither sparse nor sequential numbering; it rejects invalid field-number ranges, duplicate identifiers, and reuse of reserved names or numbers.

Every protobuf bytes and string field must appear exactly once in scalarFieldClassifications. Mark it sensitivity: "sensitive" or sensitivity: "public" explicitly and include its schema kind and owning message. The checker rejects unclassified schema additions, duplicate entries, kind mismatches, and stale classifications. Sensitive entries additionally require message-scoped Debug redaction, generated-path and final-owner wiping, and a zeroizing ProtoJSON staging owner. Nested messages fail closed until the classifier is explicitly extended to represent their ownership path.

The executable adapter boundary is intentionally narrow: the proto crate owns messages only, exposes no protobuf service, accepts binary protobuf and generated ProtoJSON requests, and returns the same binary status/payload result envelope from both paths.

License

Licensed under either the MIT License or the Apache License, Version 2.0, at your option.

Third-party components retain their own licenses and notices.

Copyright And Trademarks

Copyright © 2026 by ReallyMe LLC.

ReallyMe® is a registered trademark of ReallyMe LLC.

About

Shared release-readiness guardrails for ReallyMe repositories, including CI policy checks, SPDX enforcement, Cargo/protobuf release invariants, and generated-code hardening validation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages