Skip to content

[Release] Prepare M5Authenticator v1.0.0 #213

Description

@miso-develop

Goal

Prepare M5Authenticator for its first stable v1.0.0 production release.

The project is functionally at V1 release readiness, but the repository's canonical firmware version is still 0.1.0. The release preparation must update the canonical version sources and preserve the hardened production release contract before the protected v1.0.0 tag is created.

Current release-readiness context

At the time this request was created:

  • no open Issues or PRs remain;
  • V1 security hardening/release closeout is completed;
  • the V1 physical-device E2E Human Gate is completed;
  • the release supply-chain finding has independent Security closeout;
  • SemVer tag protection, legacy Release workflow retirement, and immutable Releases have been completed;
  • current production release profile is eligible (production_release_allowed: true);
  • current main CI is green across firmware, Web, Windows Chrome QR, security scan, and Pages.

Specification must re-check current repository state before defining the final release-preparation task; this summary is context, not authority over newer GitHub state.

Known version sources that still require reconciliation

Current repository state includes at least:

  • firmware/CMakeLists.txt: project(m5authenticator VERSION 0.1.0)
  • firmware/release-profile.json: "firmware_version": "0.1.0"

The authorized release workflow requires the requested vX.Y.Z tag to match the canonical firmware version exactly, so v1.0.0 must not be created before the version-preparation change is integrated.

Specification request

Define the minimal, complete v1.0.0 release-preparation scope, including:

  • all canonical version sources that must move from 0.1.0 to 1.0.0;
  • generated/package/release metadata expectations;
  • whether README/docs/changelog/release notes need any stable-version update;
  • regression/CI expectations;
  • exact pre-tag release gate;
  • release sequence compatibility with the existing protected-tag + Authorized Release workflow;
  • confirmation that no Product/Protocol/Storage Schema/Vault Format semantics are changed merely by the product SemVer bump.

Avoid broad feature work. This is a release-preparation task, not a new feature milestone.

Safety constraints

  • Do not create or move the v1.0.0 tag during specification or implementation.
  • Do not publish a Release as part of implementation verification.
  • Do not weaken the existing release authorization, provenance, attestation, tag-protection, immutable-release, or secret-handling controls.
  • Do not change Protocol / Storage Schema / Vault Format versions unless an independent product/compatibility requirement actually requires it.
  • Release publication remains an Integration/Human-controlled operation after the preparation change is reviewed and integrated.

Expected workflow

  1. Specification confirms the exact release-preparation contract and Acceptance Criteria.
  2. Specification routes the implementation-ready work to the appropriate Implementation Agent/domain.
  3. Implementation updates version/release-preparation sources and opens a PR.
  4. Review and Integration verify and merge the exact change.
  5. Only after the resulting exact main HEAD is green should the protected v1.0.0 tag be created and the Authorized Release flow invoked.

Specification resolution — 2026-09-19

State

BLOCKED_DEPENDENCY

Dependency sequence before the irreversible v1.0.0 tag:

  1. [Task][Infra] Set canonical Product/Firmware version to 1.0.0 #214 — canonical Product/Firmware version -> 1.0.0 — implement/review/integrate first.
  2. [Task][Infra] Add dependency-aware CI impact routing and release-oriented Pages deploys #216 — CI impact routing + release-oriented Pages cadence — implement/review/integrate second.
  3. Human-approved exact-main manual candidate Pages deployment and production-host validation.
  4. Remaining exact pre-tag gate.
  5. Explicit Human approval for protected v1.0.0 tag creation.
  6. Authorized Release + tag-triggered Pages production publication.

Current blocking dependency: #214.

#213 must remain open through #214, #216, the manual candidate Pages gate, protected tag creation, and final release verification.

Revalidated baseline

Specification rechecked current repository state rather than relying on the creation-time snapshot.

Release identity decision

The stable release target is exactly:

Product/Firmware SemVer = 1.0.0
Git tag                 = v1.0.0
Release title           = M5Authenticator v1.0.0

This SemVer bump expresses product/release maturity. It does not itself change compatibility/security formats.

The following current compatibility identities remain unchanged:

PROTOCOL_VERSION       = 2
STORAGE_SCHEMA_VERSION = 2
VAULT_FORMAT_VERSION   = 1
security profile       = encrypted-vault-ram-only-vmk / v1

Do not increment any of those solely because the Product/Firmware SemVer becomes 1.0.0.

Canonical product-version sources

Exactly these current repository sources are authoritative for the firmware/product release version and must move together from 0.1.0 to 1.0.0:

  1. firmware/CMakeLists.txt

    project(m5authenticator VERSION 1.0.0)

    This is the ESP-IDF/CMake application-project version.

  2. firmware/components/m5auth_core/include/m5auth/core/metadata.hpp

    inline constexpr char kFirmwareVersion[] = "1.0.0";

    This is the Device/runtime firmware metadata surfaced through the canonical product protocol.

  3. firmware/release-profile.json

    "firmware_version": "1.0.0"

    This is the release/package/Pages/Authorized Release identity source.

All three must agree before a release-capable build is valid.

