v1: remove DRAFT (spec lives in wiki/dod + issues), license signed off

ac76d91gl0w

all commits

Message

v1: remove DRAFT (spec lives in wiki/dod + issues), license signed off

Diff

.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/comments/5d2a15b1-156f-4852-a8ce-97a2144a36d4.md+6 −0
diff --git a/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/comments/5d2a15b1-156f-4852-a8ce-97a2144a36d4.md b/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/comments/5d2a15b1-156f-4852-a8ce-97a2144a36d4.mdnew file mode 100644index 0000000..4d0e67b--- /dev/null+++ b/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/comments/5d2a15b1-156f-4852-a8ce-97a2144a36d4.md@@ -0,0 +1,6 @@1+---2+id: 5d2a15b1-156f-4852-a8ce-97a2144a36d43+author: null4+created: 2026-09-10T09:51:08.602707703Z5+---6+Owner sign-off: license text approved as-is (2026-09-10). No lawyer, final. v1 unblocked.
.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/issue.md+2 −2
diff --git a/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/issue.md b/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/issue.mdindex 8791964..bdfca5f 100644--- a/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/issue.md+++ b/.forge/issues/130e63f1-2abf-4e3d-876d-354755ecd613/issue.md@@ -1,13 +1,13 @@11 ---22 id: 130e63f1-2abf-4e3d-876d-354755ecd61333 title: 'DEFERRED: license text owner re-read pre-v1'4-state: open4+state: closed55 labels:66 - kind:docs77 assignees: []88 milestone: m5-docker-v199 created: 2026-09-10T03:52:27.772380914Z10-updated: null10+updated: 2026-09-10T09:51:08.610256854Z1111 ---1212 Context: License text is final per owner (no lawyer). This issue enforces the deferred re-read after build+QA, before v1 tag.1313 Tasks:
DRAFT.md+0 −277
diff --git a/DRAFT.md b/DRAFT.mddeleted file mode 100644index c0527b1..0000000--- a/DRAFT.md+++ /dev/null@@ -1,277 +0,0 @@1-# hu13 — DRAFT2-3-Pronounced "hub".4-5-Status: draft. Not spec. Not approved. For chewing on.6-7-## One-liner8-9-`hu13` is a super tiny host-anywhere viewer for exactly one repo.10-You give an instance one repo, it serves a GitHub/Gitea-shaped11-read-only site for that repo plus two text-only mailboxes. No accounts.12-No multi-repo. Just replace the repo + restart.13-14-1 instance = 1 repo. Want 5 public repos? Run 5 containers.15-16-## Why17-18-`f0rge` is the forge — CLI-first, files-only, lives in the repo.19-`hu13` is the window — it makes one repo legible to a human with a20-browser AND to an agent with curl, without giving either a checkout.21-22-This is not a GitHub replacement. It's my public mirror: I work with23-agents privately, publish snapshots publicly, and let anyone (human or24-agent) suggest an issue or a prompt-style PR. My agents read the dumb25-inbox later and keep the gold. 90% will be drivel. That's fine — an26-agent chews through the whole thing fast.27-28-## Non-goals (hard)29-30-- No multi-repo hub, no orgs, no explore, no tenants.31-- No auth, no comments, no editing, no API writes, no webhooks — except32-  the two inbox POSTs, which are write-only, text-only, never rendered.33-- No JS framework. Zero JS. Forms are plain `<form>` POSTs. Fully usable34-  with JS off, curl-able by agents.35-- No search backend, no syntax engine, no analytics, no triage skill in36-  hu13. Triage is my agents' job, outside hu13.37-- No reimplementation of `f0rge`. hu13 only reads. `f0rge` is truth.38-- Hosting-agnostic. nginx in front if you want it — hu13's job is just39-  to be a good dockerised thing that serves its repo + inbox.40-41-## Mental model + update story (keep it dumb)42-43-```44-host dir (example)      container45-./repo/        -------> /data/repo   (read-only mount, the checkout)46-./inbox-vol/   -------> /data/inbox  (read-write volume, persists)47-                 |--> build on start: hu13 build /data/repo -o /srv/www48-                 |--> serve /srv/www (static) + 2 inbox POSTs -> /data/inbox49-```50-51-- To update the public version: replace `./repo/` contents, restart the52-  container. Rebuild happens at start. Nothing else to do.53-- `dist/`/`/srv/www` is ephemeral — rebuilt every start. Never persisted.54-- Inbox is a volume so restarts/deploys never lose suggestions. Inbox55-  never touches the repo, `dist/`, or `.forge/`. Separate dir, no56-  read-back over HTTP, ever.57-- Build is deterministic + offline. Same commit + same `.forge/` =58-  same site.59-60-## What it renders (v1 = all of this, 100%)61-62-Top nav: `code | commits | issues (n) | pulls (n) | tasks | ci | releases | wiki`63-64-Source of truth is git + `.forge/` on disk (real dir name `.forge/`,65-styled f0rge). Unknown frontmatter fields ignored; missing required66-fields → skip file + stderr warn, never fail build. Never parse `f0rge`67-prose — read the files.68-69-1. `index.html` — code tab.70-   - header: name, description, clone cmd, branch + short sha built71-     from, f0rge counts, last CI verdict.72-   - clone resolution (best-reliable order): `--clone-url` flag wins;73-     else `git remote get-url origin` at build time if present; else74-     no URL line. Always also built: `repo.bundle` (git bundle of the75-     pinned branch — the authoritative snapshot) + `repo.tar.gz` +76-     `/raw/` files. Bundle is what guarantees cloning works even with77-     no URL configured and no git server running.78-   - file tree (dirs first, flat per-dir, no JS) + README below.79-   - README lookup chain (f0rge convention: READMEs live in the wiki):80-     repo-root `README.md` > `readme.md` > `README`, else81-     `.forge/wiki/README.md` > `.forge/wiki/readme.md`, else none.82-   - download snapshot: `repo.tar.gz` + `repo.bundle` (made at build83-     time). No git server — bundle + tarball + raw files is cloning.84-2. `/files/<path>.html` — dir listing or file view. Escaped `<pre>` +85-   line numbers, `raw` link. Markdown rendered. Binary/>256KB:86-   placeholder + download. `/raw/<path>` byte-identical.87-3. `/commits.html` + `/commit/<sha>.html` — `git log`, latest 10088-   default. Detail page includes full message + **unified diff as89-   escaped `<pre>`** (v1, because otherwise "entire state" is a lie).90-4. `/issues/`, `/pulls/` — from `.forge/issues/<uuid>/issue.md`,91-   `.forge/prs/<uuid>/pr.md` (+ `patch.diff` shown as `<pre>` if92-   present, comments count, reviews). Number = rank of93-   `(created,id)`. Display number, link by uuid.94-5. `/tasks/` — from `.forge/tasks/`, grouped95-   todo|doing|blocked|done. No JS.96-6. `/ci/` — from `.forge/ci/` + `runs/<ts>/summary.md` if present at97-   build. Badge pass|fail|running|cancelled. Steps + logs as `<pre>`.98-7. `/releases/` + `/releases/<ver>/<file>` — from99-   `.forge/releases/<ver>.md` notes (title, body, sha). **Artifacts100-   only if `releases/out/<ver>/` exists at build time** (it's101-   gitignored, so usually absent — fine). If present, copied whole102-   to `dist/releases/<ver>/` with sha256 from notes, served as plain103-   downloads GH-style. No size cap — if the maintainer shipped it,104-   hu13 ships it. Never executed, `nosniff`, no listing beyond105-   what notes declare.106-8. `/wiki/` — from `.forge/wiki/`, markdown rendered, index = tree +107-   first H1.108-9. `feed.atom` — 50 entries, commits + release notes mixed newest-first,109-   at build time. For agents to poll N mirrors cheaply.110-10. Agent surface (static, no daemon):111-    - `/api/issues.json`, `/api/pulls.json`, `/api/commits.json`,112-      `/api/releases.json`, `/api/wiki.json` — same data as HTML,113-      compact fixed-order JSON generated at build.114-    - `/agents.html` (and `/agents.md` raw) — instructions for agents:115-      read via raw/api/tarball, submit via the two POSTs as116-      `application/x-www-form-urlencoded` text; issues = detailed117-      actionable text from your user, PRs = ONE prompt not code;118-      caps, license text, curl examples. Free textboxes — visiting119-      agents are smarter than any template.120-121-No "suggestions pending" count. No inbox contents anywhere in `dist/`.122-People see what's accepted when it shows up as a real issue/PR.123-124-## Safe mailbox (the only write path, dumb inbox, private)125-126-Exactly two things, both text and nothing else:127-128-1. `issue` — `title` + `body`. Actionable detail from your user.129-2. `pr-prompt` — `title` + `prompt`. ONE prompt, plain text. No files,130-   no diff, no branch, no bundle. Code words inside stay text — never131-   applied, never executed.132-133-Forms: `/new-issue.html`, `/new-pr.html`. Free textboxes + optional134-`handle` (≤40) + optional `contact` (≤100), both plain text + honeypot135-+ **required license checkbox** (see below). POSTs to136-`POST /inbox/issue`, `POST /inbox/pr-prompt` on the built-in server.137-No GET, no listing, no read-back. Response is a `received` page showing138-a **one-time ack uuid** (server-generated, shown once, not in a URL,139-no lookup endpoint) + nothing reflected (kills reflected XSS).140-141-Storage: `/data/inbox/<uuid4>.json`, `0600`. Server-generated filename —142-user input never touches a path. Fields: `type,title,body,handle,143-contact,license_version,received_at,salted_ip_hash`. Read path is144-filesystem/SSH + `hu13 inbox list|show` (escaped plain text). No HTTP145-read endpoint. Promotion is manual (`f0rge issue open` / `f0rge pr open`146-by hand). Mailbox never writes `.forge/`.147-148-### Safe — enforced server-side, fail closed149-150-- urlencoded-only. Reject `multipart/*`. UTF-8 only, reject null bytes,151-  strip controls except `\n\t`. Store as JSON strings, never HTML.152-- Caps (defaults, all tunable via flags/env, no config file):153-  title ≤300 chars, body/prompt ≤20000, handle ≤40, contact ≤100,154-  whole body ≤32KB → `413`. 5s timeout. No length → drop.155-  Looser on length (agents write long), tighter on volume (see next).156-- No files by construction: no file field, no filename, no157-  `Content-Disposition`, never executable, never in PATH, never sourced.158-- Never rendered: inbox never templated to HTML, never markdown-rendered,159-  never logged. Local `show` = plain text to terminal. `gl0w.md` warns:160-  don't paste inbox text into a shell.161-- Least privilege: server user writes ONLY the inbox dir. No git in162-  PATH, no write on repo/www/`.forge/`. Compromised server can't commit.163-- Abuse (tight, tunable): per-IP bucket 2/hr, ~500ms fixed delay,164-  honeypot (filled → silent `received`, dropped), global quota165-  500 files → `503` until drained by hand.166-  No CAPTCHA, no egress, no third-party JS. IPs as daily-salted hash.167-- Hygiene: POST-only, `Origin` check, `SameSite=Lax`, no cookies, no168-  CORS, `nosniff`+`no-store`, bind `0.0.0.0` in container but designed169-  for localhost-behind-proxy too. Generic responses only.170-- Quota/full/crash → `503`/`400`/`429`, lose one POST, never corrupt repo.171-172-Drivel-tolerant: drop rather than accept anything dubious, always say173-`received` either way (don't oracle spam filters).174-175-### License (binding, receiver-friendly — final text, no lawyer)176-177-Under each form, this exact text + required checkbox (unchecked = `400`):178-179-> By submitting this text you irrevocably give it to this project.180-> You keep no rights in it, you are owed nothing for it, and you will181-> make no claim over it — ownership, credit, payment, infringement,182-> or otherwise — against the maintainer or anyone who uses it. The183-> maintainer may keep, share, change, or use it for any purpose, in184-> any code or license, without notice or payment. If you cannot agree185-> to that, do not submit.186-187-Stored per-submission: `license_version` (v1 string above) + checkbox188-state + body hash + timestamp. No submission without the box checked.189-This is what lets agents freely absorb prompts. Deferred f0rge issue:190-re-read this text after build + QA, before v1 tag — owner review.191-192-## Branch193-194-`--branch <name>` pin, else `HU13_BRANCH` env, else try `main` then195-`master` then fail loudly at start. Header shows which branch + sha.196-Single branch per instance. No switcher.197-198-## Look199-200-Tokyo Night dark-first. One hand-written `style.css` (<15KB). Sharp201-corners only (`border-radius: 0`). Semantic HTML so `curl` + reader-mode202-+ `file://` all work. No fonts vendored.203-204-## CLI (flags/env only, no config file)205-206-```207-hu13 build /data/repo -o /srv/www [--branch X] [--clone-url URL]208-       [--repo-name S] [--description S] [--max-log 100]209-       # repo-name default: HU13_REPO_NAME else repo dir name (never blank;210-       #   --title still works as a deprecated alias)211-       # description default: HU13_DESCRIPTION else hidden (no empty <p>)212-       # clone-url default: git remote get-url origin at build, else none213-       # caps tunable: --max-title 300 --max-body 20000 --max-bytes 32768214-       #   --rate-per-hour 2 --quota 500 (or HU13_* env)215-hu13 serve --www /srv/www --inbox-dir /data/inbox --listen 0.0.0.0:39313216-  # static + the two POSTs, nothing else217-       # same cap flags/env apply to serve218-219-hu13 inbox list|show --inbox-dir /data/inbox   # local only220-hu13 --version221-```222-223-`serve` is the docker runtime. No `watch`, no `init`.224-225-## Docker (part of hu13, host anywhere)226-227-Single image: Rust binary + `entrypoint: build on start, then serve`.228-Mounts: `/data/repo:ro`, `/data/inbox:rw`. Expose one port. No nginx229-inside — bring your own proxy if you want. `dist` never baked in (would230-go stale); inbox never in the image (would be lost).231-232-## Engineering233-234-- Rust, one crate to start, low/no deps. Pinned `pulldown-cmark` for235-  markdown + frontmatter. No tokio/hyper if stdlib handler suffices.236-- HTML escaped by construction. No highlighting in v1 (`<pre>` + line237-  numbers, diffs included). Size budget: binary <2MB, CSS <15KB.238-- Machine JSON + `feed.atom` + `repo.bundle`/`repo.tar.gz` are build239-  artifacts in `dist/`, same caps as everything else.240-241-## Repo shape (no root clutter)242-243-```244-hu13/245-  DRAFT.md  gl0w.md  src/  static/style.css  Dockerfile246-  .gitignore  .stignore  .forge/  .gl0w/skills/247-```248-249-Docs/roadmap → `.forge/wiki/`. Root stays clean.250-251-## Process252-253-- `git init` + ignores, `f0rge init`, `.gl0w/skills/`.254-- All work via f0rge: issue → branch → PR → local-CI-gated merge.255-  CI steps are scripts in filename order; first non-zero = fail.256-- CI v1: fmt, clippy `-D warnings`, tests, self-dogfood257-  (`hu13 build` its own repo + check `dist/`, feed, api, bundle).258-- f0rge gaps → file in f0rge repo as external, never implement without259-  authorisation.260-261-## Milestones (v1 must be 100%)262-263-- m1 — code tab + files/raw + style + branch pin + bundle/tarball.264-- m2 — commits + per-commit diffs + wiki + feed.atom.265-- m3 — issues/pulls/tasks/ci/releases (+ artifacts if present) + api/*.json + agents page.266-- m4 — mailbox: forms + serve POSTs + ack uuid + license checkbox + handle/contact + caps + inbox list/show.267-- m5 — docker (build-on-start, repo:ro + inbox:rw) + dogfood + polish.268-  Deferred owner review of license text after QA. Tag v1.269-270-## Decisions locked (from review)271-272-- Clone: flag > origin remote > bundle/tarball fallback. Bundle always built.273-- Caps: loose length (300/20000/32KB), tight volume (2/hr, quota 500),274-  tunable via flags/env.275-- Artifacts: no size cap — maintainer ships it, hu13 serves it.276-- License: text above is final, no lawyer; deferred re-read issue pre-v1.277-- Feed: 50 entries, mixed commits+releases.