Spec for HTTP/Minimal
1# HTTP/Minimal
2
3**Version:** 0.1.0-draft
4**Status:** Proposal
5
6## Abstract
7
8HTTP/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.
9
10## Goals
11
121. **Radical simplicity.** A document is text and links. Maybe images.
132. **Privacy by architecture.** No cookies, no auth headers, no state.
143. **Zero JavaScript.** Not "minimal scripts" - none.
154. **Works today.** Any static file server can serve compliant content.
165. **Human-writable source.** Content is authored in Markdown, not markup soup.
17
18## Non-Goals
19
20- Replacing HTTP for applications, APIs, or dynamic content
21- Defining a new transport protocol
22- Competing with Gemini (this is HTTP; use Gemini if you want Gemini)
23
24---
25
26## 1. Transport Requirements
27
28### 1.1 TLS Required
29
30All HTTP/Minimal content MUST be served over HTTPS (TLS 1.2+, TLS 1.3 RECOMMENDED).
31
32Plain HTTP requests SHOULD receive a 301 redirect to the HTTPS equivalent and nothing else.
33
34### 1.2 HTTP Version
35
36HTTP/1.1, HTTP/2, and HTTP/3 are all acceptable. Servers SHOULD support HTTP/2 at minimum.
37
38---
39
40## 2. Request Constraints
41
42Compliant clients MUST NOT send the following headers:
43
44| Header | Reason |
45|--------|--------|
46| `Cookie` | State tracking |
47| `Authorization` | Implies authenticated content |
48| `DNT` | Unnecessary - tracking is minimized by design |
49| `X-Requested-With` | AJAX patterns not applicable |
50| Any `X-` header | Custom headers are a slippery slope |
51
52Compliant clients MUST use only these methods:
53
54- `GET` - Retrieve a document
55- `HEAD` - Check if a document exists or has changed
56
57All other methods (`POST`, `PUT`, `DELETE`, etc.) are non-compliant.
58
59### 2.1 Query Strings
60
61Query strings are PERMITTED but SHOULD be limited to:
62
63- Pagination (`?page=2`)
64
65Query strings MUST NOT be used for:
66
67- Session tracking
68- User identification
69- Analytics parameters (utm_*, fbclid, etc.)
70
71Compliant servers SHOULD ignore or strip unrecognized query parameters.
72
73---
74
75## 3. Response Constraints
76
77### 3.1 Forbidden Response Headers
78
79Compliant servers MUST NOT send:
80
81| Header | Reason |
82|--------|--------|
83| `Set-Cookie` | State tracking |
84| `WWW-Authenticate` | Implies auth-gated content |
85| `Content-Security-Policy` | Implies executable content to policy |
86| `X-Frame-Options` | Embedding restrictions suggest app behavior |
87| `Refresh` | Client-side redirects enable tracking |
88
89### 3.2 Permitted Response Headers
90
91Servers SHOULD send:
92
93| Header | Purpose |
94|--------|---------|
95| `Content-Type` | Required (`text/markdown; charset=utf-8`) |
96| `Content-Length` | Required for HTTP/1.1 |
97| `Last-Modified` | Caching |
98| `ETag` | Caching |
99| `Cache-Control` | Caching (SHOULD be generous; `max-age=3600` or higher) |
100| `Link` | Discovery (see Section 6) |
101
102### 3.3 Status Codes
103
104Compliant servers SHOULD limit responses to:
105
106| Code | Meaning |
107|------|---------|
108| `200` | OK |
109| `301` | Moved Permanently |
110| `304` | Not Modified |
111| `400` | Bad Request |
112| `404` | Not Found |
113| `410` | Gone (content deliberately removed) |
114| `500` | Server Error |
115
116Codes `302`, `303`, and `307` are NOT RECOMMENDED as they enable tracking redirects.
117
118---
119
120## 4. Content Format
121
122HTTP/Minimal uses **Markdown** as its content format, served with Content-Type `text/markdown; charset=utf-8`.
123
124### 4.1 Markdown Variant
125
126HTTP/Minimal uses [CommonMark](https://commonmark.org/) as the base specification, with the following extensions PERMITTED:
127
128- **Tables** - GitHub Flavored Markdown (GFM) pipe tables
129- **Strikethrough** - `~~text~~`
130- **Autolinks** - GFM automatic URL linking
131- **Footnotes** - `[^1]` reference-style footnotes
132
133### 4.2 Permitted Syntax
134
135All standard CommonMark elements:
136
137- Headings (`#`, `##`, etc.)
138- Paragraphs
139- Emphasis (`*italic*`, `**bold**`)
140- Links (`[text](url)` or `[text][ref]`)
141- Images (``)
142- Blockquotes (`>`)
143- Code spans (`` `code` ``)
144- Code blocks (fenced or indented)
145- Lists (ordered and unordered)
146- Horizontal rules (`---`)
147- Hard line breaks
148
149### 4.3 Forbidden Syntax
150
151The following MUST NOT appear in HTTP/Minimal documents:
152
153| Syntax | Reason |
154|--------|--------|
155| Raw HTML blocks | Enables script injection, tracking pixels, forms |
156| Raw HTML inline | Same |
157| `<script>` | No JavaScript |
158| `<iframe>` | Embedded third-party content |
159| `<form>` | Data collection |
160| `<img>` with tracking URLs | Use Markdown image syntax with compliant URLs |
161
162Clients MUST strip or ignore any raw HTML encountered in Markdown source.
163
164### 4.4 Image Requirements
165
166Images referenced via `` syntax:
167
168- MUST include alt text (the `[alt]` portion MUST NOT be empty)
169- SHOULD be same-origin or from trusted, non-tracking sources
170- MUST NOT be 1x1 tracking pixels
171
172### 4.5 Link Requirements
173
174Links are unrestricted in destination -HTTP/Minimal documents MAY link to any URL.
175
176Clients MAY warn users when following links to non-compliant origins.
177
178#### 4.5.1 URL Fragments
179
180URL fragments (`#section-name`) are supported and SHOULD work as follows:
181
182- When rendering Markdown to HTML, headings SHOULD receive auto-generated `id` attributes based on their text (lowercase, spaces replaced with hyphens)
183- Clients receiving `text/markdown` SHOULD scroll to the heading matching the fragment
184- Fragment matching SHOULD be case-insensitive
185
186For example, `## My Section` would be reachable via `#my-section`.
187
188### 4.6 Metadata
189
190Document metadata SHOULD be provided via a YAML front matter block:
191
192```markdown
193---
194title: My Document
195author: Jane Doe
196date: 2025-12-27
197lang: en
198---
199
200# My Document
201
202Content begins here.
203```
204
205Recognized front matter fields:
206
207| Field | Required | Description |
208|-------|----------|-------------|
209| `title` | RECOMMENDED | Document title |
210| `author` | No | Author name or identifier |
211| `date` | No | Publication date (ISO 8601) |
212| `lang` | No | Language code (BCP 47) |
213| `license` | No | Content license (SPDX identifier or URL) |
214
215Clients SHOULD use `title` for window/tab titles and `lang` for text rendering.
216
217---
218
219## 5. Client Rendering
220
221### 5.1 Dedicated Clients
222
223HTTP/Minimal clients SHOULD:
224
2251. Parse Markdown and render to styled, readable output
2262. Apply a legible default stylesheet (user-configurable)
2273. Strip any raw HTML before rendering
2284. Display images inline with alt text fallback
2295. Make links clearly navigable
230
231### 5.2 Browser Rendering
232
233Standard browsers receiving `text/markdown` will typically display raw source. Options for browser compatibility:
234
235**Option A: Server-side rendering**
236
237Servers MAY content-negotiate and serve pre-rendered HTML to browsers:
238
239- Request with `Accept: text/markdown` → serve Markdown
240- Request with `Accept: text/html` → serve HTML rendering
241
242The HTML rendering MUST be a direct transformation of the Markdown source with no additions (no scripts, no tracking, no analytics).
243
244**Option B: Client-side rendering via browser extension**
245
246Browser extensions may render `text/markdown` responses directly.
247
248**Option C: Raw display**
249
250Markdown is human-readable as source. No rendering required.
251
252### 5.3 Suggested Default Styles
253
254Clients SHOULD apply sensible typographic defaults:
255
256- Readable font (system serif or sans-serif)
257- Comfortable line length (45-75 characters)
258- Adequate line height (1.4-1.6)
259- Responsive viewport handling
260- Respect user preferences (dark mode, font size)
261
262---
263
264## 6. Discovery and Verification
265
266### 6.1 Well-Known Endpoint
267
268Compliant servers SHOULD serve a policy document at:
269
270```
271/.well-known/http-minimal
272```
273
274This document is a JSON object:
275
276```json
277{
278 "http_minimal": "0.1",
279 "compliant": true,
280 "scope": "/",
281 "contact": "mailto:admin@example.com",
282 "validator": "https://example.com/validation-report.json"
283}
284```
285
286| Field | Required | Description |
287|-------|----------|-------------|
288| `http_minimal` | Yes | Spec version |
289| `compliant` | Yes | Self-attestation |
290| `scope` | No | Path prefix this policy applies to (default: entire origin) |
291| `contact` | No | Maintainer contact |
292| `validator` | No | URL to a third-party validation report |
293
294### 6.2 Link Header
295
296Responses MAY include:
297
298```
299Link: </.well-known/http-minimal>; rel="profile"
300```
301
302### 6.3 Compliance Badge (Optional)
303
304Documents MAY include a compliance indicator:
305
306```markdown
307---
308[HTTP/Minimal Compliant](/.well-known/http-minimal)
309```
310
311---
312
313## 7. Example Document
314
315```markdown
316---
317title: Welcome to HTTP/Minimal
318author: Jane Doe
319date: 2025-12-27
320lang: en
321---
322
323# Welcome to HTTP/Minimal
324
325This is a document served over **HTTP/Minimal** - a constrained version of
326HTTPS for human-readable content without tracking, scripts, or manipulation.
327
328## What is this?
329
330HTTP/Minimal is not a new protocol. It's a voluntary restriction on how
331HTTP is used:
332
333- HTTPS only, no exceptions
334- No cookies or authentication headers
335- No JavaScript, ever
336- Content is Markdown, not HTML
337
338## Why Markdown?
339
340Markdown is:
341
3421. Human-readable as source
3432. Human-writable without tooling
3443. Transparent - tracking pixels are visible in source and enforceable by clients
3454. Universally supported
346
347## Learn More
348
349Read the full [specification](/spec) or view the
350[source for this page](/source/index.md).
351
352---
353
354*[HTTP/Minimal Compliant](/.well-known/http-minimal)*
355```
356
357---
358
359## 8. Relationship to Other Specifications
360
361### Gemini Protocol
362
363HTTP/Minimal shares philosophical goals with Gemini (simplicity, anti-tracking, anti-JavaScript) but differs in approach:
364
365| Aspect | Gemini | HTTP/Minimal |
366|--------|--------|--------------|
367| Transport | New protocol (gemini://) | HTTPS |
368| Content format | text/gemini | text/markdown |
369| Browser support | Requires dedicated client | Works with extensions or server-side rendering |
370| Port | 1965 | 443 |
371
372### Gemtext vs Markdown
373
374Gemini'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.
375
376### Semantic Web / Microformats
377
378HTTP/Minimal Markdown documents can include semantic meaning via:
379
380- Structured YAML front matter
381- Consistent heading hierarchies
382- Machine-parseable date/author metadata
383
384---
385
386## 9. Security Considerations
387
388- **No cookies** eliminates CSRF and session hijacking vectors
389- **No JavaScript** eliminates XSS entirely
390- **No forms** eliminates CSRF for data submission
391- **No raw HTML** prevents injection attacks
392- **HTTPS required** ensures transport security
393
394Remaining vectors:
395
396- **Malicious links** - users may still be linked to harmful external sites
397- **Image-based tracking** - external images can still leak requests; clients MAY block third-party images
398- **Cache timing** - sophisticated attackers may infer browsing history via cache timing; out of scope
399
400---
401
402## 10. Future Considerations
403
404Items explicitly deferred for future versions:
405
406- **Signed content** - integration with Signed HTTP Exchanges or content-addressed storage
407- **Content addressing** - integration with IPFS, AT Protocol, or content-hash URLs
408- **Client certificates** - Gemini-style TOFU identity without cookies
409- **Extended metadata** - richer front matter schemas (JSON-LD, etc.)
410- **Media embedding** - whether/how to handle audio and video
411
412---
413
414## Appendix A: Validator Pseudocode
415
416```python
417def validate_response(response):
418 errors = []
419
420 # Check forbidden response headers
421 forbidden = ['set-cookie', 'www-authenticate', 'refresh']
422 for header in forbidden:
423 if header in response.headers:
424 errors.append(f"Forbidden header: {header}")
425
426 # Check content type
427 content_type = response.headers.get('content-type', '')
428 if not content_type.startswith('text/markdown'):
429 errors.append("Content-Type must be text/markdown")
430
431 # Parse Markdown
432 doc = parse_markdown(response.body)
433
434 # Check for raw HTML
435 if contains_raw_html(doc):
436 errors.append("Raw HTML is forbidden")
437
438 # Check images have alt text
439 for image in doc.images:
440 if not image.alt:
441 errors.append(f"Image missing alt text: {image.url}")
442
443 return errors
444```
445
446---
447
448## Appendix B: Content-Type Registration
449
450This specification uses `text/markdown` as defined in [RFC 7763](https://datatracker.ietf.org/doc/html/rfc7763).
451
452Recommended Content-Type header:
453
454```
455Content-Type: text/markdown; charset=utf-8; variant=CommonMark
456```
457
458---
459
460## Appendix C: Migration Checklist
461
462For existing sites adopting HTTP/Minimal:
463
464- [ ] Enable HTTPS if not already
465- [ ] Convert content to Markdown (or add Markdown alongside HTML)
466- [ ] Configure server to serve `.md` files as `text/markdown`
467- [ ] Remove all analytics (Google Analytics, Plausible, etc.)
468- [ ] Remove comment systems or link to external discussion
469- [ ] Ensure all images have alt text
470- [ ] Ensure no raw HTML in Markdown source
471- [ ] Add `/.well-known/http-minimal` endpoint
472- [ ] Run validator against all documents
473- [ ] Optional: implement content negotiation for HTML clients
474
475---
476
477## Appendix D: Server Configuration Examples
478
479### Nginx
480
481```nginx
482location ~ \.md$ {
483 types { text/markdown md; }
484 charset utf-8;
485 add_header Link '</.well-known/http-minimal>; rel="profile"';
486
487 # Remove forbidden headers (shouldn't exist, but defensive)
488 proxy_hide_header Set-Cookie;
489 proxy_hide_header WWW-Authenticate;
490}
491```
492
493### Caddy
494
495```caddyfile
496@markdown path *.md
497header @markdown Content-Type "text/markdown; charset=utf-8"
498header @markdown Link "</.well-known/http-minimal>; rel=\"profile\""
499header @markdown -Set-Cookie
500```
501
502### Static file server (Go)
503
504```go
505http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
506 if r.Method != "GET" && r.Method != "HEAD" {
507 http.Error(w, "Method not allowed", 405)
508 return
509 }
510
511 if strings.HasSuffix(r.URL.Path, ".md") {
512 w.Header().Set("Content-Type", "text/markdown; charset=utf-8")
513 w.Header().Set("Link", "</.well-known/http-minimal>; rel=\"profile\"")
514 }
515
516 http.FileServer(http.Dir("./public")).ServeHTTP(w, r)
517})
518```
519
520---
521
522## Acknowledgments
523
524This specification draws inspiration from:
525
526- **[Gemini Protocol](https://geminiprotocol.net/)** - for proving that radical simplicity has an audience
527- **["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
528- **[CommonMark](https://commonmark.org/)** - for standardizing Markdown
529- **[The Web We Lost](https://www.anildash.com/2012/12/13/the-web-we-lost/)** - Anil Dash's 2012 essay on web degradation
530- **[Motherfucking Website](https://motherfuckingwebsite.com/)** - satirical proof that content needs nothing else
531- **[IndieWeb](https://indieweb.org/)** - for keeping personal publishing alive
532
533---
534
535## License
536
537This specification is released under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) - no rights reserved. Use it, fork it, improve it.