Close the existing consistency gap

Current scripts/validate_release.py already requires release-profile firmware_version to equal kFirmwareVersion, but it does not currently validate the CMake project(... VERSION ...) value.

The release-preparation implementation must extend deterministic validation so:

  • CMake project version is parsed;
  • CMake version == kFirmwareVersion;
  • CMake version == release-profile firmware_version;
  • malformed/missing/divergent values fail closed.

This check must run through the existing Foundation / release-validation path and therefore also protect the Authorized Release path.

Do not solve this by introducing a fourth hand-maintained product-version source.

Explicitly non-canonical 0.1.0 values

The implementation must perform a repository-wide audit for literal/current-version-like 0.1.0 references and classify them. The following known occurrences are not Product/Firmware release sources and do not need to move merely for this release:

  • web/package.json / root package entry in web/package-lock.json
    • package is private: true;
    • this is npm package-manager metadata;
    • production Web build identity does not read it.
  • web/vite.config.ts firmware-layout/QR smoke fixture values
    • test-only fixture;
    • not used as production release identity.
  • historical v0.1.0 references that truthfully refer to the already-published historical release.

Production Pages Web identity is intentionally derived from firmware/release-profile.json through VITE_M5AUTH_WEB_VERSION, so the Web user-facing release baseline will become v1.0.0 + <commit> on ordinary post-merge main builds and v1.0.0 only when the exact release tag points at that source SHA.

If the audit finds another current production/user-facing canonical source still asserting 0.1.0, Implementation must not silently classify it away; record it and return to Specification if its semantic ownership is unclear.

Generated package / metadata expectations

After the version-preparation PR changes the canonical sources, normal candidate packaging on the exact PR/main SHA must derive 1.0.0 without hard-coded output rewriting.

Expected properties:

  • factory-manifest.json.version == "1.0.0"
  • update-manifest.json.version == "1.0.0"
  • firmware-target.json.version == "1.0.0"
  • release-metadata.json.firmware_version == "1.0.0"
  • generated firmware asset names use the v1.0.0-<build_commit> candidate identity currently defined by package_firmware.py
  • candidate/pre-tag package has exact_release: false
  • Protocol = 2, Storage Schema = 2, Vault Format = 1 in release metadata
  • production_release_allowed == true
  • First install / state-preserving Update partition and security contracts remain unchanged
  • SHA256SUMS covers the normal generated package as before.

The implementation should add/adjust deterministic release-package assertions so 1.0.0 is verified as current repository release identity rather than relying only on indirect equality checks.

Web/Pages expectation during the preparation interval

#214 is integrated first while the current Pages cadence is still in effect.

Then #216 is intentionally integrated before the protected v1.0.0 tag. #216 changes Pages to release-oriented cadence:

  • ordinary main pushes no longer deploy public Pages;
  • protected SemVer tag pushes deploy Pages automatically;
  • an explicit Human-approved manual candidate deployment remains available for pre-release production-host validation.

After #216 integration, the ordinary merge push to main is expected not to run Pages.

Before the v1.0.0 tag is created, one manual candidate Pages deployment must be run from the exact current main SHA. Because no matching release tag exists yet, its public build identity must remain non-exact, e.g.:

v1.0.0 + <short-main-commit>

and candidate package assets may carry the commit-qualified v1.0.0-<commit> identity.

That manual candidate deployment is not the official immutable GitHub Release. Exact-release identity remains false until the protected v1.0.0 tag points at the approved source SHA.

Do not pre-create the tag merely to obtain an exact-release Pages identity.

README / documentation / changelog decision

No broad documentation rewrite is required for the SemVer bump.

Current README does not declare v0.1.0 as the current release, and durable V1 documentation intentionally describes compatibility boundaries independently from Product SemVer.

Therefore:

  • no README version badge/current-version line is required;
  • no new CHANGELOG.md is required solely for this release;
  • no V1 architecture/security doc version rewrite is required;
  • docs/DISTRIBUTION.md remains valid because it uses generic v<version> release identities and current release mechanics.

If implementation finds a current user-facing statement that specifically claims 0.1.0 is the current version, update only that stale statement.

Release notes decision

The current hardened publisher uses:

gh release create ... --title "M5Authenticator $REQUESTED_TAG" --generate-notes

Keep this behavior for v1.0.0; no repository release-notes file is required by this preparation Task.

Because future Releases are immutable, the Human/Integration release gate must accept the generated-notes policy before publication. If curated/custom v1.0.0 notes are desired instead, that is a pre-publication Specification change; do not plan to edit the Release after publication.

Implementation verification

The release-preparation PR must demonstrate on its exact head:

  • all three canonical version sources are exactly 1.0.0;
  • new consistency validation rejects divergence between CMake / runtime metadata / release profile;
  • python scripts/validate_release.py --require-production succeeds;
  • release/package tests succeed and explicitly observe 1.0.0;
  • generated candidate manifests/metadata have the expected version and unchanged compatibility values;
  • Foundation is green;
  • Security is green;
  • no protected-tag creation or Release publication occurs;
  • no product behavior, Protocol, Storage Schema, Vault Format, crypto, persistence, or release-authority change is included.

