Skip to content

docs: adopt Linked Literate Programming (LLP) — waves 0–2#81

Draft
philcunliffe wants to merge 9 commits into
masterfrom
worktree-llp-flow
Draft

docs: adopt Linked Literate Programming (LLP) — waves 0–2#81
philcunliffe wants to merge 9 commits into
masterfrom
worktree-llp-flow

Conversation

@philcunliffe
Copy link
Copy Markdown
Contributor

Stands up a Linked Literate Programming documentation system in HypAware: numbered, Systems-tagged, living design docs under llp/ that code can @ref into at section granularity. Humans stay in markdown; AI writes/reviews code against the referenced decisions.

This is the planned adoption plan first retrofit (see llp/0001-adopting-llp.plan.md), executed in three waves.

Wave 0 — foundation

  • llp/ + llp/tombstones/; LLP 0000 root explainer with the subsystem map and cross-cutting invariants.
  • LLP 0001 — the adoption plan itself (now Active).
  • LLP 0002V1 scope & cutover decisions. finish-v1.md's ## Decisions are live, as-shipped reality (publish as hypaware, bundled first-party plugins, central/gascity out of scope) and diverge from the design doc, so they became a live Decision rather than getting tombstoned.
  • AGENTS.md gains a ## Design docs (LLP) section: read-before-change, @ref policy, /ref-check.

Wave 1 — Sources exemplar (the dogfood test)

  • LLP 0012 Sources spec (design doc + CONTEXT.md glossary).
  • 4 real @ref annotations in src/core/registry/sources.js (register / start / reload), upgrading the file's pre-existing informal §Sources mention into machine-readable links with [implements] / [constrained-by] relations.
  • /ref-check4 references, 0 broken, exit 0.

Wave 2 — bulk decomposition

  • LLP 0003–0017 from hypaware-design.md's Design Decisions (core surface, activation/paths, manifest, deps/capabilities, install/lock, runtime deps, CLI, config, onboarding, cache, sinks, query+collect, AI gateway, daemon).
  • Monolithic docs tombstoned: 0018 impl-plan, 0019 finish-v1, 0020 design — each with a header explaining where its content went.
  • Repointed broken links in README.md and collectivus-plugin-kernel-types.d.ts to the LLP corpus.

Validation

  • 72 inter-LLP links + anchors resolve (fixed 2 em-dash anchor breaks).
  • All code @ref anchors resolve.
  • Final shape: 18 active LLPs (0000–0017) + 3 tombstones (0018–0020).

Reviewing

Good entry points: llp/0000-hypaware.explainer.md, the @refs in src/core/registry/sources.js, llp/0002-v1-scope.decision.md.

Notes / follow-ups

  • Numbering shifted +1 from the plan's draft map (0002 inserted) — Sources is 0012; LLP 0000's map is authoritative.
  • ~12 source/smoke files still carry prose comments like finish-v1.md §Phase 3 — not broken (prose, not links), but the natural Wave 3 boy-scout @ref conversion targets.
  • No code behavior changes; docs + comment annotations only.

🤖 Generated with Claude Code

philcunliffe and others added 9 commits June 1, 2026 14:26
Stand up an LLP documentation system: numbered, Systems-tagged, living
design docs under llp/ that code can @ref into at section granularity.

Wave 0 — foundation
- llp/ + llp/tombstones/; LLP 0000 root explainer with subsystem map
- LLP 0001 adoption plan (this rollout); LLP 0002 V1 scope & cutover
  decisions (lifted from finish-v1's live Decisions, which diverge from
  the design doc and must stay active rather than be tombstoned)
- AGENTS.md: new "Design docs (LLP)" section (read-before-change,
  @ref policy, /ref-check)

Wave 1 — Sources exemplar
- LLP 0012 Sources spec
- 4 real @ref annotations in src/core/registry/sources.js
  (register/start/reload), validated by /ref-check (0 broken)

Wave 2 — bulk decomposition
- LLP 0003–0017 from hypaware-design.md's Design Decisions
- Monolithic docs tombstoned: 0018 impl-plan, 0019 finish-v1,
  0020 design (decomposed)
- Repointed README + kernel-types.d.ts links to the LLP corpus

Validation: 72 inter-LLP links/anchors resolve; all code @ref anchors
resolve. 18 active LLPs (0000–0017) + 3 tombstones.
Commit the LLP toolset under .claude/skills/ so every clone (teammates,
CI, cloud sessions) gets the slash commands, not just this machine's
global skills dir:

- llp-init, llp-init-retrofit, llp-create, llp-list, llp-review
- ref-check, ref-story
- llp-grill — new: stress-tests a plan against the LLP corpus and
  Systems vocabulary, capturing decisions inline (the LLP-aware
  counterpart to grill-with-docs)

