Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A `PacketParts` struct decomposes a packet into its components:
let parts = PacketParts::new(id, correlation_id, payload);
```

- `id: u32` — frame identifier
- `id: u32` — packet/envelope identifier used for routing
- `correlation_id: Option<u64>` — `None` marks an unsolicited event or
server‑initiated push
- `payload: Vec<u8>` — raw message bytes
Expand Down
2 changes: 2 additions & 0 deletions docs/contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ the-road-to-wireframe-1-0-feature-set-philosophy-and-capability-maturity.md

## Reference guides

- [Developers' guide](developers-guide.md) Canonical architectural vocabulary
and naming invariants.
- [Refactoring guide](complexity-antipatterns-and-refactoring-strategies.md)
Strategies for taming code complexity and refactoring.
- [Builder pattern conventions](builder-pattern-conventions.md) Guidance for
Expand Down
51 changes: 51 additions & 0 deletions docs/developers-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Wireframe developers' guide

This guide defines the architectural vocabulary used across Wireframe source,
rustdoc, and user-facing documentation. Treat it as the naming contract for new
APIs and refactors.

## Layer model and glossary

| Layer | Canonical term | Primary types | Description |
| --------------------- | ----------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------- |
| Transport framing | Frame | `FrameCodec::Frame`, `LengthDelimitedFrameCodec` | Physical wire unit read from or written to the socket. |
| Routing envelope | Packet / Envelope | `Packet`, `Envelope`, `PacketParts` | Routable wrapper that carries route id, optional correlation id, and payload bytes. |
| Domain payload | Message | `message::Message`, extractor `Message<T>` | Typed application data encoded into packet payload bytes. |
| Transport subdivision | Fragment | `FragmentHeader`, `Fragmenter`, `Reassembler` | Size-limited chunk used when a payload exceeds frame budget. |

## Naming invariants

- Frame terms belong to codec and socket boundaries only.
- Packet or envelope terms belong to routing and middleware request/response
wrappers.
- Message terms belong to typed payload encode/decode concerns.
- Fragment terms belong to transport splitting and reassembly.
- Correlation identifiers are cross-layer metadata and may appear on frame,
packet, and message-adjacent APIs when protocol metadata requires it.

## Allowed aliases and prohibited mixing

| Canonical term | Allowed aliases | Avoid in the same context |
| ----------------- | ------------------------------ | ----------------------------------------- |
| Frame | wire frame, transport frame | packet, envelope, message |
| Packet / Envelope | routable envelope | frame (unless describing codec transport) |
| Message | payload type, domain message | frame, fragment |
| Fragment | fragment frame, fragment chunk | packet, message |

## API and docs checklist

Use this checklist before merging API naming changes:

- Confirm the identifier name matches the owning layer.
- Confirm rustdoc examples use the same term as the symbol being documented.
- Confirm `docs/users-guide.md` and migration notes describe the same meaning.
- Confirm cross-layer terms (for example, `correlation_id`) are explicitly
labelled as shared metadata.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Vary the sentence structure in the checklist.

The static analysis tool flagged three successive bullet points beginning with "Confirm". Rephrase for variety:

✏️ Suggested rewording
 Use this checklist before merging API naming changes:
 
-- Confirm the identifier name matches the owning layer.
-- Confirm rustdoc examples use the same term as the symbol being documented.
-- Confirm `docs/users-guide.md` and migration notes describe the same meaning.
-- Confirm cross-layer terms (for example, `correlation_id`) are explicitly
+- Verify the identifier name matches the owning layer.
+- Check rustdoc examples use the same term as the symbol being documented.
+- Ensure `docs/users-guide.md` and migration notes describe the same meaning.
+- Label cross-layer terms (for example, `correlation_id`) explicitly as
   labelled as shared metadata.
🧰 Tools
🪛 LanguageTool

[style] ~41-~41: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... term as the symbol being documented. - Confirm docs/users-guide.md and migration not...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~42-~42: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...tion notes describe the same meaning. - Confirm cross-layer terms (for example, `correl...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/developers-guide.md` around lines 39 - 43, The three checklist bullets
all start with "Confirm" causing repetitive phrasing; update the three lines to
use varied verbs and structures (e.g., "Ensure the identifier name matches the
owning layer," "Verify rustdoc examples use the same term as the symbol being
documented," and "Document the meaning consistently in docs/users-guide.md and
migration notes") and keep the cross-layer example (`correlation_id`) explicitly
labeled as shared metadata; adjust the three checklist items around rustdoc,
docs/users-guide.md, and identifier naming to follow this varied wording.


## Vocabulary normalization outcome (2026-02-20)

The 2026-02-20 normalization pass aligned docs and rustdoc terminology to this
model and did not rename public symbols. Existing API names (`FrameCodec`,
`Packet`, `Envelope`, `Message`, `Fragment*`) already map cleanly to separate
layers, so the implementation focused on clarifying boundaries rather than
introducing additional breaking changes.
55 changes: 45 additions & 10 deletions docs/execplans/vocabulary-normalization.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This ExecPlan is a living document. The sections `Constraints`, `Tolerances`,
`Risks`, `Progress`, `Surprises & Discoveries`, `Decision Log`, and
`Outcomes & Retrospective` must be kept up to date as work proceeds.

Status: DRAFT
Status: COMPLETE (2026-02-20)

`PLANS.md` is not present in this repository at the time this plan was drafted.

Expand Down Expand Up @@ -57,19 +57,25 @@ architectural model match.
## Progress

- [x] (2026-02-18) Drafted ExecPlan for vocabulary normalization.
- [ ] Create canonical glossary by architectural layer.
- [ ] Inventory API symbols and docs text against glossary.
- [ ] Propose targeted rename set and update map.
- [ ] Apply code and doc renames.
- [ ] Create/update developers' guide conceptual model section.
- [ ] Update migration guide and run quality gates.
- [x] (2026-02-20) Created canonical glossary by architectural layer.
- [x] (2026-02-20) Inventoried API symbols and docs text against glossary.
- [x] (2026-02-20) Proposed targeted rename set and update map.
- [x] (2026-02-20) Applied code and doc terminology updates.
- [x] (2026-02-20) Created `docs/developers-guide.md` conceptual model section.
- [x] (2026-02-20) Updated migration guide and ran quality gates.

## Surprises & Discoveries

- Observation: `docs/developers-guide.md` is currently absent.
Evidence: repository file inventory under `docs/`. Impact: this plan must
include creating the developers' guide.

- Observation: Most ambiguity was in documentation wording, not public symbol
names. Evidence: inventory audit across `src`, `docs`, and `README.md` showed
`FrameCodec`/`Packet`/`Message`/`Fragment*` symbols already follow layer
boundaries. Impact: normalized terminology in docs and rustdoc without
additional breaking API renames.

## Decision Log

- Decision: Use a glossary-first approach before any renaming.
Expand All @@ -81,9 +87,31 @@ architectural model match.
Rationale: These are the recurring conceptual boundaries in Wireframe APIs.
Date/Author: 2026-02-18 / Codex.

- Decision: Keep public symbol names unchanged in this pass and normalize
wording plus examples instead. Rationale: Existing symbols already mapped
cleanly to layers; wording fixes achieved clarity without avoidable churn.
Date/Author: 2026-02-20 / Codex.

## Outcomes & Retrospective

Not started. Populate after implementation milestones complete.
Completed implementation outcomes:

- Added a canonical layered glossary to `docs/users-guide.md`.
- Created `docs/developers-guide.md` to define naming invariants and
allowed/disallowed term mixing.
- Updated `docs/v0-1-0-to-v0-2-0-migration-guide.md` with explicit
terminology mapping and a no-additional-public-rename note.
- Updated terminology wording in public rustdoc and references
(`src/app/envelope.rs`, `docs/api.md`, `docs/contents.md`).

Validation outcomes:

- `make fmt` passed.
- `make check-fmt` passed.
- `make lint` passed.
- `make test` passed.
- `make markdownlint` passed.
- `make nixie` passed.

## Context and orientation

Expand All @@ -109,6 +137,9 @@ Potentially touched files:
- `docs/users-guide.md`
- `docs/developers-guide.md` (new file expected)
- `docs/v0-1-0-to-v0-2-0-migration-guide.md`
- `src/app/envelope.rs`
- `docs/api.md`
- `docs/contents.md`

## Plan of work

Expand Down Expand Up @@ -191,5 +222,9 @@ Expected interface effects:
- Cross-layer models are documented explicitly where names are shared.
- Developers have a stable naming contract in `docs/developers-guide.md`.

Revision note: Initial draft created on 2026-02-18 to plan layer-specific
vocabulary normalization and conceptual model documentation.
Revision notes:

- 2026-02-18: Initial draft created to plan layer-specific vocabulary
normalization and conceptual model documentation.
- 2026-02-20: Marked complete after glossary, docs/rustdoc updates, migration
mapping updates, and full quality-gate validation.
32 changes: 28 additions & 4 deletions docs/users-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ Wireframe uses progressive discovery for public APIs:
- `wireframe::prelude::*` is an optional convenience import for common
workflows.

## Conceptual model and vocabulary

Wireframe uses layer-specific terms. Keep these boundaries explicit so
transport concerns do not leak into routing or domain logic.

| Layer | Canonical term | Meaning |
| --------------------- | ----------------- | ------------------------------------------------------------------------------------- |
| Transport | Frame | The wire unit produced and consumed by `FrameCodec`. |
| Routing envelope | Packet / Envelope | The routable wrapper that carries `id`, optional `correlation_id`, and payload bytes. |
| Domain payload | Message | The typed value encoded into and decoded from payload bytes. |
| Transport subdivision | Fragment | A bounded slice of large payload bytes plus fragmentation metadata. |

Vocabulary rules:

- Use `frame` for wire-format codec units only.
- Use `packet` or `envelope` for routable wrappers (`Packet`, `Envelope`,
`PacketParts`).
- Use `message` for typed application payloads implementing
`wireframe::message::Message`.
- Use `fragment` only for transport-level split/reassembly units.

For invariants and naming rules used across internal modules, see the
[developers' guide](developers-guide.md).

## Quick start: building an application

A `WireframeApp` collects route handlers and middleware. Each handler is stored
Expand Down Expand Up @@ -1396,13 +1420,13 @@ use wireframe::app::{Packet, PacketParts};
use wireframe::correlation::CorrelatableFrame;

#[derive(bincode::BorrowDecode, bincode::Encode)]
struct MyFrame {
struct MyEnvelope {
id: u32,
correlation_id: Option<u64>,
payload: Vec<u8>,
}

impl CorrelatableFrame for MyFrame {
impl CorrelatableFrame for MyEnvelope {
fn correlation_id(&self) -> Option<u64> { self.correlation_id }
fn set_correlation_id(&mut self, cid: Option<u64>) {
self.correlation_id = cid;
Expand All @@ -1411,7 +1435,7 @@ impl CorrelatableFrame for MyFrame {

// Message is auto-implemented via the blanket impl for Encode + BorrowDecode types.

impl Packet for MyFrame {
impl Packet for MyEnvelope {
fn id(&self) -> u32 { self.id }
fn into_parts(self) -> PacketParts {
PacketParts::new(self.id, self.correlation_id, self.payload)
Expand All @@ -1423,7 +1447,7 @@ impl Packet for MyFrame {
payload: parts.into_payload(),
}
}
// A frame with id == 0 signals end-of-stream.
// An envelope with id == 0 signals end-of-stream.
fn is_stream_terminator(&self) -> bool { self.id == 0 }
}
```
Expand Down
18 changes: 18 additions & 0 deletions docs/v0-1-0-to-v0-2-0-migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ let packet_payload = packet_parts.into_payload();
let fragment_payload = fragment_parts.into_payload();
```

## Vocabulary normalization by layer

Wireframe now documents one canonical vocabulary per architectural layer in
`docs/users-guide.md` and `docs/developers-guide.md`.

No additional public symbol renames were introduced in this normalization pass.
The migration impact is terminology alignment in docs and rustdoc.

| Prior wording | Canonical wording | Scope |
| ------------------------------------------------------------- | ----------------------------- | ---------------------------------------- |
| frame identifier (routing context) | packet/envelope identifier | `Packet`, `Envelope`, `PacketParts` docs |
| frame terminator (`Packet::is_stream_terminator` docs) | envelope or packet terminator | Packet rustdoc and users' guide examples |
| generic custom packet type named `MyFrame` in packet examples | `MyEnvelope` | users' guide and rustdoc examples |

When updating application code, prefer names that follow the same layer model:
`Frame*` for transport codec units, `Packet` or `Envelope` for routing
wrappers, and `Message` for typed domain payloads.

## Unified error surface

Wireframe now exposes one canonical crate-level error type:
Expand Down
18 changes: 9 additions & 9 deletions src/app/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! These types decouple serialisation from routing by wrapping raw payloads in
//! identifiers understood by [`crate::app::builder::WireframeApp`]. This
//! allows the builder to route frames before full deserialisation. See
//! allows the builder to route packets before full deserialisation. See
Comment on lines 3 to +5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use -ize spelling for serialization terms.

Replace "serialisation" and "deserialisation" with "serialization" and
"deserialization" to match en-GB-oxendict spelling.

✏️ Proposed fix
-//! These types decouple serialisation from routing by wrapping raw payloads in
+//! These types decouple serialization from routing by wrapping raw payloads in
-//! allows the builder to route packets before full deserialisation. See
+//! allows the builder to route packets before full deserialization. See

As per coding guidelines, Comments and docs must follow en-GB-oxendict (-ize / -yse / -our) spelling and grammar.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
//! These types decouple serialisation from routing by wrapping raw payloads in
//! identifiers understood by [`crate::app::builder::WireframeApp`]. This
//! allows the builder to route frames before full deserialisation. See
//! allows the builder to route packets before full deserialisation. See
//! These types decouple serialization from routing by wrapping raw payloads in
//! identifiers understood by [`crate::app::builder::WireframeApp`]. This
//! allows the builder to route packets before full deserialization. See
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/envelope.rs` around lines 3 - 5, Update the doc-comment wording to
use en-GB-oxendict "-ize" spellings: replace "serialisation" with
"serialization" and "deserialisation" with "deserialization" in the comment that
references crate::app::builder::WireframeApp (and any other occurrences in this
module), ensuring the sentence remains grammatically correct after the
substitutions.

//! [`crate::app::builder::WireframeApp`] for how envelopes are used when
//! registering routes.

Expand Down Expand Up @@ -71,7 +71,7 @@ pub trait Packet: CorrelatableFrame + Message + Send + Sync + 'static {
/// Construct a new packet from raw parts.
fn from_parts(parts: PacketParts) -> Self;

/// Returns `true` if this frame represents an end-of-stream terminator.
/// Returns `true` if this packet represents an end-of-stream terminator.
///
/// The default implementation returns `false`. Protocol implementations
/// should override this to detect the protocol-specific terminator format
Expand All @@ -88,20 +88,20 @@ pub trait Packet: CorrelatableFrame + Message + Send + Sync + 'static {
/// };
///
/// #[derive(bincode::BorrowDecode, bincode::Encode)]
/// struct MyFrame {
/// struct MyEnvelope {
/// id: u32,
/// correlation_id: Option<u64>,
/// payload: Vec<u8>,
/// }
///
/// impl CorrelatableFrame for MyFrame {
/// impl CorrelatableFrame for MyEnvelope {
/// fn correlation_id(&self) -> Option<u64> { self.correlation_id }
/// fn set_correlation_id(&mut self, cid: Option<u64>) { self.correlation_id = cid; }
/// }
///
/// // Message is auto-implemented via the blanket impl for Encode + BorrowDecode types.
///
/// impl Packet for MyFrame {
/// impl Packet for MyEnvelope {
/// fn id(&self) -> u32 { self.id }
/// fn into_parts(self) -> PacketParts {
/// PacketParts::new(self.id, self.correlation_id, self.payload)
Expand All @@ -116,14 +116,14 @@ pub trait Packet: CorrelatableFrame + Message + Send + Sync + 'static {
/// fn is_stream_terminator(&self) -> bool { self.id == 0 }
/// }
///
/// let terminator = MyFrame {
/// let terminator = MyEnvelope {
/// id: 0,
/// correlation_id: None,
/// payload: vec![],
/// };
/// assert!(terminator.is_stream_terminator());
///
/// let data = MyFrame {
/// let data = MyEnvelope {
/// id: 1,
/// correlation_id: None,
/// payload: vec![42],
Expand All @@ -144,7 +144,7 @@ pub struct PacketParts {
/// Basic envelope type used by
/// [`crate::app::builder::WireframeApp::handle_connection`].
///
/// Incoming frames are deserialised into an `Envelope` containing the
/// Incoming packets are deserialised into an `Envelope` containing the
/// message identifier and raw payload bytes.
#[derive(bincode::Decode, bincode::Encode, Debug, Clone, PartialEq, Eq)]
pub struct Envelope {
Expand Down Expand Up @@ -206,7 +206,7 @@ impl PacketParts {
}
}

/// Return the message identifier used to route this frame.
/// Return the message identifier used to route this packet.
///
/// # Examples
///
Expand Down
Loading