feat: publish the Sandwich Hime source preview

Signed-off-by: Cole Speelman <gamertan@noreply.localhost>
This commit is contained in:
2026-08-11 20:15:06 -04:00
commit 9b29b3d7f8
100 changed files with 10989 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
# Gamertan site and vanity imports
This directory is a static, no-JavaScript site for the unsupported Sandwich Hime pre-1.0 public source preview. It is source material only: repository automation must not deploy it. The page is deliberately honest that no supported v1 version exists yet.
## Intended routes
The hosting layer must serve these files over HTTPS without an authentication challenge:
| Request path | File | Purpose |
| --- | --- | --- |
| `/sandwich-hime` and `/sandwich-hime/` | `index.html` | Project page and compiler-module `go-import` metadata |
| `/sandwich-hime/sando` and `/sandwich-hime/sando/` | `sando/index.html` | Nested-runtime metadata using the Go 1.25 `subdirectory` field |
| `/sandwich-hime/assets/site.css` | `assets/site.css` | Local-only presentation |
The Go command requests the exact import path; it does not retry at a parent
path after a 404. The hosting layer therefore needs query-scoped metadata
fallbacks:
- any `/sandwich-hime/...` request with `go-get=1`, except the nested runtime
subtree, returns the compiler `index.html` with HTTP 200;
- `/sandwich-hime/sando` and every path below it with `go-get=1` return
`sando/index.html` with HTTP 200;
- ordinary browser requests for nonexistent paths continue to return 404.
This includes `/sandwich-hime/cmd/himesan?go-get=1`, which is the path queried
by the documented `go install` command. The `go-import` tags occur early in
each document because the Go command uses a restricted HTML parser.
The nested metadata is intentionally:
```html
<meta name="go-import" content="gamertan.com/sandwich-hime/sando git https://gitea.speelman.ca/gamertan/sandwich-hime.git sando">
```
The fourth field maps the vanity path to the repositorys `sando` subdirectory. It is supported by the projects minimum Go line, Go 1.25. Runtime versions must use tags such as `sando/v1.0.0`.
## Hosting setup
1. Keep the public DNS and TLS authority for `gamertan.com` under founder control. Use an `A`/`AAAA` record or a narrowly scoped `CNAME` appropriate to the chosen static host; do not delegate the whole zone to a project contributor.
2. Configure the exact browser routes plus the query-scoped `go-get=1`
fallbacks above. Preserve ordinary 404 behavior and do not use a client-side
redirect for metadata requests.
3. Return `Content-Type: text/html; charset=utf-8` for HTML and `text/css; charset=utf-8` for CSS.
4. Add server headers at least equivalent to `Content-Security-Policy: default-src 'none'; style-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'`, `Referrer-Policy: no-referrer`, `X-Content-Type-Options: nosniff`, and a conservative `Permissions-Policy`.
5. Keep deployment credentials outside this repository. A future deploy workflow needs a separately reviewed, least-privilege credential and protected environment approval.
6. Verify from an uncached public network before announcing installs:
```sh
curl -fsS 'https://gamertan.com/sandwich-hime?go-get=1'
curl -fsS 'https://gamertan.com/sandwich-hime/cmd/himesan?go-get=1'
curl -fsS 'https://gamertan.com/sandwich-hime/sando?go-get=1'
./scripts/verify-public-install.sh --version v1.0.0
```
## Launch blockers
Do not deploy or remove the pre-release warning until all of these are evidenced:
- canonical Gitea is public, the security contact works, and protected release-key controls are active;
- root `v1.0.0` and nested `sando/v1.0.0` are signed and accompanied by checksums, SBOMs, release binaries, and reproducibility notes;
- Go 1.25 and Go 1.26 pass deterministic generation and tests on Linux, macOS, and Windows, including the canonical manual cross-platform workflow;
- vulnerability, race, fuzz, adversarial, license, accessibility, and CSP checks pass;
- EQL Wiki completes its differential pilot and 14-day production soak without Hime render, security, or accessibility regressions;
- the DCO contribution process, license map, governance, output permission, and trademark policy have final human review;
- `scripts/release-check.sh --version v1.0.0 --public` passes against a human-reviewed evidence bundle;
- the exact public `go install` and `go get` commands pass
`scripts/verify-public-install.sh` from clean direct-fetch and public-proxy
caches without repository credentials.
At launch, replace each pages `himesan-release-status` value with the exact compiler release (for example, `v1.0.0`), replace the human-facing pre-release copy with verified install information, and run `scripts/check-site.sh --public v1.0.0`. The public release preflight enforces that transition so a green evidence bundle cannot accidentally publish a page that still says the runtime does not exist.
Gitea is the sole public forge. Cross-platform evidence must come from reviewed local or Gitea-runner execution; no secondary mirror or hosted workflow is part of the release plan.
+398
View File
@@ -0,0 +1,398 @@
/* SPDX-License-Identifier: AGPL-3.0-only */
:root {
color-scheme: dark;
--ink: #fff9eb;
--muted: #c9c2dd;
--night: #100a25;
--deep: #251849;
--panel: #30235a;
--panel-light: #453476;
--pink: #ff74b8;
--cyan: #70e6e1;
--yellow: #ffe38a;
--line: #8e75c4;
--shadow: #090617;
--focus: #fff3a8;
font-family: Verdana, Geneva, Tahoma, sans-serif;
font-size: 16px;
}
* {
box-sizing: border-box;
}
html {
min-width: 20rem;
background: var(--night);
scroll-behavior: smooth;
}
body {
margin: 0;
color: var(--ink);
background-color: var(--night);
background-image:
linear-gradient(45deg, rgb(112 230 225 / 4%) 25%, transparent 25%),
linear-gradient(-45deg, rgb(255 116 184 / 4%) 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, rgb(112 230 225 / 4%) 75%),
linear-gradient(-45deg, transparent 75%, rgb(255 116 184 / 4%) 75%);
background-position: 0 0, 0 8px, 8px -8px, -8px 0;
background-size: 16px 16px;
line-height: 1.65;
}
a {
color: var(--cyan);
text-underline-offset: 0.18em;
text-decoration-thickness: 0.1em;
}
a:hover {
color: var(--yellow);
}
a:focus-visible {
color: var(--night);
background: var(--focus);
outline: 0.2rem solid var(--focus);
outline-offset: 0.2rem;
}
code,
pre {
font-family: "Courier New", Courier, monospace;
}
code {
color: var(--yellow);
}
.skip-link {
position: fixed;
z-index: 10;
top: 0.8rem;
left: 0.8rem;
padding: 0.65rem 0.9rem;
color: var(--night);
background: var(--focus);
transform: translateY(-180%);
}
.skip-link:focus {
transform: translateY(0);
}
.masthead {
border-bottom: 0.3rem ridge var(--pink);
background:
radial-gradient(circle at 20% 20%, rgb(112 230 225 / 16%), transparent 28rem),
linear-gradient(180deg, var(--deep), var(--night));
text-align: center;
}
.status-strip {
padding: 0.45rem 1rem;
color: var(--night);
background: repeating-linear-gradient(
-45deg,
var(--yellow),
var(--yellow) 0.7rem,
#ffd35a 0.7rem,
#ffd35a 1.4rem
);
border-bottom: 0.15rem solid #6c5414;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.03em;
text-transform: uppercase;
}
.masthead-inner,
main,
footer {
width: min(70rem, calc(100% - 2rem));
margin-inline: auto;
}
.masthead-inner {
padding: 4rem 0 4.5rem;
}
.compact .masthead-inner {
padding-block: 3rem;
}
.eyebrow {
margin: 0 0 0.8rem;
color: var(--pink);
font-size: 0.82rem;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.wordmark {
width: fit-content;
max-width: 100%;
margin: 0 auto 1.5rem;
overflow: hidden;
color: var(--cyan);
font-size: clamp(0.72rem, 2.8vw, 1.05rem);
font-weight: 700;
line-height: 1.15;
text-align: left;
text-shadow: 0.12rem 0.12rem 0 var(--pink);
}
h1,
h2,
h3,
p {
overflow-wrap: anywhere;
}
h1 {
max-width: 19ch;
margin: 0 auto;
font-family: Georgia, "Times New Roman", serif;
font-size: clamp(2.25rem, 7vw, 4.8rem);
line-height: 1.02;
text-wrap: balance;
text-shadow: 0.18rem 0.18rem 0 var(--shadow);
}
.compact h1 {
font-size: clamp(2rem, 6vw, 3.8rem);
}
.lede {
max-width: 47rem;
margin: 1.5rem auto 0;
color: var(--muted);
font-size: clamp(1.05rem, 2.5vw, 1.28rem);
}
.button-row {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 0.8rem;
margin-top: 2rem;
}
.button-row a {
padding: 0.7rem 1rem;
color: var(--night);
background: var(--cyan);
border: 0.15rem outset #c6ffff;
box-shadow: 0.18rem 0.18rem 0 var(--shadow);
font-weight: 700;
text-decoration: none;
}
.button-row a:nth-child(2) {
background: var(--pink);
border-color: #ffc2df;
}
.button-row a:active {
border-style: inset;
box-shadow: none;
transform: translate(0.12rem, 0.12rem);
}
.mirror-note {
margin: 1rem auto 0;
color: var(--muted);
font-size: 0.85rem;
}
main {
display: grid;
gap: 1.5rem;
padding-block: 2rem 4rem;
}
.panel {
position: relative;
padding: clamp(1.25rem, 4vw, 2.5rem);
background: linear-gradient(135deg, var(--panel), #271c4a);
border: 0.2rem ridge var(--line);
box-shadow: 0.35rem 0.35rem 0 var(--shadow);
}
.panel h2 {
margin: 0 0 1rem;
color: var(--yellow);
font-family: Georgia, "Times New Roman", serif;
font-size: clamp(1.55rem, 4vw, 2.35rem);
line-height: 1.15;
}
.panel h3 {
margin-top: 0;
font-size: 1.15rem;
}
.panel p:last-child {
margin-bottom: 0;
}
.code-panel {
display: grid;
grid-template-columns: minmax(0, 0.8fr) minmax(20rem, 1.2fr);
gap: 2rem;
align-items: center;
}
.sticker {
display: inline-block;
margin: 0 0 1rem;
padding: 0.25rem 0.55rem;
color: var(--night);
background: var(--pink);
border: 0.12rem outset #ffd2e8;
font: 700 0.72rem/1 Verdana, sans-serif;
text-transform: uppercase;
transform: rotate(-2deg);
}
.code {
margin: 0;
padding: 1.25rem;
overflow-x: auto;
color: var(--ink);
background: #0c0919;
border: 0.15rem inset var(--line);
font-size: clamp(0.78rem, 1.8vw, 0.96rem);
line-height: 1.5;
tab-size: 2;
}
.code code {
color: inherit;
}
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 1rem;
}
.cards article {
padding: 1rem;
background: rgb(16 10 37 / 55%);
border: 0.1rem solid var(--line);
}
.origin {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
gap: 1.5rem;
align-items: center;
}
.pixel-heart {
color: var(--pink);
font-family: "Courier New", monospace;
font-size: clamp(4rem, 12vw, 7rem);
line-height: 1;
text-shadow:
0.16rem 0 var(--pink),
-0.16rem 0 var(--pink),
0 0.16rem var(--pink),
0.3rem 0.3rem 0 var(--shadow);
}
.checklist {
display: grid;
gap: 0.55rem;
padding: 0;
list-style: none;
}
.checklist span {
margin-right: 0.5rem;
color: var(--cyan);
}
.honesty-box {
padding: 1rem;
color: var(--night);
background: var(--yellow);
border: 0.18rem outset #fff0b9;
font-weight: 700;
}
.names dl {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.7rem;
}
.names dl div {
padding: 0.8rem;
background: rgb(16 10 37 / 55%);
border-left: 0.3rem solid var(--pink);
}
.names dt {
color: var(--cyan);
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.names dd {
margin: 0.2rem 0 0;
}
footer {
padding-block: 2rem 3rem;
color: var(--muted);
border-top: 0.1rem dashed var(--line);
text-align: center;
}
.fine-print {
font-size: 0.78rem;
}
@media (max-width: 48rem) {
.code-panel,
.cards,
.names dl {
grid-template-columns: 1fr;
}
.origin {
grid-template-columns: 1fr;
text-align: center;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
*,
*::before,
*::after {
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
}
}
@media (forced-colors: active) {
.panel,
.cards article,
.names dl div,
.button-row a,
.honesty-box {
border: 0.12rem solid CanvasText;
box-shadow: none;
}
}
+166
View File
@@ -0,0 +1,166 @@
<!doctype html>
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="go-import" content="gamertan.com/sandwich-hime git https://gitea.speelman.ca/gamertan/sandwich-hime.git">
<meta name="go-source" content="gamertan.com/sandwich-hime https://gitea.speelman.ca/gamertan/sandwich-hime https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main{/dir} https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main{/dir}/{file}#L{line}">
<meta name="himesan-release-status" content="pre-release">
<meta name="description" content="Sandwich Hime is an HTML-first, PHP-feeling Go component compiler published as an unsupported pre-1.0 source preview.">
<meta name="theme-color" content="#251849">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; img-src 'self'; base-uri 'none'; form-action 'none'">
<title>Sandwich Hime — typed Go templates with a hand-built-web heart</title>
<link rel="stylesheet" href="./assets/site.css">
</head>
<body>
<a class="skip-link" href="#main">Skip to the sandwich</a>
<header class="masthead">
<div class="status-strip" role="status">
<span aria-hidden="true"></span>
Public pre-1.0 source preview — unsupported, no v1 release
<span aria-hidden="true"></span>
</div>
<div class="masthead-inner">
<p class="eyebrow">Gamertan dot com presents</p>
<pre class="wordmark" role="img" aria-label="Sandwich Hime">
╭────────────────────────╮
│ SANDWICH HIME-SAN │
╰──────────┬─────────────╯
HTML ♥ GO
</pre>
<h1>A tiny compiler for people who still want to touch the web.</h1>
<p class="lede">
Sandwich Hime turns one <code>.sando</code> component into ordinary,
reviewable Go. It aims for the immediacy of classic mixed markup,
while keeping typed data, contextual safety, and boring deployments.
</p>
<nav aria-label="Project destinations" class="button-row">
<a href="https://gitea.speelman.ca/gamertan/sandwich-hime">Canonical Gitea</a>
<a href="#status">Read the release status</a>
</nav>
<p class="mirror-note">
Source and contributions live only on canonical Gitea.
</p>
</div>
</header>
<main id="main">
<section class="panel code-panel" aria-labelledby="taste-heading">
<div>
<p class="sticker" aria-hidden="true">view source!</p>
<h2 id="taste-heading">A taste of <code>.sando</code></h2>
<p>
Markup is the main language. Go appears exactly where the page needs
it, and every rendered value is escaped for its known HTML context.
</p>
</div>
<pre class="code" tabindex="0" role="region" aria-label="Profile component template example"><code>&lt;?sando go
package views
func Profile(page ProfileView)
?&gt;
&lt;section class="profile"&gt;
&lt;h1&gt;&lt;?= page.Name ?&gt;&lt;/h1&gt;
&lt;? if page.IsAdmin { ?&gt;
&lt;?~ AdminBadge() ?&gt;
&lt;? } ?&gt;
&lt;/section&gt;</code></pre>
</section>
<section class="panel" aria-labelledby="boundary-heading">
<h2 id="boundary-heading">Compiler at the workbench. Small runtime in production.</h2>
<div class="cards">
<article>
<h3><code>himesan</code></h3>
<p>
A globally installed development tool that checks, generates, and
supervises a local server. It does not own your router or app.
</p>
</article>
<article>
<h3><code>page.sando.go</code></h3>
<p>
Deterministic generated Go, committed beside its source so code
review and production builds do not need the compiler.
</p>
</article>
<article>
<h3><code>sando</code></h3>
<p>
A deliberately small Apache-2.0 runtime: components, error-aware
rendering, and stable escaping helpers—no production server.
</p>
</article>
</div>
</section>
<section class="panel origin" aria-labelledby="origin-heading">
<div class="pixel-heart" aria-hidden="true"></div>
<div>
<h2 id="origin-heading">From a 2004 PSO game-club page, with love</h2>
<p>
The spirit is personal-site webmaking: open the file, understand the
page, change the page. Sandwich Hime is a love letter to a first
Geocities-era site last updated in 2004—rebuilt with the safety and
repeatability expected from a serious modern Go project.
</p>
<p>
The checkerboard, bevels, and tiny status lights are intentional.
The security model is also intentional.
</p>
</div>
</section>
<section class="panel" id="status" aria-labelledby="status-heading">
<h2 id="status-heading">Proof first. Release second.</h2>
<p>
Hime-san has no supported tagged public version yet. EQL Wiki is the
production proving ground, and v1 remains unreleased until the compiler,
runtime, development supervisor, and contextual escaping have durable
evidence behind them.
</p>
<ul class="checklist">
<li><span aria-hidden="true"></span> Cross-platform deterministic generation on Go 1.25 and 1.26</li>
<li><span aria-hidden="true"></span> Adversarial, fuzz, race, vulnerability, and accessibility gates</li>
<li><span aria-hidden="true"></span> EQL differential pilot and a clean 14-day production soak</li>
<li><span aria-hidden="true"></span> Working security contact and human-reviewed project policies</li>
<li><span aria-hidden="true"></span> Signed tags, checksums, SBOMs, binaries, and vanity paths</li>
</ul>
<p class="honesty-box">
No “fastest template engine” promises live here. Any performance claim
will ship with the hardware, commit, dataset, commands, latency, and
allocation results needed to reproduce it.
</p>
</section>
<section class="panel names" aria-labelledby="names-heading">
<h2 id="names-heading">Please keep the name tags on the right guests</h2>
<dl>
<div><dt>Project</dt><dd>Sandwich Hime / Hime-san</dd></div>
<div><dt>Command</dt><dd><code>himesan</code></dd></div>
<div><dt>Template</dt><dd><code>page.sando</code></dd></div>
<div><dt>Runtime</dt><dd><code>sando</code></dd></div>
<div><dt>San language</dt><dd><code>.san</code>—reserved, separate, and never a Hime-san template</dd></div>
</dl>
<p>
“Hime” on its own already belongs to an unrelated Go framework. The
compound Sandwich Hime and Hime-san identity avoids stepping on it.
</p>
</section>
</main>
<footer>
<p>
<span aria-hidden="true">[</span>
Hand-built for the web by Gamertan
<span aria-hidden="true">]</span>
</p>
<p class="fine-print">
Unsupported pre-1.0 preview. Compiler sources are AGPL-3.0-only; the
nested runtime is Apache-2.0; copyable examples are 0BSD.
</p>
</footer>
</body>
</html>
+47
View File
@@ -0,0 +1,47 @@
<!doctype html>
<!-- SPDX-License-Identifier: AGPL-3.0-only -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="go-import" content="gamertan.com/sandwich-hime/sando git https://gitea.speelman.ca/gamertan/sandwich-hime.git sando">
<meta name="go-source" content="gamertan.com/sandwich-hime/sando https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main/sando https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main/sando{/dir} https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main/sando{/dir}/{file}#L{line}">
<meta name="himesan-release-status" content="pre-release">
<meta name="description" content="Vanity import metadata for the Apache-2.0 Sandwich Hime sando runtime.">
<meta name="theme-color" content="#251849">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'self'; base-uri 'none'; form-action 'none'">
<title>sando runtime — Sandwich Hime</title>
<link rel="stylesheet" href="../assets/site.css">
</head>
<body>
<a class="skip-link" href="#main">Skip to the runtime note</a>
<header class="masthead compact">
<div class="status-strip" role="status">Public source-preview metadata — no public runtime tag yet</div>
<div class="masthead-inner">
<p class="eyebrow">Sandwich Hime / Hime-san</p>
<h1><code>sando</code> is the small production runtime.</h1>
<p class="lede">
This page carries Go 1.25+ vanity-import metadata for the nested module
at <code>gamertan.com/sandwich-hime/sando</code>.
</p>
</div>
</header>
<main id="main">
<section class="panel">
<h2>Not released yet</h2>
<p>
The runtime will be tagged independently as <code>sando/vX.Y.Z</code>
and licensed Apache-2.0. Do not add this vanity path to production until
a signed release exists and the install check is published.
</p>
<p>
<a href="../">Return to the Sandwich Hime project page</a> or inspect
the <a href="https://gitea.speelman.ca/gamertan/sandwich-hime/src/branch/main/sando">canonical runtime source on Gitea</a>.
</p>
</section>
</main>
<footer>
<p>HTML-first templates. Ordinary Go. A hand-built-web heart.</p>
</footer>
</body>
</html>