@jimhoyd/urlcode 0.3.0 → 0.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +106 -0
  2. package/.claude/skills/urlcode-operations/SKILL.md +114 -0
  3. package/.claude-plugin/marketplace.json +18 -0
  4. package/CONTRIBUTING.md +30 -2
  5. package/README.md +157 -230
  6. package/ROADMAP.md +85 -2
  7. package/SECURITY.md +8 -1
  8. package/dist/BUILD-MANIFEST.json +62 -32
  9. package/dist/adapters.js +4 -23
  10. package/dist/agent-lists.js +1 -1
  11. package/dist/agents-guide.js +113 -0
  12. package/dist/authoring-files.js +60 -0
  13. package/dist/authoring.js +11 -1
  14. package/dist/aws.js +4 -3
  15. package/dist/build-cloudflare.js +11 -24
  16. package/dist/bulk.js +37 -0
  17. package/dist/capabilities.js +208 -0
  18. package/dist/capability-query.js +72 -0
  19. package/dist/catalog.js +105 -0
  20. package/dist/cli.js +154 -15
  21. package/dist/client-address.js +1 -1
  22. package/dist/compliance-rules/baseline.js +8 -8
  23. package/dist/compliance-rules/privacy.js +3 -3
  24. package/dist/compliance-rules/strict.js +5 -5
  25. package/dist/conditions.js +88 -0
  26. package/dist/config.js +60 -4
  27. package/dist/context.js +156 -0
  28. package/dist/ecosystem-cli.js +88 -0
  29. package/dist/egress.js +98 -0
  30. package/dist/examples.js +92 -0
  31. package/dist/explain-cli.js +64 -0
  32. package/dist/explain.js +132 -0
  33. package/dist/extensions.js +172 -0
  34. package/dist/function-sources.js +15 -3
  35. package/dist/index.js +37 -0
  36. package/dist/init-with.js +165 -0
  37. package/dist/interchange-cli.js +42 -0
  38. package/dist/interchange.js +189 -0
  39. package/dist/link-cli.js +1 -1
  40. package/dist/management-policy.js +0 -1
  41. package/dist/manifest.js +111 -0
  42. package/dist/match.js +2 -2
  43. package/dist/mcp-authoring.js +147 -0
  44. package/dist/mcp.js +97 -0
  45. package/dist/observability.js +6 -0
  46. package/dist/operator-host.js +29 -0
  47. package/dist/plugins.js +12 -0
  48. package/dist/policies/agents.js +2 -2
  49. package/dist/policies/compression.js +2 -1
  50. package/dist/policies/security.js +0 -0
  51. package/dist/policies.js +1 -1
  52. package/dist/policy.js +29 -7
  53. package/dist/prerender.js +100 -41
  54. package/dist/project-tests.js +3 -3
  55. package/dist/provider-verification.js +92 -0
  56. package/dist/proxy.js +44 -0
  57. package/dist/readiness.js +5 -5
  58. package/dist/recipes.js +41 -0
  59. package/dist/route-diff.js +106 -0
  60. package/dist/router.js +42 -2
  61. package/dist/runtime.js +95 -14
  62. package/dist/schema-query.js +62 -0
  63. package/dist/signals.js +24 -0
  64. package/dist/site.js +0 -0
  65. package/dist/tooling.js +96 -0
  66. package/dist/types/adapters.d.ts +7 -4
  67. package/dist/types/agent-lists.d.ts +0 -1
  68. package/dist/types/agents-guide.d.ts +17 -0
  69. package/dist/types/authoring-files.d.ts +10 -0
  70. package/dist/types/aws.d.ts +3 -1
  71. package/dist/types/build-cloudflare.d.ts +1 -0
  72. package/dist/types/bulk.d.ts +27 -0
  73. package/dist/types/capabilities.d.ts +55 -0
  74. package/dist/types/capability-query.d.ts +24 -0
  75. package/dist/types/catalog.d.ts +65 -0
  76. package/dist/types/client-address.d.ts +0 -1
  77. package/dist/types/compliance-rules/baseline.d.ts +1 -9
  78. package/dist/types/compliance-rules/privacy.d.ts +1 -4
  79. package/dist/types/compliance-rules/strict.d.ts +0 -5
  80. package/dist/types/conditions.d.ts +19 -0
  81. package/dist/types/config.d.ts +20 -2
  82. package/dist/types/context.d.ts +65 -0
  83. package/dist/types/ecosystem-cli.d.ts +17 -0
  84. package/dist/types/egress.d.ts +46 -0
  85. package/dist/types/examples.d.ts +50 -0
  86. package/dist/types/explain-cli.d.ts +11 -0
  87. package/dist/types/explain.d.ts +95 -0
  88. package/dist/types/extensions.d.ts +122 -0
  89. package/dist/types/function-sources.d.ts +5 -0
  90. package/dist/types/index.d.ts +33 -0
  91. package/dist/types/init-with.d.ts +30 -0
  92. package/dist/types/interchange-cli.d.ts +16 -0
  93. package/dist/types/interchange.d.ts +42 -0
  94. package/dist/types/link-cli.d.ts +2 -1
  95. package/dist/types/management-policy.d.ts +0 -1
  96. package/dist/types/manifest.d.ts +81 -0
  97. package/dist/types/match.d.ts +1 -0
  98. package/dist/types/mcp-authoring.d.ts +92 -0
  99. package/dist/types/mcp.d.ts +12 -0
  100. package/dist/types/observability.d.ts +2 -0
  101. package/dist/types/operator-host.d.ts +8 -0
  102. package/dist/types/plugins.d.ts +2 -0
  103. package/dist/types/policies/agents.d.ts +0 -2
  104. package/dist/types/policies/compression.d.ts +2 -0
  105. package/dist/types/policies/security.d.ts +0 -1
  106. package/dist/types/policy.d.ts +15 -4
  107. package/dist/types/project-tests.d.ts +3 -1
  108. package/dist/types/provider-verification.d.ts +53 -0
  109. package/dist/types/proxy.d.ts +21 -0
  110. package/dist/types/readiness.d.ts +1 -1
  111. package/dist/types/recipes.d.ts +30 -0
  112. package/dist/types/route-diff.d.ts +27 -0
  113. package/dist/types/runtime.d.ts +11 -0
  114. package/dist/types/schema-query.d.ts +12 -0
  115. package/dist/types/signals.d.ts +25 -0
  116. package/dist/types/site.d.ts +0 -1
  117. package/dist/types/tooling.d.ts +115 -0
  118. package/dist/types/types.d.ts +57 -0
  119. package/dist/types/typescript-authoring.d.ts +12 -0
  120. package/dist/types/vercel.d.ts +3 -1
  121. package/dist/types/verify-deployment.d.ts +47 -0
  122. package/dist/types.js +21 -2
  123. package/dist/typescript-authoring.js +104 -0
  124. package/dist/vercel.js +4 -3
  125. package/dist/verify-deployment.js +270 -0
  126. package/docs/AI-AUTHORING.md +130 -8
  127. package/docs/BULK.md +79 -0
  128. package/docs/CAPABILITIES.md +179 -0
  129. package/docs/CAPACITY.md +1 -1
  130. package/docs/CI.md +142 -0
  131. package/docs/CONDITIONS.md +74 -0
  132. package/docs/DEPLOYMENT-CHECKS.md +108 -0
  133. package/docs/DYNAMIC-LINKS.md +18 -518
  134. package/docs/EGRESS.md +125 -0
  135. package/docs/EXTENSIONS.md +226 -0
  136. package/docs/FRAMEWORK.md +182 -0
  137. package/docs/INSTALL.md +45 -7
  138. package/docs/INTERCHANGE.md +134 -0
  139. package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
  140. package/docs/MIDDLEWARE.md +2 -0
  141. package/docs/NEXT-PHASE-PLAN.md +90 -0
  142. package/docs/NEXT-STEPS.md +415 -0
  143. package/docs/OBSERVABILITY.md +4 -2
  144. package/docs/OPERATIONAL-PROOF.md +4 -1
  145. package/docs/OPERATIONS.md +6 -3
  146. package/docs/PLUGINS.md +37 -0
  147. package/docs/POLICIES.md +12 -309
  148. package/docs/PRERENDER.md +40 -0
  149. package/docs/PROJECT-DIRECTION.md +42 -0
  150. package/docs/PROVIDER-VERIFICATION.md +84 -0
  151. package/docs/READINESS.md +21 -1
  152. package/docs/README.md +82 -31
  153. package/docs/RECIPES.md +99 -0
  154. package/docs/RELEASE-READINESS.md +11 -9
  155. package/docs/RELEASE-SECURITY.md +27 -4
  156. package/docs/SECURITY-AUDIT.md +1 -1
  157. package/docs/SPECIFICATION.md +95 -8
  158. package/docs/SPIKE-BUSINESS-SUITE.md +1013 -0
  159. package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
  160. package/docs/SPIKE-EXTENSIONS.md +1 -0
  161. package/docs/SPIKE-LAMBDA-COMPILE.md +199 -0
  162. package/docs/STANDARDS.md +150 -142
  163. package/docs/STARTERS.md +21 -1
  164. package/docs/TOOLING.md +291 -0
  165. package/docs/TYPESCRIPT-AUTHORING.md +67 -0
  166. package/docs/TYPESCRIPT.md +1 -1
  167. package/docs/USABILITY-REVIEW.md +123 -0
  168. package/docs/YAML-GUIDE.md +18 -479
  169. package/docs/YAML-REFERENCE.md +127 -16
  170. package/docs/links/cli.md +110 -0
  171. package/docs/links/limits.md +175 -0
  172. package/docs/links/management-api.md +80 -0
  173. package/docs/links/pools.md +75 -0
  174. package/docs/links/setup.md +135 -0
  175. package/docs/policies/agents.md +1 -1
  176. package/docs/policies/contract.md +52 -0
  177. package/docs/policies/hardened.md +56 -0
  178. package/docs/policies/interoperability.md +169 -0
  179. package/docs/policies/operations.md +45 -0
  180. package/docs/yaml/assets.md +36 -0
  181. package/docs/yaml/conditions.md +20 -0
  182. package/docs/yaml/functions.md +160 -0
  183. package/docs/yaml/links.md +30 -0
  184. package/docs/yaml/middleware.md +29 -0
  185. package/docs/yaml/organization.md +74 -0
  186. package/docs/yaml/policies.md +37 -0
  187. package/docs/yaml/redirects.md +64 -0
  188. package/docs/yaml/responses.md +57 -0
  189. package/docs/yaml/site.md +24 -0
  190. package/examples/assets/example.yaml +17 -0
  191. package/examples/aws/example.yaml +20 -0
  192. package/examples/cloudflare/example.yaml +19 -0
  193. package/examples/compliance/example.yaml +11 -0
  194. package/examples/conditions/README.md +12 -0
  195. package/examples/conditions/example.yaml +19 -0
  196. package/examples/conditions/tests/requests.json +13 -0
  197. package/examples/conditions/urlcode.yaml +24 -0
  198. package/examples/cookbook/README.md +8 -4
  199. package/examples/cookbook/example.yaml +17 -0
  200. package/examples/cookbook/functions/catalog.mjs +3 -0
  201. package/examples/cookbook/functions/fail.mjs +4 -0
  202. package/examples/cookbook/functions/items.mjs +3 -0
  203. package/examples/cookbook/functions/profile.mjs +3 -0
  204. package/examples/cookbook/functions/resource.mjs +3 -0
  205. package/examples/cookbook/functions/status.mjs +3 -0
  206. package/examples/cookbook/middleware/auth.mjs +48 -0
  207. package/examples/cookbook/middleware/body.mjs +15 -0
  208. package/examples/cookbook/middleware/bucket.mjs +19 -0
  209. package/examples/cookbook/middleware/cors.mjs +21 -0
  210. package/examples/cookbook/middleware/debug.mjs +13 -0
  211. package/examples/cookbook/middleware/envelope.mjs +11 -0
  212. package/examples/cookbook/middleware/errors.mjs +11 -0
  213. package/examples/cookbook/middleware/etag.mjs +18 -0
  214. package/examples/cookbook/middleware/locale.mjs +16 -0
  215. package/examples/cookbook/middleware/maintenance.mjs +10 -0
  216. package/examples/cookbook/middleware/methods.mjs +15 -0
  217. package/examples/cookbook/middleware/negotiate.mjs +20 -0
  218. package/examples/cookbook/middleware/referer.mjs +12 -0
  219. package/examples/cookbook/middleware/request-id.mjs +16 -0
  220. package/examples/cookbook/route-index.json +676 -0
  221. package/examples/cookbook/routes/middleware.yaml +126 -0
  222. package/examples/cookbook/tests/requests.json +526 -0
  223. package/examples/cookbook/urlcode.yaml +1 -0
  224. package/examples/egress/README.md +22 -0
  225. package/examples/egress/example.yaml +19 -0
  226. package/examples/egress/urlcode.yaml +19 -0
  227. package/examples/extensions/README.md +7 -0
  228. package/examples/extensions/example.yaml +21 -0
  229. package/examples/extensions/urlcode.yaml +25 -0
  230. package/examples/live-links/example.yaml +21 -0
  231. package/examples/monitoring/example.yaml +8 -0
  232. package/examples/prerender/example.yaml +16 -0
  233. package/examples/provider-conformance/README.md +12 -0
  234. package/examples/provider-conformance/example.yaml +14 -0
  235. package/examples/provider-conformance/urlcode.yaml +34 -0
  236. package/examples/tunnel/example.yaml +8 -0
  237. package/examples/vercel/example.yaml +19 -0
  238. package/llms-full.txt +2709 -0
  239. package/llms.txt +48 -19
  240. package/package.json +29 -7
  241. package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
  242. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +106 -0
  243. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +114 -0
  244. package/recipes/authenticated-json-api/README.md +51 -0
  245. package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
  246. package/recipes/authenticated-json-api/recipe.yaml +34 -0
  247. package/recipes/authenticated-json-api/tests/requests.json +39 -0
  248. package/recipes/authenticated-json-api/urlcode.yaml +12 -0
  249. package/recipes/contact-form/README.md +25 -0
  250. package/recipes/contact-form/functions/contact.mjs +17 -0
  251. package/recipes/contact-form/recipe.yaml +33 -0
  252. package/recipes/contact-form/tests/requests.json +47 -0
  253. package/recipes/contact-form/urlcode.yaml +18 -0
  254. package/recipes/cors-api/README.md +16 -0
  255. package/recipes/cors-api/functions/items.mjs +3 -0
  256. package/recipes/cors-api/middleware/cors.mjs +21 -0
  257. package/recipes/cors-api/recipe.yaml +26 -0
  258. package/recipes/cors-api/tests/requests.json +65 -0
  259. package/recipes/cors-api/urlcode.yaml +12 -0
  260. package/recipes/health-page/README.md +13 -0
  261. package/recipes/health-page/recipe.yaml +23 -0
  262. package/recipes/health-page/tests/requests.json +36 -0
  263. package/recipes/health-page/urlcode.yaml +19 -0
  264. package/recipes/json-api/README.md +6 -0
  265. package/recipes/json-api/functions/echo.mjs +3 -0
  266. package/recipes/json-api/recipe.yaml +25 -0
  267. package/recipes/json-api/tests/requests.json +34 -0
  268. package/recipes/json-api/urlcode.yaml +12 -0
  269. package/recipes/middleware/README.md +34 -0
  270. package/recipes/middleware/functions/catalog.mjs +3 -0
  271. package/recipes/middleware/functions/fail.mjs +4 -0
  272. package/recipes/middleware/functions/items.mjs +3 -0
  273. package/recipes/middleware/functions/profile.mjs +3 -0
  274. package/recipes/middleware/functions/resource.mjs +3 -0
  275. package/recipes/middleware/functions/status.mjs +3 -0
  276. package/recipes/middleware/middleware/auth.mjs +48 -0
  277. package/recipes/middleware/middleware/body.mjs +15 -0
  278. package/recipes/middleware/middleware/bucket.mjs +19 -0
  279. package/recipes/middleware/middleware/cors.mjs +21 -0
  280. package/recipes/middleware/middleware/debug.mjs +13 -0
  281. package/recipes/middleware/middleware/envelope.mjs +11 -0
  282. package/recipes/middleware/middleware/errors.mjs +11 -0
  283. package/recipes/middleware/middleware/etag.mjs +18 -0
  284. package/recipes/middleware/middleware/locale.mjs +16 -0
  285. package/recipes/middleware/middleware/maintenance.mjs +10 -0
  286. package/recipes/middleware/middleware/methods.mjs +15 -0
  287. package/recipes/middleware/middleware/negotiate.mjs +20 -0
  288. package/recipes/middleware/middleware/referer.mjs +12 -0
  289. package/recipes/middleware/middleware/request-id.mjs +16 -0
  290. package/recipes/middleware/public/guide.txt +1 -0
  291. package/recipes/middleware/recipe.yaml +50 -0
  292. package/recipes/middleware/tests/requests.json +528 -0
  293. package/recipes/middleware/urlcode.yaml +127 -0
  294. package/recipes/protected-download/README.md +22 -0
  295. package/recipes/protected-download/files/report.txt +1 -0
  296. package/recipes/protected-download/recipe.yaml +31 -0
  297. package/recipes/protected-download/tests/requests.json +32 -0
  298. package/recipes/protected-download/urlcode.yaml +15 -0
  299. package/recipes/redirect/README.md +7 -0
  300. package/recipes/redirect/recipe.yaml +25 -0
  301. package/recipes/redirect/tests/requests.json +19 -0
  302. package/recipes/redirect/urlcode.yaml +9 -0
  303. package/recipes/static-plus-api/README.md +15 -0
  304. package/recipes/static-plus-api/functions/info.mjs +3 -0
  305. package/recipes/static-plus-api/public/assets/index.html +3 -0
  306. package/recipes/static-plus-api/public/assets/site.css +1 -0
  307. package/recipes/static-plus-api/public/index.html +8 -0
  308. package/recipes/static-plus-api/recipe.yaml +29 -0
  309. package/recipes/static-plus-api/tests/requests.json +56 -0
  310. package/recipes/static-plus-api/urlcode.yaml +23 -0
  311. package/recipes/typescript/README.md +7 -0
  312. package/recipes/typescript/functions/hello.ts +5 -0
  313. package/recipes/typescript/recipe.yaml +23 -0
  314. package/recipes/typescript/tests/requests.json +18 -0
  315. package/recipes/typescript/urlcode.yaml +5 -0
  316. package/recipes/webhook-receiver/README.md +16 -0
  317. package/recipes/webhook-receiver/functions/receive.mjs +16 -0
  318. package/recipes/webhook-receiver/recipe.yaml +26 -0
  319. package/recipes/webhook-receiver/tests/requests.json +59 -0
  320. package/recipes/webhook-receiver/urlcode.yaml +16 -0
  321. package/schemas/recipe.schema.json +138 -0
  322. package/schemas/urlcode.schema.json +656 -80
  323. package/skills/urlcode/SKILL.md +98 -0
  324. package/starters/default/.github/workflows/urlcode.yml +23 -0
  325. package/starters/default/.mcp.json +12 -0
  326. package/starters/default/AGENTS.md +79 -0
