Prefix all SX URLs with /sx/ for WhatsApp-safe sharing

All routes moved under /sx/ prefix:
- / redirects to /sx/
- /sx/ serves home page
- /sx/<path:expr> is the catch-all for SX expression URLs
- Bare /(...) and /~... redirect to /sx/(...) and /sx/~...
- All ~600 hrefs, sx-get attrs, defhandler paths, redirect
  targets, and blueprint routes updated across 44 files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 19:07:09 +00:00
parent acd2fa6541
commit de80d921e9
44 changed files with 701 additions and 687 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@
(p :class "text-stone-600"
"The property these systems lack has a name: " (a :href "https://en.wikipedia.org/wiki/Reflection_(computer_programming)" :class "text-violet-600 hover:underline" "reflexivity") ". A reflexive system can represent itself, reason about its own structure, and modify itself based on that reasoning. " (a :href "https://en.wikipedia.org/wiki/Lisp_(programming_language)" :class "text-violet-600 hover:underline" "Lisp") " has had this property " (a :href "https://en.wikipedia.org/wiki/Lisp_(programming_language)#History" :class "text-violet-600 hover:underline" "since 1958") ". The web has never had it.")
(p :class "text-stone-600"
"SX is a complete Lisp. It has " (a :href "https://en.wikipedia.org/wiki/Homoiconicity" :class "text-violet-600 hover:underline" "homoiconicity") " — code is data, data is code. It has a " (a :href "/(language.(spec.core))" :class "text-violet-600 hover:underline" "self-hosting specification") " — SX defined in SX. It has " (code "eval") " and " (code "quote") " and " (a :href "https://en.wikipedia.org/wiki/Macro_(computer_science)#Syntactic_macros" :class "text-violet-600 hover:underline" "macros") ". And it runs on the wire — the format that travels between server and client IS the language. This combination has consequences."))
"SX is a complete Lisp. It has " (a :href "https://en.wikipedia.org/wiki/Homoiconicity" :class "text-violet-600 hover:underline" "homoiconicity") " — code is data, data is code. It has a " (a :href "/sx/(language.(spec.core))" :class "text-violet-600 hover:underline" "self-hosting specification") " — SX defined in SX. It has " (code "eval") " and " (code "quote") " and " (a :href "https://en.wikipedia.org/wiki/Macro_(computer_science)#Syntactic_macros" :class "text-violet-600 hover:underline" "macros") ". And it runs on the wire — the format that travels between server and client IS the language. This combination has consequences."))
(~doc-section :title "What homoiconicity changes" :id "homoiconicity"
(p :class "text-stone-600"
@@ -27,7 +27,7 @@
(p :class "text-stone-600"
"In an SX web, the AI reads the same s-expressions the browser reads. The component definitions " (em "are") " the documentation — a " (code "defcomp") " declares its parameters, its structure, and its semantics in one expression. There is no " (a :href "https://en.wikipedia.org/wiki/OpenAPI_Specification" :class "text-violet-600 hover:underline" "Swagger spec") " describing an API. The API " (em "is") " the language, and the language is self-describing.")
(p :class "text-stone-600"
"An AI that understands SX understands the " (a :href "/(language.(spec.core))" :class "text-violet-600 hover:underline" "spec") ". And the spec is written in SX. So the AI understands the definition of the language it is using, in the language it is using. This " (a :href "https://en.wikipedia.org/wiki/Reflexivity_(social_theory)" :class "text-violet-600 hover:underline" "reflexive") " property means the AI does not need a separate mental model for \"the web\" and \"the language\" — they are the same thing."))
"An AI that understands SX understands the " (a :href "/sx/(language.(spec.core))" :class "text-violet-600 hover:underline" "spec") ". And the spec is written in SX. So the AI understands the definition of the language it is using, in the language it is using. This " (a :href "https://en.wikipedia.org/wiki/Reflexivity_(social_theory)" :class "text-violet-600 hover:underline" "reflexive") " property means the AI does not need a separate mental model for \"the web\" and \"the language\" — they are the same thing."))
(~doc-section :title "Live system modification" :id "live-modification"
(p :class "text-stone-600"
@@ -51,7 +51,7 @@
(p :class "text-stone-600"
"A macro is a function that takes code and returns code. An AI generating macros is writing programs that write programs. With " (code "eval") ", those generated programs can generate more programs at runtime. This is not a metaphor — it is the literal mechanism.")
(p :class "text-stone-600"
"The " (a :href "/(etc.(philosophy.godel-escher-bach))" :class "text-violet-600 hover:underline" "Gödel numbering") " parallel is not incidental. " (a :href "https://en.wikipedia.org/wiki/Kurt_G%C3%B6del" :class "text-violet-600 hover:underline" "Gödel") " showed that any sufficiently powerful formal system can encode statements about itself. A complete Lisp on the wire is a sufficiently powerful formal system. The web can make statements about itself — components that inspect other components, macros that rewrite the page structure, expressions that generate new expressions based on the current state of the system.")
"The " (a :href "/sx/(etc.(philosophy.godel-escher-bach))" :class "text-violet-600 hover:underline" "Gödel numbering") " parallel is not incidental. " (a :href "https://en.wikipedia.org/wiki/Kurt_G%C3%B6del" :class "text-violet-600 hover:underline" "Gödel") " showed that any sufficiently powerful formal system can encode statements about itself. A complete Lisp on the wire is a sufficiently powerful formal system. The web can make statements about itself — components that inspect other components, macros that rewrite the page structure, expressions that generate new expressions based on the current state of the system.")
(p :class "text-stone-600"
"Consider what this enables for AI:")
(ul :class "space-y-2 text-stone-600 mt-2"
@@ -63,7 +63,7 @@
(p :class "text-stone-600"
"The same " (a :href "https://en.wikipedia.org/wiki/Homoiconicity" :class "text-violet-600 hover:underline" "homoiconicity") " that makes this powerful makes it dangerous. Code-as-data means an AI can inject " (em "behaviour") ", not just content. A malicious expression evaluated in the wrong context could exfiltrate data, modify other components, or disrupt the system.")
(p :class "text-stone-600"
"This is why the " (a :href "/(language.(spec.primitives))" :class "text-violet-600 hover:underline" "primitive set") " is the critical security boundary. The spec defines exactly which operations are available. A sandboxed evaluator that only exposes pure primitives (arithmetic, string operations, list manipulation) cannot perform I/O. Cannot access the network. Cannot modify the DOM outside its designated target. The language is " (a :href "https://en.wikipedia.org/wiki/Turing_completeness" :class "text-violet-600 hover:underline" "Turing-complete") " within the sandbox and powerless outside it.")
"This is why the " (a :href "/sx/(language.(spec.primitives))" :class "text-violet-600 hover:underline" "primitive set") " is the critical security boundary. The spec defines exactly which operations are available. A sandboxed evaluator that only exposes pure primitives (arithmetic, string operations, list manipulation) cannot perform I/O. Cannot access the network. Cannot modify the DOM outside its designated target. The language is " (a :href "https://en.wikipedia.org/wiki/Turing_completeness" :class "text-violet-600 hover:underline" "Turing-complete") " within the sandbox and powerless outside it.")
(p :class "text-stone-600"
"Different contexts grant different primitive sets. A component evaluated in a page slot gets rendering primitives. A macro gets code-transformation primitives. A federated expression from an untrusted node gets the minimal safe set. The sandbox is not bolted on — it is inherent in the language's architecture. What you can do depends on which primitives are in scope.")
(p :class "text-stone-600"

View File

@@ -37,11 +37,11 @@
(p :class "text-stone-600"
"In SX, this is literal:")
(ul :class "space-y-2 text-stone-600 mt-2"
(li (strong "A URL is an s-expression.") " " (code "/(language.(doc.introduction))") " is not an opaque string — it is a parseable, composable expression. It can be decomposed into parts, transformed by functions, and reasoned about by the same evaluator that renders pages.")
(li (strong "A URL is an s-expression.") " " (code "/sx/(language.(doc.introduction))") " is not an opaque string — it is a parseable, composable expression. It can be decomposed into parts, transformed by functions, and reasoned about by the same evaluator that renders pages.")
(li (strong "A response is an s-expression.") " What the server sends is " (code "(div :class \"p-4\" (h2 \"Hello\"))") " — the same notation as the component that produced it. The wire format is the language.")
(li (strong "A component is an s-expression.") " " (code "(defcomp ~card (&key title) (div (h2 title)))") " is simultaneously a definition, a value, and data that can be inspected and transformed.")
(li (strong "A query is an s-expression.") " The URL " (code "/(language.(spec.core))") " is a function call. The response is the return value. Routing is evaluation.")
(li (strong "The specification is s-expressions.") " The " (a :href "/(language.(spec.core))" :class "text-violet-600 hover:underline" "SX spec") " is written in SX. The evaluator is defined in the language it evaluates. The parser is defined in the language it parses."))
(li (strong "A query is an s-expression.") " The URL " (code "/sx/(language.(spec.core))") " is a function call. The response is the return value. Routing is evaluation.")
(li (strong "The specification is s-expressions.") " The " (a :href "/sx/(language.(spec.core))" :class "text-violet-600 hover:underline" "SX spec") " is written in SX. The evaluator is defined in the language it evaluates. The parser is defined in the language it parses."))
(p :class "text-stone-600"
"There is " (em "one") " kind of stuff. Everything is made of it. The address of a thing and the thing itself are the same kind of thing."))
@@ -50,19 +50,19 @@
"When the medium is uniform, operations that were impossible become trivial:")
(ul :class "space-y-3 text-stone-600 mt-2"
(li (strong "URLs compose.") " If " (code "(language (doc introduction))") " and " (code "(language (spec core))") " are both expressions, then " (code "(diff (language (spec signals)) (language (spec eval)))") " is a natural composition. Two queries, side by side. The URL algebra falls out of the expression algebra. You do not need to design it separately — it was always there.")
(li (strong "The site can show its own source.") " " (code "/(source.(~essay-self-defining-medium))") " returns the component definition of this essay. Not a screenshot. Not a prettified view. The actual s-expression that, when evaluated, produces what you are reading now. The page and its source code are the same kind of thing, so displaying one as the other is just evaluation.")
(li (strong "The spec is executable documentation.") " The " (a :href "/(language.(bootstrapper.self-hosting))" :class "text-violet-600 hover:underline" "self-hosting bootstrapper") " reads the SX spec (written in SX) and produces a working evaluator. The documentation is the implementation. The implementation is the documentation. There is no drift because there is no gap.")
(li (strong "Inspection is free.") " " (code "/(inspect.(language.(doc.primitives)))") " can show the dependency graph, CSS footprint, and render plan of any page — because the page is data, and data can be walked, analysed, and reported on by the same system that renders it.")
(li (strong "The site can show its own source.") " " (code "/sx/(source.(~essay-self-defining-medium))") " returns the component definition of this essay. Not a screenshot. Not a prettified view. The actual s-expression that, when evaluated, produces what you are reading now. The page and its source code are the same kind of thing, so displaying one as the other is just evaluation.")
(li (strong "The spec is executable documentation.") " The " (a :href "/sx/(language.(bootstrapper.self-hosting))" :class "text-violet-600 hover:underline" "self-hosting bootstrapper") " reads the SX spec (written in SX) and produces a working evaluator. The documentation is the implementation. The implementation is the documentation. There is no drift because there is no gap.")
(li (strong "Inspection is free.") " " (code "/sx/(inspect.(language.(doc.primitives)))") " can show the dependency graph, CSS footprint, and render plan of any page — because the page is data, and data can be walked, analysed, and reported on by the same system that renders it.")
(li (strong "AI is a native speaker.") " An AI reading SX reads the same notation as the server, the client, the wire, and the spec. There is no translation layer. The AI does not generate code that must be compiled and deployed — it generates expressions that are evaluated. The medium is shared between human, machine, and network.")))
(~doc-section :title "The metacircular web" :id "metacircular-web"
(p :class "text-stone-600"
"McCarthy's " (a :href "https://en.wikipedia.org/wiki/Lisp_(programming_language)#Connection_to_artificial_intelligence" :class "text-violet-600 hover:underline" "metacircular evaluator") " proved that a computing language can define itself. SX extends this proof to a networked hypermedium:")
(ul :class "space-y-2 text-stone-600 mt-2"
(li "The " (strong "evaluator") " is defined in SX: " (a :href "/(language.(spec.eval))" :class "text-violet-600 hover:underline" "eval.sx") " specifies the evaluation rules for all expression types, and this specification is itself an SX document.")
(li "The " (strong "parser") " is defined in SX: " (a :href "/(language.(spec.parser))" :class "text-violet-600 hover:underline" "parser.sx") " specifies tokenization, grammar, and serialization — written in the language it parses.")
(li "The " (strong "renderer") " is defined in SX: " (a :href "/(language.(spec.render))" :class "text-violet-600 hover:underline" "render.sx") " specifies how s-expressions become HTML, SX wire format, or DOM nodes.")
(li "The " (strong "router") " is an expression: " (code "/(language.(doc.introduction))") " is a function call that resolves to content. " (a :href "/(language.(spec.router))" :class "text-violet-600 hover:underline" "router.sx") " specifies the matching — in SX.")
(li "The " (strong "evaluator") " is defined in SX: " (a :href "/sx/(language.(spec.eval))" :class "text-violet-600 hover:underline" "eval.sx") " specifies the evaluation rules for all expression types, and this specification is itself an SX document.")
(li "The " (strong "parser") " is defined in SX: " (a :href "/sx/(language.(spec.parser))" :class "text-violet-600 hover:underline" "parser.sx") " specifies tokenization, grammar, and serialization — written in the language it parses.")
(li "The " (strong "renderer") " is defined in SX: " (a :href "/sx/(language.(spec.render))" :class "text-violet-600 hover:underline" "render.sx") " specifies how s-expressions become HTML, SX wire format, or DOM nodes.")
(li "The " (strong "router") " is an expression: " (code "/sx/(language.(doc.introduction))") " is a function call that resolves to content. " (a :href "/sx/(language.(spec.router))" :class "text-violet-600 hover:underline" "router.sx") " specifies the matching — in SX.")
(li "The " (strong "site itself") " is s-expressions: this essay, the navigation tree, the component registry, the wire protocol — all the way down."))
(p :class "text-stone-600"
"At every level, the description and the described are the same kind of thing. The specification is not " (em "about") " the system — it " (em "is") " the system. This is not metaphor. It is the literal architecture."))

