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.
- 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
bytesandstringschema 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.
Run this repository's checks with:
npm run checkThe GitHub Actions workflow runs the same command on Node 24.
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.mjsAlternatively, npm can execute the package directly from the same reviewed commit:
npm exec --yes --package=github:reallyme/release-readiness#FULL_COMMIT_SHA -- \
reallyme-release-readinessBoth 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 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.
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 © 2026 by ReallyMe LLC.
ReallyMe® is a registered trademark of ReallyMe LLC.