package/README.md CHANGED
@@ -1,30 +1,89 @@
1
1
  # URLCode
2
2
 
3
- **A portable runtime for programmable URL behavior.** Define an application's
4
- public URL surface in YAML, add isolated JavaScript only where declarative
5
- handlers are not enough, and run the same project locally or on your own
6
- infrastructure. Your routes, source and data remain yours.
3
+ **A portable runtime for programmable URL behavior, and the framework that grows
4
+ from it.** Declare an application's public URL surface in YAML, add isolated
5
+ JavaScript only where declarative handlers are not enough, and run the same
6
+ project locally, in a container, on your own infrastructure or on a provider
7
+ adapter. When the project gets serious, add accounts and an administration
8
+ console as operator-installed extensions instead of building them again.
9
+ **URL behavior as code.**
7
10
 
8
11
  [![Verify](https://github.com/jimhoyd-com/urlcode/actions/workflows/ci.yml/badge.svg)](https://github.com/jimhoyd-com/urlcode/actions/workflows/ci.yml)
9
12
 
10
- [Documentation](docs/README.md) · [Starter](https://github.com/jimhoyd-com/urlcode-template) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md)
13
+ [Documentation](docs/README.md) · [The framework](docs/FRAMEWORK.md) · [For AI agents](llms.txt) · [Starter](https://github.com/jimhoyd-com/urlcode-template) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md)
14
+
15
+ **Your AI should build your application, not your framework.** Coding agents
16
+ rebuild the same routing, validation, middleware, policies and authentication
17
+ plumbing on every project, and the person ends up owning the plumbing. URLCode
18
+ represents those behaviors as a strict, portable YAML contract that both people
19
+ and agents can read: the agent describes what, the runtime owns how, and
20
+ generated code goes to the part that is actually the application. It is
21
+ infrastructure for AI-built software, not a framework for building AI models.
22
+ [Why](docs/PROJECT-DIRECTION.md#why-your-ai-should-build-your-application-not-your-framework) ·
23
+ [next steps](docs/NEXT-STEPS.md).
24
+
25
+ ## What it is
26
+
27
+ A project is a `urlcode.yaml` with `version: "1"`. Each route has exactly one
28
+ handler: `redirect`, `respond`, `page`, `static`, `download`, `function`,
29
+ `link`, `proxy`, `conditional` or an `extension` mount, with optional ordered
30
+ `middleware`. The runtime validates the whole project before serving it,
31
+ compiles it once, and refuses anything a target cannot enforce with the route
32
+ named. Functions run in a QuickJS/WebAssembly sandbox with a fresh heap per
33
+ call and no Node, filesystem or network; secrets reach them only through
34
+ operator grants pinned to the project revision.
35
+
36
+ URLCode is not a URL shortener: short links are one handler. It is not a
37
+ general Node web framework: guest code cannot reach the host. It is not a
38
+ provider configuration format: infrastructure settings stay out of route YAML.
39
+ See [project direction](docs/PROJECT-DIRECTION.md).
40
+
41
+ ## The framework
42
+
43
+ Four packages, one project shape. A project climbs from redirects to a full
44
+ application by adding YAML; the operator wires trusted packages in one host
45
+ file outside the project. The full map, the composition contract and the rules
46
+ an AI agent must follow are in [the framework](docs/FRAMEWORK.md).
47
+
48
+ | Package | Adds | Status |
49
+ |---|---|---|
50
+ | [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, live links, provider adapters, extension contract | `0.4.0-alpha.1` (alpha) on top of the `0.3.0` release, Apache-2.0 |
51
+ | [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations | `0.1.0-alpha.1` on npm, alpha: review pending |
52
+ | [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page | `0.1.0-alpha.1` on npm, alpha: review pending |
53
+ | [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin) | Administration: users, sessions, roles, audit, approvals, cases, impersonation | `0.1.0-alpha.1` on npm, alpha: review pending |
11
54
 
12
- URLCode is not a URL shortener. Short links are one supported route type beside
13
- redirects, validated HTTP responses, isolated request functions, middleware,
14
- pages, static assets and downloads. It is also not a general Node web framework:
15
- the project format intentionally describes bounded behavior that a runtime can
16
- validate, inspect and eventually carry across hosting providers.
55
+ ```yaml
56
+ version: "1"
57
+ extensions:
58
+ auth: { version: "1", config: { registration: "off" } }
59
+ admin: { version: "1", config: {} }
60
+ routes:
61
+ /go: { redirect: { url: https://example.com, status: 302 } }
62
+ /account/*: { extension: auth, methods: [GET, HEAD, POST] }
63
+ /admin/*: { extension: admin, methods: [GET, HEAD, POST] }
64
+ /private:
65
+ respond: { text: Signed in }
66
+ policies: { extensions: { auth: {} } }
67
+ ```
17
68
 
18
- See [project direction](docs/PROJECT-DIRECTION.md) for the product boundary,
19
- the relationship to application projects and the license.
69
+ The YAML names logical extensions; it never names packages, code, databases
70
+ or credentials. `urlcode-auth init` writes the operator host, keys and a
71
+ private data directory beside the project; `urlcode serve --host-file` loads
72
+ it. Cross-repository acceptance is tracked in
73
+ [issue 58](https://github.com/jimhoyd-com/urlcode/issues/58).
20
74
 
21
75
  ## Status
22
76
 
23
- `0.2.0` is the current local/self-hosted release of the implemented
24
- contract, following `0.1.0`, the first stable one. It includes redirects, parameters, JavaScript
25
- functions, middleware, live short-link storage, pages, static assets, downloads, starters, tests and process/container packaging. See the
26
- [implemented contract](docs/SPECIFICATION.md), [operations guide](docs/OPERATIONS.md)
27
- and [roadmap](ROADMAP.md) for limits and unfinished work.
77
+ `0.4.0-alpha.1` is the current release of the extension contract and the
78
+ agent tooling, on top of the `0.3.0` self-hosted release. It adds the
79
+ extension contract, capabilities and provider conformance, strict redirect
80
+ interchange, bulk import, recipes and search, TypeScript guest authoring,
81
+ conditions, bounded proxy and signals, and the MCP read and authoring modes;
82
+ use the schema and docs from the runtime revision you run.
83
+ The [roadmap](ROADMAP.md) separates implemented from planned, and
84
+ [release readiness](docs/RELEASE-READINESS.md) records what is proven and
85
+ what is not: provider deployments, soak and independent security review
86
+ remain open.
28
87
 
29
88
  Live-link storage uses separate bounded reader/writer pools. It requires a Node
30
89
  build containing a patched SQLite version — 3.51.3 or newer, 3.50.7, or 3.44.6 —
@@ -42,7 +101,9 @@ self-hosting are permitted under its terms.
42
101
  Start with the [YAML guide and recipe book](docs/YAML-GUIDE.md),
43
102
  [complete field reference](docs/YAML-REFERENCE.md), and
44
103
  [runnable 25-route cookbook](examples/cookbook/README.md). For AI-assisted
45
- authoring, use [the AI guide](docs/AI-AUTHORING.md) and [llms.txt](llms.txt).
104
+ authoring, use [the AI guide](docs/AI-AUTHORING.md), the bundled agent skills
105
+ ([authoring](.claude/skills/urlcode-authoring/SKILL.md),
106
+ [operations](.claude/skills/urlcode-operations/SKILL.md)) and [llms.txt](llms.txt).
46
107
  Follow [organization and readability practices](docs/BEST-PRACTICES.md) as your
47
108
  project grows. Operators should read [capacity/concurrency](docs/CAPACITY.md) and the
48
109
  [DDoS and recovery playbook](docs/RESILIENCE.md). Embedding the runtime from
@@ -94,249 +155,115 @@ Already wrote `urlcode.yaml`? Run `urlcode scaffold --project ./my-links --dry-r
94
155
  then remove `--dry-run` to create missing modules, pages and directories. Existing
95
156
  files are preserved; code placeholders return 501 until implemented.
96
157
  [Scaffolding guide](docs/SCAFFOLDING.md).
158
+ Live-link storage and the auth extension need a Node build whose SQLite is
159
+ 3.51.3 or newer, 3.50.7 or 3.44.6. `urlcode doctor` reports `liveLinks`;
160
+ everything else runs on any supported Node (22.13+ installed, 22.18+ to run
161
+ the TypeScript source).
97
162
 
98
163
  ## Try it
99
164
 
100
- Requires Node.js 22.13+ and npm; CI targets Node 22, 24 and 26 on macOS, Linux and
101
- Windows.
102
-
103
165
  ```sh
104
- npm install --global urlcode # or: brew tap jimhoyd-com/urlcode && brew install urlcode
166
+ npm install --global @jimhoyd/urlcode # or: brew tap jimhoyd-com/urlcode && brew install urlcode
105
167
  urlcode init my-urls && cd my-urls
106
168
  urlcode dev
107
169
  ```
108
170
 
109
- See [installation](docs/INSTALL.md) for the install script, the container image
110
- and verifying a release's signed provenance. To work from a clone instead:
111
-
112
- ```sh
113
- git clone https://github.com/jimhoyd-com/urlcode.git
114
- cd urlcode
115
- make dev
116
- ```
117
-
118
- `make dev` installs dependencies if needed and starts the included function/redirect demo.
119
- No global install, account, database, Docker or configuration step is required.
120
- A clone runs the TypeScript source directly (`node src/cli.ts`, which needs
121
- Node 22.18+); the installed package runs the built `dist/cli.js`.
122
- Without Make (including Windows), use:
123
-
124
- ```sh
125
- npm ci
126
- npm run dev
127
- ```
128
-
129
- Open `http://127.0.0.1:3000/hello/Ada` to run your custom function,
130
- `/go` for a regular redirect.
131
- Edit `starters/default/routes/` or `functions/hello.mjs` under
132
- that starter; valid changes reload automatically. Press Ctrl+C to stop.
133
- In another terminal, run `make test-project` or `npm run test:project`.
134
-
135
- To create your own independent project:
136
-
137
- ```sh
138
- make init DEST=../my-links
139
- make dev PROJECT=../my-links PORT=3001
140
- # Without Make:
141
- npm run init -- ../my-links
142
- npm run dev -- --project ../my-links --port 3001
143
- ```
144
-
145
- Choose either command pair; initialization refuses to overwrite existing work.
146
- [Starters](docs/STARTERS.md) are ordinary application files, independent of the
147
- runtime checkout. Own them in your own Git repository. Global `npm link` remains
148
- optional if you want the `urlcode` command everywhere. See
149
- [local development](docs/LOCAL-DEVELOPMENT.md) for commands and troubleshooting.
171
+ Open `http://127.0.0.1:3000/hello/Ada` for the function route and `/go` for
172
+ the redirect. Edit the YAML; valid changes reload. `urlcode test` runs the
173
+ project's HTTP fixtures. The [install guide](docs/INSTALL.md) covers the
174
+ checksum-verified script, project-local installs, the container image and
175
+ signed provenance. To work from a clone: `git clone … && make dev`.
150
176
 
151
177
  ## A URL that runs your function
152
178
 
153
- A request to `/hello/Ada` runs your JavaScript and returns
154
- `{"message":"Hello, Ada!"}`. Put this in `urlcode.yaml`:
155
-
156
179
  ```yaml
157
180
  version: "1"
158
181
  routes:
159
182
  /hello/{name}:
160
183
  parameters:
161
- - name: name
162
- in: path
163
- required: true
164
- schema: {type: string, minLength: 1, maxLength: 80}
184
+ - { name: name, in: path, required: true, schema: { type: string, minLength: 1, maxLength: 80 } }
165
185
  function:
166
186
  source: functions/hello.mjs
167
- args:
168
- name: {from: path, name: name}
187
+ args: { name: { from: path, name: name } }
169
188
  env:
170
- GREETING: {value: Hello}
189
+ GREETING: { value: Hello }
171
190
  ```
172
191
 
173
- And in `functions/hello.mjs`:
174
-
175
192
  ```js
176
193
  export default function hello(request, { args, env }) {
177
194
  return Response.json({ message: `${env.GREETING}, ${args.name}!` });
178
195
  }
179
196
  ```
180
197
 
181
- Your function chooses the response: JSON, text, HTML, or a redirect via
182
- `Response.redirect("https://example.com", 302)`. The starter includes
183
- this runnable example. Functions run in an isolated sandbox; see its supported
184
- [API and security boundaries](docs/FUNCTION-SECURITY.md).
185
-
186
- ## Reusable middleware
198
+ Add `middleware: [{ source: middleware/headers.mjs }]` to wrap any handler with
199
+ `await next()`. Fourteen ready-made middleware patterns ship in the cookbook
200
+ and as `urlcode recipes add middleware`. See [functions and the sandbox](docs/FUNCTION-SECURITY.md)
201
+ and [middleware](docs/MIDDLEWARE.md).
202
+
203
+ ## Everything else in YAML
204
+
205
+ - **Pages, files, downloads:** `page`, `static`, `download` with MIME detection,
206
+ ETags, ranges and safety limits. [Assets](docs/ASSETS.md).
207
+ - **Live short links:** a `link` route on an optional SQLite store; create,
208
+ update and delete without reloads through the CLI or the private management
209
+ API. [Dynamic links](docs/DYNAMIC-LINKS.md).
210
+ - **HTTP:** methods, validated path/query/header inputs, body limits, response
211
+ headers and cookies. [HTTP](docs/HTTP.md).
212
+ - **Policies and site conventions:** throttle, agents, security headers,
213
+ compression, cache; robots, sitemap, favicon, security.txt, llms.txt.
214
+ [Policies](docs/POLICIES.md), [site](docs/SITE.md).
215
+ - **Conditions, proxy, signals:** exact predicates with disjoint cases; a bounded
216
+ HTTPS proxy and best-effort webhooks behind operator grants.
217
+ [Conditions](docs/CONDITIONS.md), [egress](docs/EGRESS.md).
218
+ - **Organization:** `includes` across folders; strict CSV/JSON/YAML and
219
+ provider-file import; searchable recipes and examples. [Organization](docs/ORGANIZATION.md),
220
+ [interchange](docs/INTERCHANGE.md), [bulk](docs/BULK.md), [recipes](docs/RECIPES.md).
221
+ - **Checks:** `validate`, `test`, `routes`, `audit --expect-routes`, `benchmark`,
222
+ `capabilities`, deployment verification and a GitHub Action.
223
+ [Readiness](docs/READINESS.md), [CI](docs/CI.md).
224
+
225
+ ## Deploy
226
+
227
+ Self-hosted Node process or container first. `@jimhoyd/urlcode/vercel` and
228
+ `@jimhoyd/urlcode/aws` serve declarative projects as native handlers;
229
+ `urlcode build --target cloudflare` compiles redirects and declared responses
230
+ into a Worker. Each target refuses at activation or build time what it cannot
231
+ run, with the route named. None has been exercised on its provider yet; the
232
+ adapters have local conformance tests only. [Operations](docs/OPERATIONS.md),
233
+ [capabilities](docs/CAPABILITIES.md), [Vercel](docs/VERCEL.md), [AWS](docs/AWS.md),
234
+ [Cloudflare](docs/CLOUDFLARE.md).
235
+
236
+ ## For AI agents
237
+
238
+ [llms.txt](llms.txt) is the compact index; [the framework](docs/FRAMEWORK.md)
239
+ is the map; [AI authoring](docs/AI-AUTHORING.md) is the contract with the
240
+ capability matrix and a copyable task prompt. `urlcode mcp` exposes read-only
241
+ inspection, validation and conversion previews over stdio, and
242
+ `--allow-authoring` adds project-confined authoring tools
243
+ ([tooling](docs/TOOLING.md)).
187
244
 
188
- Add an ordered `middleware` list alongside any route handler:
189
-
190
- ```yaml
191
- middleware:
192
- - source: middleware/headers.mjs
193
- ```
194
-
195
- ```js
196
- export default async function headers(request, context, next) {
197
- const response = await next();
198
- response.headers.set('x-example-middleware', 'active');
199
- return response;
200
- }
201
- ```
202
-
203
- Middleware can return a response early, share request-local `context.state`, or
204
- wrap the handler with `await next()`. It runs in the same isolated sandbox and
205
- under one deadline for the whole chain. The starter's function route includes
206
- this example. See [middleware semantics and limits](docs/MIDDLEWARE.md).
207
-
208
- ## A URL that redirects
209
-
210
- ```yaml
211
- version: "1"
212
- routes:
213
- /go:
214
- redirect:
215
- url: https://example.com
216
- status: 302
217
- ```
218
-
219
- Ordinary redirects use an indexed lookup: no database, Lambda or per-route
220
- user function. Configuration is compiled at startup, not parsed per request.
221
- Literal paths win over parameterized routes; conflicting definitions fail validation.
222
-
223
- Custom functions are ES modules using a documented text/JSON `Request`/`Response`
224
- subset and validated context. See the
225
- [starter](starters/default/urlcode.yaml) and [function](starters/default/functions/hello.mjs).
226
- Functions are treated as untrusted and run inside a QuickJS/WebAssembly sandbox,
227
- with a fresh heap per invocation. No Node APIs, filesystem, shell, network or
228
- ambient environment is exposed. Independent worker deadlines bound execution.
229
- External env/secret bindings require route-scoped operator grants pinned to the
230
- project revision. See the [security model](docs/FUNCTION-SECURITY.md).
231
-
232
- ## Pages, files and downloads
233
-
234
- Add these routes alongside your functions and redirects:
235
-
236
- ```yaml
237
- /about:
238
- page:
239
- file: public/about.html
240
- /assets/*:
241
- static:
242
- directory: public/assets
243
- /download:
244
- download:
245
- file: public/guide.txt
246
- filename: urlcode-guide.txt
247
- ```
248
-
249
- Create the referenced files first. MIME types are detected from file extensions;
250
- unknown types use `application/octet-stream`. Downloads set attachment headers.
251
- Optional `contentType` overrides detection. HEAD, ETags, conditional requests and
252
- single byte ranges are supported. Files are served natively without executing a
253
- function. See [asset configuration and safety limits](docs/ASSETS.md).
254
-
255
- ## Organize routes across files
245
+ ## Documentation
256
246
 
257
- Keep everything in `urlcode.yaml`, or use its `includes` list to load files from
258
- folders you choose. The [public template](https://github.com/jimhoyd-com/urlcode-template)
259
- demonstrates a function file and a redirect file in a nested folder. All commands
260
- see one combined project. See [organization examples](docs/ORGANIZATION.md).
247
+ Full documentation lives in
248
+ [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs). It is authored
249
+ there directly, not generated from this repository, and it is where new guides,
250
+ references and recipes belong.
261
251
 
262
- ## Route matching and adding links
252
+ `docs/` in this repository is contributor and maintainer material — local
253
+ development, CI, the release process, reviews and the generated field
254
+ reference. Reader-facing pages still under `docs/` are being migrated.
263
255
 
264
- Routes support exact paths and non-greedy single-segment parameters such as
265
- `/r/{code}`. Only static-file mounts support a trailing `/*`; regex routing is
266
- not supported. `dev` swaps validated configuration snapshots when YAML changes;
267
- `serve` requires restart/redeployment for YAML changes. Stored short links can
268
- now be created/updated/deleted live without reloads through the optional
269
- [dynamic-link handler and management API](docs/DYNAMIC-LINKS.md). See [matching, precedence and dynamic-link behavior](docs/ROUTING.md).
256
+ ## Built with URLCode
270
257
 
271
- ## Create short links without restarting
258
+ [urlcode-short](https://github.com/jimhoyd-com/urlcode-short), an
259
+ account-free short-link demo with a shadcn/ui front end, and
260
+ [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs), a static
261
+ documentation site rendered through sandboxed middleware at build time. Both are
262
+ ordinary consumers of the public runtime; their retrospectives list what the
263
+ runtime supplied and what they still had to build.
272
264
 
273
- ```yaml
274
- /r/{code}:
275
- parameters:
276
- - name: code
277
- in: path
278
- required: true
279
- schema: {type: string, minLength: 1, maxLength: 128}
280
- link:
281
- collection: links
282
- code: {from: path, name: code}
283
- ```
265
+ ## License and contributing
284
266
 
285
- Keep this route in YAML; store individual codes outside Git. Bind an optional
286
- local SQLite store with `--link-store links=/absolute/links.sqlite`, then use
287
- `urlcode links create` or the separate authenticated management API. Successful
288
- record changes are visible without rewriting YAML or rebuilding the route table.
289
- Ordinary YAML routes still need no database. See [setup, API and limitations](docs/DYNAMIC-LINKS.md).
290
-
291
- ## HTTP in YAML
292
-
293
- Configure methods and validated path/query/header inputs, request body size and
294
- media types, response headers, cookies, and declared text/JSON responses.
295
- See the [HTTP configuration reference](docs/HTTP.md) for supported fields and
296
- examples. Runtime framing and asset validators stay protected.
297
-
298
- ## Check your links before release
299
-
300
- `urlcode routes` lists the configured routes. `urlcode audit --expect-routes 2`
301
- checks the count, generates native response checks and reports missing route/method
302
- coverage in your request fixtures. `urlcode benchmark --requests 1000 --concurrency 2`
303
- measures your local project without following external redirects. Each command
304
- accepts `--project`. See [readiness and release checks](docs/READINESS.md).
305
-
306
- ## Commands available
307
-
308
- | Command | Purpose |
309
- |---|---|
310
- | `init <directory>` | Create an independent starter; refuse existing destinations |
311
- | `add <url> --alias <code>` | Validate and atomically add a redirect; generate a code if omitted |
312
- | `validate --local` | Validate config, references, bindings and function initialization; read `.env.local` |
313
- | `dev` | Local server, watched reload and `.env.local` |
314
- | `serve` | Fixed production process snapshot; environment injection, no dotenv loading |
315
- | `test` | Local HTTP assertions from `tests/requests.json`; never follow redirects |
316
- | `permissions` | Inspect requested bindings and project digest without executing code; grants nothing |
317
- | `doctor` | Report runtime/platform details and implemented provider scope |
318
-
319
- Use `--project <directory>` to select an app. Servers accept `--host`, `--port`
320
- and `--origin` (public URL origin for functions). Bind defaults to `127.0.0.1`.
321
-
322
- ## Production direction
323
-
324
- The free runtime is meant to be useful and production-capable for people who
325
- operate it themselves. Current hardening includes strict YAML/schema checks,
326
- request/response limits, worker deadlines, bounded function concurrency, safe
327
- configuration replacement, graceful shutdown, health/readiness and structured
328
- logs without request content. It still needs broader deployment/soak validation
329
- and the remaining release features. Read [operations](docs/OPERATIONS.md) before
330
- exposing a server. [Benchmark instructions and measurements](docs/PERFORMANCE.md)
331
- are available; measurements are not capacity guarantees.
332
-
333
- Git owns definitions and code. Secrets stay in ignored `.env.local` for development
334
- or injected environment values for serving, accessible to functions only through
335
- an explicit operator policy. Vercel, AWS Lambda and Cloudflare Workers each have a
336
- target guide in [docs](docs/README.md); none has been deployed to its platform
337
- yet. Provider secret-store integration, CSV tools, templates/signals,
338
- Homebrew and richer monitoring are future work. Unsupported config fails rather
339
- than silently losing behavior. There is no required admin UI or database.
340
-
341
- See [contributing](CONTRIBUTING.md), [security](SECURITY.md), and the
342
- [roadmap](ROADMAP.md).
267
+ Apache-2.0. Commercial use, modification, redistribution and self-hosting are
268
+ permitted. See [contributing](CONTRIBUTING.md), [security](SECURITY.md),
269
+ [governance](GOVERNANCE.md) and the [roadmap](ROADMAP.md).
package/ROADMAP.md CHANGED
@@ -11,6 +11,89 @@ separate late phase. The stable 0.1 self-hosted release covers much of M0/M1 plu
11
11
  process/container packaging and benchmarks. Provider adapters and the remaining
12
12
  production-readiness gates remain open.
13
13
 
14
+ ## 0.4.0-alpha.1 — current alpha
15
+
16
+ `0.4.0-alpha.1` is the first alpha of the extension contract and the agent
17
+ tooling on top of the `0.3.0` self-hosted release. It carries: the
18
+ revision-pinned extension contract, capabilities and provider conformance,
19
+ strict redirect interchange, bulk import, recipes and search, TypeScript
20
+ guests, conditions, bounded proxy and signals, MCP read and authoring modes,
21
+ the `context`, `explain`, `manifest` and `schema` queries, short forms,
22
+ route-level auth, `init --with`, the agent benchmark harness, `llms-full`,
23
+ and the generated `AGENTS.md` and skill. It is an alpha: provider
24
+ deployments, soak and independent security review remain open. The
25
+ extension packages declare `@jimhoyd/urlcode >=0.4.0-alpha.1 <0.5.0` and
26
+ are published after core.
27
+
28
+ ## Extensions: accounts, administration and presentation — implemented, unreleased
29
+
30
+ The runtime now carries a generic, revision-pinned extension contract
31
+ (`@jimhoyd/urlcode/extensions`, [extensions](docs/EXTENSIONS.md)): a project
32
+ declares versioned `extensions.<name>` blocks, exclusive `extension` mounts and
33
+ `policies.extensions` requirements; the operator supplies the implementations
34
+ in a host file loaded with `--host-file`, outside the project. Guest requests
35
+ never see `Cookie`, `Authorization` or declared credential headers. Cloudflare
36
+ refuses extensions until its artifact format can run them.
37
+
38
+ The implementations live in their own repositories, each with an
39
+ implementation-status file that is the authoritative feature list:
40
+ [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth) (accounts, sessions,
41
+ MFA, roles, account page, operator CLI), [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin)
42
+ (users, sessions, roles, audit, approvals, cases, impersonation) and
43
+ [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui) (escaped templates,
44
+ partials, themes, translations). All three are Apache-2.0 and published to
45
+ npm as `0.1.0-alpha.1` while first-release acceptance is reviewed; see
46
+ [issue 58](https://github.com/jimhoyd-com/urlcode/issues/58) for what remains:
47
+ browser and device WebAuthn coverage, accessibility assessment, soak, backup
48
+ and recovery drills on a deployment, live provider senders and independent
49
+ security review. [The framework](docs/FRAMEWORK.md) describes how the four
50
+ packages compose, and [next steps](docs/NEXT-STEPS.md) is the phased plan to
51
+ close the remaining gaps.
52
+
53
+ ## Capability foundation — implemented, unreleased
54
+
55
+ `urlcode capabilities [--target self-hosted|cloudflare|aws|vercel] [--json]`
56
+ and the public capability API centralize target support for handlers, bindings
57
+ and effective policies. Runtime activation and Cloudflare builds use the shared
58
+ preflight; unknown targets fail closed and unsupported requirements identify the
59
+ route and capability before resources or artifacts are created. The existing
60
+ compiled route IR is documented, not replaced. Configuration-dependent and
61
+ delegated behavior remain explicit; all provider deployments remain unverified.
62
+ See [capabilities](docs/CAPABILITIES.md) and the
63
+ [next-phase review and implementation status](docs/NEXT-PHASE-PLAN.md).
64
+
65
+ ## Portability and URL behavior — implemented, unreleased
66
+
67
+ Strict redirect interchange supports CSV/JSON/YAML, Netlify and Cloudflare
68
+ `_redirects`, a bounded Netlify TOML subset and Vercel redirects. Conversion
69
+ reports refuse unsupported semantics; provider differences require explicit
70
+ acknowledgment and are never called lossless. A synthetic conformance fixture
71
+ and bounded HTTPS runner distinguish local adapter tests from observed
72
+ provider deployments. Actual Cloudflare/AWS/Vercel deployment evidence remains
73
+ pending; this does not complete M4.
74
+
75
+ Exact query/header/cookie/origin/method conditions and disjoint conditional
76
+ redirect/response cases run in the self-hosted, AWS and Vercel runtimes.
77
+ Cloudflare refuses these until its compiler can preserve their semantics.
78
+ Self-hosted proxy and webhook signals use explicit revision-pinned operator
79
+ origin grants, connection-pinned public DNS and bounded transport. Signals
80
+ have no durable delivery or retry guarantee. Other targets refuse proxy and
81
+ signals. See [conditions](docs/CONDITIONS.md), [egress](docs/EGRESS.md),
82
+ [interchange](docs/INTERCHANGE.md) and
83
+ [provider verification](docs/PROVIDER-VERIFICATION.md).
84
+
85
+ ## Developer ecosystem — implemented, unreleased
86
+
87
+ Bundled Git-owned recipes, safe bulk imports into route includes, build-time
88
+ TypeScript guest transpilation, read-only inspection APIs and optional stdio
89
+ MCP tooling are available. The runtime still executes only JavaScript inside
90
+ QuickJS/WASM; TypeScript authoring does not add host execution. Bulk benchmarks
91
+ successfully cover 1,000, 10,000 and 100,000 routes without relaxing parser
92
+ limits. See [recipes](docs/RECIPES.md), [bulk evidence](docs/BULK.md),
93
+ [TypeScript authoring](docs/TYPESCRIPT-AUTHORING.md) and
94
+ [SDK/MCP](docs/TOOLING.md). These features do not supply durable signals,
95
+ protected downloads, a remote marketplace or provider deployment proof.
96
+
14
97
  ## TypeScript source and shipped declarations — implemented, unreleased
15
98
 
16
99
  The runtime, scripts, tests and benchmarks are TypeScript under a strict
@@ -167,7 +250,7 @@ Implemented the page/static/download portion of M2: project-contained asset
167
250
  snapshots, automatic MIME types, attachment names, HEAD, cache validators and
168
251
  single byte ranges. Dedicated public directories, symlink/hardlink rejection and
169
252
  bounded memory are part of the contract. [Asset guide](docs/ASSETS.md).
170
- Bulk tools, templates and signals remain open; M2 is not complete.
253
+ Bulk tools, recipes and best-effort signals were added in the unreleased next-phase work above; they were not part of alpha.3.
171
254
 
172
255
  ## Security correction — 0.1.0-alpha.2
173
256
 
@@ -190,7 +273,7 @@ CI and a non-root container build are included. See the [contract](docs/SPECIFIC
190
273
  and [operations guide](docs/OPERATIONS.md) for exact support and evidence limits.
191
274
 
192
275
  Still open in the early contract: host namespaces, stable identity beyond paths,
193
- TypeScript support, fuller parameter vocabulary and capability/artifact planning.
276
+ fuller parameter vocabulary. Build-time TypeScript authoring and capability planning are now implemented in the unreleased work above.
194
277
  No claims of complete M0/M1 or stable production readiness. M2–M4 work continues
195
278
  in the order below; a few independently useful operational foundations shipped early.
196
279
 
package/SECURITY.md CHANGED
@@ -16,6 +16,13 @@ execution platform. Authorized inputs/secrets can be exposed
16
16
  by code receiving them; grant the minimum required authority. Do not deploy
17
17
  older snapshots for untrusted functions; review and upgrade to the current revision.
18
18
 
19
+ Declarative proxy and signal handlers run in a separate bounded host transport;
20
+ they do not grant guest networking. They require per-route, per-purpose HTTPS
21
+ origin grants pinned to the project revision. Every connection checks public
22
+ addresses and pins DNS, refuses redirects, filters headers and limits resources.
23
+ See [egress semantics and limitations](docs/EGRESS.md). Build-time TypeScript
24
+ transpilation and read-only MCP do not execute project code in the host.
25
+
19
26
  ## Report a vulnerability privately
20
27
 
21
28
  Use [GitHub private vulnerability reporting](https://github.com/jimhoyd-com/urlcode/security/advisories/new).
@@ -36,5 +43,5 @@ Bind loopback by default; protect public deployments with HTTPS, rate limits,
36
43
  network controls and restricted operational endpoints. See [operations](docs/OPERATIONS.md).
37
44
 
38
45
  See the [internal security reviews](docs/SECURITY-AUDIT.md) — most recently
39
- 2026-09-17 — for fixed findings and remaining gates. Use a current reviewed commit: the shared 0.2.0
46
+ 2026-09-17 — for fixed findings and remaining gates. Use a current reviewed commit: the shared 0.3.0
40
47
  version label alone does not identify which hardening patches are present.