writeonce/docs/stories/language-runtime-database/15-deps-package-manager.md
shoney.arickathil 976ccda225 docs: web framework + deps design — spec + iterations 15/16
Brainstorm outcome (forks locked with the developer):
- TLS: proxy-terminated (nginx/caddy gives browsers TLS+ALPN+h2; the
  framework speaks HTTP/1.1 behind it) — zero TLS in the toolchain, no
  doctrine fight; homegrown TLS refused outright.
- Dependencies: a real mini package manager — wo.toml [deps] with exact-rev
  git deps, wo.lock, .wo-deps cache, `use <dep>` as a module root; fetch by
  shelling to the git binary (no network code in woc); flat-only v1.
- HTTP/2: v1 is HTTP/1.1 keep-alive; h2c is the parked successor behind
  iterations 8/9f/11 (multiplexing needs a scheduler to pay off); the
  bytes/buffer type rides with it, not v1.
- Handler model: no function values by doctrine, so Handler/Middleware are
  structural interfaces (ICALL dispatch, WO-E205-checked); middleware returns
  ?Resp and rides the shipped ?T narrowing.
- Incubation: framework at docs/examples/writeonce-framework/, consuming
  storefront at docs/examples/web-app/ importing it THROUGH [deps] — the
  sample exercises fetch -> lock -> build -> serve -> durable-restart.
- Iteration 10 relationship: service blocks later LOWER ONTO this library.

Files: specs/2026-08-18-web-framework-design.md (A deps normative, B
framework normative, C h2c parked); stories 15-deps-package-manager.md +
16-web-framework.md; roadmap + board rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:07:16 +02:00

2.3 KiB

Iteration 15 — dependencies: wo.toml [deps], git fetch, wo.lock

Format: product/story-iteration-template. Part of Story — one language, one runtime, one database, one binary.

Inserted 2026-08-18. The enabler for code shared between writeonce repositories — the web framework (iteration 16) is the driving consumer.

Spec exists: 2026-08-18-web-framework-design.md section A is normative for this iteration.

Goals

  • A project declares exact-rev git dependencies in wo.toml [deps] (name = { git = "...", rev = "..." }); woc fetches them (via the git binary — no network code in the compiler) into .wo-deps/<name>/ and resolves use <name> / use <name>/sub into the dep's module tree.
  • wo.lock pins resolved SHAs: builds are reproducible, a moved tag is reported rather than silently followed, and a lock-satisfied build never touches the network.
  • Honest edges: transitive [deps] refused with a diagnostic (flat-only v1), dep/local module-name collisions diagnosed, a dep's fn main ignored, pub applies across the boundary exactly as across modules.

Acceptance Criteria

  • Given an app whose [deps] names a framework in a local file:// git repo, when woc <app> runs twice, then the first run fetches + writes wo.lock, the second builds offline from .wo-deps, and the built binary runs.
  • Given the dep's tag moved after wo.lock was written, when the app builds, then the lock wins and the drift is reported; woc --update-deps refreshes it.
  • Given a dep whose own wo.toml has [deps], or a dep name colliding with a local module, when the app builds, then each is a named diagnostic, never silent misresolution.

Out Of Scope

Registries, version ranges/semver solving, transitive dependencies (the successor's first fork), private-remote auth handling beyond what ambient git config provides, vendoring commands.

Proposed Solution

Manifest parsing extends compiler/bin/main.ml's existing wo.toml reader; fetch = Sys.command over the git binary; resolution plugs the dep root into the existing directory-as-module discovery. Fixtures under tests/ use local file:// remotes so the suite stays network-free.