Independent Review remains required.

Exact pre-tag gate

After both #214 and #216 are independently reviewed and integrated, do not create v1.0.0 immediately from stale handoff data.

Integration/Human must establish one exact current protected main SHA and require all of the following:

  1. exact current protected main SHA is recorded;
  2. canonical CMake / runtime metadata / release-profile versions all equal 1.0.0;
  3. production_release_allowed: true;
  4. Protocol = 2 / Storage Schema = 2 / Vault Format = 1 unchanged;
  5. exact-main security:scan is successful;
  6. exact-main Foundation impact routing is correct for the [Task][Infra] Add dependency-aware CI impact routing and release-oriented Pages deploys #216-integrated state, with every heavy job required by that change classification successful;
  7. the ordinary main push after [Task][Infra] Add dependency-aware CI impact routing and release-oriented Pages deploys #216 integration does not run Pages build/deploy and creates no Pages staging artifact; this is the expected success condition, not a missing gate;
  8. one Human-approved manual candidate Pages deployment is executed from the exact same current-main SHA before tag creation;
  9. that manual candidate deployment succeeds through production firmware packaging, production Web build, staging artifact upload, public Pages deploy, and exact-ID artifact cleanup;
  10. production-host validation on that candidate Pages deployment is completed and recorded, at minimum confirming:
    • GitHub Pages loads Provisioner, Firmware, and Help from the production /m5authenticator/ base path;
    • production CSP does not break required local QR/image/WASM behavior covered by the hosted application;
    • Firmware route can load the same-origin firmware target/manifest assets;
    • displayed Web build identity corresponds to v1.0.0 + <short exact-main commit> (non-exact release before tag);
    • deployed firmware/package metadata identifies build commit as the same exact main SHA;
    • no broken/stale asset, unexpected cross-origin dependency, or release-blocking production-host regression is observed;
  11. after the manual candidate deploy/validation, current main is re-read and must still equal the candidate SHA. If main moved, the candidate gate is stale and must be rerun on the new exact main;
  12. no unresolved release/security blocker exists;
  13. refs/tags/v1.0.0 still does not exist;
  14. hardened .github/workflows/release-authorized.yml remains the sole production GitHub Release publisher and its authorization/attestation contract is unchanged;
  15. legacy Release workflow identity remains retired/disabled per [Decision][Release] Retire deleted legacy workflow via disabled tombstone identity #200/[Human Task][Repository] Protect SemVer tags and enable immutable Releases #165;
  16. SemVer creation and immutability rulesets remain active;
  17. immutable Releases remains enabled;
  18. Human explicitly approves creation of the irreversible protected v1.0.0 identity at that exact SHA.

A failure in any item blocks tag creation.

The manual candidate Pages deployment is a required pre-tag Human Gate for this first stable release under the new cadence. It intentionally replaces the former requirement that an ordinary main push itself produce a successful Pages deployment.

Production release sequence after the pre-tag Human Gate

Use the already-approved #199 / docs/DISTRIBUTION.md pre-existing protected-tag sequence after the exact-main manual candidate Pages Human Gate has passed:

  1. Human/Integration confirms the exact protected-main SHA.
  2. Create v1.0.0 at that exact SHA through the authorized tag-creation path.
  3. Immediately re-read refs/tags/v1.0.0 and require that it resolves/peels to the exact approved SHA.
  4. Do not move/delete/recreate the tag if anything is wrong; the immutability control is intentional. Escalate instead.
  5. Submit repository_dispatch:
    event_type=publish_semver_release
    client_payload.tag=v1.0.0
    
  6. Let the default-branch-owned Authorized Release workflow independently re-authorize exact main/tag/checks/profile, build in the pinned isolated ESP-IDF environment, verify, attest, and publish the exact verified bytes.
  7. Require the Authorized Release workflow to succeed.
  8. Verify the resulting immutable Release is M5Authenticator v1.0.0, its assets identify firmware version 1.0.0, and signed attestation verification succeeds per docs/DISTRIBUTION.md.
  9. Verify the tag-triggered production Pages deployment succeeds and identifies the exact release as v1.0.0 rather than the manual candidate identity v1.0.0 + <commit>.
  10. Verify the final public Pages deployment corresponds to the same exact release/source identity as the immutable GitHub Release.

Tag creation, Authorized Release dispatch, and tag-triggered production Pages publication are not part of #214 or #216 Implementation.

Safety boundary

This release bump changes only Product/Firmware SemVer and deterministic consistency coverage.

It must not change:

  • Protocol vocabulary/version;
  • Storage Schema;
  • Vault Format or migration behavior;
  • cryptographic algorithms/keys/KDF parameters;
  • Trusted Browser / recovery / Lock semantics;
  • firmware Flash layout/update semantics;
  • production eligibility;
  • ESP-IDF version/digest;
  • release privilege separation / attestation authority;
  • SemVer tag Rulesets;
  • immutable Releases;
  • legacy workflow retirement;
  • any secret-handling boundary.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions