Document Jerboa site sync workflow
ober
689621839604f01dcdd629a601c9f8dc800e29d7
--- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ STATIC_XPATCH ?= $(JERBOA_HOME)/build/chez/xc-$(STATIC_TARGET_MACHINE)/s/xpatch STATIC_MUSL_CC ?= x86_64-linux-musl-gcc STATIC_OS_LIBS ?= -lm -ldl -lpthread -static -no-pie -lstdc++ -.PHONY: deps binary static-binary clean distclean +.PHONY: deps binary static-binary sync-jerboa clean distclean deps: $(MAKE) -C $(JERBOA_SINATRA) build @@ -33,6 +33,9 @@ static-binary: deps mkdir -p $(dir $(STATIC_BINARY_OUTPUT)) JERBOA_HOME="$(JERBOA_HOME)" $(JERBUILD) binary --static-native --cc "$(STATIC_MUSL_CC)" --rust-target "$(STATIC_RUST_TARGET)" --csv-dir "$(STATIC_CSV_DIR)" --xpatch "$(STATIC_XPATCH)" --os-libs "$(STATIC_OS_LIBS)" --libdirs "$(SINATRA_LIBDIR)" $(ENTRY) $(STATIC_BINARY_OUTPUT) +sync-jerboa: + tools/sync-jerboa --jerboa "$(JERBOA_HOME)" --write + clean: rm -rf build --- a/README.md +++ b/README.md @@ -2,6 +2,21 @@ Private jerboa.sh website content built with `jerboa-sinatra`. +## Source of Truth + +This repo owns the private site presentation and deployable web binary. +Canonical docs, examples, public assets, and machine-readable API or +feature data live in `~/mine/jerboa`. + +Sync the pinned Jerboa metadata snapshot with: + +```sh +make sync-jerboa +``` + +See [`docs/site-sync.md`](docs/site-sync.md) for the update workflow and +LLM-assisted documentation guardrails. + ## Build This repo keeps only the site entry point and content. It builds against the local framework checkout at `~/mine/jerboa-sinatra` by default. new file mode 100644 --- /dev/null +++ b/data/jerboa-source.json @@ -0,0 +1,149 @@ +{ + "schema": "jerboa.site-source.v1", + "repo": { + "path": "/Users/user/mine/jerboa", + "remote": "git@git.sr.ht:~lisp/jerboa", + "branch": "master", + "commit": "1cf9afb74a3d5da7ff9ee76e477dae2332364f74", + "version": "0.2.3", + "source_tree": "HEAD", + "working_tree_dirty": true + }, + "generated_at": "2026-06-19T21:47:35Z", + "site_contract": { + "human_docs": "docs/", + "machine_data": "data/", + "examples": "examples/", + "assets": "assets/" + }, + "canonical_sources": { + "docs": [ + {"path": "docs/Chez-changes.md", "sha256": "f8866866fe2eac24b969470b41c5e89ed63703b831b6c43ae37053dcae97facf", "bytes": 4500}, + {"path": "docs/Future-proofing.md", "sha256": "927b8f6ec50d338e570c90e0f1decf7cfd8847824646ceae6b3079910841a310", "bytes": 17232}, + {"path": "docs/JERBOA-LANG.md", "sha256": "60acc5ef32957b9e4608a65c237993e5699bcead31e570ad377175931573f49f", "bytes": 27440}, + {"path": "docs/Philosophy.md", "sha256": "8d388cb1162837f0a53311f71bcc4e98dbbd184832ca83c649f58b2170c70669", "bytes": 13970}, + {"path": "docs/actor-model.md", "sha256": "6a9e075ae78290dcf56b8038b47f530d7541f980e7cf9eccc52065bf4e4ea8f8", "bytes": 144631}, + {"path": "docs/ai-threat.md", "sha256": "528fe24f97745fa6589cd9b4e4aad6d649f9f24f4c2619103df2cb6a01f4799d", "bytes": 9587}, + {"path": "docs/anti-cookbook.md", "sha256": "c6fdbd78121ff4ee0b9f142b46ecfc0f5b07d62a7c7ced328620839fcd996701", "bytes": 9876}, + {"path": "docs/api-index.md", "sha256": "21516670e6c9433c5495c8191634999f53837a513fb9f10cb451cc30c8a87c18", "bytes": 710877}, + {"path": "docs/aproc.md", "sha256": "b872800394492c25b4fc5565b3b501daba95c5b69c3187dba30f39a7cfde8996", "bytes": 14247}, + {"path": "docs/architecture-split.md", "sha256": "f578a99486ed230e16a5efd24c39171078bf21c35af0eb5606c85f1e9834ebd2", "bytes": 9168}, + {"path": "docs/async.md", "sha256": "9ae56e12f9cb819e97f2a9417a57a15baf01b4e7a82e24522f51d381ad47252a", "bytes": 16426}, + {"path": "docs/build.md", "sha256": "482c11bba136154eef7565ab830e3664032f5a4452410a01d6d37e1ea2308490", "bytes": 18569}, + {"path": "docs/bundling-chez.md", "sha256": "39aeb7852d5ed9654d43f22ebfc88f40f13979f37566fe81eb18e5d44b49690e", "bytes": 8203}, + {"path": "docs/capability.md", "sha256": "1cc15b742a7a557f1833d2fd60f9ea96e2f6b7d999bb9e5887332b2e0829a368", "bytes": 15647}, + {"path": "docs/chez-fork.md", "sha256": "71b3dadb5df1a487f7eea7980aa3d8b4dd47931381a4ecea98da31b8d05807f2", "bytes": 5413}, + {"path": "docs/chez-gc-findings.md", "sha256": "c2561cfeca85fc99752d3b277ad764056ab4a13401270619ea8a2fd5b8fcf8b5", "bytes": 17378}, + {"path": "docs/chez-hardening.md", "sha256": "ab1660f1d0491fb5b32b7441f6e3b7d60a2decb2a5922882822d53df5098d7f7", "bytes": 21668}, + {"path": "docs/chez-limits.md", "sha256": "f34f7d0304ecbc97ed0970410a60de3ddb5d82f9a231c050d1d660530ef639e5", "bytes": 12635}, + {"path": "docs/clojure-vs-jerboa.md", "sha256": "8899f0f39cf7abb3bce70221f4b1955b908e6301475b527022f5d87b15b81c14", "bytes": 106638}, + {"path": "docs/compiling-gerbil-projects.md", "sha256": "d26ba7b07ae7cf2362cb2c81025140959fc0a02ac02b070ebd4bfc6f2395db07", "bytes": 12214}, + {"path": "docs/completion.md", "sha256": "8570b09216316c8431ed470613758fcc18e2e9a753fd9c23a02ffffd6ae8b6d9", "bytes": 15964}, + {"path": "docs/concurrency-extended.md", "sha256": "2e1b25d164bb1527a2d91db2a92bd1015fa8a61e8f5926d3e61d6e0dbad06932", "bytes": 20410}, + {"path": "docs/concurrency.md", "sha256": "46bb5891a0fb9563f69409333b563eb69e87c8f11f886323ee93bb7505b1e0e6", "bytes": 7091}, + {"path": "docs/contracts.md", "sha256": "3a347ad4b546d1b3516854efa59fbb14a306496dcc81b4b657d497686f4db3ce", "bytes": 13865}, + {"path": "docs/core-async.md", "sha256": "b82e8413a648578bf62ddc489e6afb44341cd96daadf564bf165930d2d39a934", "bytes": 34686}, + {"path": "docs/cp0-passes.md", "sha256": "903a2696d7b1cef0fe8cbbd96bb4a2b393813d0dbb59a2524113dde918b5f34c", "bytes": 5780}, + {"path": "docs/cross-compile.md", "sha256": "b8251cbe347ee0deb8d3fe80ec83513653de707bc0de4c0e6e68be9d19f31034", "bytes": 10227}, + {"path": "docs/data-structures.md", "sha256": "681c9e77f2f22b4803108892198a90f6ed171e38fb9757abd05a3865865cf23f", "bytes": 24145}, + {"path": "docs/devex.md", "sha256": "0145c797ad9e4a23160b81d35d9f6af55d9c518e0960e661691ea75abe78f128", "bytes": 7168}, + {"path": "docs/disassembly.md", "sha256": "1732617f8f965b90e1ed25639494f00be244added6765d277b4f4df8249ac967", "bytes": 11495}, + {"path": "docs/distributed.md", "sha256": "24e0142e4ce6f9b4498c444c92f8739bccd0b661a2826f5578d3774d3deb1a01", "bytes": 29049}, + {"path": "docs/divergence.md", "sha256": "995a4ce967b81468f1e81a222000949147167360fee59b308a74ed4c44f2eba3", "bytes": 41668}, + {"path": "docs/effects.md", "sha256": "bddd0732484bc9c7c7ea820bea3f9b1117c2f18e334339992255e95e64b30e13", "bytes": 23399}, + {"path": "docs/ffi.md", "sha256": "ed1408793c740aa3746f90b82087251492d7fc58c46fe26cd42e032bddb9904a", "bytes": 7455}, + {"path": "docs/fiber.md", "sha256": "9f62082caf1ccaf780aea611cb6bc7d90fb3ff22b7cbc10cd348cb7ec426d8e2", "bytes": 16242}, + {"path": "docs/finalizer-safety-net.md", "sha256": "0036c32bf19c2bc023318eb519556aabbf44f37dee1f625bce32093af06892eb", "bytes": 3007}, + {"path": "docs/gerbil-contracts.md", "sha256": "960764c09b0a7cf66b87224d3e4f46484268b4b8b933be8f70810da941ea2ce1", "bytes": 25456}, + {"path": "docs/gerbil-like.md", "sha256": "231cfb62b628d511bd768859e4600a0e39e2a0796bec01b9439080f98da89699", "bytes": 16316}, + {"path": "docs/green-wins.md", "sha256": "eb7d9e2cca2fdd89f3c65ada5789ede59a42bb4328a8971742444e8a23e2495a", "bytes": 18945}, + {"path": "docs/harden-usage.md", "sha256": "9d417190bb4533e6708b00eb186ca0694a61f1ac5a13ccd3257d984c91cb8466", "bytes": 15819}, + {"path": "docs/harden.md", "sha256": "a9451f3f8f3004a7a91eeb56ac838c4051cd830a2df420a41bd5518395e48ce9", "bytes": 23959}, + {"path": "docs/hide.md", "sha256": "9021dbbbfe5081dda3cda89478acc39add425de4cd9eaa0546a1be065378580e", "bytes": 24491}, + {"path": "docs/import-conflicts.md", "sha256": "608c581b1c4246fb6eb2ba05c60725347336e12340541ec9a7684d7e0c237eee", "bytes": 4955}, + {"path": "docs/index.md", "sha256": "c859b43f46dfbb9af761f8b7dfba21f11c5c2a73ec58fc8ae6b1a441368c62ae", "bytes": 9768}, + {"path": "docs/jerboa-code-typed-static-plan.md", "sha256": "e279b3a0d59a57c6bf72971910077a6b800d39331063b3c472f73590076ca065", "bytes": 9902}, + {"path": "docs/jerboa-db.md", "sha256": "8262d1272ab7e0384050e83d5508f15ab785059cf7f47504a64df767bcf09fd6", "bytes": 66395}, + {"path": "docs/jerboa-edge.md", "sha256": "2798ba6b8aabd2c73865a5dd9adb6f998c91303f214692cf6d21f9e33ae5c3d5", "bytes": 37373}, + {"path": "docs/jerboa-for-clojure-devs.md", "sha256": "abafe620f03e4c89975bdaab0dde22c26a1df8b4c9392ac13b7496960d0cde9d", "bytes": 16855}, + {"path": "docs/jerboa-on-jerboa-idiom.md", "sha256": "ec1e5d65efba9a8b128e0f308463c4eac396eef28f58449d791962a55bc9dd8f", "bytes": 9116}, + {"path": "docs/jerboa-on-jerboa.md", "sha256": "65550f8c737540aeda8187423b68d94ee167db317da6f229c67e54b2a62792ae", "bytes": 12065}, + {"path": "docs/jerboa-to-llvmir.md", "sha256": "d53c6f852a9e8de23f95cdd8c2431850e32585fef00e9cf79a1ee2a793331392", "bytes": 16756}, + {"path": "docs/jerboa-to-rust.md", "sha256": "d4b2ab445f9e98f449cfdffcfd4b3ab28082f6fa5aca16ea5956c71c3ddc703b", "bytes": 31844}, + {"path": "docs/jpkg-guide.md", "sha256": "2e2cbb29b2a078ddcb9bdf19f263e6011dc4a7f7594f7b36083f0093db86e591", "bytes": 19114}, + {"path": "docs/jpkg-migration.md", "sha256": "3a06019d9a1da9aeb750a3c2723274b4e966953b9f91578b149a537d8a80cb97", "bytes": 9434}, + {"path": "docs/jpkg-plan.md", "sha256": "9cbda6b05fc3512e1ccc957552d2a1d807e5d232177a0abbed0d387a8f40e54e", "bytes": 27492}, + {"path": "docs/libraries.md", "sha256": "5f7f38604019921fbe7bacab0ac9bfc7b9b5dbe922a54a70e9fb7a30a95932fa", "bytes": 9766}, + {"path": "docs/lightweight-concurrency.md", "sha256": "918e53054edd2fe8e3437ecfddb8f3618b00db87e97a74460786eeb85c905af9", "bytes": 11851}, + {"path": "docs/limits.md", "sha256": "f87754af6e106eded8f5bc88199c4f47ee0606c920f15db1a72a63e327c87afd", "bytes": 35713}, + {"path": "docs/llvmir-backend.md", "sha256": "1abcc2f6b00604ad7c98f9d6fa4c10dc71b4a7b79567b865fe7463d69ec14791", "bytes": 10615}, + {"path": "docs/llvmir-crypto-shim.md", "sha256": "ada3e2399d6e950afec04d437a414cb12db4464d8a0ddcfebde2f5b2abeab486", "bytes": 6591}, + {"path": "docs/llvmir-handoff.md", "sha256": "1ddc09506439a26b31f74ca81040d7e703b5a5051d847f0310966a56c0e76541", "bytes": 16827}, + {"path": "docs/mcp-advisor-plan.md", "sha256": "0bcac272d227151a8b220d43e9ce0144090768ff63dd83a53fe2a8d1422a1a11", "bytes": 9449}, + {"path": "docs/metaprogramming.md", "sha256": "2b429e7a9f7a6980f74440df97917fbff8a2bdbe3be19e79a8a97b01e48df011", "bytes": 22462}, + {"path": "docs/migration.md", "sha256": "5a71ee619a7e4ae0fd6ac41d1fc7d43a64ca1e50728f44a353540624c6e78bf0", "bytes": 5890}, + {"path": "docs/module-quickstarts.md", "sha256": "c6c3ea553c6d4434f890602010608832b7b975c279fa943aa9aa1853396a89a3", "bytes": 10665}, + {"path": "docs/native-rust.md", "sha256": "cda3c58f767c4ca62ea02e7c6bf96693689b4dd8b791026cb6b2dc2e02cdd835", "bytes": 36071}, + {"path": "docs/optimization.md", "sha256": "bea4c617f7279b29117a34265c29eb57d0d5905da790f827e5a8ae0efd2ec364", "bytes": 11101}, + {"path": "docs/packages.md", "sha256": "90f5c43c3eced73c3524daa426cdb7f6e0d9b5f523582f31c611909a1d551e3e", "bytes": 5576}, + {"path": "docs/partial-evaluation.md", "sha256": "669fd4555ad10a283098fbde0b48c8eb5ec27b3fa884a2a741cd6addc8f3350e", "bytes": 7909}, + {"path": "docs/pattern-matching.md", "sha256": "184eb3cf8194040a37145b288eaa052233810f49b08195ee96c23ce42ca30dfb", "bytes": 21222}, + {"path": "docs/ports.md", "sha256": "714221e118893c81201688ca23e1bd91a310c51da202e5e7d4e7f1fdc70f31bd", "bytes": 4362}, + {"path": "docs/protocols.md", "sha256": "4932a2fa39d98e456524c65a0b901e351b48a007580b8a621f803d3f08e40052", "bytes": 16517}, + {"path": "docs/pure-jerboa-migration.md", "sha256": "6feca7d165f17af1afc434929c34e5442037a819b8490bd0573c45f6208b963d", "bytes": 6713}, + {"path": "docs/quickstart.md", "sha256": "ed100f8f5897e9aa4ecb81968726d8617ebeb5a7b410fffc24cd6d68722184b3", "bytes": 3930}, + {"path": "docs/reader-syntax.md", "sha256": "94ecbb3218f3d8f38ddc1c15212c53a550a838222c083e7e3996c85f87671c9d", "bytes": 12692}, + {"path": "docs/regex.md", "sha256": "b1cb2933a38f92ab76bff3f1def1d7ca1b2f4bd5f5e58e67cd7d4c68e44e1063", "bytes": 41575}, + {"path": "docs/release-artifacts.md", "sha256": "8760ad5decdf830d72f4d3bfc597401c570d55eea93d1e9f0a70762656e446b0", "bytes": 3876}, + {"path": "docs/repl-protocol.md", "sha256": "87d0677ebee0b668e98b5a280c4fa67c7688593f22b36e6fb7567eff4c0f613c", "bytes": 5652}, + {"path": "docs/rocks.md", "sha256": "725f75b0f0322955c43f4acc28d315ac4a4faa52f12769792efdd805f24dc3ff", "bytes": 15949}, + {"path": "docs/rust-target.md", "sha256": "955445041b8c317e64dce76a6a895f8eb9c4c642aeb80cd209121f0825491434", "bytes": 2728}, + {"path": "docs/safety-guide.md", "sha256": "01f3933b15f180ce4baabb8d3d836a1212de77fe2ca50f9528adb7b682d6b21d", "bytes": 25529}, + {"path": "docs/secure.md", "sha256": "dec555db1f1e10bd263171a628c622b86111afe14cb195b5da3bdf2c2f92ef8f", "bytes": 23819}, + {"path": "docs/security-reference.md", "sha256": "8ba4375cab933df903d4868170bacadd1c039c79800085861a54231e1e585ae4", "bytes": 27738}, + {"path": "docs/sequences.md", "sha256": "c7f18578a176ed078607ea056aae5cb004d6a26e23d19b9a7ed8ab91b8bc1f14", "bytes": 8686}, + {"path": "docs/single-binary.md", "sha256": "1e4b044a6ed1234deaff0ff303af90771c56b65653cb0c9d049d377f0c9a02c5", "bytes": 21769}, + {"path": "docs/single-file-packages.md", "sha256": "ef22b7b6f25d8ce4794b2c8b5e0e1908bfff313187db869a85601194770e94f9", "bytes": 3481}, + {"path": "docs/site-publishing.md", "sha256": "9c5b5c910afa2d9c0119fe9acb7078b556a7cf6e3fbd3a1368b68ae6400f1321", "bytes": 2633}, + {"path": "docs/slang.md", "sha256": "c9332327595b1c11d260c8ecf95ed191aaa98b36737057223a9a44d3c4ebc9fd", "bytes": 25195}, + {"path": "docs/staging.md", "sha256": "3abf62b641b77d1b1a7d9928e8b56e7637198beb3b1eec04a0a6d9c405a7c9d5", "bytes": 18661}, + {"path": "docs/static-binary-gotchas.md", "sha256": "025bfc9994a963c6a6a8d8ddb69219382e81af7e89f1eb939b835d71b47e54dd", "bytes": 14671}, + {"path": "docs/status.md", "sha256": "de8dd05f38852924f93628897b2c06d3e352af7ee788c279e2f8d98abdffd51e", "bytes": 24479}, + {"path": "docs/std-perf.md", "sha256": "7f1b1b24f0d9852764cb8b186744922b5967ab510a2b5ba1dcff76ad6475463b", "bytes": 16289}, + {"path": "docs/stm.md", "sha256": "2ea2f6b0d250855c5d094915cc84e82f4ecd2f21a38a2e29883d44662d8a9a38", "bytes": 15298}, + {"path": "docs/testing-and-infrastructure.md", "sha256": "3e637b462ed7fb1d80204f1c9c6d8127d6d551b4ecd230e63c66111cc2131584", "bytes": 30267}, + {"path": "docs/thread-safe-hash.md", "sha256": "754de955cdd8b42f555beffa487f034c621f89a8001bdf7964907793fb96c843", "bytes": 13855}, + {"path": "docs/tutorial.md", "sha256": "3c9b4cb01d89b8d1b215f60aa8e4e3c45d1c63e46dc6c10d849731906dcb8814", "bytes": 13261}, + {"path": "docs/typed-jerboa.md", "sha256": "8072cde2e6254f7fa259a4272cd2c66f72063738a6433398360730111d4aa086", "bytes": 44594}, + {"path": "docs/typing.md", "sha256": "33bb924a84b11e9cebb94e913d4a366e4fd801840ef3d986cc74002a5dbc4b64", "bytes": 20059}, + {"path": "docs/uhoh.md", "sha256": "76b155a614925daaee7386fc853995c682fc8c8da729cac032e64958a4634398", "bytes": 11081}, + {"path": "docs/unification.md", "sha256": "128da45c3d1b9e3bbc20839327086ab68d6dae461c043d2284218e3d38dd8c10", "bytes": 33371}, + {"path": "docs/vs-rust.md", "sha256": "57c993f42ccd77076c219b9eeae5704915358cf817aeba7cffa8f1c61468bee4", "bytes": 20798}, + {"path": "docs/wasm-example.md", "sha256": "6addcbe6d93dc565e35b87362dfd25053709f36fcb919237852ada94e8712f59", "bytes": 21859}, + {"path": "docs/wasm.md", "sha256": "b1acac7f5e84b5ebe4ea059f5c4abad120b9273772e3eb7c01d4c42b40884648", "bytes": 11984}, + {"path": "docs/whats-new.md", "sha256": "4c8b8eccbe0b465bff1f5b2e64f1b9930c0412013504c33441c44ebcd5db31b1", "bytes": 41856}, + {"path": "docs/zig-ideas.md", "sha256": "f8b6aacfb187e241f8dc218cab20696a17fc77021d6ce61e7feb638e547992ff", "bytes": 2607} + ], + "data": [ + {"path": "data/anti-patterns.sexp", "sha256": "ac23b3998de2243dba862c70763415c9f2f88bcc17a7bc649fb265b5babb881d", "bytes": 41291}, + {"path": "data/api-signatures.sexp", "sha256": "0861ad11333d334af9284c362027b53ed1f3813cf3e87d595a6b221e4f089f5f", "bytes": 837976}, + {"path": "data/changelog.sexp", "sha256": "43457a6374436414bdd191067c47f25784ab3789df6d8a7d0be530c3d80029da", "bytes": 16283}, + {"path": "data/cookbooks.sexp", "sha256": "7f1528b0aab4e37748ff76979fd68ea5d58c0ad5c9eafc2626f631e46e9c3b84", "bytes": 931531}, + {"path": "data/divergence.sexp", "sha256": "89998895f6f330a8b6d7f8f8b06a8b5aa588d05170b47f12bf88225bd792fae6", "bytes": 58225}, + {"path": "data/error-fixes.sexp", "sha256": "619bb4158d570ed690b98c1f122bf96a0a4077803662a8711a64183976bd102d", "bytes": 119666}, + {"path": "data/features.sexp", "sha256": "00bc78b0ab9b99c85eb3735d3ff62f9550b004bb5f993bdefb8f980c89782fdf", "bytes": 203654}, + {"path": "data/security-rules.sexp", "sha256": "a9c3b9b736474440826eb4dbc8b14921c9e47ed1fbea31f6d66d461288eca486", "bytes": 60814} + ], + "examples": [ + {"path": "examples/audit-events.sexp", "sha256": "ad38f25f891e456e20f827129413e041f2fb4b15909ad465a55369e23968cd38", "bytes": 1933}, + {"path": "examples/chat-server.ss", "sha256": "2e2f95dd959ade362999e4467789e58ac1f74daa38a8162a7dbf99ea7cd5a5ed", "bytes": 4993}, + {"path": "examples/cli-tool.ss", "sha256": "a04adc7da7a1b47c916134ef4e3b501172d258460e34f908acd986dfc24649f5", "bytes": 5566}, + {"path": "examples/data-pipeline.ss", "sha256": "37b9082c208ffbc513433e506e384cdb1caeb06229e2724de099bc0625918160", "bytes": 5599}, + {"path": "examples/hello-api.ss", "sha256": "86e2d494bc5d0e155db6d6bb302de3fba5fc3a2254f9e3aaa730485dc7fbfa16", "bytes": 3894} + ], + "assets": [ + {"path": "assets/jerboa-logo.png", "sha256": "7603e424cdb8c0993e65757b9b1c978970583530d4e89516acb6dd7bf6ea906b", "bytes": 247280}, + {"path": "assets/jerboa-logo.svg", "sha256": "9d3071e88a2dc92ebe15346ccf56b4a86b05986285ab15c816946be218e6128d", "bytes": 5743} + ] + } +} new file mode 100644 --- /dev/null +++ b/docs/site-sync.md @@ -0,0 +1,72 @@ +# Site Sync + +`jerboa-site` keeps the private web presentation for `jerboa.sh`. +Canonical language, runtime, package, API, and security facts come from +the public `jerboa` repository. + +## Source Split + +`~/mine/jerboa` owns: + +- canonical docs in `docs/` +- source examples in `examples/` +- machine-readable data in `data/` +- public logo and brand assets in `assets/` + +This repository owns: + +- page layout and visual design +- the Jerboa web entry point +- generated snapshots imported from a specific Jerboa commit +- the build artifact used by deployment + +The generated snapshot lives at `data/jerboa-source.json`. Its +`repo.commit` field is the exact Jerboa revision represented by the +site. The snapshot is generated from Jerboa's committed `HEAD` tree; if +the local checkout had uncommitted changes at sync time, the +`repo.working_tree_dirty` field records that. + +## Updating From Jerboa + +Preview the metadata that would be imported: + +```sh +tools/sync-jerboa --jerboa ~/mine/jerboa --dry-run +``` + +Write the site snapshot: + +```sh +tools/sync-jerboa --jerboa ~/mine/jerboa --write +``` + +Or use the Makefile target: + +```sh +make sync-jerboa +``` + +Then review and build: + +```sh +git diff +make binary +``` + +Commit the site sync separately from the Jerboa source change. This +makes the site pin explicit and easy to audit. + +## LLM Use + +LLM output is allowed for drafted summaries, homepage highlights, and +release prose, but not for extracted facts. The safe flow is: + +1. Generate `data/jerboa-source.json`. +2. Give the LLM only bounded diffs, selected canonical docs, and the + generated metadata. +3. Require source paths or commit ids for generated claims. +4. Review the rendered diff before committing. +5. Deploy only after normal local verification. + +Do not let automated prose replace generated module, package, or API +data. new file mode 100755 --- /dev/null +++ b/tools/sync-jerboa @@ -0,0 +1,89 @@ +#!/bin/sh +set -eu + +usage() { + cat <<'USAGE' +usage: tools/sync-jerboa [--jerboa PATH] [--dry-run|--write] [--commit] + +Import the generated Jerboa metadata snapshot into this site. + +Options: + --jerboa PATH Jerboa repository path. Defaults to $JERBOA_HOME or ~/mine/jerboa. + --dry-run Print the pending metadata diff. This is the default. + --write Write data/jerboa-source.json. + --commit Write and commit the generated snapshot. +USAGE +} + +jerboa=${JERBOA_HOME:-"$HOME/mine/jerboa"} +write=0 +commit=0 + +while [ "$#" -gt 0 ]; do + case "$1" in + --jerboa) + shift + if [ "$#" -eq 0 ]; then + echo "sync-jerboa: --jerboa requires a path" >&2 + exit 2 + fi + jerboa=$1 + ;; + --dry-run) + write=0 + commit=0 + ;; + --write) + write=1 + ;; + --commit) + write=1 + commit=1 + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "sync-jerboa: unknown argument: $1" >&2 + usage >&2 + exit 2 + ;; + esac + shift +done + +if [ ! -x "$jerboa/tools/emit-site-data" ]; then + echo "sync-jerboa: missing executable $jerboa/tools/emit-site-data" >&2 + exit 1 +fi + +tmp_dir=$(mktemp -d "${TMPDIR:-/tmp}/jerboa-site-sync.XXXXXX") +trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM + +"$jerboa/tools/emit-site-data" --out-dir "$tmp_dir" +snapshot=$tmp_dir/jerboa-source.json +target=data/jerboa-source.json + +if [ "$write" -eq 0 ]; then + if [ -f "$target" ]; then + diff -u "$target" "$snapshot" || true + else + cat "$snapshot" + fi + exit 0 +fi + +mkdir -p data +cp "$snapshot" "$target" +echo "synced $target from $jerboa" + +if [ "$commit" -eq 1 ]; then + short_commit=$(git -C "$jerboa" rev-parse --short HEAD 2>/dev/null || printf unknown) + git add "$target" + if git diff --cached --quiet -- "$target"; then + echo "no site metadata changes to commit" + exit 0 + fi + git commit -m "Sync Jerboa site metadata from $short_commit" +fi