···11+# Binaries
22+httpmini-refserver
33+*.exe
44+55+# IDE
66+.idea/
77+.vscode/
88+*.swp
99+*.swo
1010+1111+# OS
1212+.DS_Store
1313+Thumbs.db
1414+1515+# Local dev
1616+*.local
+116
LICENSE
···11+CC0 1.0 Universal
22+33+Statement of Purpose
44+55+The laws of most jurisdictions throughout the world automatically confer
66+exclusive Copyright and Related Rights (defined below) upon the creator and
77+subsequent owner(s) (each and all, an "owner") of an original work of
88+authorship and/or a database (each, a "Work").
99+1010+Certain owners wish to permanently relinquish those rights to a Work for the
1111+purpose of contributing to a commons of creative, cultural and scientific
1212+works ("Commons") that the public can reliably and without fear of later
1313+claims of infringement build upon, modify, incorporate in other works, reuse
1414+and redistribute as freely as possible in any form whatsoever and for any
1515+purposes, including without limitation commercial purposes. These owners may
1616+contribute to the Commons to promote the ideal of a free culture and the
1717+further production of creative, cultural and scientific works, or to gain
1818+reputation or greater distribution for their Work in part through the use and
1919+efforts of others.
2020+2121+For these and/or other purposes and motivations, and without any expectation
2222+of additional consideration or compensation, the person associating CC0 with a
2323+Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
2424+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
2525+and publicly distribute the Work under its terms, with knowledge of his or her
2626+Copyright and Related Rights in the Work and the meaning and intended legal
2727+effect of CC0 on those rights.
2828+2929+1. Copyright and Related Rights. A Work made available under CC0 may be
3030+protected by copyright and related or neighboring rights ("Copyright and
3131+Related Rights"). Copyright and Related Rights include, but are not limited
3232+to, the following:
3333+3434+ i. the right to reproduce, adapt, distribute, perform, display, communicate,
3535+ and translate a Work;
3636+3737+ ii. moral rights retained by the original author(s) and/or performer(s);
3838+3939+ iii. publicity and privacy rights pertaining to a person's image or likeness
4040+ depicted in a Work;
4141+4242+ iv. rights protecting against unfair competition in regards to a Work,
4343+ subject to the limitations in paragraph 4(a), below;
4444+4545+ v. rights protecting the extraction, dissemination, use and reuse of data in
4646+ a Work;
4747+4848+ vi. database rights (such as those arising under Directive 96/9/EC of the
4949+ European Parliament and of the Council of 11 March 1996 on the legal
5050+ protection of databases, and under any national implementation thereof,
5151+ including any amended or successor version of such directive); and
5252+5353+ vii. other similar, equivalent or corresponding rights throughout the world
5454+ based on applicable law or treaty, and any national implementations thereof.
5555+5656+2. Waiver. To the greatest extent permitted by, but not in contravention of,
5757+applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
5858+unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
5959+and Related Rights and associated claims and causes of action, whether now
6060+known or unknown (including existing as well as future claims and causes of
6161+action), in the Work (i) in all territories worldwide, (ii) for the maximum
6262+duration provided by applicable law or treaty (including future time
6363+extensions), (iii) in any current or future medium and for any number of
6464+copies, and (iv) for any purpose whatsoever, including without limitation
6565+commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
6666+the Waiver for the benefit of each member of the public at large and to the
6767+detriment of Affirmer's heirs and successors, fully intending that such Waiver
6868+shall not be subject to revocation, rescission, cancellation, termination, or
6969+any other legal or equitable action to disrupt the quiet enjoyment of the Work
7070+by the public as contemplated by Affirmer's express Statement of Purpose.
7171+7272+3. Public License Fallback. Should any part of the Waiver for any reason be
7373+judged legally invalid or ineffective under applicable law, then the Waiver
7474+shall be preserved to the maximum extent permitted taking into account
7575+Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
7676+is so judged Affirmer hereby grants to each affected person a royalty-free,
7777+non transferable, non sublicensable, non exclusive, irrevocable and
7878+unconditional license to exercise Affirmer's Copyright and Related Rights in
7979+the Work (i) in all territories worldwide, (ii) for the maximum duration
8080+provided by applicable law or treaty (including future time extensions), (iii)
8181+in any current or future medium and for any number of copies, and (iv) for any
8282+purpose whatsoever, including without limitation commercial, advertising or
8383+promotional purposes (the "License"). The License shall be deemed effective as
8484+of the date CC0 was applied by Affirmer to the Work. Should any part of the
8585+License for any reason be judged legally invalid or ineffective under
8686+applicable law, such partial invalidity or ineffectiveness shall not
8787+invalidate the remainder of the License, and in such case Affirmer hereby
8888+affirms that he or she will not (i) exercise any of his or her remaining
8989+Copyright and Related Rights in the Work or (ii) assert any associated claims
9090+and causes of action with respect to the Work, in either case contrary to
9191+Affirmer's express Statement of Purpose.
9292+9393+4. Limitations and Disclaimers.
9494+9595+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
9696+ surrendered, licensed or otherwise affected by this document.
9797+9898+ b. Affirmer offers the Work as-is and makes no representations or warranties
9999+ of any kind concerning the Work, express, implied, statutory or otherwise,
100100+ including without limitation warranties of title, merchantability, fitness
101101+ for a particular purpose, non infringement, or the absence of latent or
102102+ other defects, accuracy, or the present or absence of errors, whether or not
103103+ discoverable, all to the greatest extent permissible under applicable law.
104104+105105+ c. Affirmer disclaims responsibility for clearing rights of other persons
106106+ that may apply to the Work or any use thereof, including without limitation
107107+ any person's Copyright and Related Rights in the Work. Further, Affirmer
108108+ disclaims responsibility for obtaining any necessary consents, permissions
109109+ or other rights required for any use of the Work.
110110+111111+ d. Affirmer understands and acknowledges that Creative Commons is not a
112112+ party to this document and has no duty or obligation with respect to this
113113+ CC0 or use of the Work.
114114+115115+For more information, please see
116116+<http://creativecommons.org/publicdomain/zero/1.0/>
+131
README.md
···11+# HTTP/Minimal Reference Server
22+33+A reference implementation of an HTTP/Minimal compliant server in Go.
44+55+## Features
66+77+- Serves Markdown files with proper `text/markdown` Content-Type
88+- Content negotiation: serves HTML to browsers, Markdown to clients that request it
99+- Strips raw HTML from Markdown sources (compliance enforcement)
1010+- YAML front matter support for metadata
1111+- `/.well-known/http-minimal` endpoint
1212+- Method restrictions (GET/HEAD only)
1313+- Forbidden header removal
1414+- Designed to run behind nginx/Caddy reverse proxy
1515+1616+## Quick Start
1717+1818+```bash
1919+# Install dependencies
2020+go mod download
2121+2222+# Run the server
2323+go run main.go -dir ./content -port 8080
2424+```
2525+2626+## Usage
2727+2828+```
2929+Usage of http-minimal-server:
3030+ -port string
3131+ Listen port (default "8080")
3232+ -base-url string
3333+ Base URL for the site (default "http://localhost:8080")
3434+ -contact string
3535+ Contact email for /.well-known/http-minimal
3636+ -dir string
3737+ Content directory (default "./content")
3838+ -template string
3939+ HTML template file (default: built-in template)
4040+```
4141+4242+## Content Directory Structure
4343+4444+```
4545+content/
4646+├── index.md # Served at /
4747+├── about.md # Served at /about
4848+├── posts/
4949+│ ├── index.md # Served at /posts
5050+│ └── first.md # Served at /posts/first
5151+└── images/
5252+ └── logo.png # Served at /images/logo.png
5353+```
5454+5555+## Front Matter
5656+5757+Documents can include YAML front matter:
5858+5959+```markdown
6060+---
6161+title: My Page Title
6262+author: Jane Doe
6363+date: 2025-12-27
6464+lang: en
6565+license: CC0-1.0
6666+---
6767+6868+# Content starts here
6969+```
7070+7171+## Content Negotiation
7272+7373+The server respects the `Accept` header:
7474+7575+```bash
7676+# Get HTML (default for browsers)
7777+curl http://localhost:8080/
7878+7979+# Get raw Markdown
8080+curl -H "Accept: text/markdown" http://localhost:8080/
8181+8282+# Check compliance policy
8383+curl http://localhost:8080/.well-known/http-minimal
8484+```
8585+8686+## Compliance
8787+8888+The server enforces HTTP/Minimal compliance:
8989+9090+- **Methods**: Only GET and HEAD are allowed
9191+- **Response Headers**: Forbidden headers (Set-Cookie, WWW-Authenticate, etc.) are removed
9292+- **Content**: Raw HTML is stripped from Markdown before serving
9393+- **Validation**: Images without alt text are logged as warnings
9494+9595+## Extending
9696+9797+### Custom HTML Template
9898+9999+Modify the `htmlTemplate` constant in `main.go` to customize the HTML rendering. Keep it minimal - no JavaScript, no external resources except same-origin images.
100100+101101+### Adding Middleware
102102+103103+The server implements `http.Handler`, so you can wrap it with standard Go middleware:
104104+105105+```go
106106+server, _ := NewServer(config)
107107+handler := loggingMiddleware(server)
108108+http.ListenAndServe(":8080", handler)
109109+```
110110+111111+### Integration with AT Protocol
112112+113113+The `/.well-known/http-minimal` endpoint could be extended to include:
114114+115115+```json
116116+{
117117+ "http_minimal": "0.1",
118118+ "compliant": true,
119119+ "did": "did:plc:example",
120120+ "atproto_pds": "https://bsky.social"
121121+}
122122+```
123123+124124+## Dependencies
125125+126126+- [goldmark](https://github.com/yuin/goldmark) - Markdown parser (CommonMark + GFM)
127127+- [yaml.v3](https://gopkg.in/yaml.v3) - YAML front matter parsing
128128+129129+## License
130130+131131+This reference implementation is released under CC0 1.0 Universal - no rights reserved.
+47
content/about.md
···11+---
22+title: About HTTP/Minimal
33+date: 2025-12-27
44+lang: en
55+---
66+77+# About HTTP/Minimal
88+99+HTTP/Minimal is a response to the modern web's complexity and hostility toward users.
1010+1111+## The Problem
1212+1313+The web today requires:
1414+1515+- Executing arbitrary JavaScript from strangers
1616+- Accepting tracking cookies
1717+- Loading megabytes of frameworks to read a paragraph
1818+- Fighting against dark patterns designed to manipulate you
1919+2020+## The Solution
2121+2222+HTTP/Minimal constrains HTTP to its document-serving roots:
2323+2424+| Feature | Modern Web | HTTP/Minimal |
2525+|---------|-----------|--------------|
2626+| JavaScript | Required | Forbidden |
2727+| Cookies | Everywhere | Forbidden |
2828+| Tracking | Default | Minimized |
2929+| Content | HTML soup | Clean Markdown |
3030+| Page weight | 2-10 MB | ~10 KB |
3131+3232+## Philosophy
3333+3434+> The web was designed as a document system. HTTP/Minimal returns it to that purpose.
3535+3636+We believe:
3737+3838+1. **Documents should be readable** - both by humans and machines
3939+2. **Privacy is the default** - not something you opt into
4040+3. **Simplicity scales** - complex systems fail in complex ways
4141+4. **Constraints are features** - what you *can't* do matters
4242+4343+## Get Involved
4444+4545+This is an open specification. Fork it, improve it, adopt it.
4646+4747+The spec is released under [CC0](https://creativecommons.org/publicdomain/zero/1.0/) - no rights reserved.
+51
content/index.md
···11+---
22+title: Welcome to HTTP/Minimal
33+date: 2025-12-27
44+lang: en
55+---
66+77+# Welcome to HTTP/Minimal
88+99+This is a document served over **HTTP/Minimal** - a constrained version of HTTP for human-readable content without tracking, scripts, or manipulation.
1010+1111+## What is this?
1212+1313+HTTP/Minimal is not a new protocol. It's a voluntary restriction on how HTTP is used:
1414+1515+- HTTPS only, no exceptions
1616+- No cookies or authentication headers
1717+- No JavaScript, ever
1818+- Content is Markdown, not HTML
1919+2020+## Why Markdown?
2121+2222+Markdown is:
2323+2424+1. Human-readable as source
2525+2. Human-writable without tooling
2626+3. Transparent - tracking pixels are visible in source and enforceable by clients
2727+4. Universally supported
2828+2929+## Try It
3030+3131+Request this page with different Accept headers:
3232+3333+```bash
3434+# Get rendered HTML (default)
3535+curl https://httpmini.com/
3636+3737+# Get raw Markdown
3838+curl -H "Accept: text/markdown" https://httpmini.com/
3939+4040+# Check compliance
4141+curl https://httpmini.com/.well-known/http-minimal
4242+```
4343+4444+## Learn More
4545+4646+- Read the [specification](/spec)
4747+- View the [about page](/about)
4848+4949+---
5050+5151+*[HTTP/Minimal Compliant](/.well-known/http-minimal)*
+537
content/spec.md
···11+# HTTP/Minimal
22+33+**Version:** 0.1.0-draft
44+**Status:** Proposal
55+66+## Abstract
77+88+HTTP/Minimal is a constrained version of HTTP designed for serving human-readable documents without tracking, scripting, or behavioral manipulation. It is not a new protocol - it is a voluntary restriction on how HTTP is used, enforceable by clients and verifiable by automated tools.
99+1010+## Goals
1111+1212+1. **Radical simplicity.** A document is text and links. Maybe images.
1313+2. **Privacy by architecture.** No cookies, no auth headers, no state.
1414+3. **Zero JavaScript.** Not "minimal scripts" - none.
1515+4. **Works today.** Any static file server can serve compliant content.
1616+5. **Human-writable source.** Content is authored in Markdown, not markup soup.
1717+1818+## Non-Goals
1919+2020+- Replacing HTTP for applications, APIs, or dynamic content
2121+- Defining a new transport protocol
2222+- Competing with Gemini (this is HTTP; use Gemini if you want Gemini)
2323+2424+---
2525+2626+## 1. Transport Requirements
2727+2828+### 1.1 TLS Required
2929+3030+All HTTP/Minimal content MUST be served over HTTPS (TLS 1.2+, TLS 1.3 RECOMMENDED).
3131+3232+Plain HTTP requests SHOULD receive a 301 redirect to the HTTPS equivalent and nothing else.
3333+3434+### 1.2 HTTP Version
3535+3636+HTTP/1.1, HTTP/2, and HTTP/3 are all acceptable. Servers SHOULD support HTTP/2 at minimum.
3737+3838+---
3939+4040+## 2. Request Constraints
4141+4242+Compliant clients MUST NOT send the following headers:
4343+4444+| Header | Reason |
4545+|--------|--------|
4646+| `Cookie` | State tracking |
4747+| `Authorization` | Implies authenticated content |
4848+| `DNT` | Unnecessary - tracking is minimized by design |
4949+| `X-Requested-With` | AJAX patterns not applicable |
5050+| Any `X-` header | Custom headers are a slippery slope |
5151+5252+Compliant clients MUST use only these methods:
5353+5454+- `GET` - Retrieve a document
5555+- `HEAD` - Check if a document exists or has changed
5656+5757+All other methods (`POST`, `PUT`, `DELETE`, etc.) are non-compliant.
5858+5959+### 2.1 Query Strings
6060+6161+Query strings are PERMITTED but SHOULD be limited to:
6262+6363+- Pagination (`?page=2`)
6464+6565+Query strings MUST NOT be used for:
6666+6767+- Session tracking
6868+- User identification
6969+- Analytics parameters (utm_*, fbclid, etc.)
7070+7171+Compliant servers SHOULD ignore or strip unrecognized query parameters.
7272+7373+---
7474+7575+## 3. Response Constraints
7676+7777+### 3.1 Forbidden Response Headers
7878+7979+Compliant servers MUST NOT send:
8080+8181+| Header | Reason |
8282+|--------|--------|
8383+| `Set-Cookie` | State tracking |
8484+| `WWW-Authenticate` | Implies auth-gated content |
8585+| `Content-Security-Policy` | Implies executable content to policy |
8686+| `X-Frame-Options` | Embedding restrictions suggest app behavior |
8787+| `Refresh` | Client-side redirects enable tracking |
8888+8989+### 3.2 Permitted Response Headers
9090+9191+Servers SHOULD send:
9292+9393+| Header | Purpose |
9494+|--------|---------|
9595+| `Content-Type` | Required (`text/markdown; charset=utf-8`) |
9696+| `Content-Length` | Required for HTTP/1.1 |
9797+| `Last-Modified` | Caching |
9898+| `ETag` | Caching |
9999+| `Cache-Control` | Caching (SHOULD be generous; `max-age=3600` or higher) |
100100+| `Link` | Discovery (see Section 6) |
101101+102102+### 3.3 Status Codes
103103+104104+Compliant servers SHOULD limit responses to:
105105+106106+| Code | Meaning |
107107+|------|---------|
108108+| `200` | OK |
109109+| `301` | Moved Permanently |
110110+| `304` | Not Modified |
111111+| `400` | Bad Request |
112112+| `404` | Not Found |
113113+| `410` | Gone (content deliberately removed) |
114114+| `500` | Server Error |
115115+116116+Codes `302`, `303`, and `307` are NOT RECOMMENDED as they enable tracking redirects.
117117+118118+---
119119+120120+## 4. Content Format
121121+122122+HTTP/Minimal uses **Markdown** as its content format, served with Content-Type `text/markdown; charset=utf-8`.
123123+124124+### 4.1 Markdown Variant
125125+126126+HTTP/Minimal uses [CommonMark](https://commonmark.org/) as the base specification, with the following extensions PERMITTED:
127127+128128+- **Tables** - GitHub Flavored Markdown (GFM) pipe tables
129129+- **Strikethrough** - `~~text~~`
130130+- **Autolinks** - GFM automatic URL linking
131131+- **Footnotes** - `[^1]` reference-style footnotes
132132+133133+### 4.2 Permitted Syntax
134134+135135+All standard CommonMark elements:
136136+137137+- Headings (`#`, `##`, etc.)
138138+- Paragraphs
139139+- Emphasis (`*italic*`, `**bold**`)
140140+- Links (`[text](url)` or `[text][ref]`)
141141+- Images (``)
142142+- Blockquotes (`>`)
143143+- Code spans (`` `code` ``)
144144+- Code blocks (fenced or indented)
145145+- Lists (ordered and unordered)
146146+- Horizontal rules (`---`)
147147+- Hard line breaks
148148+149149+### 4.3 Forbidden Syntax
150150+151151+The following MUST NOT appear in HTTP/Minimal documents:
152152+153153+| Syntax | Reason |
154154+|--------|--------|
155155+| Raw HTML blocks | Enables script injection, tracking pixels, forms |
156156+| Raw HTML inline | Same |
157157+| `<script>` | No JavaScript |
158158+| `<iframe>` | Embedded third-party content |
159159+| `<form>` | Data collection |
160160+| `<img>` with tracking URLs | Use Markdown image syntax with compliant URLs |
161161+162162+Clients MUST strip or ignore any raw HTML encountered in Markdown source.
163163+164164+### 4.4 Image Requirements
165165+166166+Images referenced via `` syntax:
167167+168168+- MUST include alt text (the `[alt]` portion MUST NOT be empty)
169169+- SHOULD be same-origin or from trusted, non-tracking sources
170170+- MUST NOT be 1x1 tracking pixels
171171+172172+### 4.5 Link Requirements
173173+174174+Links are unrestricted in destination -HTTP/Minimal documents MAY link to any URL.
175175+176176+Clients MAY warn users when following links to non-compliant origins.
177177+178178+#### 4.5.1 URL Fragments
179179+180180+URL fragments (`#section-name`) are supported and SHOULD work as follows:
181181+182182+- When rendering Markdown to HTML, headings SHOULD receive auto-generated `id` attributes based on their text (lowercase, spaces replaced with hyphens)
183183+- Clients receiving `text/markdown` SHOULD scroll to the heading matching the fragment
184184+- Fragment matching SHOULD be case-insensitive
185185+186186+For example, `## My Section` would be reachable via `#my-section`.
187187+188188+### 4.6 Metadata
189189+190190+Document metadata SHOULD be provided via a YAML front matter block:
191191+192192+```markdown
193193+---
194194+title: My Document
195195+author: Jane Doe
196196+date: 2025-12-27
197197+lang: en
198198+---
199199+200200+# My Document
201201+202202+Content begins here.
203203+```
204204+205205+Recognized front matter fields:
206206+207207+| Field | Required | Description |
208208+|-------|----------|-------------|
209209+| `title` | RECOMMENDED | Document title |
210210+| `author` | No | Author name or identifier |
211211+| `date` | No | Publication date (ISO 8601) |
212212+| `lang` | No | Language code (BCP 47) |
213213+| `license` | No | Content license (SPDX identifier or URL) |
214214+215215+Clients SHOULD use `title` for window/tab titles and `lang` for text rendering.
216216+217217+---
218218+219219+## 5. Client Rendering
220220+221221+### 5.1 Dedicated Clients
222222+223223+HTTP/Minimal clients SHOULD:
224224+225225+1. Parse Markdown and render to styled, readable output
226226+2. Apply a legible default stylesheet (user-configurable)
227227+3. Strip any raw HTML before rendering
228228+4. Display images inline with alt text fallback
229229+5. Make links clearly navigable
230230+231231+### 5.2 Browser Rendering
232232+233233+Standard browsers receiving `text/markdown` will typically display raw source. Options for browser compatibility:
234234+235235+**Option A: Server-side rendering**
236236+237237+Servers MAY content-negotiate and serve pre-rendered HTML to browsers:
238238+239239+- Request with `Accept: text/markdown` → serve Markdown
240240+- Request with `Accept: text/html` → serve HTML rendering
241241+242242+The HTML rendering MUST be a direct transformation of the Markdown source with no additions (no scripts, no tracking, no analytics).
243243+244244+**Option B: Client-side rendering via browser extension**
245245+246246+Browser extensions may render `text/markdown` responses directly.
247247+248248+**Option C: Raw display**
249249+250250+Markdown is human-readable as source. No rendering required.
251251+252252+### 5.3 Suggested Default Styles
253253+254254+Clients SHOULD apply sensible typographic defaults:
255255+256256+- Readable font (system serif or sans-serif)
257257+- Comfortable line length (45-75 characters)
258258+- Adequate line height (1.4-1.6)
259259+- Responsive viewport handling
260260+- Respect user preferences (dark mode, font size)
261261+262262+---
263263+264264+## 6. Discovery and Verification
265265+266266+### 6.1 Well-Known Endpoint
267267+268268+Compliant servers SHOULD serve a policy document at:
269269+270270+```
271271+/.well-known/http-minimal
272272+```
273273+274274+This document is a JSON object:
275275+276276+```json
277277+{
278278+ "http_minimal": "0.1",
279279+ "compliant": true,
280280+ "scope": "/",
281281+ "contact": "mailto:admin@example.com",
282282+ "validator": "https://example.com/validation-report.json"
283283+}
284284+```
285285+286286+| Field | Required | Description |
287287+|-------|----------|-------------|
288288+| `http_minimal` | Yes | Spec version |
289289+| `compliant` | Yes | Self-attestation |
290290+| `scope` | No | Path prefix this policy applies to (default: entire origin) |
291291+| `contact` | No | Maintainer contact |
292292+| `validator` | No | URL to a third-party validation report |
293293+294294+### 6.2 Link Header
295295+296296+Responses MAY include:
297297+298298+```
299299+Link: </.well-known/http-minimal>; rel="profile"
300300+```
301301+302302+### 6.3 Compliance Badge (Optional)
303303+304304+Documents MAY include a compliance indicator:
305305+306306+```markdown
307307+---
308308+[HTTP/Minimal Compliant](/.well-known/http-minimal)
309309+```
310310+311311+---
312312+313313+## 7. Example Document
314314+315315+```markdown
316316+---
317317+title: Welcome to HTTP/Minimal
318318+author: Jane Doe
319319+date: 2025-12-27
320320+lang: en
321321+---
322322+323323+# Welcome to HTTP/Minimal
324324+325325+This is a document served over **HTTP/Minimal** - a constrained version of
326326+HTTPS for human-readable content without tracking, scripts, or manipulation.
327327+328328+## What is this?
329329+330330+HTTP/Minimal is not a new protocol. It's a voluntary restriction on how
331331+HTTP is used:
332332+333333+- HTTPS only, no exceptions
334334+- No cookies or authentication headers
335335+- No JavaScript, ever
336336+- Content is Markdown, not HTML
337337+338338+## Why Markdown?
339339+340340+Markdown is:
341341+342342+1. Human-readable as source
343343+2. Human-writable without tooling
344344+3. Transparent - tracking pixels are visible in source and enforceable by clients
345345+4. Universally supported
346346+347347+## Learn More
348348+349349+Read the full [specification](/spec) or view the
350350+[source for this page](/source/index.md).
351351+352352+---
353353+354354+*[HTTP/Minimal Compliant](/.well-known/http-minimal)*
355355+```
356356+357357+---
358358+359359+## 8. Relationship to Other Specifications
360360+361361+### Gemini Protocol
362362+363363+HTTP/Minimal shares philosophical goals with Gemini (simplicity, anti-tracking, anti-JavaScript) but differs in approach:
364364+365365+| Aspect | Gemini | HTTP/Minimal |
366366+|--------|--------|--------------|
367367+| Transport | New protocol (gemini://) | HTTPS |
368368+| Content format | text/gemini | text/markdown |
369369+| Browser support | Requires dedicated client | Works with extensions or server-side rendering |
370370+| Port | 1965 | 443 |
371371+372372+### Gemtext vs Markdown
373373+374374+Gemini's text/gemini format is simpler than Markdown (one link per line, no inline formatting). HTTP/Minimal accepts the tradeoff of a slightly more complex format for broader tooling support.
375375+376376+### Semantic Web / Microformats
377377+378378+HTTP/Minimal Markdown documents can include semantic meaning via:
379379+380380+- Structured YAML front matter
381381+- Consistent heading hierarchies
382382+- Machine-parseable date/author metadata
383383+384384+---
385385+386386+## 9. Security Considerations
387387+388388+- **No cookies** eliminates CSRF and session hijacking vectors
389389+- **No JavaScript** eliminates XSS entirely
390390+- **No forms** eliminates CSRF for data submission
391391+- **No raw HTML** prevents injection attacks
392392+- **HTTPS required** ensures transport security
393393+394394+Remaining vectors:
395395+396396+- **Malicious links** - users may still be linked to harmful external sites
397397+- **Image-based tracking** - external images can still leak requests; clients MAY block third-party images
398398+- **Cache timing** - sophisticated attackers may infer browsing history via cache timing; out of scope
399399+400400+---
401401+402402+## 10. Future Considerations
403403+404404+Items explicitly deferred for future versions:
405405+406406+- **Signed content** - integration with Signed HTTP Exchanges or content-addressed storage
407407+- **Content addressing** - integration with IPFS, AT Protocol, or content-hash URLs
408408+- **Client certificates** - Gemini-style TOFU identity without cookies
409409+- **Extended metadata** - richer front matter schemas (JSON-LD, etc.)
410410+- **Media embedding** - whether/how to handle audio and video
411411+412412+---
413413+414414+## Appendix A: Validator Pseudocode
415415+416416+```python
417417+def validate_response(response):
418418+ errors = []
419419+420420+ # Check forbidden response headers
421421+ forbidden = ['set-cookie', 'www-authenticate', 'refresh']
422422+ for header in forbidden:
423423+ if header in response.headers:
424424+ errors.append(f"Forbidden header: {header}")
425425+426426+ # Check content type
427427+ content_type = response.headers.get('content-type', '')
428428+ if not content_type.startswith('text/markdown'):
429429+ errors.append("Content-Type must be text/markdown")
430430+431431+ # Parse Markdown
432432+ doc = parse_markdown(response.body)
433433+434434+ # Check for raw HTML
435435+ if contains_raw_html(doc):
436436+ errors.append("Raw HTML is forbidden")
437437+438438+ # Check images have alt text
439439+ for image in doc.images:
440440+ if not image.alt:
441441+ errors.append(f"Image missing alt text: {image.url}")
442442+443443+ return errors
444444+```
445445+446446+---
447447+448448+## Appendix B: Content-Type Registration
449449+450450+This specification uses `text/markdown` as defined in [RFC 7763](https://datatracker.ietf.org/doc/html/rfc7763).
451451+452452+Recommended Content-Type header:
453453+454454+```
455455+Content-Type: text/markdown; charset=utf-8; variant=CommonMark
456456+```
457457+458458+---
459459+460460+## Appendix C: Migration Checklist
461461+462462+For existing sites adopting HTTP/Minimal:
463463+464464+- [ ] Enable HTTPS if not already
465465+- [ ] Convert content to Markdown (or add Markdown alongside HTML)
466466+- [ ] Configure server to serve `.md` files as `text/markdown`
467467+- [ ] Remove all analytics (Google Analytics, Plausible, etc.)
468468+- [ ] Remove comment systems or link to external discussion
469469+- [ ] Ensure all images have alt text
470470+- [ ] Ensure no raw HTML in Markdown source
471471+- [ ] Add `/.well-known/http-minimal` endpoint
472472+- [ ] Run validator against all documents
473473+- [ ] Optional: implement content negotiation for HTML clients
474474+475475+---
476476+477477+## Appendix D: Server Configuration Examples
478478+479479+### Nginx
480480+481481+```nginx
482482+location ~ \.md$ {
483483+ types { text/markdown md; }
484484+ charset utf-8;
485485+ add_header Link '</.well-known/http-minimal>; rel="profile"';
486486+487487+ # Remove forbidden headers (shouldn't exist, but defensive)
488488+ proxy_hide_header Set-Cookie;
489489+ proxy_hide_header WWW-Authenticate;
490490+}
491491+```
492492+493493+### Caddy
494494+495495+```caddyfile
496496+@markdown path *.md
497497+header @markdown Content-Type "text/markdown; charset=utf-8"
498498+header @markdown Link "</.well-known/http-minimal>; rel=\"profile\""
499499+header @markdown -Set-Cookie
500500+```
501501+502502+### Static file server (Go)
503503+504504+```go
505505+http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
506506+ if r.Method != "GET" && r.Method != "HEAD" {
507507+ http.Error(w, "Method not allowed", 405)
508508+ return
509509+ }
510510+511511+ if strings.HasSuffix(r.URL.Path, ".md") {
512512+ w.Header().Set("Content-Type", "text/markdown; charset=utf-8")
513513+ w.Header().Set("Link", "</.well-known/http-minimal>; rel=\"profile\"")
514514+ }
515515+516516+ http.FileServer(http.Dir("./public")).ServeHTTP(w, r)
517517+})
518518+```
519519+520520+---
521521+522522+## Acknowledgments
523523+524524+This specification draws inspiration from:
525525+526526+- **[Gemini Protocol](https://geminiprotocol.net/)** - for proving that radical simplicity has an audience
527527+- **["Gemini is Solutionism at its Worst"](https://xn--gckvb8fzb.com/gemini-is-solutionism-at-its-worst/)** - マリウス's critique arguing Gemini's goals could be achieved via HTTP with constraints, not a new protocol
528528+- **[CommonMark](https://commonmark.org/)** - for standardizing Markdown
529529+- **[The Web We Lost](https://www.anildash.com/2012/12/13/the-web-we-lost/)** - Anil Dash's 2012 essay on web degradation
530530+- **[Motherfucking Website](https://motherfuckingwebsite.com/)** - satirical proof that content needs nothing else
531531+- **[IndieWeb](https://indieweb.org/)** - for keeping personal publishing alive
532532+533533+---
534534+535535+## License
536536+537537+This specification is released under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) - no rights reserved. Use it, fork it, improve it.