AGENTS.md now points at .claude/skills/ as the in-repo home of the
tooling.
Fill the one subsystem gap from the decomposition: src/core/observability
(~1.8k LOC) had no governing LLP. Captures the load-bearing decisions:

- dual exporter strategy (JSONL dev vs OTLP) and the self-loop guard
  (!devTelemetry && otlpEndpoint) behind the otel_self_loop_guard smoke
- the normalized, queryable attribute contract (Attr.* + buildAttrs:
  snake_case keys, fixed status vocabulary, bounded cardinality)
- withSpan/runRoot as the sanctioned lifecycle-instrumentation wrappers
- secret-safety policy and shutdown/flush semantics

Adds Observability to the Systems vocabulary and the LLP 0000 map.
No @ref annotations yet — those land with the separate Wave 3 pass.
Link the self-instrumentation code to its governing spec, upgrading the
informal "Phase 0 contract" / "self-instrumentation contract" prose to
real @ref annotations:

- tracer.js: exporter-selection strategy + the self-loop guard
  (!devTelemetry && otlpEndpoint) as [constrained-by]
- attrs.js: buildAttrs + Attr vocabulary -> the-attribute-contract
- span_helpers.js: withSpan/runRoot -> span-helpers
- index.js: idempotent install + reverse-order shutdown/flush
- jsonl_exporters.js: lazy-open file mechanics + flatten-for-queryability
- meter.js: mirrored exporter strategy + kernel instrument set

/ref-check src/core/observability: 12 refs, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Link the kernel registries to their governing specs:

- sinks.js: export-targets framing, the blob/table-format/request
  instantiation shapes (bytes-flow-down), and the writer+destination
  intersection that makes a sink queryable (0014)
- datasets.js: core registers zero datasets; plugins contribute all (0015)
- query/sql.js: core-owned read-only SQL, IO only via storage service (0015)
- commands.js: core owns dispatch, plugins only register (0009)
- capabilities.js: requireCapability as the sole cross-plugin channel and
  semver range travelling with the require, not the name (0006)

/ref-check src/core/registry src/core/query: 13 refs, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Link activation, paths, and the config model to their specs (and retire
the "Phase 2 contract in hypaware-implementation-plan.md" pointer, now in
the tombstoned 0018):

- paths.js: kernel-owned scoped per-plugin dirs (0004#state-directories)
- activation.js: the per-plugin activation context, and the capability
  facade that pins the activating plugin's identity (0004, 0006)
- config/schema.js: v2 shape with no mode field, the blob-vs-request sink
  shapes, per-plugin section validation (0010, 0014)
- config/validate.js: cross-plugin validation after manifests load, the
  writer/destination blob-store check, and 5-field-cron-only schedules

/ref-check src/core/runtime src/core/config: 9 refs, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0017

Link the remaining V1 subsystems to their decisions, and retire stale
pointers into the now-tombstoned finish-v1 / implementation plans:

- cache: retention as the central tradeoff (permanent per-dataset
  eviction) and the parsed-but-unwired wait_for_sink_ack open question;
  the kernel-owned cache write path (0013)
- plugin_install: the single resolution precedence and the git-artifact
  install that never runs npm install on the user's machine (0007)
- daemon: the primary daemon loop, and launchd/systemd install pointed at
  the stable global binary; dropped finish-v1.md §Phase 4 pointers (0017)
- cli: the interactive picker, autodetect-only-seeds-checkbox, config
  composition with no role labels, and the non-interactive init path
  (0011, 0002)

/ref-check src/core/{cache,plugin_install,daemon,cli}: 15 refs, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…0008

Link the plugin layer and representative smokes to the category decisions
they realize and exercise:

- plugins: ai-gateway knows nothing about Claude/Codex; claude/codex are
  adapters that require the gateway capability (and contribute walkthrough
  skills); otel is an OTLP source; local-fs/s3 provide hypaware.blob-store
  with format kept separable; format-parquet's encoder declares queryable
- runtime/loader.js: plugins load only through their single manifest
  entrypoint — the pure-JS, no-npm-install consequence (0008)
- smokes (daemon, otel, parquet sink, attach, config validate, cache
  roundtrip): tagged [tests] against the decision each one proves

/ref-check src + hypaware-core: 64 refs, 0 broken, across 14 active LLPs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two active specs had no code annotation. Both have a clean home:

- manifest.js validateManifest -> LLP 0005#declarative: one manifest shape
  declares requires/provides/contributes; plugin category is emergent.
- activation.js createKernelRuntime -> LLP 0003#intrinsic-not-plugin-provided:
  query + storage are wired in as intrinsic services, not contributions.

Leaves only 0000 (root map) and 0001 (LLP-adoption plan) unreferenced —
both meta docs with no subsystem code to annotate. 66 refs, 0 broken.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant