release: prepare Sandwich Hime v1 beta

Publish the sanitized Beta 1 source candidate with version-stable generated provenance, classroom/evaluation support boundaries, provisional macOS support, signed-source release policy, and an exact candidate preflight.

Material implementation, drafting, and review were assisted by OpenAI Codex. Cole Speelman reviewed the public snapshot and accepts human responsibility for the contribution.

Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
2026-08-12 14:37:53 -04:00
parent 113c95c21e
commit b7a84054d7
22 changed files with 824 additions and 193 deletions
+46 -8
View File
@@ -2,9 +2,16 @@
# Changelog
Sandwich Hime follows semantic versioning after v1. Compiler and nested runtime releases are listed separately.
Sandwich Hime follows semantic versioning after final v1. Compiler and nested
runtime releases are versioned independently and listed together when they form
one coordinated release.
## Unreleased — v1 proof
## v1.0.0-beta.1 — 2026-08-12
This is the first installable public beta: `sando/v1.0.0-beta.1` for the
Apache-2.0 runtime and `v1.0.0-beta.1` for the compiler and CLI. The beta is
for learning, classroom projects, evaluation, and compatibility feedback. It is
not a production-stability promise.
### Added
@@ -12,15 +19,46 @@ Sandwich Hime follows semantic versioning after v1. Compiler and nested runtime
- Context-annotated renderer IR with deterministic, atomic Go generation.
- Read-only stale-output checking and structured diagnostics.
- Independent Apache-2.0 `sando` component/runtime ABI.
- Loopback-only last-good development supervisor with SSE reload and diagnostic overlay.
- Loopback-only last-good development supervisor with SSE reload and diagnostic
overlay.
- Compiler-owned deterministic golden fixture and standalone release gates.
- Multi-license, security, governance, trademark, AI contribution, and release policies.
- Multi-license, security, governance, trademark, AI contribution, and release
policies.
- Public beta support policy for evaluation and classroom use, including a
provisional macOS lane and a community compatibility-reporting path.
### Removed
### Pre-beta verification baseline
- Unpublished `.go.hime` syntax and 2025 generated API.
- Injected helper directories, nested demo modules, Go plugins, and manually repaired generated output.
Maintainer-run Linux and native Windows matrices passed on public commit
`113c95c21e57227b4675c9fda015ada59cc9e9a6` (tree
`a2aeb4dac22853cb3894e3e487b94bbeff5051e5`) with Go 1.25.12 and Go
1.26.5. The tested golden output had the same SHA-256 on each tested host:
`63fa75a3049a3a8a12d769d7f9b6b510dfe763baacf706775b75cef2c57a984f`.
That commit is a pre-beta baseline, not evidence for the later Beta 1 commit.
The required matrix must be rerun from the exact candidate before its tags are
published. Native macOS execution remains pending and is explicitly provisional
for this beta.
### Known limitations
- Source syntax, generated format, CLI details, and runtime API may change
before final v1.
- Native macOS behavior has not yet been maintainer-validated.
- Prebuilt binary artifacts, checksums, SBOMs, reproducible archives,
key-recovery rehearsal, systematic browser differential, long fuzz,
benchmark, and final compatibility gates remain work toward the release
candidate and final v1. Beta 1 itself is a signed source/module release.
- The project has no independent security audit, certification, or formal
verification.
### Removed since the private prototype
- Unpublished `.go.hime` syntax and the 2025 generated API.
- Injected helper directories, nested demo modules, Go plugins, and manually
repaired generated output.
- Repository-bundled application examples and deployment-specific evidence.
- Placeholder novelty commands that did not perform project work.
Private prototype history is intentionally outside the sanitized public repository. The public changelog begins with the pre-1.0 source preview.
Private prototype history is intentionally outside the sanitized public
repository. The public changelog begins with Beta 1.
+1 -1
View File
@@ -5,7 +5,7 @@
The canonical public project and only contribution venue is the
[founder-controlled Gitea repository](https://gitea.speelman.ca/gamertan/sandwich-hime).
Repository maintainers may temporarily disable issue or patch intake during the
pre-1.0 preview; do not route around a closed intake channel by sending
pre-1.0 period; do not route around a closed intake channel by sending
unsolicited private patches.
Public pre-1.0 contributions use Developer Certificate of Origin 1.1 sign-off. The proposed `CLA.md` is an inactive draft, is not a condition of contribution, and creates no contributor or project obligations. If a contribution agreement is ever activated after legal review, the project will announce its prospective terms rather than silently applying the draft.
+2 -2
View File
@@ -2,9 +2,9 @@
# Founder-led governance
Sandwich Hime is founder-led. Cole Speelman is lead maintainer and has final authority over product direction, merges, releases, project identity, and security coordination. Authority is exercised through reviewable public releases, written rationale for material public decisions, and the published compatibility and release policies. Publishing a source preview does not create a promise of support or transfer stewardship.
Sandwich Hime is founder-led. Cole Speelman is lead maintainer and has final authority over product direction, merges, releases, project identity, and security coordination. Authority is exercised through reviewable public releases, written rationale for material public decisions, and the published compatibility and release policies. Publishing a prerelease creates only the support commitment stated for that version; it does not transfer stewardship.
Pre-1.0 contributions use the DCO process described in `CONTRIBUTING.md`; the CLA draft is inactive. Acceptance is never guaranteed. Maintainers may close work that expands the product beyond an HTML-first Go component compiler, weakens fail-closed safety, couples the runtime to a framework, or imposes unsustainable maintenance.
Pre-1.0 contributions use the DCO process described in `CONTRIBUTING.md`; the CLA draft is inactive. Acceptance is never guaranteed. Maintainers may close work that expands the product beyond an HTML-first, ahead-of-time Go template engine, weakens fail-closed safety, couples the runtime to a framework, or imposes unsustainable maintenance.
Maintainers disclose relevant employment or financial conflicts and recuse when a conflict would compromise review. If the project reaches three maintainers, no single employer may control a majority of seats.
+1 -1
View File
@@ -33,4 +33,4 @@ SPDX identifiers state the applicable license for comment-capable source and doc
The snapshot exporter's `PUBLIC-SNAPSHOT.json` and `PUBLIC-SNAPSHOT.sha256` are generated factual provenance records and intentionally carry no inline SPDX comment. They do not change the license of any listed file.
These are practical project licensing terms, not legal advice or a prediction of how every jurisdiction will classify a particular work. The inactive CLA draft and pre-registration trademark policy say so explicitly. Qualified legal review remains prudent before changing these terms, activating a CLA, registering marks, or making a fact-specific licensing decision; it is not represented as a prerequisite to publishing the current unsupported source preview.
These are practical project licensing terms, not legal advice or a prediction of how every jurisdiction will classify a particular work. The inactive CLA draft and pre-registration trademark policy say so explicitly. Qualified legal review remains prudent before changing these terms, activating a CLA, registering marks, or making a fact-specific licensing decision; it is not represented as a prerequisite to publishing the current narrowly scoped public beta.
+1 -1
View File
@@ -1 +1 @@
{"schema_version":2,"project":"sandwich-hime","export_policy":"exact-allowlist-v1","export_mode":"release","file_count":80,"allowlist_sha256":"e40a56b3431efdd99b3a78c38c387722de347216640383fc849569a817edf5c6","manifest_sha256":"0b27ea55bc1f2083ac07ae777d20735e651c5026888b973bfe02ee764b9487dc"}
{"schema_version":2,"project":"sandwich-hime","export_policy":"exact-allowlist-v1","export_mode":"release","file_count":80,"allowlist_sha256":"e40a56b3431efdd99b3a78c38c387722de347216640383fc849569a817edf5c6","manifest_sha256":"93870a8c1e91602754de257c30249892821356ea9bf8d89e1b4502b62d769b06"}
+20 -20
View File
@@ -2,45 +2,45 @@
658ba4b4645426f8c3249337f47669074ae9249a31703dcd9ea4c1afec45e20b ./.gitattributes
d5ae411fb422b2388cac220f9655900eecbc49ece961b2bb2a6610347733b756 ./.gitignore
98f663ab0f376b4550094465ec2e06192d1e0b0707604ec6794f20b0d10952c1 ./AI_CONTRIBUTIONS.md
7f4414fed21e9578b8d1a0d109ba807cb79d28a9290d58df49cc75145d9d1068 ./CHANGELOG.md
8bc6c7586a58bdc648c7d3df2db33fa6db6381a111da9d8fc2d5817b5e0517ad ./CHANGELOG.md
b696cab3cf482ff5737501371cca749369b119351383e698ced42bcdbcbfc8ae ./CLA.md
2d98826969cd492cc4dd10c595be21a608def5aacbec40ea5e25f1c3a617d8e6 ./CONTRIBUTING.md
797e884105738fc931b585b695424f43ec5f296d8ab9bba5191b096e87a9e2c2 ./CONTRIBUTING.md
86d7e49d5d90e0f98a4ad0f14b5d8b9f11ed09a1e29ecdf27388316b28e195e8 ./COPYRIGHT
f7ac75b443f4ca16b503241344b41aeff9503b0c30bedc2b119551d83cb0fa90 ./DCO.txt
73cb1b092a40c56e522c5a0ebddf2b44f347cdb57bf6994cdb305d0e5697b55e ./GENERATED_CODE.md
048f96acecd3af84d6abc4f8c38108dff2171445417e5132318a1d18de4279fe ./GOVERNANCE.md
a4570d054f072d33b8f17b0c8b162a6ee0ca37d7df2b1aee7e4b728ab350a892 ./GOVERNANCE.md
0d96a4ff68ad6d4b6f1f30f713b18d5184912ba8dd389f86aa7710db079abcb0 ./LICENSE
6587e439cb3c39dce9aaa5b51facdbd78c0e86c24e9e3fb9537b944435a74410 ./LICENSES.md
47d857e49f89596bac9b09fc8ca57a668a33d01e2b51508acfc92ed321cdc27f ./LICENSES.md
b6aa08e5ccaec3c5dccdc19d7cd7f54a70adae4d57966263c7aa353c7ba70e08 ./MAINTAINERS.md
6638db2f1fba831c79de835ce95c847a5b36c5b5c693b99a28655b2d096cc440 ./OUTPUT_EXCEPTION.md
327386b40ee9fb92a8568b6a51722578890393fa23051af632f3180385a4e739 ./README.md
ce32945cf5f16ab1a0202615bcf2053f46d421dcdd8ff2f1292f95bb5cf4493d ./RELEASE.md
419c334aeb20dc22ceba8d031aaa95314b77125bf3267fd9fdc003e3865f0327 ./ROADMAP.md
d70d89db6bf0142a42a95f45537be5a4562258646d36d56bd9a70096ec78ed91 ./SECURITY.md
dda0ffee17bc1586ac16cc9707999cde2909a116c98cd43aeab85e0d3da7b636 ./README.md
9895823f9f7ba88ddf048c53c23ed32298b151ab049a9c4470366389d9498ff4 ./RELEASE.md
6d1e49dd72ba9592a3fd0562fcca1857803a3dd86dc097b36043e20f5d5cd591 ./ROADMAP.md
50a24995b39a957e47e0e181f8771a87141302b4d308fa8d8bfdc2e70121c2b9 ./SECURITY.md
53bd6eda804d6b782bdb07115ec197c890813cf2d5d0125dfe8f47f5f92f75b0 ./SPEC.md
842beff8afa72d120fcad0ac73afb2049d580ff3000975f3b1786c4ade6a14d4 ./TRADEMARKS.md
3d9e680cdfe147df7cc9ff29ecf1d3e566e9cd559ae84db4880e559b9c7c7205 ./TRADEMARKS.md
136a6d82db842547b342f8b0c9ffdc7c04f7c9b473b4ef6dca9dbc940cb24b54 ./cmd/himesan/main.go
3011a435aaeb572d34e2d2b582865fd63268c92a9ae3f0ae1a56d1a59d83cd43 ./cmd/himesan/main_test.go
1ecbba46f8b1b2d548a01d7e98afae17b2dd17a814338ff1f88db885655d1c07 ./docs/ARCHITECTURE.md
9c598559a89fa4a9bdd2311bd1ed8330992d0a0f74ec8b29ac151fc0ff8fef16 ./docs/BENCHMARKS.md
5c3a62fed80ca28d56558b8c75e8b5be8ba7d2554127adf4609d96da314e85b0 ./docs/BRAND.md
35f5b4b7d195a7b5c071d4665505afef189c7b386d4e3079e9ce8a96ace07f3a ./docs/COMPATIBILITY.md
4f7b04b3f74a2e90fc69019cad78a1287f4806ae84e7207cfdf000971702395d ./docs/COMPATIBILITY.md
5f4ac209a16ab110baeaa64a40c19d9239c903e17550c3f05e1e1473ddcc33a3 ./docs/DEVELOPMENT_SERVER.md
51aa57a81131b64f76c45552122de842f22be92d81c8bba8f6fd38a18a7670d6 ./docs/DIAGNOSTICS.md
04c6b3f93588177a87edbca8f56af0e0f2a7c5ba31936f3174570c8282a1a7c2 ./docs/SECURITY_EVIDENCE.md
9bd43853d91b841c4879dac94dda5aafefa25bcdf4a02763445e2506fc618b03 ./docs/SECURITY_EVIDENCE.md
d969c7b5486ee93e54232fd69d9db06f3b4dc1bba63001596ec48545073c2680 ./docs/THREAT_MODEL.md
76ac444771ac0a4f584ee0cf86ebfd34233412e6e511485f6cc90131a9a50387 ./docs/V1_RELEASE_PLAN.md
82107c57043af40b9e3ec03f4ed9efddcf3bcdda1765b99ec413f835be4a46e3 ./docs/V1_RELEASE_PLAN.md
f27c46ca63707bb8cc570eab1ea521824e94bc59b1d153998a5e91c2c7340d16 ./go.mod
ca0bf5051d356d2602f46201fb1637ce48b629ad42161877eec13f743f215dc5 ./internal/compiler/abi_test.go
0a624f76214afbed561a6f6490405c5083e49a53ae301c6ede763b78407ec0c7 ./internal/compiler/backend.go
7c96a4b31a34201cb9c48a7f0bac1c201865e4ecc7c080691af5ce68b3d7c207 ./internal/compiler/compiler_test.go
6ef6a0f15a5aca1c8708cbf24218372e1fca9c6fead1a5a75d261faa69651af7 ./internal/compiler/backend.go
4d309392a7739b26e41cd9d9db71b52077bb8198573634ddf793ad531acc81cf ./internal/compiler/compiler_test.go
dbba23e360bd6dd1e8f42953a49a7cfcc241aa3ac76f5ce505ec8f8558833c84 ./internal/compiler/context.go
b2a96ef1ad572ad9cd0e9247328ca261de6f9f3689da41e3f3e111d405a6dee6 ./internal/compiler/diagnostic.go
45562a41ef9ab1116746e4962ce8f93d4d8651e1e468a38122c626f8a34a2874 ./internal/compiler/discover.go
f5a6b31416027cb69a61d1a1421cba779ec3accae59c9ba9dd45d2c31b72149e ./internal/compiler/e2e_test.go
50a8bad11deea99faf0c7c9de1266bc086b7a1247ff9dd275ffedfc69a3be81d ./internal/compiler/e2e_test.go
eefb05a35bd07660a293c8af97949cd6f69a22709728f3fe2cc9132b863b7d5a ./internal/compiler/fuzz_test.go
d166096f185d76b2698aa3ab3251f00e58f84cdedc3af667e88ddd528ca0cb76 ./internal/compiler/model.go
0c7a7a4d6a51a8b58dfe7c12ecd8c608aff639fd6157a9657a0663ceb58c3c8c ./internal/compiler/operation.go
01516c0330b14a1970019690d8efcc9004d2dcfa59e82fef1b67f98005b67532 ./internal/compiler/operation.go
d7d8181455d5f37ef9bcc6bdbf86e0630f20e8a5b3b81688d12742687b434c99 ./internal/compiler/parse.go
80cf170514a3b955d24440cb086d34e19f3a305510e3c5db95cb897be91f922a ./internal/compiler/replace_unix.go
0fff1c67447bf5353ed1df6e7dfc4b14581b67adc1bf02f7a4a7c1f2680c392f ./internal/compiler/replace_windows.go
@@ -62,7 +62,7 @@ b94103cd4b582968cdb0b61b0164f57ade006fa4e5187fcaa05944274192526a ./internal/dev
e0a682c0153bf4f2a1f26cc6095d7893ad96e6199cbe76d0150785fc996f1141 ./internal/devserver/watch.go
b7a7fabf9a6c497f7ac2262628c5fb37a6bd00da676e1b7d5088d5f649c9f14c ./internal/devserver/watch_test.go
d8c6f37c94ef426fc2d95c82331265f7d700d2e2a23100ad78c92849280ff6d8 ./internal/version/version.go
15cf04427c5239cf6985a24c62c888013137205b8159f8f24189a16c22ac6cf3 ./internal/version/version_test.go
9b615038a1178eedbcab299d90548e259ac34d2f5c51deadd79ed16f51ef6911 ./internal/version/version_test.go
e8a3026ec920d7312f843e2001e50ae4e34fd1ba5f9b2ae25a6113de1fa88385 ./sando/COPYRIGHT
c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4 ./sando/LICENSE
b4a7bffe678a97209881e07989563a5085aa0ead9e1b67306087dac6b97bad70 ./sando/README.md
@@ -72,9 +72,9 @@ ff76daee5b642ad84af31701833246d68b54d09580192312d750a7a2e893a692 ./sando/go.mod
80ff53787919e809b8085d6ad9c3e183c9c7c1d74cfeda73369ac5c4607c236f ./sando/trust.go
85621a44c730582f4410ac2c70418b739fb55e916f7e6b73a1a619982c459572 ./sando/write.go
b188917e258890e6b6e4840a6fd946fc9a77cabc2068da3764f221e4a6a5df97 ./sando/write_test.go
ecae2e2938da982001eb1e10d7e9869e191669a776336b89f5cb181b18678701 ./scripts/README.md
504897b29686e0ea7adff8beb8ec91612df3ee169397309c3b6b69eb0393491b ./scripts/README.md
0bc796f71c863aa898674a26c56f055e3d81cf20629ca7b32fbae87d8841e0a8 ./scripts/check-licenses.sh
502da1760bc87f260d474d81fe8f015a6e198f8d1ebf96db6b3f460ce4ef3b02 ./scripts/release-check.sh
6be2fc6b8c3e0a7dd85437fa4089e75b772baa7556675081e6956a1b9f207fb4 ./scripts/verify-public-install.sh
6c73ad46beb642836ae4d462f40e7ecc8d86a3cc194e71a5d0859dac73af0410 ./scripts/release-check.sh
9cd43005a7d0f3659b11c5c14e4e0b9e7f675b695da185f4ee97c54edebf0dc6 ./scripts/verify-public-install.sh
24ed3c9a1d37e46a856cbbd68e5c58ae04c6c9852902b99ed675e1f428339a9f ./scripts/verify.ps1
f0cbd86759fa729064cb1c69991db2ac291792dadb6b1e1ba83794f2e390404d ./scripts/verify.sh
+41 -13
View File
@@ -42,11 +42,44 @@ request object, or production server.
## Status
This repository is an unsupported public pre-1.0 source preview, not a
supported v1 release. V1 is gated only by repository-owned compiler, runtime,
security, compatibility, and release checks. Application-specific deployments,
examples, and case studies live in their own repositories and are not imported
as release evidence here.
`v1.0.0-beta.1` is the first installable public beta. It is supported for
learning, classroom projects, evaluation, and compatibility feedback. It is a
semantic-version prerelease: source syntax, generated output, the runtime API,
and CLI behavior may change before final v1, and this beta is not recommended
for production deployment.
Maintainer-run testing has established a pre-beta baseline on native Windows
and on Linux with Go 1.25 and Go 1.26. That matrix must pass again on the exact
Beta 1 commit before its tags are published. Native macOS validation is still
pending, so macOS support is provisional in this beta. Mac learners and Go
developers are warmly invited to try it and share their macOS version,
architecture, Go version, command, and smallest useful reproduction. Community
reports broaden the evidence; maintainers remain responsible for security
review, triage, fixes, and release decisions.
Install the beta compiler:
```sh
go install gamertan.com/sandwich-hime/cmd/himesan@v1.0.0-beta.1
```
Add the small runtime to an application module:
```sh
go get gamertan.com/sandwich-hime/sando@v1.0.0-beta.1
```
For a reproducible one-off or classroom invocation that does not depend on the
learner's `PATH`:
```sh
go run gamertan.com/sandwich-hime/cmd/himesan@v1.0.0-beta.1 --help
```
The runtime is released first as `sando/v1.0.0-beta.1`; the compiler follows as
`v1.0.0-beta.1`. If a newly announced version is not immediately available
through a module proxy, retry after the proxy has discovered the immutable tag
or use the canonical Gitea release instructions.
For repository development:
@@ -64,14 +97,9 @@ and serves it through `http://127.0.0.1:7331` with local-only reload
diagnostics. That is a Cole-shaped convenience, not a production server or a
requirement. Take the paved path—or don't.
The eventual versioned installs are:
```sh
go install gamertan.com/sandwich-hime/cmd/himesan@v1.0.0
go get gamertan.com/sandwich-hime/sando@v1.0.0
```
Those vanity paths must not be advertised as working until the corresponding signed releases and `gamertan.com` metadata exist.
Final-v1 installs will use the same paths with `@v1.0.0`. A version is
advertised as available only after its immutable tags, `gamertan.com`
metadata, and clean direct-fetch installation have been verified.
## The contract
+106 -25
View File
@@ -2,41 +2,122 @@
# Release process
Sandwich Hime uses separate root and runtime version lines. Compiler tags are `vX.Y.Z`; runtime tags are `sando/vX.Y.Z`. Generated headers record both compiler version and runtime ABI.
Sandwich Hime uses separate root and runtime version lines. Compiler tags are
`vX.Y.Z`; runtime tags are `sando/vX.Y.Z`. Generated headers record both the
compiler version and runtime ABI. The runtime is always published before the
compiler that references it.
The public pre-1.0 source snapshot is not a supported release and does not imply that the v1 gates below have passed.
Every tag is immutable. A failed publication is corrected with a new version,
never by moving or replacing a tag.
No v1.0.0 release occurs until every gate in this repository is evidenced,
including cross-platform deterministic generation, temporary-module
compilation, fuzz/adversarial suites, race/vet/vulnerability/license checks on
the latest two supported Go lines, development-supervisor failure tests, and
reproducible repository-owned benchmark and security results. A deployment,
example, or case study in another repository is neither imported nor required
as release evidence.
## What the version stages mean
Release candidates require a clean canonical checkout, reviewed changelog, compatible vanity-import metadata, reproducible binaries, signed annotated tags, checksums, SBOMs, vulnerability results, and verification on Linux, macOS, and Windows. The runtime is tagged and published independently before the compiler that references its ABI.
### Beta
A beta is an installable public evaluation release. The current
`v1.0.0-beta.1` scope is learning, classroom projects, prototypes, and
compatibility feedback. It receives best-effort security assessment and fixes
while it is the current prerelease, but it is not recommended or supported as a
production-stable dependency. Syntax, generated output, runtime APIs, CLI
behavior, and diagnostics may change in a later prerelease.
Beta 1 may publish with native macOS validation pending when Windows and Linux
have passed the exact-candidate matrix and macOS is clearly marked provisional.
Community Mac results are valuable compatibility input; they do not transfer
security review, triage, remediation, or release responsibility away from the
maintainers.
Beta tags are signed, annotated, and immutable. Beta 1 is a source/module
release installed through the Go toolchain; it does not promise downloadable
prebuilt binaries. Signed binary artifacts, checksums, SBOMs, reproducible
archives, and key-recovery rehearsal are mandatory for release candidates and
final v1.
### Release candidate
An RC means the intended v1 source, runtime, CLI, diagnostics, schemas, and
generated contract are frozen except for release-blocking fixes. An RC requires
maintainer-run native Linux, macOS, and Windows evidence, complete release
artifacts and provenance, signed tags, clean direct/proxy installs, and every RC
gate in this repository. Findings produce a new RC rather than a moved tag.
### Final v1
Final v1 is the compatibility and support commitment. It requires the complete
repository-owned evidence campaign, resolution or explicit acceptance of every
published assurance gap, and the documented RC observation period. A
deployment, example, classroom project, or case study in another repository is
neither imported nor required as release evidence.
## Beta 1 publication gates
Before `sando/v1.0.0-beta.1` and `v1.0.0-beta.1` are created:
1. Use a clean reviewed canonical public commit with no private identifiers,
paths, credentials, or history.
2. Run license, root/runtime test, vet, build, race, deterministic-generation,
and candidate-version freshness checks on supported Go 1.25 and Go 1.26
lanes on Windows and Linux.
3. Confirm generated bytes match across those exact-candidate lanes and record
all skips or platform limitations.
4. Run the bounded fuzz and known-vulnerability checks from a clean release
host.
5. Review the changelog, security policy, compatibility policy, support scope,
provisional macOS wording, and vanity-import metadata.
6. Build the candidate compiler at its candidate version and prove its committed
generated fixtures are current under that exact binary.
7. Create signed annotated tags and publish the runtime tag first, then the
compiler tag, from the same reviewed commit.
8. Verify both documented installs from fresh `GOPROXY=direct` and public-proxy
caches. Record propagation delays as delays, not test passes.
The passing public commit
`113c95c21e57227b4675c9fda015ada59cc9e9a6` (tree
`a2aeb4dac22853cb3894e3e487b94bbeff5051e5`) is only the pre-beta
platform baseline. Any documentation, versioning, or code change produces a new
candidate and requires the candidate matrix to run again before tagging.
## RC and final gates
No release candidate or v1.0.0 release occurs until every applicable gate in
this repository is evidenced, including cross-platform deterministic
generation, temporary-module compilation, fuzz/adversarial suites,
race/vet/vulnerability/license checks on the latest two supported Go lines,
development-supervisor failure tests, and reproducible repository-owned
benchmark and security results.
Release candidates require a clean canonical checkout, reviewed changelog,
compatible vanity-import metadata, reproducible binaries, signed annotated
tags, checksums, SBOMs, vulnerability results, and verification on Linux,
macOS, and Windows.
## Public source and artifacts
Gitea is the only canonical public forge. Public source is exported into a
separate, sanitized Gitea repository with fresh history; private development
history and the private-to-public commit mapping are not published. A
sanitized GitHub discovery snapshot may copy reviewed public source, but it is
not an issue, contribution, release, or module origin and must never receive
private development refs or an indiscriminate Git mirror. Release binaries and
provenance are built from the reviewed canonical Gitea commit. Compiler
documentation, binaries, checksums, SBOMs, and the independently versioned
runtime tag form the coordinated v1 release. Example applications and product
sites keep their own history, deployment, and evidence.
separate, sanitized Gitea repository with fresh reviewed history. A sanitized
GitHub discovery snapshot may copy reviewed public source, but it is not an
issue, contribution, release, or module origin and must never receive private
development refs or an indiscriminate Git mirror. Release binaries and
provenance are built from the reviewed canonical Gitea commit.
The hosting configuration must answer exact package discovery requests, not
only module-root pages. In particular,
`/sandwich-hime/cmd/himesan?go-get=1` returns compiler metadata and the
`/sandwich-hime/sando` subtree returns runtime metadata. After signed tags and
public metadata exist, run `scripts/verify-public-install.sh --version
vX.Y.Z`; it exercises the documented `go install` and `go get` commands from
fresh direct-fetch and public-proxy caches. This post-publication check is
separate from the pre-tag, read-only `scripts/release-check.sh`.
`/sandwich-hime/sando` subtree returns runtime metadata. After tags and public
metadata exist, run:
Release notes report hardware, commit, datasets, commands, `ns/op`, allocations, response latency, and methodology for performance claims. “Fastest” or equivalent language is prohibited without durable, reproducible evidence.
```sh
scripts/verify-public-install.sh --version vX.Y.Z
```
That check exercises the documented `go install` and `go get` commands from
fresh direct-fetch and public-proxy caches. It is separate from the pre-tag,
read-only `scripts/release-check.sh`.
Release notes report hardware, commit, datasets, commands, `ns/op`,
allocations, response latency, and methodology for any performance claim.
“Fastest” or equivalent language is prohibited without durable, reproducible
evidence.
Production applications compile and deploy their committed `.sando.go` files
with the Apache-2.0 `sando` runtime. They do not need the AGPL compiler or the
+64 -28
View File
@@ -2,41 +2,77 @@
# Proof-in-the-pudding roadmap
Unchecked items are release blockers, not aspirational marketing.
Unchecked items are release blockers for the milestone that contains them, not
necessarily blockers for an earlier prerelease. The ordered initiative,
repository topology, release-candidate sequence, and definition of confidence
are maintained in [docs/V1_RELEASE_PLAN.md](docs/V1_RELEASE_PLAN.md).
The ordered initiative, repository topology, release-candidate sequence, and
definition of confidence are maintained in
[docs/V1_RELEASE_PLAN.md](docs/V1_RELEASE_PLAN.md).
## Beta 1: public learning and evaluation
## Compiler and runtime
Beta 1 deliberately ships before the final-v1 compatibility and artifact gates.
Its scope is classroom use, learning, prototypes, and compatibility feedback;
it is not a production-stability promise.
- [ ] Compiler-owned deterministic golden output repeated across Linux, macOS, and Windows.
- [ ] Temporary consumer modules compile using committed Go and only the Apache runtime.
- [ ] Parser, delimiter, context, path, and source-map fuzz targets survive the release campaign.
- [ ] Adversarial escaping and filesystem cases are evidenced.
- [ ] Latest two Go lines pass test, race, vet, vulnerability, and license gates.
- [ ] Signed compiler/runtime release artifacts, checksums, and SBOMs reproduce.
- [x] Define beta versus RC/final support and compatibility policy.
- [x] Establish a public pre-beta Linux/Windows matrix on Go 1.25 and Go 1.26.
- [x] Document macOS as provisional and invite useful community reports while
retaining maintainer responsibility for security and releases.
- [ ] Rerun all required Windows/Linux checks and deterministic generation on
the exact Beta 1 candidate.
- [ ] Publish immutable `sando/v1.0.0-beta.1`, then
`v1.0.0-beta.1`, from the reviewed public commit.
- [ ] Verify clean direct and public-proxy installs after publication.
- [ ] Complete native macOS maintainer validation. This is an RC/final gate,
not a Beta 1 gate.
## Development supervisor
## Compiler and runtime for RC/final
- [ ] Generation/build/start/health failures keep the previous healthy server live.
- [ ] SSE reconnect/reload and mapped overlay diagnostics pass browser-level tests.
- [ ] CSP hash injection, fragment/API/download exclusion, and cache disabling pass.
- [ ] Replaced and interrupted child processes leave no descendants on supported systems.
- [ ] Freeze and machine-check the compiler, CLI, diagnostic, schema, generated,
and runtime compatibility contracts.
- [ ] Repeat compiler-owned deterministic golden output across Linux, macOS,
and Windows on the exact candidate.
- [ ] Compile temporary consumer modules using committed Go and only the Apache
runtime.
- [ ] Run the parser, delimiter, context, path, and source-map release fuzz
campaign.
- [ ] Evidence adversarial escaping and filesystem cases.
- [ ] Pass test, race, vet, vulnerability, and license gates on the latest two
supported Go lines.
- [ ] Reproduce signed compiler/runtime release artifacts, checksums, and SBOMs.
## Development supervisor for RC/final
- [ ] Generation/build/start/health failures keep the previous healthy server
live.
- [ ] SSE reconnect/reload and mapped overlay diagnostics pass browser-level
tests.
- [ ] CSP hash injection, fragment/API/download exclusion, and cache disabling
pass.
- [ ] Replaced and interrupted child processes leave no descendants on
supported systems.
## Repository-owned release evidence
- [ ] Contextual escaping is differentially tested against Go's documented `html/template` safety baseline.
- [ ] Repository-owned synthetic benchmark cases and methodology are reproducible from a clean checkout.
- [ ] Generated output is reviewed for stable provenance, source mappings, and absence of compiler-license headers.
- [ ] Production application boundaries are documented: committed generated Go plus the Apache runtime, with no compiler or development supervisor in the deployed binary.
- [ ] Unsupported or unmeasured performance and production claims are absent from release materials.
- [ ] Differentially test contextual escaping against Go's documented
`html/template` safety baseline.
- [ ] Reproduce repository-owned synthetic benchmark cases and methodology from
a clean checkout.
- [ ] Review generated output for stable provenance, source mappings, and
absence of compiler-license headers.
- [ ] Document the production boundary: committed generated Go plus the Apache
runtime, with no compiler or development supervisor in the deployed binary.
- [ ] Keep unsupported or unmeasured performance and production claims out of
release materials.
## Public launch
## Final public launch
- [ ] Ownership notices, output permission, DCO contribution process, and pre-registration trademark terms receive final human review.
- [ ] Name clearance, security mailbox, two-person credential recovery, and signing keys complete.
- [ ] `gamertan.com` vanity-import metadata and documented installs verified from a clean machine.
- [ ] Sanitized fresh-history public Gitea snapshot contains no private paths, identifiers, history, or unsupported release claims.
- [x] Canonical public Gitea source and project documentation launch, with any
secondary forge explicitly limited to a sanitized discovery snapshot.
- [ ] Complete final human review of ownership notices, output permission, DCO
contribution process, and pre-registration trademark terms.
- [ ] Complete name clearance, security-mailbox recovery, release signing, and
two-person credential recovery.
- [ ] Verify `gamertan.com` vanity metadata and documented installs from clean
machines.
- [ ] Confirm the sanitized public Gitea source contains no private paths,
identifiers, history, or unsupported claims.
- [ ] Publish and observe a signed RC on every supported native platform.
- [ ] Publish `sando/v1.0.0`, then `v1.0.0`, without moving either tag.
+31 -13
View File
@@ -2,21 +2,28 @@
# Security policy
Sandwich Hime is a public pre-1.0 source preview. Security reports are welcome
now, even though no version is currently designated as supported for production
use. The project would rather receive a careful early report than project
confidence it has not earned.
Sandwich Hime `v1.0.0-beta.1` is supported within a deliberately narrow
scope: learning, classroom projects, evaluation, and compatibility testing.
Security reports are welcome and receive best-effort maintainer assessment and
fixes while Beta 1 is the current prerelease. This is not production support,
an SLA, a fitness guarantee, or a promise that a fix will preserve beta APIs.
The community is invited to help find compatibility gaps, especially on macOS.
That invitation does not outsource security assurance. Maintainers retain
responsibility for vulnerability review, triage, remediation decisions,
advisories, and release decisions.
## Supported versions
| Version | Security status |
| --- | --- |
| Public `main` source preview | Best-effort assessment and fixes; interfaces may change |
| Versioned releases | None published yet |
| `v1.0.0-beta.1` and `sando/v1.0.0-beta.1` | Current evaluation/classroom prerelease once published; best-effort security assessment and fixes; interfaces may change |
| Public `main` | Development source; reports welcome, but no compatibility or production-support promise |
| Older prereleases | Superseded when a newer prerelease or final version is published; reports are still triaged to determine affected versions |
This table will name supported release lines once immutable compiler and runtime
versions are published. A pre-1.0 release is not a promise of API stability or
fitness for a particular application.
Beta support lasts until it is superseded or explicitly withdrawn in the
supported-version table and release notes. Published tags are immutable. A
security fix is issued as a new version, never by silently replacing a tag.
## Report a vulnerability privately
@@ -24,6 +31,12 @@ Email **security@sandwichhime.com**. Please do not put an undisclosed
vulnerability, working exploit, credential, secret, or personal data in a
public issue.
If that new mailbox rejects or bounces a message, retain the report and open a
canonical Gitea issue containing only the fact that the private security contact
failed. Do not include technical details or sensitive data. The maintainer will
publish a corrected private route. Ordinary usage, classroom, and macOS
compatibility reports that do not reveal a vulnerability may use a public issue.
Helpful reports include:
- the affected compiler/runtime version or exact commit;
@@ -40,7 +53,9 @@ ownership, backup, and recovery procedure have been tested.
## What to expect
These are best-effort targets for a founder-maintained project, not an SLA:
These are best-effort targets for a founder-maintained project, not an SLA.
They describe maintainer responsibilities; asking the community to test a beta
does not ask reporters to investigate or remediate it:
- acknowledge a report within 7 calendar days;
- provide an initial severity/scope assessment within 14 calendar days when a
@@ -118,8 +133,11 @@ an independent security audit, certification, or formal verification. Coverage
percentages, passing scanners, and a clean vulnerability database result are
evidence of specific checks—not proof that no vulnerability exists.
Release artifacts and tags are intended to carry signatures, checksums, an
SBOM, and exact source/build provenance. Those controls are publication gates
until the first versioned release is actually available.
Beta 1 publication requires signed annotated source tags, but may precede the
complete prebuilt-artifact and key-recovery system. Signed binaries, checksums,
an SBOM, reproducible archives, and complete source/build provenance are
release-candidate and final-v1 gates. Their absence from a source-only beta must
not be read as evidence of artifact authenticity beyond the verified tag and
canonical source.
This policy is practical project guidance, not legal advice.
+1 -1
View File
@@ -12,4 +12,4 @@ Community discussion, commentary, criticism, tutorials, and truthful nominative
Trademark permission does not supply a copyright license for artwork. If the project publishes an official flag, mascot, or “Built with Sandwich Hime” badge, that asset must identify its own copyright holder and reuse license before others are asked to copy it.
This policy grants permission only to the extent the project steward controls the relevant rights. It is not a claim that a mark is registered, cleared in every territory, or legally exclusive, and it does not override uses permitted by applicable law. Professional clearance and qualified legal advice remain prudent before registration, enforcement, or material investment in a mark; they are not represented as prerequisites to publishing the unsupported source preview.
This policy grants permission only to the extent the project steward controls the relevant rights. It is not a claim that a mark is registered, cleared in every territory, or legally exclusive, and it does not override uses permitted by applicable law. Professional clearance and qualified legal advice remain prudent before registration, enforcement, or material investment in a mark; they are not represented as prerequisites to publishing the current narrowly scoped public beta.
+63 -4
View File
@@ -2,10 +2,69 @@
# Compatibility policy
Before v1.0.0, source syntax and generated ABI may change without compatibility shims, but each public change must be documented and deterministic. Private prototype history is intentionally outside the sanitized public repository and carries no public compatibility promise.
## Beta 1 contract
At v1, semantic versions apply independently to the compiler and `sando` runtime. Generated files record the exact compiler version and required runtime ABI. Patch releases do not intentionally change accepted source semantics or generated public signatures. Minor releases may add fail-closed syntax or API capabilities while continuing to render previously valid components. Major releases may remove or reinterpret behavior.
`v1.0.0-beta.1` and `sando/v1.0.0-beta.1` are semantic-version
prereleases. They are supported for learning, classroom projects, evaluation,
and compatibility testing. Before final v1, source syntax, generated output,
the runtime API, CLI behavior, diagnostics, and configuration may change
without compatibility shims. Every public change must still be documented and
generation must remain deterministic.
The compiler supports the latest two Go release lines validated in CI. A support change is announced before release. Generated files are source artifacts, not a stable interchange format across compiler versions; `himesan check` defines whether they are current.
The beta is not a production-stability commitment. Maintainers accept and
triage security reports within the boundary described in
[SECURITY.md](../SECURITY.md), but cannot promise that a beta fix preserves its
public API.
The project makes no compatibility promise for internal packages, development SSE payloads before v1, or hand-edited generated files.
## Final-v1 contract
At final v1, semantic versions apply independently to the compiler and
`sando` runtime. Generated files record the exact compiler version and
required runtime ABI. Patch releases do not intentionally change accepted
source semantics or generated public signatures. Minor releases may add
fail-closed syntax or API capabilities while continuing to render previously
valid components. Major releases may remove or reinterpret behavior.
Generated files are source artifacts, not a stable interchange format across
compiler versions; `himesan check` defines whether they are current. The
project makes no compatibility promise for internal packages, development SSE
payloads before final v1, or hand-edited generated files.
## Go and platform support
Beta 1 targets Go 1.25 and Go 1.26. Support is based on point-in-time,
maintainer-run release matrices, not an implication of continuous CI coverage.
A Go support change is announced in release notes before it takes effect.
The current public evidence is a **pre-beta baseline** on commit
`113c95c21e57227b4675c9fda015ada59cc9e9a6` (tree
`a2aeb4dac22853cb3894e3e487b94bbeff5051e5`):
| Platform | Go lanes | Maintainer-run result |
| --- | --- | --- |
| Windows 11/amd64 on NTFS | 1.25.12, 1.26.5 | Native tests, race, vet, builds, generation, process cleanup, watcher boundaries, and temporary consumer compilation passed; privileged symlink and POSIX-only permission cases were not exercised |
| Linux/amd64 on WSL2 with an ext4 checkout | 1.25.12, 1.26.5 | Tests, race, vet, builds, generation, focused filesystem/development cases, and license checks passed |
| Linux/amd64 in isolated containers on a Linux server | 1.25.12, 1.26.5 | Tests, race, vet, builds, deterministic generation, and license checks passed |
| macOS | — | Native maintainer validation pending; provisional for Beta 1 |
The golden generated file had SHA-256
`63fa75a3049a3a8a12d769d7f9b6b510dfe763baacf706775b75cef2c57a984f`
on every tested Windows and Linux lane.
Because the Beta 1 candidate contains changes after that public baseline, the
complete Windows/Linux matrix must be rerun on the exact candidate before the
tags are published. The baseline does not become beta evidence merely because
its code is nearby in history.
## macOS feedback
Mac learners, teachers, and Go developers are warmly invited to try the beta.
A useful compatibility report includes the macOS version, Intel or Apple
Silicon architecture, `go version`, the exact command, and a minimal
reproduction or diagnostic output. Ordinary compatibility reports belong on
the canonical Gitea project. Suspected vulnerabilities must use the private
route in [SECURITY.md](../SECURITY.md).
Community reports can reveal gaps and help prioritize maintainer testing. They
do not constitute an independent audit or shift responsibility for security
review, triage, fixes, and release decisions to the community.
+64 -21
View File
@@ -11,19 +11,30 @@ verification, or guarantee that no vulnerability exists.
| Field | Value |
| --- | --- |
| Assessment date | 2026-08-12 |
| Public evidence identity | Exact file checksums in the co-published `PUBLIC-SNAPSHOT.sha256`; private/public commit mapping is retained only in the non-exported operational ledger |
| Assessment phases | Clean pre-remediation source followed by clean remediated source |
| Primary environment | Linux amd64 under WSL, Go 1.26.5 |
| Evidence sets | Clean security self-assessment plus an exact-commit pre-beta platform baseline; neither is evidence for the later Beta 1 candidate |
| Public commit | `113c95c21e57227b4675c9fda015ada59cc9e9a6` |
| Public tree | `a2aeb4dac22853cb3894e3e487b94bbeff5051e5` |
| Maintainer-run environments | Windows 11/amd64 on NTFS; Ubuntu 20.04/amd64 under WSL2 on ext4; Linux/amd64 server containers |
| Supported Go lanes exercised | Go 1.25.12 and Go 1.26.5 |
| Declared minimum Go | Go 1.25 |
| Assessor | Project maintainer with AI-assisted code review; human responsibility retained |
Security remediation discovered during this assessment was committed and the
named checks were rerun from a clean source state. Before this ledger can support
a versioned release, the complete campaign must be rerun from the exact
sanitized public release commit. Private-to-public commit mappings are retained
outside the exported source rather than being disclosed here.
The named platform runs used the exact public commit and tree above. Hostnames,
network addresses, account names, private paths, private repository identities,
and private commit mappings are intentionally absent from this public ledger.
## Observed evidence
Beta 1 necessarily changes the tree through versioning, provenance,
documentation, or source fixes. Therefore this baseline cannot be relabeled as
Beta 1 evidence. The required Windows/Linux campaign must pass again on the
exact Beta 1 candidate before either tag is published. Native macOS execution
remains pending and is provisional for the beta.
## Observed security self-assessment evidence
These commands were observed on clean remediated source during the dated
assessment. Except where the exact-commit platform matrix below says otherwise,
the table does not claim that every command was rerun on the named public
baseline commit.
| Property examined | Enforcement or test surface | Result observed on 2026-08-12 |
| --- | --- | --- |
@@ -41,7 +52,7 @@ outside the exported source rather than being disclosed here.
| URL scheme handling | ordinary/trusted URL test matrix | Pass for enumerated cases |
| Filesystem boundaries | symlink, nested-module, VCS, ownership, stale-output tests | Pass for tested cases; see open findings |
| Development proxy browser boundary | Host, Origin, Fetch Metadata, CSP, fragment and response tests | Pass for tested cases |
| Native platform behavior | Linux execution; Windows/macOS cross-compilation | Native Windows/macOS execution not yet evidenced |
| Platform behavior | Native Windows and executed Linux matrices; macOS cross-compilation | Windows/Linux pass for tested lanes; native macOS pending |
Coverage measures statements executed by tests. It is not branch completeness
and is not evidence that the executed behavior is secure.
@@ -50,6 +61,31 @@ and is not evidence that the executed behavior is secure.
and reachable through its analysis. A clean result cannot detect unknown flaws,
design errors, or vulnerabilities outside its model.
## Pre-beta native compatibility matrix
These are maintainer-run, point-in-time results, not continuous CI and not an
independent audit.
| Environment | Go lanes | Commands and focused evidence | Result and limits |
| --- | --- | --- | --- |
| Windows 11/amd64, NTFS | 1.25.12, 1.26.5 | Native PowerShell verifier with race; root/runtime tests, vet, trimpath build, freshness, two generation passes, process-tree cleanup, watcher boundaries, and temporary consumer compilation | Pass. Symlink-output rejection skipped because the test account lacked symlink privilege; the read-only-directory case is POSIX-only |
| Ubuntu 20.04/amd64 under WSL2, native ext4 checkout | 1.25.12, 1.26.5 | Race-enabled verifier; root/runtime tests, vet, build, two generation passes, ten focused filesystem cases, five focused development-process/watcher cases, and license check | Pass. This is Linux execution under WSL2, not bare-metal or Linux/arm64 evidence |
| Linux/amd64 server containers | 1.25.12, 1.26.5 | Root/runtime tests, vet, builds, race, licensing, and deterministic generation in sequential isolated official Go containers | Pass. Container resources were capped at 1 CPU and 2 GiB; this is not Linux/arm64 evidence |
| macOS | — | Cross-compilation only | Native maintainer execution pending; provisional for Beta 1 |
The generated golden `basic.sando.go` was 1,399 bytes and had SHA-256
`63fa75a3049a3a8a12d769d7f9b6b510dfe763baacf706775b75cef2c57a984f`
on every tested Windows and Linux lane. Repeated generation also preserved its
timestamp. This demonstrates cross-host agreement for one compiler-owned
fixture, not equivalence for every possible template.
Mac learners and Go developers are warmly invited to report ordinary
compatibility results with macOS version, architecture, `go version`, exact
command, and a minimal reproduction. Suspected vulnerabilities use the private
route in [SECURITY.md](../SECURITY.md). Community reports help find gaps;
maintainers remain responsible for reproducing security-relevant behavior,
triage, remediation, and release decisions.
## Security-relevant design evidence
### Production boundary
@@ -115,8 +151,8 @@ not yet prove semantic HTML safety.
## Assessment findings and remediation status
The 2026-08-12 assessment identified six concrete gaps. Their current
working-tree status is recorded here without rewriting the original baseline:
The 2026-08-12 assessment identified six concrete gaps. Their status in the
named public pre-beta baseline is recorded here:
| Finding | Current remediation | Executable evidence |
| --- | --- | --- |
@@ -127,19 +163,26 @@ working-tree status is recorded here without rewriting the original baseline:
| Trusted-value warnings were described more broadly than their analysis supports | Policy and threat-model copy now call them best-effort lexical audit hints rather than type or taint analysis | Documentation assertion and review |
| Public copy implied a completed systematic `html/template` differential campaign | Policy and public security copy now describe fixed adversarial cases and list systematic differential work as open | Documentation assertion and review |
The remediated clean source passed the race-enabled repository verifier,
sanitized-snapshot tests, both bounded fuzz-smoke targets, compiler/runtime
known-vulnerability scans, and Windows/macOS cross-compilation on 2026-08-12.
Those results do not become release evidence until the changes are committed,
exported to the sanitized canonical public tree, and re-run from that exact
public commit. Native Windows/macOS execution and the other gaps below remain
separate release decisions.
The clean remediated assessment source passed the race-enabled repository
verifier, sanitized-snapshot tests, both bounded fuzz-smoke targets,
compiler/runtime known-vulnerability scans, and Windows/macOS cross-compilation
on 2026-08-12. Separately, the exact public pre-beta commit passed the native
Windows and executed Linux matrices recorded above. These results still do not
become Beta 1 evidence: both sets of required checks must run on the exact
candidate after all candidate changes. Native macOS and the other gaps below
remain separate release decisions.
## Open assurance gaps
- the exact Beta 1 candidate Windows/Linux matrix and post-tag install checks
must still run;
- confidential mailbox delivery and response/recovery procedure must be tested;
- release signing, checksum, SBOM, and provenance rehearsal is incomplete;
- native Windows/macOS execution remains outstanding;
- SSH tag-signing rehearsal passed, but the candidate tags still require
post-publication verification; prebuilt-artifact signing, checksums, SBOM,
reproducible provenance, and key recovery remain incomplete;
- native macOS, Linux/arm64, and Windows/arm64 execution remain outstanding;
- Windows symlink rejection was not natively exercised because the test account
lacked symlink privilege;
- browser-parser differential and semantic property testing need expansion;
- compiler input size, CPU, and memory have no built-in hard budget;
- filesystem checks do not defend against a hostile local actor racing path
+61 -33
View File
@@ -7,55 +7,83 @@ accumulate features. The intended product is already visible: an HTML-first,
ahead-of-time template engine for Go, typed generated components, a small
HTTP-independent runtime, and an optional opinionated local development loop.
The private development initiative lives on `codex/v1-launch` in
`sandwich-hime-dev`. Public releases never originate from that private history.
Development records may remain private, but their repository names, branch
names, paths, commit mappings, and history are not release provenance. Public
releases originate only from the reviewed canonical public tree.
## Repository and publication topology
| Surface | Purpose | History and tags |
| --- | --- | --- |
| Private Gitea `sandwich-hime-dev` | development, working branches, private review records, and historical context | normal private history; no public release tags |
| Public Gitea `sandwich-hime` | canonical sanitized source, contribution venue, module origin, releases, and signed tags | fresh reviewed publication history; authoritative `sando/vX.Y.Z` and `vX.Y.Z` tags |
| GitHub `gamertan/sandwich-hime` | discoverability and a convenient sanitized source snapshot | no private refs, force-mirrors, workflows, contribution authority, release artifacts, or semver tags |
| Private development storage | Working branches, private review records, and historical context | identities and history are not exported; no public release tags |
| Public Gitea `sandwich-hime` | Canonical sanitized source, contribution venue, module origin, and releases | fresh reviewed history; authoritative immutable `sando/vX.Y.Z` and `vX.Y.Z` tags |
| GitHub `gamertan/sandwich-hime` | Discoverability and a convenient sanitized source snapshot | no private refs, force-mirrors, workflows, contribution authority, release artifacts, or semver tags |
Each public update is exported through the exact committed allowlist, inspected,
committed as a fresh public snapshot, and compared byte-for-byte with the
reviewed export. GitHub receives that public tree only. It never receives the
private repository or an indiscriminate Git mirror.
reviewed export. GitHub receives that public tree only. It never receives
private history or an indiscriminate Git mirror.
## Current readiness
At the 2026-08-12 v1 initiative baseline, the project is a strong engineering
preview, but not yet a release candidate. Exact private/public commit mappings
remain in the non-exported operational ledger.
Beta 1 is deliberately earlier than a release candidate. It creates a real,
repeatable install for learners and evaluators without claiming that the final
v1 compatibility, native-platform, artifact, signing, or soak gates are
complete.
### Demonstrated now
### Demonstrated in the pre-beta public baseline
- race-enabled tests, vet, builds, deterministic generation, license checks,
and sanitized-export tests pass on Linux;
- the compiler module and nested `sando` runtime declare zero third-party Go
module requirements;
- generated/runtime compatibility uses a version-specific compile-time ABI
marker with an incompatible-runtime regression;
- owned-output, orphan, stale, symlink, nested-module, restrictive-permission,
last-good, writer-error, and enumerated contextual-output cases are tested;
- the development proxy is loopback-only, browser-origin hardened, and clears
a dead selected upstream immediately; and
- the security policy, threat model, and dated evidence ledger state both the
demonstrated controls and the unresolved limits.
Public commit `113c95c21e57227b4675c9fda015ada59cc9e9a6` (tree
`a2aeb4dac22853cb3894e3e487b94bbeff5051e5`) passed maintainer-run Go
1.25.12 and Go 1.26.5 matrices on native Windows/amd64, Linux/amd64 under WSL2,
and isolated Linux/amd64 server containers. The same generated golden SHA-256
was observed across those lanes.
That result is a pre-beta baseline only. The exact Beta 1 candidate must rerun
the required Windows/Linux matrix after all version, documentation, and source
changes and before tags are created.
Other demonstrated controls include:
- zero third-party Go module requirements in the compiler and nested `sando`
runtime;
- a version-specific compile-time runtime ABI marker;
- owned-output, orphan, stale, symlink, nested-module, permission, last-good,
writer-error, and enumerated contextual-output tests;
- loopback-only, browser-origin-hardened development proxy behavior; and
- a public threat model, security policy, and dated evidence ledger.
### Not demonstrated yet
- native Windows and macOS execution of the complete supported matrix;
- a stable public API/CLI/schema snapshot and compatibility test;
- native maintainer-run macOS execution; macOS is provisional for Beta 1;
- stable final-v1 API, CLI, schema, diagnostic, and generated snapshots;
- systematic browser-parser and `html/template` differential testing;
- a long semantic fuzz campaign beyond bounded no-panic smoke;
- committed, reproducible comparative benchmarks and a predefined regression
threshold;
- real-browser SSE/reload/overlay evidence for `himesan dev`;
- deterministic release artifacts, checksums, SBOMs, signatures, and tested
signing/recovery procedures; or
- clean direct and public-proxy installation of signed release tags.
- committed comparative benchmarks and predefined regression thresholds;
- complete real-browser development-supervisor evidence;
- deterministic prebuilt archives, checksums, SBOMs, signed binaries, and
tested signing/recovery procedures; or
- clean direct and public-proxy installation of the not-yet-published Beta 1
tags.
## Beta 1 publication lane
Beta 1 is supported for learning, classroom projects, evaluation, prototypes,
and compatibility feedback. It is not recommended as a production-stable
dependency, and its interfaces may change.
- [x] Define beta support, security, compatibility, and macOS-provisional
language.
- [x] Establish the named public pre-beta Linux/Windows baseline.
- [ ] Rerun the supported Go matrix and deterministic generation on the exact
Beta 1 candidate.
- [ ] Run the candidate-version freshness, bounded fuzz, vulnerability, and
license gates.
- [ ] Publish immutable `sando/v1.0.0-beta.1`, then
`v1.0.0-beta.1`, from the same reviewed public commit.
- [ ] Verify clean direct and public-proxy installs and record the result.
- [ ] Add native macOS maintainer evidence before RC; community reports inform
that work but do not replace maintainer responsibility.
## Milestone 1: contract freeze
@@ -126,8 +154,8 @@ Required before security/platform release-candidate work is declared complete:
4. Run the complete evidence suite again from the exact public commit.
5. Operate the official Sandwich Hime website on the RC runtime for a 14-day
observation period with no unresolved Hime render, security, accessibility,
or rollback regression. This is product dogfooding, not a dependency on EQL
or another application's private repository.
or rollback regression. This is product dogfooding, not a dependency on
another application's private repository.
6. Fix findings in a new RC; restart the observation period when the affected
boundary warrants it.
7. Finalize the changelog, supported-version table, migration notes, release
+24 -2
View File
@@ -316,6 +316,28 @@ func auditTrustCalls(file *sourceFile) []Diagnostic {
return diagnostics
}
func bytesEqual(a, b []byte) bool {
return bytes.Equal(a, b)
// generatedCodeEqual compares the freshness-relevant portions of two
// generated files. The compiler release is informational provenance: changing
// only that line must not make otherwise identical output stale. Every other
// byte remains part of the generated-code contract.
func generatedCodeEqual(a, b []byte) bool {
if bytes.Equal(a, b) {
return true
}
aBody, aOK := generatedCodeWithoutCompilerVersion(a)
bBody, bOK := generatedCodeWithoutCompilerVersion(b)
return aOK && bOK && bytes.Equal(aBody, bBody)
}
func generatedCodeWithoutCompilerVersion(code []byte) ([]byte, bool) {
prefix := []byte(generatedPrefix + "\n// himesan:compiler ")
if !bytes.HasPrefix(code, prefix) {
return nil, false
}
remainder := code[len(prefix):]
lineEnd := bytes.IndexByte(remainder, '\n')
if lineEnd <= 0 {
return nil, false
}
return remainder[lineEnd:], true
}
+50 -1
View File
@@ -67,11 +67,42 @@ func TestCommittedGoldenOutput(t *testing.T) {
wantPath := sourcePath + ".go"
compiled, diagnostics := compileWithMapping(sourcePath, mustRead(t, sourcePath), "internal/compiler/testdata/golden/basic.sando")
assertNoErrorDiagnostics(t, diagnostics)
if want := mustRead(t, wantPath); !bytes.Equal(compiled.Code, want) {
if want := mustRead(t, wantPath); !generatedCodeEqual(compiled.Code, want) {
t.Fatalf("committed golden output is stale; run himesan generate\n--- got ---\n%s\n--- want ---\n%s", compiled.Code, want)
}
}
func TestGeneratedCodeEqualityIgnoresOnlyCompilerProvenance(t *testing.T) {
t.Parallel()
compiled, diagnostics := Compile("hello.sando", []byte(simpleSource("Hello", "hello")))
assertNoErrorDiagnostics(t, diagnostics)
beta := replaceGeneratedCompilerVersion(t, compiled.Code, "v1.0.0-beta.1")
if !generatedCodeEqual(compiled.Code, beta) {
t.Fatal("compiler provenance alone made generated output unequal")
}
changes := map[string][]byte{
"runtime ABI": bytes.Replace(beta, []byte("himesan:runtime-abi sando.v1"), []byte("himesan:runtime-abi sando.v2"), 1),
"source digest": bytes.Replace(beta, []byte("himesan:source-sha256"), []byte("himesan:source-sha257"), 1),
"generated semantics": bytes.Replace(beta, []byte(".WriteString("), []byte(".WriteText("), 1),
"missing provenance marker": bytes.Replace(beta, []byte("// himesan:compiler "), []byte("// compiler: "), 1),
"empty provenance": replaceGeneratedCompilerVersion(t, beta, ""),
}
for name, changed := range changes {
name, changed := name, changed
t.Run(name, func(t *testing.T) {
t.Parallel()
if bytes.Equal(beta, changed) {
t.Fatalf("test mutation %q did not change generated output", name)
}
if generatedCodeEqual(compiled.Code, changed) {
t.Fatalf("generatedCodeEqual ignored %s change", name)
}
})
}
}
func TestHeaderAllowsBOMWhitespaceAndGoLexicalDelimiters(t *testing.T) {
t.Parallel()
source := "\xef\xbb\xbf \r\n\t<?sando go\npackage views\nfunc Lexical(v struct { Tag string `json:\"?>\"` })\n?>\n<p><?= \"?>\" ?></p>"
@@ -580,6 +611,24 @@ func mustRead(t *testing.T, path string) []byte {
return content
}
func replaceGeneratedCompilerVersion(t *testing.T, code []byte, compilerVersion string) []byte {
t.Helper()
prefix := []byte(generatedPrefix + "\n// himesan:compiler ")
if !bytes.HasPrefix(code, prefix) {
t.Fatal("generated output has no compiler provenance line")
}
remainder := code[len(prefix):]
lineEnd := bytes.IndexByte(remainder, '\n')
if lineEnd < 0 {
t.Fatal("generated compiler provenance line has no terminator")
}
replaced := make([]byte, 0, len(code)-lineEnd+len(compilerVersion))
replaced = append(replaced, prefix...)
replaced = append(replaced, compilerVersion...)
replaced = append(replaced, remainder[lineEnd:]...)
return replaced
}
func assertNoErrorDiagnostics(t *testing.T, diagnostics []Diagnostic) {
t.Helper()
if hasErrors(diagnostics) {
+118
View File
@@ -3,7 +3,9 @@
package compiler
import (
"bytes"
"context"
"encoding/json"
"os"
"os/exec"
"path/filepath"
@@ -12,6 +14,79 @@ import (
"testing"
)
func TestDevelopmentAndBetaBinariesShareGeneratedOutput(t *testing.T) {
if testing.Short() {
t.Skip("skipping compiler-binary integration in short mode")
}
t.Parallel()
_, thisFile, _, ok := runtime.Caller(0)
if !ok {
t.Fatal("runtime.Caller failed")
}
repositoryRoot := filepath.Clean(filepath.Join(filepath.Dir(thisFile), "..", ".."))
developmentBinary := buildHimesanBinary(t, repositoryRoot, "himesan-development", "")
betaVersion := "v1.0.0-beta.1"
betaBinary := buildHimesanBinary(t, repositoryRoot, "himesan-beta", "-X gamertan.com/sandwich-hime/internal/version.Compiler="+betaVersion)
if got := compilerVersionFromBinary(t, developmentBinary, repositoryRoot); got != "0.1.0-dev" {
t.Fatalf("development binary version = %q, want 0.1.0-dev", got)
}
if got := compilerVersionFromBinary(t, betaBinary, repositoryRoot); got != betaVersion {
t.Fatalf("beta binary version = %q, want %q", got, betaVersion)
}
directory := resolvedTempDir(t)
mustWrite(t, filepath.Join(directory, "go.mod"), "module example.test/provenance\n\ngo 1.25\n")
sourcePath := filepath.Join(directory, "hello.sando")
mustWrite(t, sourcePath, `<?sando go
package views
func Hello(name string)
?>
<p>Hello <?= name ?></p>
`)
runHimesanBinary(t, developmentBinary, directory, "generate", "hello.sando")
outputPath := sourcePath + ".go"
developmentOutput := mustRead(t, outputPath)
if !bytes.Contains(developmentOutput, []byte("// himesan:compiler 0.1.0-dev\n")) {
t.Fatalf("development compiler did not record honest provenance:\n%s", developmentOutput)
}
runHimesanBinary(t, betaBinary, directory, "check", "hello.sando")
runHimesanBinary(t, betaBinary, directory, "generate", "hello.sando")
if after := mustRead(t, outputPath); !bytes.Equal(after, developmentOutput) {
t.Fatalf("beta compiler rewrote otherwise-current development provenance\n--- before ---\n%s\n--- after ---\n%s", developmentOutput, after)
}
if err := os.Remove(outputPath); err != nil {
t.Fatal(err)
}
runHimesanBinary(t, betaBinary, directory, "generate", "hello.sando")
betaOutput := mustRead(t, outputPath)
if !bytes.Contains(betaOutput, []byte("// himesan:compiler "+betaVersion+"\n")) {
t.Fatalf("beta compiler did not record honest provenance:\n%s", betaOutput)
}
runHimesanBinary(t, developmentBinary, directory, "check", "hello.sando")
runHimesanBinary(t, developmentBinary, directory, "generate", "hello.sando")
if after := mustRead(t, outputPath); !bytes.Equal(after, betaOutput) {
t.Fatalf("development compiler rewrote otherwise-current beta provenance\n--- before ---\n%s\n--- after ---\n%s", betaOutput, after)
}
tampered := bytes.Replace(betaOutput, []byte(".WriteText("), []byte(".WriteAttr("), 1)
if bytes.Equal(tampered, betaOutput) {
t.Fatal("semantic tamper did not find generated WriteText call")
}
if err := os.WriteFile(outputPath, tampered, 0o644); err != nil {
t.Fatal(err)
}
command := exec.Command(betaBinary, "check", "hello.sando")
command.Dir = directory
output, err := command.CombinedOutput()
if err == nil || !strings.Contains(string(output), "HIM2204") {
t.Fatalf("beta check accepted semantic generated-code tamper: err=%v\n%s", err, output)
}
}
func TestGeneratedOutputCompilesInTemporaryModule(t *testing.T) {
if testing.Short() {
t.Skip("skipping temporary-module compilation in short mode")
@@ -81,3 +156,46 @@ func Page(view View)
t.Fatal("generated output leaked the compiler checkout path")
}
}
func buildHimesanBinary(t *testing.T, repositoryRoot, name, linkerFlags string) string {
t.Helper()
if runtime.GOOS == "windows" {
name += ".exe"
}
path := filepath.Join(t.TempDir(), name)
arguments := []string{"build", "-trimpath"}
if linkerFlags != "" {
arguments = append(arguments, "-ldflags", linkerFlags)
}
arguments = append(arguments, "-o", path, "./cmd/himesan")
command := exec.Command("go", arguments...)
command.Dir = repositoryRoot
command.Env = append(os.Environ(), "GOWORK=off")
if output, err := command.CombinedOutput(); err != nil {
t.Fatalf("build %s: %v\n%s", name, err, output)
}
return path
}
func compilerVersionFromBinary(t *testing.T, binary, directory string) string {
t.Helper()
output := runHimesanBinary(t, binary, directory, "version", "--json")
var information struct {
Compiler string `json:"compiler"`
}
if err := json.Unmarshal(output, &information); err != nil {
t.Fatalf("decode compiler version from %s: %v\n%s", binary, err, output)
}
return information.Compiler
}
func runHimesanBinary(t *testing.T, binary, directory string, arguments ...string) []byte {
t.Helper()
command := exec.Command(binary, arguments...)
command.Dir = directory
output, err := command.CombinedOutput()
if err != nil {
t.Fatalf("%s %s: %v\n%s", binary, strings.Join(arguments, " "), err, output)
}
return output
}
+2 -2
View File
@@ -56,7 +56,7 @@ func Generate(ctx context.Context, paths []string) (Result, error) {
break
}
existing, readErr := os.ReadFile(file.OutputPath)
if readErr == nil && bytesEqual(existing, file.Code) {
if readErr == nil && generatedCodeEqual(existing, file.Code) {
result.Files[index].Changed = false
result.Unchanged++
continue
@@ -112,7 +112,7 @@ func Check(ctx context.Context, paths []string) (Result, error) {
}
continue
}
if bytesEqual(existing, file.Code) {
if generatedCodeEqual(existing, file.Code) {
result.Unchanged++
continue
}
+4
View File
@@ -16,6 +16,7 @@ func TestSelectCompilerVersion(t *testing.T) {
{name: "local build", linkerValue: developmentCompilerVersion, moduleVersion: "(devel)", want: developmentCompilerVersion},
{name: "missing build info", linkerValue: developmentCompilerVersion, moduleVersion: "", want: developmentCompilerVersion},
{name: "versioned go install", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0", want: "v1.0.0"},
{name: "beta launch install", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0-beta.1", want: "v1.0.0-beta.1"},
{name: "versioned prerelease install", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0-rc.1", want: "v1.0.0-rc.1"},
{name: "hyphenated prerelease install", linkerValue: developmentCompilerVersion, moduleVersion: "v1.2.3-beta-2", want: "v1.2.3-beta-2"},
{name: "pseudo version", linkerValue: developmentCompilerVersion, moduleVersion: "v0.0.0-20260811120000-0123456789ab", want: developmentCompilerVersion},
@@ -26,6 +27,9 @@ func TestSelectCompilerVersion(t *testing.T) {
{name: "build metadata", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0+build.1", want: developmentCompilerVersion},
{name: "leading zero release", linkerValue: developmentCompilerVersion, moduleVersion: "v01.0.0", want: developmentCompilerVersion},
{name: "leading zero numeric prerelease", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0-rc.01", want: developmentCompilerVersion},
{name: "leading zero numeric beta identifier", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0-beta.01", want: developmentCompilerVersion},
{name: "empty beta identifier", linkerValue: developmentCompilerVersion, moduleVersion: "v1.0.0-beta..1", want: developmentCompilerVersion},
{name: "beta linker override wins", linkerValue: "v1.0.0-beta.1", moduleVersion: "(devel)", want: "v1.0.0-beta.1"},
{name: "linker override wins", linkerValue: "v1.0.0-rc.1", moduleVersion: "v1.0.0", want: "v1.0.0-rc.1"},
}
for _, test := range tests {
+1 -1
View File
@@ -7,7 +7,7 @@ These scripts are intentionally understandable shell and PowerShell rather than
- `verify.sh` runs root and nested-module tests and vet, builds `himesan`, checks the compiler-owned golden output, and proves two generation passes leave the same bytes and unchanged modification times. Set `HIMESAN_RACE=1` for race tests.
- `verify.ps1` provides the equivalent native Windows lane; pass `-Race` to include the race detector.
- `check-licenses.sh` enforces the AGPL compiler / Apache runtime boundary and prevents generated application Go from inheriting an AGPL identifier.
- `release-check.sh --version vX.Y.Z` is a clean-checkout technical preflight. Add `--public` and point `HIMESAN_RELEASE_EVIDENCE_DIR` at a human-reviewed evidence bundle for the public-launch gate. It never tags, pushes, publishes, or deploys.
- `release-check.sh --version vX.Y.Z` is a clean-checkout technical preflight, including exact candidate-version and generated-provenance checks. Beta publication follows the narrower prerelease gates in `RELEASE.md`; release candidates and final v1 additionally use `--public` with a human-reviewed `HIMESAN_RELEASE_EVIDENCE_DIR`. The script never tags, pushes, publishes, or deploys.
- `verify-public-install.sh --version vX.Y.Z` is a post-tag/publication check. It verifies exact `go-get=1` package routes and runs the documented compiler install and runtime get from fresh direct-fetch and public-proxy caches without interactive Git credentials.
The canonical Linux CI and release preflight also run bounded fuzz sessions for the parser/context compiler and Go-aware delimiter scanner. Seed-corpus execution remains part of ordinary `go test`; the bounded sessions are extra evidence, not a substitute for longer scheduled fuzzing before v1.
+107 -14
View File
@@ -15,8 +15,9 @@ artifacts in the repository, pushes, or deploys.
--version Candidate compiler version. The corresponding runtime tag is
sando/vX.Y.Z.
--public Additionally require the human-reviewed launch evidence bundle
named by HIMESAN_RELEASE_EVIDENCE_DIR.
--public Require the human-reviewed RC/final launch evidence bundle named
by HIMESAN_RELEASE_EVIDENCE_DIR. Canonical beta prereleases may
run their narrower publication preflight without this flag.
EOF
}
@@ -45,8 +46,31 @@ while (( $# > 0 )); do
esac
done
if [[ ! "$version" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?(\+[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]]; then
printf 'error: --version must be a semantic version beginning with v\n' >&2
if [[ ! "$version" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$ ]]; then
printf 'error: --version must be a canonical semantic version beginning with v (build metadata is not allowed)\n' >&2
exit 2
fi
prerelease=${BASH_REMATCH[5]:-}
if [[ "$prerelease" =~ (^|[.-])(0\.)?[0-9]{14}-[0-9a-f]{12,}$ ]]; then
printf 'error: --version must be a signed release tag, not a Go pseudo-version\n' >&2
exit 2
fi
if [[ -n "$prerelease" ]]; then
IFS=. read -r -a prerelease_identifiers <<<"$prerelease"
for identifier in "${prerelease_identifiers[@]}"; do
if [[ "$identifier" =~ ^[0-9]+$ && "$identifier" =~ ^0[0-9]+$ ]]; then
printf 'error: numeric prerelease identifiers must not contain leading zeroes: %s\n' "$identifier" >&2
exit 2
fi
done
fi
beta_release=0
if [[ "$prerelease" == beta || "$prerelease" == beta.* ]]; then
beta_release=1
fi
if (( public_release == 0 && beta_release == 0 )); then
printf 'error: RC and final release preflights require --public and the human-reviewed evidence bundle\n' >&2
exit 2
fi
@@ -90,6 +114,73 @@ for tag in "$version" "$runtime_tag"; do
fi
done
artifact_dir=$(mktemp -d "${TMPDIR:-/tmp}/himesan-release-check.XXXXXXXX")
cleanup() {
if [[ -n "${artifact_dir:-}" && -d "$artifact_dir" ]]; then
rm -rf -- "$artifact_dir"
fi
}
trap cleanup EXIT HUP INT TERM
compiler_linker_flags="-X gamertan.com/sandwich-hime/internal/version.Compiler=$version"
candidate_binary="$artifact_dir/himesan-candidate"
printf '\n==> exact release candidate identity\n'
go build -trimpath -ldflags "$compiler_linker_flags" -o "$candidate_binary" ./cmd/himesan
candidate_go_version=$(go env GOVERSION)
expected_human_version="himesan $version (runtime ABI sando.v1, $candidate_go_version)"
actual_human_version=$("$candidate_binary" version)
if [[ "$actual_human_version" != "$expected_human_version" ]]; then
printf 'error: candidate human version mismatch\nexpected: %s\nactual: %s\n' \
"$expected_human_version" "$actual_human_version" >&2
exit 1
fi
expected_json_version=$(printf '{"compiler":"%s","runtime_abi":"sando.v1","go":"%s"}' "$version" "$candidate_go_version")
actual_json_version=$("$candidate_binary" version --json)
if [[ "$actual_json_version" != "$expected_json_version" ]]; then
printf 'error: candidate JSON version mismatch\nexpected: %s\nactual: %s\n' \
"$expected_json_version" "$actual_json_version" >&2
exit 1
fi
file_mtime() {
if stat --printf='%y' "$1" >/dev/null 2>&1; then
stat --printf='%y' "$1"
else
stat -f '%m' "$1"
fi
}
printf '\n==> candidate generated-output provenance compatibility\n'
golden_source=internal/compiler/testdata/golden/basic.sando
golden_output="$golden_source.go"
if ! grep -Fqx '// himesan:compiler 0.1.0-dev' "$golden_output"; then
printf 'error: golden fixture no longer provides development-to-release provenance coverage: %s\n' "$golden_output" >&2
exit 1
fi
golden_hash_before=$(git hash-object "$golden_output")
golden_mtime_before=$(file_mtime "$golden_output")
check_summary=$("$candidate_binary" check "$golden_source")
if [[ "$check_summary" != 'checked 1 .sando files: 1 current' ]]; then
printf 'error: candidate did not consider the development-produced golden current: %s\n' "$check_summary" >&2
exit 1
fi
for pass in 1 2; do
generate_summary=$("$candidate_binary" generate "$golden_source")
if [[ "$generate_summary" != 'generated 0, unchanged 1 (1 .sando files)' ]]; then
printf 'error: candidate generation pass %d reported unexpected changes: %s\n' "$pass" "$generate_summary" >&2
exit 1
fi
if [[ "$(git hash-object "$golden_output")" != "$golden_hash_before" ]]; then
printf 'error: candidate generation pass %d changed golden bytes\n' "$pass" >&2
exit 1
fi
if [[ "$(file_mtime "$golden_output")" != "$golden_mtime_before" ]]; then
printf 'error: candidate generation pass %d changed the golden mtime\n' "$pass" >&2
exit 1
fi
done
./scripts/check-licenses.sh
HIMESAN_RACE=1 ./scripts/verify.sh
@@ -104,14 +195,6 @@ go run golang.org/x/vuln/cmd/govulncheck@v1.6.0 ./...
go run golang.org/x/vuln/cmd/govulncheck@v1.6.0 ./...
)
artifact_dir=$(mktemp -d "${TMPDIR:-/tmp}/himesan-release-check.XXXXXXXX")
cleanup() {
if [[ -n "${artifact_dir:-}" && -d "$artifact_dir" ]]; then
rm -rf -- "$artifact_dir"
fi
}
trap cleanup EXIT HUP INT TERM
printf '\n==> cross-compiling release binary smoke set\n'
for target in \
linux/amd64 \
@@ -127,7 +210,8 @@ for target in \
extension='.exe'
fi
CGO_ENABLED=0 GOOS="$target_os" GOARCH="$target_arch" \
go build -trimpath -o "$artifact_dir/himesan-$target_os-$target_arch$extension" ./cmd/himesan
go build -trimpath -ldflags "$compiler_linker_flags" \
-o "$artifact_dir/himesan-$target_os-$target_arch$extension" ./cmd/himesan
done
for required in \
@@ -158,9 +242,18 @@ if (( public_release == 1 )); then
exit 1
fi
done
fi
if [[ -n "$(git status --porcelain=v1 --untracked-files=all)" ]]; then
printf 'error: release preflight left tracked changes or untracked artifacts in the canonical checkout\n' >&2
git status --short >&2
exit 1
fi
if (( public_release == 1 )); then
printf '\nHuman review is still required; evidence presence is not automatic approval.\n'
else
printf '\nTechnical preflight passed. Public launch remains blocked until --public evidence review passes.\n'
printf '\nBeta technical publication preflight passed. This does not establish RC/final launch evidence or production stability.\n'
fi
printf 'No tag, push, publication, or deployment was performed for %s / %s.\n' "$version" "$runtime_tag"
+16 -2
View File
@@ -33,10 +33,24 @@ while (( $# > 0 )); do
esac
done
if [[ ! "$version" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?(\+[0-9A-Za-z]+([.-][0-9A-Za-z]+)*)?$ ]]; then
printf 'error: --version must be a semantic version beginning with v\n' >&2
if [[ ! "$version" =~ ^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$ ]]; then
printf 'error: --version must be a canonical semantic version beginning with v (build metadata is not allowed)\n' >&2
exit 2
fi
prerelease=${BASH_REMATCH[5]:-}
if [[ "$prerelease" =~ (^|[.-])(0\.)?[0-9]{14}-[0-9a-f]{12,}$ ]]; then
printf 'error: --version must identify a signed release tag, not a Go pseudo-version\n' >&2
exit 2
fi
if [[ -n "$prerelease" ]]; then
IFS=. read -r -a prerelease_identifiers <<<"$prerelease"
for identifier in "${prerelease_identifiers[@]}"; do
if [[ "$identifier" =~ ^0[0-9]+$ ]]; then
printf 'error: numeric prerelease identifiers must not contain leading zeroes: %s\n' "$identifier" >&2
exit 2
fi
done
fi
for command_name in curl go git false; do
command -v "$command_name" >/dev/null 2>&1 || {