Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/docs/conduct/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ How work is done in Comline's repositories.

- [Branch rules](branch-rules.md): how changes reach a default branch, the
required checks, review, and accepting a benchmark regression.
- [Phases and promises](phases.md): early days, previews and the 1.0
announcement, and what is promised in each.
57 changes: 57 additions & 0 deletions docs/docs/conduct/phases.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Phases and promises

What Comline promises, and when. Decided 2026-10-27.

## Phases

- **Early days,** which is now.
- **Previews,** smaller announcements before 1.0. Still early days.
- **The 1.0 announcement,** which is what sets stability.

## Always

- Correctness, conformance, performance and safety are never lowered.
- The [branch rules](branch-rules.md) and required checks apply.
- A change to wire behaviour comes with conformance vectors, and every
runtime passes them.

## Early days

Until the 1.0 announcement.

- Every version is `0.x`.
- Anything may break:
- APIs and generated code;
- the C ABI, where a minor bump counts as breaking;
- the IR and config formats.
- Wire formats (`packed@1`, `datagram@2`, `jsonrpc@1`, `comline@1`) may change
their bytes in place, but only in one cascade:
- the vectors change;
- every runtime (Rust, TypeScript, the simulator) passes them;
- all of it before anything merges.
- No deprecation periods.
- Everything is consumed by git revision, with pins such as `VECTORS_REV` and
the comline-core revision.
- No registry publishing, no release workflow, no prebuilt binaries.
- Proposals may still change.

## Previews

- Smaller announcements before 1.0.
- They keep the early-days rules and say so: `0.x`, breaks allowed.

## From the 1.0 announcement

