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>
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>
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>
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>
Audit all plan files and create documentation pages for what remains:
- Status overview with green/amber/stone badges for all 15 plans
- Fragment Protocol: what exists (GET), what remains (POST sexp, structured response)
- Glue Decoupling: 25+ cross-app imports to eliminate via glue service layer
- Social Sharing: 6-phase OAuth-based sharing to major platforms
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wire async rendering into client-side routing: pages whose component
trees reference IO primitives (highlight, current-user, etc.) now
render client-side via Promise-aware asyncRenderToDom. IO calls proxy
through /sx/io/<name> endpoint, which falls back to page helpers.
- Add has-io flag to page registry entries (helpers.py)
- Remove IO purity filter — include IO-dependent components in bundles
- Extend try-client-route with 4 paths: pure, data, IO, data+IO
- Convert tryAsyncEvalContent to callback style, add platform mapping
- IO proxy falls back to page helpers (highlight works via proxy)
- Demo page: /isomorphism/async-io with inline highlight calls
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Client router uses first-match, so /isomorphism/data-test was matching
the /isomorphism/<slug> wildcard instead of the specific data-test route.
Moved bundle-analyzer, routing-analyzer, data-test before the wildcard.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spec layer (orchestration.sx):
- try-client-route now handles :data pages instead of falling back to server
- New abstract primitive resolve-page-data(name, params, callback) — platform
decides transport (HTTP, IPC, cache, etc)
- Extracted swap-rendered-content and resolve-route-target helpers
Platform layer (bootstrap_js.py):
- resolvePageData() browser implementation: fetches /sx/data/<name>, parses
SX response, calls callback. Other hosts provide their own transport.
Server layer (pages.py):
- evaluate_page_data() evaluates :data expr, serializes result as SX
- auto_mount_page_data() mounts /sx/data/ endpoint with per-page auth
- _build_pages_sx now computes component deps for all pages (not just pure)
Test page at /isomorphism/data-test exercises the full pipeline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three levels of ../ overshot from /app/sxc/pages/ to /. Use same
two-level pattern with /app/shared fallback as _read_spec_file.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4-phase design: server endpoint for on-demand component defs,
SX-specced client prefetch logic (hover/viewport triggers),
boundary declarations, and bootstrap integration.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tailwind's prose class applies dark backgrounds to pre/code elements,
overriding the intended bg-stone-100. Adding not-prose to every code
container div across docs, specs, and examples pages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Click a page row to expand its component bundle tree. Each component
shows pure/IO badge, IO refs, dep count. Click a component to expand
its full defcomp SX source. Uses <details>/<summary> for zero-JS
expand/collapse.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend the spec with IO scanning functions (scan-io-refs, transitive-io-refs,
compute-all-io-refs, component-pure?) that detect IO primitive references in
component ASTs. Components are classified as pure (no IO deps, safe for client
rendering) or IO-dependent (must expand server-side).
The partial evaluator (_aser) now uses per-component IO metadata instead of
the global _expand_components toggle: IO-dependent components expand server-
side, pure components serialize for client. Layout slot context still expands
all components for backwards compat.
Spec: 5 new functions + 2 platform interface additions in deps.sx
Host: io_refs field + is_pure property on Component, compute_all_io_refs()
Bootstrap: both sx_ref.py and sx-ref.js updated with IO functions
Bundle analyzer: shows pure/IO classification per page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move isomorphic architecture roadmap and bundle analyzer from Plans
into their own top-level "Isomorphism" section. The roadmap is the
default page at /isomorphism/, bundle analyzer at /isomorphism/bundle-analyzer.
Plans section retains reader macros and SX-Activity.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Demonstrates Phase 1 dep analysis in action: computes per-page component
bundles for all sx-docs pages using the deps.sx transitive closure
algorithm, showing needed vs total components with visual progress bars.
- New page at /plans/bundle-analyzer with Python data helper
- New components: ~bundle-analyzer-content, ~analyzer-stat, ~analyzer-row
- Linked from Phase 1 section and Plans nav
- Added sx/sx/ to tailwind content paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reader Macros: # dispatch for datum comments (#;), raw strings (#|...|),
and quote shorthand (#').
SX-Activity: ActivityPub federation with SX wire format, IPFS-backed
component registry, content-addressed media, Bitcoin-anchored provenance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New top-level nav section at /plans/ with the 6-phase isomorphic
architecture plan: component distribution, smart boundary, SPA routing,
client IO bridge, streaming suspense, and full isomorphism.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Parses special-forms.sx spec into categorized form cards with syntax,
description, tail-position info, and highlighted examples. Follows the
same pattern as the Primitives page: Python helper returns structured
data, .sx components render it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Optional bolt-on extensions to the SX spec. continuations.sx defines
delimited continuations for all targets. callcc.sx defines full call/cc
for targets where it's native (Scheme, Haskell). Shared continuation
type if both are loaded. Wired into specs section of sx-docs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the boundary enforcement model: three tiers, boundary types,
runtime validation, the SX-in-Python rule, and the multi-language story.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add boundary.sx declaring all 34 I/O primitives, 32 page helpers, and 9
allowed boundary types. Runtime validation in boundary.py checks every
registration against the spec — undeclared primitives/helpers crash at
startup with SX_BOUNDARY_STRICT=1 (now set in both dev and prod).
Key changes:
- Move 5 I/O-in-disguise primitives (app-url, asset-url, config,
jinja-global, relations-from) from primitives.py to primitives_io.py
- Remove duplicate url-for/route-prefix from primitives.py (already in IO)
- Fix parse-datetime to return ISO string instead of raw datetime
- Add datetime→isoformat conversion in _convert_result at the edge
- Wrap page helper return values with boundary type validation
- Replace all SxExpr(f"...") patterns with sx_call() or _sx_fragment()
- Add assert declaration to primitives.sx
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SX_STANDALONE=true env var: no OAuth, no root header, no cross-service
fragments. Same image runs in both rose-ash cooperative and standalone.
- Factory: added no_oauth parameter to create_base_app()
- Standalone layout defcomps skip ~root-header-auto/~root-mobile-auto
- Fixed Dockerfile: was missing sx/sx/ component directory copy
- CI: deploys sx-web swarm stack on main branch when sx changes
- Stack config at ~/sx-web/ (Caddy → sx_docs, Redis)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New Bootstrappers top-level section with overview index and JS bootstrapper
page that runs bootstrap_js.py and displays both source and generated output
with live script injection (full page load, not SX navigation)
- Essays section: index page with linked cards and summaries, sx-sucks moved
to end of nav, removed "grand tradition" line
- Specs: English prose descriptions alongside all canonical .sx specs, added
Boot/CSSX/Browser spec files to architecture page
- Layout: menu bar nav items wrap instead of overflow, baseline alignment
between label and nav options
- Homepage: added copyright line
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spec file registry (slugs, filenames, titles, descriptions) now lives in
nav-data.sx as SX data definitions. Python helper reduced to pure file I/O
(read-spec-file). Architecture page updated with engine/orchestration split
and dependency graph.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Architecture intro page explaining the spec's two-layer design
(core language + selectable adapters) with dependency graph
- Split specs into Core (parser, eval, primitives, render) and
Adapters (DOM, HTML, SX wire, SxEngine) overview pages
- Add individual detail pages for all adapter and engine specs
- Update nav with Architecture landing, Core, Adapters, and all
individual spec file links
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix highlight() returning SxExpr so syntax-highlighted code renders
as DOM elements instead of leaking SX source text into the page
- Add Specs section that reads and displays canonical SX spec files
from shared/sx/ref/ with syntax highlighting
- Add "The Reflexive Web" essay on SX becoming a complete LISP with
AI as native participant
- Change logo from (<x>) to (<sx>) everywhere
- Unify all backgrounds to bg-stone-100, center code blocks
- Skip component/style cookie cache in dev mode so .sx edits are
visible immediately on refresh without clearing localStorage
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _expand_components contextvar so _aser only expands components
during page slot evaluation (fixes highlight on examples, avoids
breaking fragment responses)
- Fix nth arg order (nth coll n) in docs.sx, examples.sx (delete-row,
edit-row, bulk-update)
- Add "Godel, Escher, Bach and SX" essay with Wikipedia links
- Update SX Manifesto: new authors, Wikipedia links throughout,
remove Marx/Engels link
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sx-headers attributes now use native SX dict format {:key val} instead of
JSON strings. Eliminates manual JSON string construction in both .sx files
and Python callers.
- sx.js: parse sx-headers/sx-vals as SX dict ({: prefix) with JSON fallback,
add _serializeDict for dict→attribute serialization, fix verbInfo scope in
_doFetch error handler
- html.py: serialize dict attribute values via SX serialize() not str()
- All .sx files: {:X-CSRFToken csrf} replaces (str "{\"X-CSRFToken\": ...}")
- All Python callers: {"X-CSRFToken": csrf} dict replaces f-string JSON
- Blog like: extract ~blog-like-toggle, fix POST returning wrong component,
fix emoji escapes in .sx (parser has no \U support), fix card :hx-headers
keyword mismatch, wrap sx_content in SxExpr for evaluation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nav data, section nav, example content, reference table builders, and
all slug dispatch now live in .sx files. Python helpers reduced to
data-only returns (highlight, primitives-data, reference-data,
attr-detail-data). Deleted essays.py and utils.py entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three issues fixed:
- async_eval_slot_to_sx (and async_eval_to_sx) was calling serialize()
on plain strings returned by page helpers, quoting them as literals
instead of treating them as sx source. Added str check to wrap
directly in SxExpr.
- _render_to_sx_with_env passed layout kwargs only as env free
variables, but _aser_component defaults all declared params to NIL
regardless of env. Now builds the AST with extra_env entries as
keyword args so they bind through normal param mechanism.
- _nav_items_sx returned plain str; changed to SxExpr so nav fragments
serialize unquoted when passed as layout kwargs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>