Pet epics

Document versionDateSummary
v72026-07-24Archive the completed v0.2.0 epics and open the next release map
v82026-07-25Define the v0.3.0 embedded firmware foundation and project UX epics
v92026-07-25Add v0.3.0 release verification and hardening as the final epic
v102026-07-27Complete E17 after accepting the v0.3.0 architecture and release scope
v112026-07-27Record completion of E18, E19, and E20
v122026-07-27Clarify the T-Display family and selected S3 variant contract
v132026-07-28Record completion of E21
v142026-07-28Record completion of E22
v152026-08-01Archive the completed v0.3.0 epics and open the next release map
v162026-08-02Define the v0.4.0 local persistence foundation epics
v172026-08-03Bring the wall-clock stamp and bounded absence into v0.4.0 scope
v182026-08-04Archive the completed v0.4.0 epics and await the next release map
v192026-08-05Define the v0.5.0 board runtime and embedded asset pipeline epics

Status: Draft

Current release: v0.5.0

Related documents: Product specification, milestones, general architecture, and the release archives for v0.1.0, v0.2.0, v0.3.0, and v0.4.0.

1. Purpose

This document defines the product and engineering outcomes required by each epic.

An epic belongs to one release and contains multiple PBIs. An epic describes a verifiable outcome rather than a source directory, implementation phase, or team activity.

Epic identifiers are permanent and are not reused. Future releases continue the sequence instead of restarting at E01.

2. Epic completion rules

An epic is completed only when:

  • all child PBIs are completed
  • all epic completion criteria are satisfied
  • required tests pass
  • accepted architecture decisions are reflected in code and documentation
  • new limitations are recorded in known-limitations.md
  • deferred defects are recorded in bugs.md
  • architecture deviations are documented
  • verified support claims are not broader than the available evidence

An epic must not be marked completed because its main implementation exists while tests or required documentation remain unfinished.

3. Archived releases

Completed v0.1.0 epics are archived in release v0.1.0. That archive holds E01 through E07 with their full outcomes, scope, and completion criteria.

Completed v0.2.0 epics are archived in release v0.2.0. That archive holds E08 through E16 with their full outcomes, scope, and completion criteria.

Completed v0.3.0 epics are archived in release v0.3.0. That archive holds E17 through E23 with their full outcomes, scope, and completion criteria.

Completed v0.4.0 epics are archived in release v0.4.0. That archive holds E24 through E29 with their full outcomes, scope, and completion criteria.

Epic identifiers continue from E30. They are permanent and are not reused, so a future release never restarts the sequence.

4. Release v0.5.0 epic map

EpicTitleStatusPrimary outcome
E30v0.5.0 architecture and release scopeCompletedThe board runtime, the frontend split, the pack format direction, the verification composition, and the device evidence model for v0.5.0 are documented and accepted
E31Board execution and panel bring-upCompletedThe classic T-Display can be flashed and monitored through a documented project command, and its panel is lit and measured on real hardware
E32Continuous embedded runtimeCompletedThe firmware application runs as a non-returning loop driven by a monotonic clock and a bounded delta, and survives a long device run
E33TFT presentation frontendCompletedA hosted-buildable TFT frontend composes the pet into one frame buffer and presents it through a thin ESP-IDF backend
E34Embedded asset pack and converterCompletedA deterministic build-time converter compiles the canonical manifest and images into one embedded asset pack with a decided format
E35Embedded asset-backed presentationCompletedThe firmware image carries the pack, the reader resolves frames in place, and the canonical pet reaches the panel
E36Board input and semantic actionsPlannedBoth board buttons are sampled and filtered through a pure rule, and a filtered edge becomes an existing semantic action
E37Release verification and hardeningPlannedThe release meets its hosted, cross-build, device, limitation, and support-claim evidence requirements

The release goal and expected capabilities are recorded in milestones. The concrete architecture is recorded in architecture for v0.5.0. PBIs for this release start at PBI-103 and the ADRs its epics write continue from ADR-016, because ADR-015 was written during planning.

4.1 Dependency view

flowchart TD
    E30[E30 Architecture and scope]
    E31[E31 Board execution and panel bring-up]
    E32[E32 Continuous embedded runtime]
    E33[E33 TFT presentation frontend]
    E34[E34 Embedded asset pack and converter]
    E35[E35 Embedded asset-backed presentation]
    E36[E36 Board input and semantic actions]
    E37[E37 Release verification]

    E30 --> E31
    E31 --> E32
    E31 --> E33
    E31 --> E34
    E31 --> E36
    E33 --> E35
    E34 --> E35
    E32 --> E37
    E33 --> E37
    E35 --> E37
    E36 --> E37

Every epic descends from E30 through E31, because no epic may implement a design the release has not accepted. The edges below E30 are ordering constraints rather than preferences.

E31 precedes everything that touches the device, because an epic that cannot flash a board and read its output cannot produce evidence for anything it builds. It also precedes E34, which is the panel before pipeline rule the roadmap recorded. The pack encoding is chosen against a measured colour path, so a converter written first would be encoding for a display nobody had lit.

E33 and E34 both precede E35, because asset-backed presentation is the first place where a composed frame and a generated artefact meet. Neither alone can produce it, and both can be finished without it.

E36 depends on E31 alone. Its outcome is that a filtered edge becomes a semantic action that the serial diagnostics report, which needs a running board rather than a presented pet. The visible response to a button press is release-level integration evidence and belongs to E37, which keeps E36 verifiable on its own.

E37 is the release-level convergence point. Testing is not deferred to it. Every implementation epic carries its own tests and evidence, and E37 adds the end-to-end device observation, the final gates, the support-claim review, the limitation status review, and documentation hardening.

5. E30: v0.5.0 architecture and release scope [+]

Release: v0.5.0

Status: Completed

Dependencies: None

5.1 Outcome

The release architecture defines the firmware run loop and time policy, the split between the common TFT sources and the ESP-IDF backends, the ownership split between the pack and the board profile, the hosted verification composition, the serial diagnostic contract, and the device evidence model for v0.5.0.

The result is an accepted implementation plan that lets later epics build a decided design rather than negotiate one against a vendor SDK.

5.2 In scope

  • arch-v0.5.0.md
  • the continuous run loop, its time source, and its bounded delta policy
  • the frontend split between hosted-buildable common sources and selectable ESP-IDF backends
  • the ownership split between asset facts in the pack and board facts in the board profile
  • the registered firmware-tft composition and what claim it supports
  • the serial diagnostic line format and its event vocabulary
  • the device evidence model, including what a maintainer observes and what a transcript proves
  • the limitation intake for LIM-012, LIM-013, LIM-015, and the new LIM-018

5.3 Out of scope

  • implementing the loop, the frontend, the converter, the reader, or the input path
  • measuring the panel
  • fixing the final pixel encoding
  • non-volatile storage, wireless facilities, and adapter work

5.4 Completion criteria

  • arch-v0.5.0.md exists and follows the version architecture policy
  • the run loop, time source, and delta bound policy are recorded with their reasons
  • the frontend split names which sources are hosted-buildable and which are backend-only
  • the pack and the board profile have no overlapping ownership
  • the firmware-tft composition and its claim boundary are recorded
  • the serial diagnostic format and event vocabulary are recorded
  • the support matrix separates hosted evidence, cross-build evidence, and device observation
  • the decisions that need an ADR are named with the epic that will write each one
  • open decisions are named for PBI or later-release resolution

5.5 Traceability

  • SPEC-NFR-001: portability
  • SPEC-NFR-003: testability
  • SPEC-NFR-006: maintainability
  • SPEC-FR-029: frontend independence
  • LIM-012: the selected board has never been flashed or run
  • LIM-013: no embedded asset storage or reader exists
  • ADR-016: the hosted firmware and TFT verification composition
  • arch-v0.5.0: sections 1, 2, 4, 5, 7, 8, 9, 10, and 11

6. E31: Board execution and panel bring-up [+]

Release: v0.5.0

Status: Completed

Dependencies: E30

6.1 Outcome

The classic LILYGO T-Display can be flashed and monitored through a documented project command, and its panel is lit, measured, and recorded as a board profile.

The result is the first physical evidence the project holds. Every later device claim depends on this epic being able to put an image on the board and read what it says.

6.2 In scope

  • ./pet.py flash and ./pet.py monitor, following the existing command-first grammar
  • the project command tests that cover the new surface
  • the ESP-IDF display bring-up path over esp_lcd, including the bus, the reset, and the backlight
  • a procedural diagnostic presentation sufficient to measure the panel, such as a colour and corner pattern
  • measuring the visible area, the panel offsets, the native orientation, the transfer orientation, and the panel colour order
  • recording the measured values in the classic board profile and marking which values remain vendor-documented
  • the serial diagnostic line format and its first events

6.3 Out of scope

  • presenting the pet
  • the asset pack, the converter, and the reader
  • the continuous run loop
  • button sampling and semantic actions
  • any board variant other than the classic one

6.4 Completion criteria

  • the firmware can be flashed and monitored through the documented project command
  • the command surface is covered by the project command test suite
  • the panel is lit on the physical board and shows the diagnostic pattern
  • the visible area, offsets, native orientation, transfer orientation, and colour order are measured and recorded
  • the board profile distinguishes measured values from vendor-documented values
  • the serial output follows the documented line format and event vocabulary
  • the ESP-IDF build continues to configure, compile, and link
  • the hosted compositions are unaffected and continue to pass the required gate

6.5 Traceability

  • SPEC-FR-026: varied frontend capabilities
  • SPEC-NFR-005: responsiveness
  • LIM-012: the selected board has never been flashed or run
  • arch-v0.5.0: sections 5.4, 5.6, 7.3, and 8.7

7. E32: Continuous embedded runtime

Release: v0.5.0

Status: Completed

Dependencies: E31

7.1 Outcome

The firmware application runs as a non-returning loop driven by a monotonic platform clock and a bounded elapsed delta, and it survives a long continuous device run without resetting, stalling, or leaking.

The result is the difference between a board that boots and a companion that lives on a board.

7.2 In scope

  • the run loop in apps/firmware, which does not return in normal operation and does not busy spin
  • the monotonic time source behind a platform seam, and the conversion to milliseconds
  • the bounded delta policy, including what is recorded when a delta is clamped
  • a stepped lifecycle form so a host test can drive iterations with supplied time values
  • the runtime and fault diagnostic events
  • host tests over the stepped lifecycle
  • a soak observation on the physical board, including the minimum free heap at both ends
  • an ADR for the run loop and time source policy

7.3 Out of scope

  • what is drawn during the loop
  • asset resolution
  • button input
  • power management, sleep modes, and duty cycling

7.4 Completion criteria

  • the application does not return in normal operation and does not busy spin
  • the elapsed time delivered to the Core is monotonic and bounded
  • a clamped delta is recorded through a diagnostic rather than silently dropped
  • the stepped lifecycle is driven by host tests with supplied time values, including a clamp
  • a two-hour device run shows no unexpected reset, no watchdog abort, no stalled presentation, and no continuously falling minimum free heap
  • the run loop and time source policy are recorded in an ADR
  • the firmware performs no dynamic allocation of its own

7.5 Traceability

  • SPEC-FR-013: explicit time progression
  • SPEC-FR-014: autonomous activities
  • SPEC-FR-010: valid absence
  • SPEC-NFR-002: resource awareness
  • SPEC-NFR-005: responsiveness
  • arch-v0.5.0: sections 5.2, 6.2, 8.1, and 8.8

8. E33: TFT presentation frontend

Release: v0.5.0

Status: Completed

Dependencies: E31

8.1 Outcome

A TFT frontend composes the pet into one frame buffer from a presentation snapshot and presents it through a thin ESP-IDF backend, with every composition decision asserted by host tests.

The result is the project’s second frontend and the first one whose platform half is small enough to be the only part a device has to confirm.

8.2 In scope

  • frontends/tft with its public contract and its common sources
  • the registered firmware-tft composition in config/compositions.json and the tooling it touches
  • one full frame buffer, composed whole and transferred whole
  • skipping composition and transfer when the frame selection is unchanged
  • role selection, integer scaling, placement, and clipping through the existing components
  • the procedural fallback appearance drawn without any asset
  • the ESP-IDF display backend, selected by a build option and absent from hosted builds
  • host tests over composition, clipping, scaling, and the fallback
  • an ADR for the frame buffer strategy

8.3 Out of scope

  • the asset pack, the converter, and the reader
  • button sampling and filtering
  • partial or dirty-region updates
  • any panel other than the classic one

8.4 Completion criteria

  • the common sources build and their tests run in the firmware-tft composition without ESP-IDF
  • no ESP-IDF header or symbol reaches a hosted composition
  • the frontend receives a snapshot and never a mutable world pointer
  • composition, scaling, placement, and clipping are asserted over a caller-owned buffer
  • an unchanged frame selection composes nothing and transfers nothing
  • the procedural fallback presents with no asset present
  • the pet is visible on the physical panel through the fallback path
  • the frame buffer strategy is recorded in an ADR
  • the tooling that assumed no hosted firmware composition is reconciled rather than left to drift

8.5 Traceability

  • SPEC-FR-025: presentation state
  • SPEC-FR-026: varied frontend capabilities
  • SPEC-FR-029: frontend independence
  • SPEC-NFR-002: resource awareness
  • SPEC-NFR-003: testability
  • arch-v0.5.0: sections 5.3, 5.4, 5.10, 6.4, and 8.5

9. E34: Embedded asset pack and converter [+]

Release: v0.5.0

Status: Completed

Dependencies: E31

9.1 Outcome

A deterministic build-time converter compiles the canonical manifest and its images into one embedded asset pack whose format is decided, versioned, and recorded.

The result is the artefact that lets a runtime with no parser, no filesystem, and no PNG decoder present the same pet the desktop presents.

9.2 In scope

  • the pack format, including its magic value, format version, compiled presentation structure, entry table, pixel encoding, and transparency representation
  • tools/assets/pack.py, using the standard library only
  • the converter’s manifest grammar reading as an isolated module with its own tests, so that the collapse ADR-015 decides moves a module later rather than rewriting a program
  • the accepted PNG subset and the named rejection of everything outside it
  • the pack generation build step and its output in the build directory
  • tools/tests/test_pack.py covering determinism, known outputs, and rejections
  • an ADR for the pack format, its converter contract, and its compatibility promise

9.3 Out of scope

  • reading the pack on a device
  • embedding the pack into the firmware image
  • changing the canonical manifest, its grammar, or its images
  • moving the desktop frontend onto the pack
  • collapsing the grammar onto one reader, which ADR-015 accepts and defers to a later release

9.4 Completion criteria

  • the pack format is recorded in an ADR before the converter is implemented
  • the format carries the compiled presentation structure derived from the canonical manifest
  • the format carries no board offset, no rotation, and no panel colour order
  • the declared pixel encoding matches what the measured panel consumes
  • the converter is deterministic, so equal inputs produce equal bytes
  • the converter rejects an unsupported image with a named reason rather than guessing
  • the converter fails loudly rather than writing a partial pack
  • the pack is generated into the build directory and no pack is committed
  • the converter suite runs as a gate step beside the existing tool suites
  • the grammar reading is a separate module with its own tests rather than being woven into the pack encoder, and the duplication it creates is recorded as a limitation

9.5 Traceability

  • SPEC-FR-025: presentation state
  • SPEC-NFR-002: resource awareness
  • SPEC-NFR-007: compatibility awareness
  • ADR-007: canonical visual assets and manifest
  • ADR-015: the canonical manifest grammar has one reader
  • ADR-019: embedded asset pack format version 1
  • LIM-013: no embedded asset storage or reader exists
  • arch-v0.5.0: sections 5.7, 8.3, and 8.4

10. E35: Embedded asset-backed presentation [+]

Release: v0.5.0

Status: Completed

Dependencies: E33, E34

10.1 Outcome

The firmware image carries the pack, the reader validates and resolves it in place, and the canonical pet reaches the physical panel.

The result closes the embedded asset gap that has been open since v0.3.0, and it is the criterion a fallback-only run does not satisfy.

10.2 In scope

  • the pack reader in components/assets, selected by a build option
  • validation of the header, the entry table, and the declared offsets before any lookup
  • materialising the compiled presentation structure into a caller-owned manifest
  • resolving frames as pointers into read-only memory without copying pixels
  • linking the pack into the firmware image as embedded read-only bytes
  • the TFT frontend consuming pack frames instead of the fallback when a pack is accepted
  • host tests over valid packs, malformed packs, and the equivalence between the parsed manifest and the materialised one

10.3 Out of scope

  • generating the pack, which E34 owns
  • a separate asset partition or a flashing lifecycle for assets
  • runtime asset replacement or updates
  • desktop consumption of the pack

10.4 Completion criteria

  • the reader validates the header, the entry table, and every declared offset before a lookup
  • a truncated, corrupted, or unknown-version pack is rejected rather than interpreted
  • a rejected pack selects the procedural fallback and never ends the application
  • the materialised manifest resolves the same role, animation, frame, and duration as the parsed manifest over every canonical role
  • no pixel is copied out of the pack to present it
  • the firmware image carries the pack and reports its size and entry count through diagnostics
  • a canonical frame is visibly presented on the physical classic T-Display
  • the embedded boundary check holds over the new sources

10.5 Traceability

  • SPEC-FR-025: presentation state
  • SPEC-FR-012: capability aware behaviour
  • SPEC-NFR-002: resource awareness
  • SPEC-NFR-004: robustness
  • LIM-013: no embedded asset storage or reader exists
  • arch-v0.5.0: sections 5.5, 6.4, 6.5, 8.3, and 8.8

11. E36: Board input and semantic actions

Release: v0.5.0

Status: Planned

Dependencies: E31

11.1 Outcome

Both board buttons are sampled and filtered through a pure debounce rule, and a filtered edge becomes an existing semantic action that the serial diagnostics report.

The result is the first physical user input the project has ever accepted, and it is accepted without opening the adapter interface question.

11.2 In scope

  • the GPIO backend that configures both pins, samples their levels, and supplies timestamps
  • the pure debounce rule beside the frontend that consumes it
  • the mapping from a filtered edge to an existing semantic action, in the firmware application
  • the behaviour of GPIO 0 at reset and during a run, recorded in the board profile
  • the input diagnostic event
  • host tests over stable, bouncing, and held level sequences, and over unmapped edges

11.3 Out of scope

  • inventing a new Core action for the second button
  • adapters, sensors, and external sources
  • gesture, long-press, or chord vocabularies beyond what the mapped action needs
  • the visible pet response, which is release-level integration evidence in E37

11.4 Completion criteria

  • both pins are configured and sampled on the physical board
  • the debounce rule is pure and is asserted by host tests over supplied levels and timestamps
  • one press produces exactly one edge rather than one edge per sample
  • a filtered edge produces an existing semantic action through the Core public API
  • an unmapped edge produces no action and no diagnostic noise
  • no GPIO number, pin, or button index reaches the Core
  • the strapping behaviour of GPIO 0 is recorded, and the mapped action sits on a pin that behaves reliably
  • the input diagnostic reports the button and the action it produced

11.5 Traceability

  • SPEC-FR-008: semantic actions
  • SPEC-FR-009: limited input operation
  • SPEC-FR-036: input validation
  • SPEC-NFR-003: testability
  • arch-v0.5.0: sections 5.3, 5.4, 6.3, and 8.6

12. E37: Release verification and hardening

Release: v0.5.0

Status: Planned

Dependencies: E32, E33, E35, E36

12.1 Outcome

The release meets its hosted, cross-build, and device evidence requirements, its limitations are reconciled, and no claim it records is broader than the evidence behind it.

The result is a release that a reviewer who did not plan it can check.

12.2 In scope

  • the audit gate from a clean tree over headless, desktop-sdl, and firmware-tft
  • the ESP-IDF build evidence, including the image size and the embedded pack
  • the end-to-end device observation, where a button press produces a visible pet response drawn from the pack
  • the serial transcript that accompanies the device observation
  • the soak result and the heap readings
  • closing LIM-012 for the classic variant on esp32 only
  • closing LIM-013 through the canonical frame evidence
  • keeping LIM-015 open and correcting its tracking column
  • opening LIM-018 for the absent hardware-in-the-loop gate
  • the support matrix, the release evidence file, and the release archive
  • documentation hardening across the release documents

12.3 Out of scope

  • new capabilities
  • new board variants or targets
  • deferred defect fixes that belong to a later release rather than this one

12.4 Completion criteria

  • ./gate.py audit --all-compositions passes from a clean tree over all three compositions
  • the ESP-IDF build is recorded with its framework version, toolchain, image size, and pack size
  • a maintainer records a button press producing a visible pet response drawn from the pack
  • the serial transcript follows the documented format and accompanies the observation
  • the two-hour soak result and its heap readings are recorded
  • LIM-012 is closed for the classic variant on esp32 only, with no wider claim
  • LIM-013 is closed by the canonical frame evidence, and a fallback-only run would not have closed it
  • LIM-015 remains open and no longer names this release in its tracking column
  • LIM-018 is recorded with hosted assertions and physical observation kept apart
  • the support matrix records no device claim as automated evidence
  • every v0.5.0 exit criterion in milestones is satisfied or explicitly carried with a reason

12.5 Traceability

  • SPEC-NFR-004: robustness
  • SPEC-NFR-006: maintainability
  • SPEC-NFR-007: compatibility awareness
  • LIM-011: rendering and interaction remain manual evidence
  • LIM-012, LIM-013, LIM-015, LIM-018
  • arch-v0.5.0: sections 7.2, 10.3, 10.4, and 10.5

13. Crosscutting rules

The following rules apply to every epic:

  • code and developer documentation use British English
  • Core code uses ISO C99
  • public domain identifiers use the pet prefix
  • no hidden global mutable world is introduced
  • time and randomness remain explicit
  • tests are implemented with the behaviour they verify
  • invalid public input must not partially mutate authoritative state
  • no frontend, adapter, storage, or networking dependency enters the Core
  • implementation remains within the assigned epic and PBI scope
  • deferred work is recorded instead of being hidden in comments

14. PBI preparation rules

The next planning document is 03-pbis.md.

PBIs derived from these epics must:

  • belong to exactly one epic
  • produce one reviewable outcome
  • include explicit in scope and out of scope boundaries
  • include testable acceptance criteria
  • identify dependencies
  • link to relevant architecture sections
  • identify required verification commands or evidence
  • avoid combining implementation, unrelated refactoring, and future feature work

A PBI set should cover its epic completely before later epic implementation PBIs are marked ready.

15. References