View File

@@ -36,7 +36,7 @@
(p :class "text-stone-600"
"This makes it trivial to build AI pipelines that generate SX. Parse the output. If it parses, evaluate it in a sandbox. If it does not parse, the error is always the same kind — unmatched parentheses — and the fix is always mechanical. There is no \"your JSX is invalid because you used " (code "class") " instead of " (code "className") "\" or \"you forgot the semicolon after the type annotation but before the generic constraint.\"")
(p :class "text-stone-600"
"Beyond parsing, the SX " (a :href "/(language.(spec.primitives))" :class "text-violet-600 hover:underline" "boundary system") " provides semantic validation. A pure component cannot call IO primitives — not by convention, but by the evaluator refusing to resolve them. An AI generating a component can produce whatever expressions it wants; the sandbox ensures only permitted operations execute. Validation is not a separate step bolted onto the pipeline. It is the language."))
"Beyond parsing, the SX " (a :href "/sx/(language.(spec.primitives))" :class "text-violet-600 hover:underline" "boundary system") " provides semantic validation. A pure component cannot call IO primitives — not by convention, but by the evaluator refusing to resolve them. An AI generating a component can produce whatever expressions it wants; the sandbox ensures only permitted operations execute. Validation is not a separate step bolted onto the pipeline. It is the language."))
(~doc-section :title "Components are self-documenting" :id "self-documenting"
(p :class "text-stone-600"
@@ -98,7 +98,7 @@
(p :class "text-stone-600"
"This is only possible because the representation is uniform. The AI does not need to switch between \"writing HTML mode\" and \"writing CSS mode\" and \"writing JavaScript mode\" and \"writing deployment config mode.\" It is always writing s-expressions. The cognitive load is constant. The error rate is constant. The speed is constant — regardless of whether it is generating a page layout, a macro expander, or a Docker healthcheck.")
(p :class "text-stone-600"
"The " (a :href "/(etc.(essay.sx-sucks))" :class "text-violet-600 hover:underline" "sx sucks") " essay copped to the AI authorship and framed it as a weakness — microwave dinner on a nice plate. But the framing was wrong. If a language is so well-suited to machine generation that one person with no Lisp experience can build a self-hosting language, a multi-target bootstrapper, a reactive component framework, and a full documentation site through pure agentic AI — that is not a weakness of the language. That is the language working exactly as it should."))
"The " (a :href "/sx/(etc.(essay.sx-sucks))" :class "text-violet-600 hover:underline" "sx sucks") " essay copped to the AI authorship and framed it as a weakness — microwave dinner on a nice plate. But the framing was wrong. If a language is so well-suited to machine generation that one person with no Lisp experience can build a self-hosting language, a multi-target bootstrapper, a reactive component framework, and a full documentation site through pure agentic AI — that is not a weakness of the language. That is the language working exactly as it should."))
(~doc-section :title "What this changes" :id "what-changes"
(p :class "text-stone-600"

File diff suppressed because one or more lines are too long

View File

@@ -127,7 +127,7 @@
(p :class "text-stone-600"
"Every page you are reading was produced through conversation with an agentic AI. The SX evaluator — a self-hosting interpreter with tail-call optimization, delimited continuations, macro expansion, and three rendering backends — was developed without opening a code editor. The specification files that define the language were written without an IDE. The bootstrappers that compile the spec to JavaScript and Python were produced without syntax highlighting or autocomplete. The test suite — hundreds of tests across evaluator, parser, renderer, router, dependency analyzer, and engine — was written without a test runner GUI. This documentation site — with its navigation, its code examples, its live demos — was built without a web development framework's CLI.")
(p :class "text-stone-600"
"The developer sat in a terminal. They described what they wanted. The AI produced the code. When something was wrong, they described what was wrong. The AI fixed it. When something needed to change, they described the change. The AI made the change. Across thousands of files, tens of thousands of lines of code, and months of development. Even the jokes — the " (a :href "/(etc.(essay.sx-sucks))" :class "text-violet-600 hover:underline" "self-deprecating essay") " about everything wrong with SX, the deadpan tone of the documentation, the essay you are reading right now — all produced through conversation, not through typing.")
"The developer sat in a terminal. They described what they wanted. The AI produced the code. When something was wrong, they described what was wrong. The AI fixed it. When something needed to change, they described the change. The AI made the change. Across thousands of files, tens of thousands of lines of code, and months of development. Even the jokes — the " (a :href "/sx/(etc.(essay.sx-sucks))" :class "text-violet-600 hover:underline" "self-deprecating essay") " about everything wrong with SX, the deadpan tone of the documentation, the essay you are reading right now — all produced through conversation, not through typing.")
(p :class "text-stone-600"
"No build step. No bundler. No transpiler. No package manager. No CSS preprocessor. No dev server. No linter. No formatter. No type checker. No framework CLI. No code editor.")
(p :class "text-stone-600"