You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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)
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
Specification confirms the exact release-preparation contract and Acceptance Criteria.
Specification routes the implementation-ready work to the appropriate Implementation Agent/domain.
Implementation updates version/release-preparation sources and opens a PR.
Review and Integration verify and merge the exact change.
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:
This is the Device/runtime firmware metadata surfaced through the canonical product protocol.
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
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.
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;
one Human-approved manual candidate Pages deployment is executed from the exact same current-main SHA before tag creation;
that manual candidate deployment succeeds through production firmware packaging, production Web build, staging artifact upload, public Pages deploy, and exact-ID artifact cleanup;
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;
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;
no unresolved release/security blocker exists;
refs/tags/v1.0.0 still does not exist;
hardened .github/workflows/release-authorized.yml remains the sole production GitHub Release publisher and its authorization/attestation contract is unchanged;
SemVer creation and immutability rulesets remain active;
immutable Releases remains enabled;
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.mdpre-existing protected-tag sequence after the exact-main manual candidate Pages Human Gate has passed:
Human/Integration confirms the exact protected-main SHA.
Create v1.0.0 at that exact SHA through the authorized tag-creation path.
Immediately re-read refs/tags/v1.0.0 and require that it resolves/peels to the exact approved SHA.
Do not move/delete/recreate the tag if anything is wrong; the immutability control is intentional. Escalate instead.
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.
Require the Authorized Release workflow to succeed.
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.
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>.
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.
Goal
Prepare M5Authenticator for its first stable
v1.0.0production 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 protectedv1.0.0tag is created.Current release-readiness context
At the time this request was created:
production_release_allowed: true);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.Ztag to match the canonical firmware version exactly, sov1.0.0must not be created before the version-preparation change is integrated.Specification request
Define the minimal, complete v1.0.0 release-preparation scope, including:
0.1.0to1.0.0;Avoid broad feature work. This is a release-preparation task, not a new feature milestone.
Safety constraints
v1.0.0tag during specification or implementation.Expected workflow
v1.0.0tag be created and the Authorized Release flow invoked.Specification resolution — 2026-09-19
State
BLOCKED_DEPENDENCYDependency sequence before the irreversible
v1.0.0tag:1.0.0— implement/review/integrate first.v1.0.0tag creation.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.
main:bc5c3b90f57952f04a80c8ddfcb55b6d384c882esecurity:scan: SUCCESSweb: SUCCESSweb QR Windows Chrome: SUCCESSfirmware: SUCCESSbuild-pages: SUCCESSdeploy-pages: SUCCESS354596449: durable Human/API evidence recordsdisabled_manually; tombstone remains on mainenabled: truev0.1.0tag: present at historical commitcbb30802896e9bde81f26c12a0e3255d1436c2b7v0.1.0refs/tags/v1.0.0: does not exist (GitHub ref lookup returned 404)v1.0.0Release existsRelease identity decision
The stable release target is exactly:
This SemVer bump expresses product/release maturity. It does not itself change compatibility/security formats.
The following current compatibility identities remain unchanged:
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.0to1.0.0:firmware/CMakeLists.txtThis is the ESP-IDF/CMake application-project version.
firmware/components/m5auth_core/include/m5auth/core/metadata.hppThis is the Device/runtime firmware metadata surfaced through the canonical product protocol.
firmware/release-profile.jsonThis 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.pyalready requires release-profilefirmware_versionto equalkFirmwareVersion, but it does not currently validate the CMakeproject(... VERSION ...)value.The release-preparation implementation must extend deterministic validation so:
kFirmwareVersion;firmware_version;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.0valuesThe implementation must perform a repository-wide audit for literal/current-version-like
0.1.0references 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 inweb/package-lock.jsonprivate: true;web/vite.config.tsfirmware-layout/QR smoke fixture valuesv0.1.0references that truthfully refer to the already-published historical release.Production Pages Web identity is intentionally derived from
firmware/release-profile.jsonthroughVITE_M5AUTH_WEB_VERSION, so the Web user-facing release baseline will becomev1.0.0 + <commit>on ordinary post-merge main builds andv1.0.0only 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.0without 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"v1.0.0-<build_commit>candidate identity currently defined bypackage_firmware.pyexact_release: falseproduction_release_allowed == trueThe implementation should add/adjust deterministic release-package assertions so
1.0.0is 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.0tag. #216 changes Pages to release-oriented cadence:After #216 integration, the ordinary merge push to
mainis expected not to run Pages.Before the
v1.0.0tag 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.: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.0tag 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.0as the current release, and durable V1 documentation intentionally describes compatibility boundaries independently from Product SemVer.Therefore:
CHANGELOG.mdis required solely for this release;docs/DISTRIBUTION.mdremains valid because it uses genericv<version>release identities and current release mechanics.If implementation finds a current user-facing statement that specifically claims
0.1.0is the current version, update only that stale statement.Release notes decision
The current hardened publisher uses:
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:
1.0.0;python scripts/validate_release.py --require-productionsucceeds;1.0.0;Independent Review remains required.
Exact pre-tag gate
After both #214 and #216 are independently reviewed and integrated, do not create
v1.0.0immediately from stale handoff data.Integration/Human must establish one exact current protected
mainSHA and require all of the following:mainSHA is recorded;1.0.0;production_release_allowed: true;security:scanis successful;/m5authenticator/base path;v1.0.0 + <short exact-main commit>(non-exact release before tag);mainis 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;refs/tags/v1.0.0still does not exist;.github/workflows/release-authorized.ymlremains the sole production GitHub Release publisher and its authorization/attestation contract is unchanged;Releaseworkflow 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;v1.0.0identity 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.mdpre-existing protected-tag sequence after the exact-main manual candidate Pages Human Gate has passed:v1.0.0at that exact SHA through the authorized tag-creation path.refs/tags/v1.0.0and require that it resolves/peels to the exact approved SHA.repository_dispatch:M5Authenticator v1.0.0, its assets identify firmware version1.0.0, and signed attestation verification succeeds perdocs/DISTRIBUTION.md.v1.0.0rather than the manual candidate identityv1.0.0 + <commit>.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: