Skip to content
Merged
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
126 changes: 126 additions & 0 deletions docs/v0.4-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Bakelite 0.4 — Remaining Work

Items to implement after the modernization PR chain (PRs #1–7) lands.
Reference: original PR #10 (`feature/modernization-and-async`).

## 1. Simplified type system (breaking change)

The biggest change in 0.4. All `bytes[N]`, `string[N]`, and `T[N]` become
variable-length with max capacity N. No more fixed-length semantics.

### Wire format

- `bytes[N]` — 1-byte length prefix + up to N bytes
- `string[N]` — null-terminated, up to N chars (no padding)
- `T[N]` — 1-byte length prefix + up to N elements

Comment on lines +13 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Define behavior for capacities above 255 in the new wire format.

Using a fixed 1-byte length prefix conflicts with unconstrained N. Please explicitly constrain N <= 255 in grammar/spec, or switch to a wider/variable-length prefix to avoid silent truncation/format ambiguity.

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

In `@docs/v0.4-plan.md` around lines 13 - 16, The spec's 1-byte length prefix for
bytes[N], string[N], and T[N] is ambiguous for capacities >255; update the
grammar to either explicitly constrain the capacity by adding "N <= 255" to the
definitions of bytes[N], string[N], and T[N], or replace the 1-byte prefix with
a wider/variable-length length-field (e.g., 2-byte fixed width or a varint) and
describe its encoding (endianness/varint scheme) and max representable length so
the wire format no longer silently truncates or misinterprets lengths above 255.

### Grammar changes

The Lark grammar (`protodef.lark`) needs updating:

- `bytes[N]` and `string[N]` require a size — no more bare `bytes[]`/`string[]`
- `T[N]` always requires a size
- The `prim_variable` rule becomes `prim_sized` with higher priority

### Code generator changes

**Python** — Arrays and bytes use length-prefix encode/decode in the generated
`pack()`/`unpack()` methods. Strings use null-termination helpers.

**cpptiny** — New `SizedArray<T, N>` template with vector-like API (`size()`,
`push_back()`, iterators). Strings map to `char[N+1]`. The serializer
(`serializer.h`) gains variable-length read/write helpers.

**ctiny** — `bytes[N]` and `T[N]` use inline anonymous structs:
`{ T data[N]; uint8_t len; }`. Strings map to `char[N+1]`.

### Other effects

- Remove heap parameter from ctiny/cpptiny decode functions
- Structs become self-contained with inline storage
- Parser type representation (`types.py`) needs adjustment — the `size` field
on `ProtoType` becomes the max capacity
- All tests and examples need updating for new wire format

### New module: `sizes.py` + `bakelite info` command

A size calculator (`bakelite/generator/sizes.py`) that computes min/max wire
sizes for every struct and protocol-level RAM estimates for embedded targets.

Key types:
- `SizeInfo(min_size, max_size, kind)` — where kind is `FIXED` or `BOUNDED`
- `StructSizeInfo(name, size)`
- `ProtocolSizeInfo` — protocol-level aggregation including CRC overhead,
COBS framing overhead, and estimated RAM for ctiny/cpptiny

The `bakelite info -i <file>` command renders this as a rich table (via `rich`)
or JSON (`--json`). Add `rich` as a dependency.

## 2. Documentation rewrites

### Protocol specification (`docs/protocol.md`)

Full rewrite of the protocol spec:
- Replace HTML tables with Unicode box-drawing diagrams
- Remove unimplemented "Not for V1" sections
- Add quick reference table for all types
- Add formal grammar reference
- Reorganize into: Overview → Types → Structs → Enums → Protocol blocks

### Python docs (`docs/python.md`)

- Add async examples using `messages()` iterator
- Document `async_=True` parameter
- Update version requirement to Python 3.13+

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

What Python language/runtime features introduced in Python 3.13 would justify setting a project minimum version to 3.13+, and what are common compatibility tradeoffs for CLI/library projects?

💡 Result:

Key Python 3.13 features justifying a minimum version of 3.13+ for projects include an improved interactive interpreter (REPL) with multi-line editing, colorized tracebacks by default, experimental free-threaded mode (no-GIL, PEP 703) for better multi-threading performance in CPU-bound tasks, an experimental JIT compiler (PEP 744) for potential speedups, defined semantics for locals mutations (PEP 667), typing improvements like default type parameters (PEP 696), and removal of 19 dead battery stdlib modules (PEP 594) plus lib2to3. For CLI/library projects, common compatibility tradeoffs are minimal for pure Python code: most changes are additive or opt-in. However, projects using removed modules (e.g., cgi, pipes, telnetlib, audioop) must migrate to alternatives like shlex for pipes or third-party libs. C extensions need checking for free-threading compatibility if using that mode (via Py_mod_gil slot); standard builds are backward-compatible. Some third-party libs had initial issues (e.g., docstring handling, argparse output changes, removed module deps like pipes in python-fire), but most popular packages now support 3.13. Test thoroughly, especially REPL-dependent CLIs benefit greatly. Longer support (2 years bugfixes + 3 years security) vs older versions aids maintenance.

Citations:


🏁 Script executed:

# Find project metadata files to understand current Python requirements
git ls-files | grep -E "(pyproject\.toml|setup\.py|setup\.cfg|tox\.ini|.github)" | head -20

Repository: emmapowers/bakelite

Length of output: 133


🏁 Script executed:

# Look at the v0.4-plan.md file to understand context
head -100 docs/v0.4-plan.md | tail -50

Repository: emmapowers/bakelite

Length of output: 1657


🏁 Script executed:

# Search for any Python version constraints in project files
fd -e toml -e py -e cfg -e ini | xargs grep -l "python" 2>/dev/null | head -10

Repository: emmapowers/bakelite

Length of output: 262


🏁 Script executed:

cat pyproject.toml

Repository: emmapowers/bakelite

Length of output: 2155


🏁 Script executed:

cat .github/workflows/test.yaml

Repository: emmapowers/bakelite

Length of output: 686


🏁 Script executed:

cat .github/workflows/lint.yaml

Repository: emmapowers/bakelite

Length of output: 621


🏁 Script executed:

# Search for any Python version-specific imports or features
rg "sys\.version|python_requires|TaskGroup|override|PEP 6[67][0-9]" --type py

Repository: emmapowers/bakelite

Length of output: 45


🏁 Script executed:

# Check dependencies for Python version requirements
grep -A 20 "tool.poetry.dependencies" pyproject.toml | grep -E "python|click|jinja|lark|dataclasses"

Repository: emmapowers/bakelite

Length of output: 154


🏁 Script executed:

# Check if there's broader context in v0.4-plan.md about the version bump
cat docs/v0.4-plan.md | grep -B5 -A5 "3.13"

Repository: emmapowers/bakelite

Length of output: 352


🏁 Script executed:

# Search codebase for async usage that might benefit from 3.13
rg "async|await|asyncio" --type py | head -20

Repository: emmapowers/bakelite

Length of output: 45


🏁 Script executed:

# Check if git history shows any 3.13-related discussions
git log --oneline -20 2>/dev/null | head -20

Repository: emmapowers/bakelite

Length of output: 102


Confirm or reject Python 3.13+ floor—no concrete features justify this break.

Current code targets Python 3.8+ with no dependencies requiring 3.13+. No async/await usage, removed stdlib modules, or runtime features in the codebase justify requiring 3.13+. Proposed async examples in v0.4 do not depend on Python 3.13 (async available since 3.4). Before committing this as policy in docs, either identify concrete features requiring 3.13+ and update pyproject.toml and CI test matrix accordingly, or retain 3.8+ compatibility.

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

In `@docs/v0.4-plan.md` at line 74, The docs currently propose bumping the minimum
Python to 3.13 without evidence; either remove that change and keep Python 3.8+
everywhere or provide concrete code/stdlib/features that require 3.13 and update
the configuration accordingly: if keeping 3.13+, update the version specifier in
pyproject.toml (the python requirement under [tool.poetry.dependencies] or
equivalent), update the docs line in the v0.4 plan that reads "Update version
requirement to Python 3.13+", and adjust the CI test matrix entries to include
only 3.13+; otherwise revert the docs change and ensure CI and pyproject.toml
continue to test and allow 3.8+.

- Add runtime generation steps to quickstart

### CLAUDE.md

- Add project purpose, target platforms, architecture overview
- Document project structure including templates, runtimes, examples
- Add 80% code coverage requirement

## 3. Benchmarking suite

Cross-architecture benchmarking under `bench/`:

### Structure

```
bench/
harness/ — C/C++ benchmark programs (one per protocol × language)
protocols/ — .bakelite protocol definitions (simple, framing, serialize, typical)
scripts/
run_benchmarks.py — orchestrate builds and measurements
download_toolchains.py — auto-download cross-compilers
analyze.py — parse results
```

### Targets

- ARM Cortex-M0 (thumb), Cortex-M3 (thumb2)
- AVR ATmega328P
- RISC-V RV32IMC
- x86-64

### Metrics

- Code size (text, data, bss)
- RAM usage
- Instruction count
- Stack usage (via `-fstack-usage`)
- Generates disassembly for manual analysis

### Toolchains

Auto-downloaded to `bench/toolchains/`:
- xPack ARM GCC
- xPack RISC-V GCC
- ZakKemble AVR GCC

## 4. Copyright / housekeeping

Already handled in PR #7. If anything was missed:
- License year → 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Update the housekeeping year to the current year.

Line 124 says 2025, but today is April 14, 2026; this should be updated to avoid stale license metadata guidance.

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

In `@docs/v0.4-plan.md` at line 124, Update the stale license year string "2025"
to the current year "2026" in the docs content (the line containing "License
year → 2025"); search for any other occurrences of the same "License year" token
in this document and replace them as well to keep license metadata consistent.

- Email → emma@emmaponders.com
- Applies to: LICENSE.md, pyproject.toml, template headers, bin/update
Loading