- Semver: a break needs a major version.
- Anything users rely on is marked deprecated, with its replacement already
available, in at least one minor release before the major that removes it.
The changelog says so both times.
- A wire format's bytes never change again. A change is a new `@N`.
- The C ABI's structs are frozen within a major. Status codes and flags are
append-only.
- Packages go to registries (npm, crates.io, …) under ComlineProject-owned
names.
- Published from CI with trusted publishing (OIDC), no long-lived tokens.
- Reproducible builds, with published checksums.
- Inter-repo development may keep using git revisions.
- Background: [Ownership & packaging](../design/runtime-repo-structure.md#ownership-packaging).
10 changes: 6 additions & 4 deletions docs/docs/design/runtime-repo-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ overhead with no payoff, so `comline-core` and `comline-codegen` are consumed by
git rev — the way `generation` and `cli` already consume `core`. The cost is
coordinated rev bumps across repos (and one `comline-core` in any given tree, so
the CLI composes targets pinned to the same rev). Publishing to crates.io is a
later call, not a prerequisite for anything below.
later call, not a prerequisite for anything below; the
[phases page](../conduct/phases.md) says when.

### Why the reversal

Expand Down Expand Up @@ -215,9 +216,10 @@ Steps 2–3 are the real prerequisites for a *second* target repo. `generation`'
G3 in [Generation → G3](generation.md#g3-split-to-per-language-repos) is steps
1 + 4 + 5 + 6 from the codegen side.

**Publishing to crates.io** stays an open call for later. If the coordinated
git-rev bumps across `comline-<lang>` repos get painful, that is the trigger to
revisit — releasing `comline-core` and `comline-codegen` with semver is the fix,
**Publishing to crates.io** stays an open call for later; registries come
with the 1.0 rules on the [phases page](../conduct/phases.md). If the
coordinated git-rev bumps across `comline-<lang>` repos get painful, that is the
trigger to revisit — releasing `comline-core` and `comline-codegen` with semver is the fix,
and it slots in without reordering anything here.

## Ownership & packaging
Expand Down
3 changes: 2 additions & 1 deletion docs/docs/proposals/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ reference. One proposal in three stages, read in order:
handshake, framings and connection state machine behind a stable C ABI and
WASM, built from one crate. ***accepted***, steps 1–3 built: the core
changes, the C ABI at 0.1 ([reference](../reference/c-abi.md)), and its
vectors, fuzzing and benchmarks. Bindings and ABI 1.0 are next.
vectors, fuzzing and benchmarks. Bindings are next: TypeScript through wasm. The ABI stays `0.x` until the
[1.0 announcement](../conduct/phases.md).
- [Stage 3 — generated codecs](shared-runtime-core/generated-codecs.md):
native per-type codecs and protocol glue rendered from one plan in the
codegen kernel. *under discussion.*
Expand Down
36 changes: 20 additions & 16 deletions docs/docs/proposals/shared-runtime-core/core-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ else on this page is as proposed.
The glue also reserves its regions on every call, not up front, and returns
copies, so no view of wasm memory outlives a call.
- **Deferred:**
- `comline_connection_size` and `comline_connection_init` come after 1.0, as a
minor addition;
- `comline_connection_size` and `comline_connection_init` are a later
addition;
- `comline@2`'s negotiation comes before 1.0 if it changes the event struct.

### Found along the way
Expand Down Expand Up @@ -420,7 +420,7 @@ The FFI layer is for every other language, and Rust never pays for it.
serde_json. See [Found along the way](#found-along-the-way).
- A host with no allocator story of its own (embedded C, Zig) can get a
later `comline_connection_size(cfg)` / `comline_connection_init(mem, …)`
pair. That is a minor ABI addition, **after 1.0**, not part of it.
pair. That is a later addition, not part of the ABI as built.

**Panics never cross.**
- Since Rust 1.81, a panic unwinding out of an `extern "C"` function aborts
Expand Down Expand Up @@ -468,6 +468,9 @@ The FFI layer is for every other language, and Rust never pays for it.
first use.
- **Before 1.0, a minor counts as a major.** A binding built against `0.n`
accepts only `0.n`, so nothing pre-release is mistaken for compatible.
- **The freeze comes with the project's 1.0 announcement,** not with a
milestone of the ABI's own ([phases](../../conduct/phases.md)). The ABI stays
`0.x` until then.
- **Structs are frozen within a major.** New data comes through new
functions or new flag bits. A `struct_size` field is not used, because
every binding would have to honour it.
Expand Down Expand Up @@ -627,9 +630,11 @@ addition, not a replacement.

## Distribution

**This is a sketch and an open question.** It needs its own pass before the
release workflow and prebuilt binaries ([rollout](#rollout) step 5). Nothing
in it is built.
**This is a sketch and an open question.** Nothing in it is built.

- Releases, registries and prebuilt binaries follow the post-1.0 rules on the
[phases page](../../conduct/phases.md).
- Until then, bindings pin a runtime revision.

**Targets.** Prebuilt binaries per triple, from `runtime`'s release
workflow:
Expand Down Expand Up @@ -714,7 +719,7 @@ stays a separate idea.
**Settled by the build:**

- **Handle memory for no-allocator hosts:** `comline_connection_size` /
`comline_connection_init` come after 1.0, as a minor addition.
`comline_connection_init` are a later addition.
- **`max_waiting` overflow:** an error to the caller of `encode_request`,
`COMLINE_ERR_BUSY`. Queueing is the binding's job.
- **Whether `jsonrpc@1`'s `serde_json` dependency fits the no-`std` FFI
Expand All @@ -725,8 +730,8 @@ stays a separate idea.
**Still open:**

- **Whether `comline@2`'s negotiation** (protocol numbers handed out at the
handshake) changes the event struct. If so, it should land before ABI 1.0
freezes.
handshake) changes the event struct. If so, it should land before 1.0,
when the ABI freezes.
- **`pyo3` vs `cffi` for Python,** and whether a second binding surface is
ever worth it. Decided by gates, but the default needs picking.
- **Go without cgo:** wazero against pure Go, measured on the same
Expand All @@ -748,13 +753,12 @@ Steps 1–3 are done ([What's built](#whats-built)).
3. **A C test binding** in `runtime` CI runs the conformance vectors through
the C ABI and the wasm32 build: **done.** C and Node replay the same 65
cases as Rust. This proves the boundary before any language depends on it.
4. **The first two real bindings, chosen to stress the boundary:**
- **TypeScript**, through WASM and napi: stage 4's question;
- **Go**, through cgo: the most expensive call.
Both run the stage 1 gates against the TypeScript runtime and a pure-Go
baseline.
5. **ABI 1.0** once both bindings pass, then the release workflow and
prebuilt binaries.
4. **The first real binding: TypeScript, through WASM** (stage 4). Each
piece moves only where instruction counts show the core costs no more than
the TypeScript it replaces. napi and Go (cgo, the most expensive call)
come later, chosen by those numbers.
5. **Bindings pin a runtime revision.** Releases and prebuilt binaries come
with the 1.0 rules ([phases](../../conduct/phases.md)).
6. **Further languages** each bring a binding and a generator backend in
their own repo.

Expand Down
6 changes: 5 additions & 1 deletion docs/docs/proposals/shared-runtime-core/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ Split the work by what can cross a language boundary cheaply.
| Stage | Page | State |
|---|---|---|
| 1 | [Verification: differential fuzzing and benchmark gates](verification.md) | accepted, in progress |
| 2 | [One protocol core: a C ABI and WASM from one crate](core-interface.md) | accepted; rollout steps 1–3 built, bindings and ABI 1.0 next; see the [C ABI reference](../../reference/c-abi.md) |
| 2 | [One protocol core: a C ABI and WASM from one crate](core-interface.md) | accepted; rollout steps 1–3 built, bindings next: TypeScript through wasm; see the [C ABI reference](../../reference/c-abi.md) |
| 3 | [Codecs and protocol glue generated from one plan](generated-codecs.md) | proposal |
| 4 | Move TypeScript onto the core where the benchmarks allow | agreed |
| 5 | Clean up the leftovers and the documents that contradict this | agreed |
Expand All @@ -129,6 +129,10 @@ rule CI enforces. Without it, stages 2–4 would be judged by opinion.
vectors, fuzzing and gates.
- The browser has no native option at all. The playground simulator already
runs the core there.
- The current plan is TypeScript through wasm only, each piece moving only
where instruction counts show the core is at least as fast. napi and Go
come later, chosen by those numbers. The C ABI stays `0.x` until the project
announces 1.0 ([phases](../../conduct/phases.md)).

**Stage 5: the cleanup.**
- **Remove or split `runtime/core/src/package_abi`.** It pulls `abi_stable`
Expand Down
10 changes: 7 additions & 3 deletions docs/docs/reference/c-abi.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ for the `comline@1` handshake, the connection framings (`datagram@2`,
`jsonrpc@1`), envelopes, connection state and frame limits. Codecs,
transports, async and dispatch stay in each host.

- **ABI version 0.1.** It is not frozen; see [Version](#version).
- **ABI version 0.1.** It is not frozen; it freezes when the project announces
1.0 ([phases](../conduct/phases.md)). See [Version](#version).
- **Source:** [`runtime/ffi`](https://github.com/ComlineProject/runtime/tree/main/runtime/ffi)
in the runtime repository.
- **Header:** [`include/comline.h`](https://github.com/ComlineProject/runtime/blob/main/runtime/ffi/include/comline.h).
Expand All @@ -30,6 +31,8 @@ header disagree, the header is right.

- **Before 1.0, a minor counts as a major.** A host built against `0.1` accepts
only `0.1`. The JS glue does exactly this.
- **The freeze comes with the project's 1.0 announcement,** not with an ABI
milestone of its own ([phases](../conduct/phases.md)).
- The major changes when a signature, a struct layout or the meaning of a code
changes. The minor changes when functions, codes or flag bits are added.
- Structs are frozen within a major. New data comes through new functions or new
Expand Down Expand Up @@ -430,8 +433,9 @@ a 1% rise, like the core's benches. Both sides of each pair are gated.
## Not here yet

- **`comline_connection_size` and `comline_connection_init`,** for a host that
supplies the handle's memory. After 1.0.
supplies the handle's memory. A later addition.
- **`comline@2`'s negotiation** hands protocol numbers out at the handshake and
may change the event struct. If it does, it lands before 1.0 freezes the ABI.
may change the event struct. If it does, it lands before the 1.0
announcement freezes the ABI.
- **Bindings.** No language binds the ABI yet; the JS glue is the only host
code, and it is a thin wrapper, not a binding.
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ nav:
- Conduct:
- 'conduct/index.md'
- 'Branch rules': 'conduct/branch-rules.md'
- 'Phases and promises': 'conduct/phases.md'

extra_css:
- stylesheets/nav.css?v=21 # bump on every nav.css change — it is not cache-busted otherwise
Expand Down
Loading