- "Zero-Tooling" → "Tools for Fools"
- "Separation of Concerns" → "Separate your Own Concerns"
- Bold "...and yet." after Carson Gross reference
- Add broken keyboard origin story
- Fix language list (never Lisp)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New essay arguing SX eliminates the entire conventional web toolchain
(bundlers, transpilers, package managers, CSS tools, dev servers, linters,
type checkers, framework CLIs) and that agentic AI replaces the code editor
itself. Links Carson Gross's "Yes, and..." essay with a Zen Buddhism framing
of the write→read→describe progression.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7c: Client data cache management via element attributes
(sx-cache-invalidate) and response headers (SX-Cache-Invalidate,
SX-Cache-Update). Programmatic API: invalidate-page-cache,
invalidate-all-page-cache, update-page-cache.
7d: Service Worker (sx-sw.js) with IndexedDB for offline-capable
data caching. Network-first for /sx/data/ and /sx/io/, stale-while-
revalidate for /static/. Cache invalidation propagates from
in-memory cache to SW via postMessage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Moved on-demand CSS delivery protocol from docs/css into /cssx/delivery,
framed as one strategy among several. Removed the CSSX Components plan
(now redundant with the top-level /cssx/ section).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New top-level section in sx-docs: /cssx/ with 6 pages:
- Overview: the idea, what changed, advantages
- Patterns: class mapping, data-driven, style functions, responsive, emitting CSS
- Async CSS: components that fetch/cache CSS before rendering via ~suspense
- Live Styles: SSE/WS examples for real-time style updates (noted as future)
- Comparisons: vs styled-components, CSS Modules, Tailwind, Vanilla Extract
- Philosophy: proof by deletion, the right abstraction level
Also:
- Remove CSSX from specs nav (spec file deleted)
- Fix renderer spec prose (no longer mentions StyleValue)
- Update On-Demand CSS essay summary
- Mark CSSX Components plan as done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
defpage is already portable: server executes via execute_page(),
client via try-client-route. Add render plan logging to client
routing so console shows boundary decisions on navigation:
"sx:route plan pagename — N server, M client"
Mark Phase 7 (Full Isomorphism) as complete:
- 7a: affinity annotations + render-target
- 7b: page render plans (boundary optimizer)
- 7e: cross-host isomorphic testing (61 tests)
- 7f: universal page descriptor + visibility
7c (optimistic updates) and 7d (offline data) remain as future work.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
61 tests evaluate the same SX expressions on both Python (sx_ref.py)
and JS (sx-browser.js via Node.js), comparing output:
- 37 eval tests (arithmetic, strings, collections, logic, HO forms)
- 24 render tests (elements, attrs, void elements, components, escaping)
All pass — both hosts produce identical results from the same spec.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add page-render-plan to deps.sx: given page source + env + IO names,
computes a dict mapping each needed component to "server" or "client",
with server/client lists and IO dep collection. 5 new spec tests.
Integration:
- PageDef.render_plan field caches the plan at registration
- compute_page_render_plans() called from auto_mount_pages()
- Client page registry includes :render-plan per page
- Affinity demo page shows per-page render plans
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The entire parallel CSS system (StyleValue type, style dictionary,
keyword atom resolver, content-addressed class generation, runtime
CSS injection, localStorage caching) was built but never adopted —
the codebase already uses :class strings with defcomp components
for all styling. Remove ~3,000 lines of unused infrastructure.
Deleted:
- cssx.sx spec module (317 lines)
- style_dict.py (782 lines) and style_resolver.py (254 lines)
- StyleValue type, defkeyframes special form, build-keyframes platform fn
- Style dict JSON delivery (<script type="text/sx-styles">), cookies, localStorage
- css/merge-styles primitives, inject-style-value, fnv1a-hash platform interface
Simplified:
- defstyle now binds any value (string, function) — no StyleValue type needed
- render-attrs no longer special-cases :style StyleValue → class conversion
- Boot sequence skips style dict init step
Preserved:
- tw.css parsing + CSS class delivery (SX-Css headers, <style id="sx-css">)
- All component infrastructure (defcomp, caching, bundling, deps)
- defstyle as a binding form for reusable class strings
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add :affinity :client/:server/:auto annotations to defcomp, with
render-target function combining affinity + IO analysis. Includes
spec (eval.sx, deps.sx), tests, Python evaluator, and demo page.
Fix critical bug: Python SX parser _ESCAPE_MAP was missing \r and \0,
causing bootstrapped JS parser to treat 'r' as whitespace — breaking
all client-side SX parsing. Also add \0 to JS string emitter and
fix serializer round-tripping for \r and \0.
Reserved word escaping: bootstrappers now auto-append _ to identifiers
colliding with JS/Python reserved words (e.g. default → default_,
final → final_), so the spec never needs to avoid host language keywords.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comparisons with styled-components, CSS Modules, Tailwind, Vanilla
Extract, and Design Tokens. Add example of components emitting <style>
blocks directly. Fix "CSS-agnostic" to "strategy-agnostic" — components
can generate CSS, not just reference existing classes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the existing CSSX plan with a component-based approach where styling
is handled by regular defcomp components that apply classes, respond to data,
and compose naturally — eliminating opaque hash-based class names.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Complete badge with live demo link to Phase 6 section
- Replace Verification with Demonstration + What to verify sections
- Update Files list: boot.sx spec, bootstrap_js.py, demo files
- Add streaming/suspense and client IO to Current State summary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Server streams HTML shell with ~suspense placeholders immediately,
then sends resolution <script> chunks as async IO completes. Browser
renders loading skeletons instantly, replacing them with real content
as data arrives via __sxResolve().
- defpage :stream true opts pages into streaming response
- ~suspense component renders fallback with data-suspense attr
- resolve-suspense in boot.sx (spec) + bootstrapped to sx-browser.js
- __sxPending queue handles resolution before sx-browser.js loads
- execute_page_streaming() async generator with concurrent IO tasks
- Streaming demo page at /isomorphism/streaming with 1.5s simulated delay
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SX parser counts \n inside string literals as line breaks, so the
parser's line numbers differ from file line numbers. The naive paren
counter was wrong — the original 8 closing parens was correct.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 5 was solved by IO proxy registration + async DOM renderer +
JavaScript Promises — no continuations needed on the client side.
Continuations remain a prerequisite for Phase 6 (server-side streaming).
Updated plan status: Phases 1-5 complete. Phase 4 moved from Partial.
Renumbered: streaming/suspense is now Phase 6, full iso is Phase 7.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pipeline definitions as .sx files evaluated by a minimal Python runner.
CI primitives (shell-run, docker-build, git-diff-files) are boundary-declared
IO, only available to the runner. Steps are defcomp components composable
by nesting. Fixes pre-existing unclosed parens in isomorphic roadmap section.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
read-spec-file is a server-only page helper. When the client router
tried to evaluate :content, it couldn't find the function. Move all
file reads into the :data expression (evaluated server-side) so
:content only references data bindings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New /testing/ section with 6 pages: overview (all specs), evaluator,
parser, router, renderer, and runners. Each page runs tests server-side
(Python) and offers a browser "Run tests" button (JS). Modular browser
runner (sxRunModularTests) loads framework + per-spec sources from DOM.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Systematic examination of XML, JSON, YAML, JSX, Tcl, Rebol, and Forth
against the six roles SX requires (markup, language, wire format, data
notation, spec language, metaprogramming). Comparison table across five
properties. Every candidate either fails requirements or converges
toward s-expressions under a different name.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The web's HTML/CSS/JS split separates the framework's concerns,
not the application domain's. Real separation of concerns is
domain-specific and cannot be prescribed by a platform.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Python evaluator runs test.sx at page load, results shown alongside
the browser runner. Both hosts prove the same 81 tests from the same
spec file — server on render, client on click.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SX testing SX is the strange loop made concrete — the language proves
its own correctness using its own macros. Links to /specs/testing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sx-browser.js evaluates test.sx directly in the browser — click
"Run 81 tests" to see SX test itself. Uses the same Sx global that
rendered the page.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
test.sx now defines deftest/defsuite as macros. Any host that provides
5 platform functions (try-call, report-pass, report-fail, push-suite,
pop-suite) can evaluate the file directly — no bootstrap compilation
step needed for JS.
- Added defmacro for deftest (wraps body in thunk, catches via try-call)
- Added defmacro for defsuite (push/pop suite context stack)
- Created run.js: sx-browser.js evaluates test.sx directly (81/81 pass)
- Created run.py: Python evaluator evaluates test.sx directly (81/81 pass)
- Deleted bootstrap_test_js.py and generated test_sx_spec.js
- Updated testing docs page to reflect self-executing architecture
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test framework is written in SX and tests SX — the language proves
its own correctness. test.sx defines assertion helpers (assert-equal,
assert-true, assert-type, etc.) and 15 test suites covering literals,
arithmetic, comparison, strings, lists, dicts, predicates, special forms,
lambdas, higher-order forms, components, macros, threading, truthiness,
and edge cases.
Two bootstrap compilers emit native tests from the same spec:
- bootstrap_test.py → pytest (81/81 pass)
- bootstrap_test_js.py → Node.js TAP using sx-browser.js (81/81 pass)
Also adds missing primitives to spec and Python evaluator: boolean?,
string-length, substring, string-contains?, upcase, downcase, reverse,
flatten, has-key?. Fixes number? to exclude booleans, append to
concatenate lists.
Includes testing docs page in SX app at /specs/testing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded IO primitive lists on both client and server with
data-driven registration. Page registry entries carry :io-deps (list
of IO primitive names) instead of :has-io boolean. Client registers
proxied IO on demand per page via registerIoDeps(). Server builds
allowlist from component analysis.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrote the closing sections to state plainly: every spec file, bootstrapper,
component, page, and deployment was produced through Claude in a terminal.
No VS Code, no vi, no prior Lisp. The proof that SX is AI-amenable is
that this site exists.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers syntax tax (zero for s-expressions), uniform representation,
spec fits in context window, trivial structural validation, self-documenting
components, token efficiency (~40% fewer than JSX), free composability,
and the instant feedback loop with no build step.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>