Product Backlog Items

Document versionDateSummary
v12026-07-17Initial V0 product backlog
v22026-07-20Add the v0.2.0 desktop reference app PBIs
v32026-07-21Refine PBI-050 and PBI-051 around the reusable asset-set layer
v42026-07-22Refine E13 PBIs around the shared presentation component
v52026-07-22Refine PBI-054 as fallback-only SDL render foundation
v62026-07-24Refine PBI-060 around verification config without CMake refactoring

1. Purpose

This document defines the Product Backlog Items for V0. It decomposes the epics in epics into independently verifiable increments.

The backlog is ordered by dependency and risk. A PBI may be refined before implementation, but its outcome and acceptance criteria must remain aligned with the specification, milestones, the general architecture, and the active version architecture document.

2. PBI structure

Each PBI contains:

  • an epic reference
  • an intended outcome
  • the work included in the PBI
  • acceptance criteria
  • dependencies

Implementation details may change when evidence supports a better solution. Acceptance criteria describe required behaviour and evidence rather than a preferred internal implementation.

3. Shared Definition of Done

Every completed PBI must satisfy all applicable acceptance criteria and the following shared rules.

3.1 Required strict quality gate

The strict quality gate must run after every PBI that changes code, build configuration, tests, or developer tooling. It includes:

  1. formatting verification with clang-format
  2. a clean GCC build using ISO C99 without compiler extensions
  3. the complete unit test suite built and run with GCC
  4. a clean Clang build using ISO C99 without compiler extensions
  5. the complete unit test suite built and run with Clang
  6. the agreed GCC and Clang warnings treated as errors for project code
  7. Cppcheck analysis of project code
  8. parallel Clang-Tidy analysis of project code
  9. an AddressSanitizer build and test run
  10. an UndefinedBehaviourSanitizer build and test run
  11. a Pet Core symbol scan against the allowlist for the toolchain that built the archive
  12. a self-containment compilation of every public header, alone, for GCC and Clang

A documentation-only PBI does not require compiler checks unless it changes a technical contract that can be verified immediately.

If a required check cannot run, the PBI is not complete unless the maintainer explicitly accepts and records the exception.

The canonical strict gate runs on Linux. A Windows developer runs the native Windows gate before handover. The PBI remains incomplete until the canonical Linux strict gate also passes. This keeps the completion rule consistent without requiring Linux-only tools on Windows.

The native Windows gate includes formatting verification, MSVC warnings, an MSVC build, CTest, and Cppcheck. An optional Windows Clang and Ninja gate adds parallel Clang-Tidy, ASan, and UBSan where the selected toolchain supports them. Valgrind is not a Windows requirement.

3.2 Audit quality gate

The audit quality gate includes the strict gate plus:

  • branch coverage generation
  • Valgrind memory analysis
  • runtime allocation verification of Pet Core, requiring zero heap usage
  • clean rebuilds from empty build directories
  • release support matrix verification

The audit gate runs:

  • before a version release
  • before closing a milestone
  • after material ownership, storage layout, capacity, or lifetime changes
  • when requested by the assigned PBI

Coverage and Valgrind do not need to run after every ordinary PBI.

3.3 Scope and documentation

Before a PBI is complete:

  • its acceptance criteria must be checked
  • relevant tests must be added or updated
  • affected component knowledge files must be updated when required by agent rules
  • progress and last development must be updated according to agent rules
  • newly discovered deferred work must be recorded in the appropriate backlog or limitation file
  • unrelated behaviour must not be added to the PBI

3.4 Portability status

Linux GCC and Linux Clang are the verified host toolchains for v0.1.0.

Windows compatibility is a design requirement from the first PBI. Project code, public headers, paths, CMake logic, tests, and developer workflows must avoid unnecessary POSIX assumptions. Windows must not be described as build tested until the project has been built and tested using an actual Windows developer environment or Windows CI runner.

Embedded portability is also a design requirement. It does not mean that v0.1.0 supports an embedded deployment. Pet Core must remain independent from operating system windows, filesystems, sockets, threads, sensors, and platform clocks.

MSVC is the native Windows compatibility compiler. Windows uses C17 mode to compile the C99 Core because MSVC does not provide a C99 language mode. GCC and Clang remain the strict C99 conformance toolchains. An optional Windows Clang and Ninja configuration owns compilation database analysis and sanitiser checks.

4. Quality tooling policy

4.1 Tool names

Project configuration and commands use unversioned executable names:

gcc
clang
clang-format
clang-tidy
run-clang-tidy
cppcheck
gcovr
valgrind
cmake
ninja
nm
python3

Local environments may select a specific installed version outside project files when required.

4.2 Formatting baseline

The initial .clang-format configuration is:

Language:        C
BasedOnStyle:    LLVM
IndentWidth:     4
UseTab:          Never
ColumnLimit:     100
PointerAlignment: Right
 
BreakBeforeBraces:          Attach
SpaceBeforeParens:          ControlStatements
SpaceAfterCStyleCast:       false
IndentCaseLabels:           true
BreakBeforeBinaryOperators: None
SortIncludes:               Never
 
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep:              1
 
AlignConsecutiveAssignments:
  Enabled:          true
  AcrossEmptyLines: false
  AcrossComments:   false
  AlignCompound:    true
  PadOperators:     false
 
AlignConsecutiveDeclarations:
  Enabled:          true
  AcrossEmptyLines: false
  AcrossComments:   false

4.3 Clang-Tidy baseline

The initial .clang-tidy configuration is based on:

Checks: >
  clang-analyzer-*,
  bugprone-*,
  cert-*,
  misc-*,
  performance-*,
  portability-*,
  readability-*,
  -readability-magic-numbers,
  -readability-identifier-length,
  -readability-function-cognitive-complexity,
  -readability-braces-around-statements,
  -misc-include-cleaner,
  -bugprone-easily-swappable-parameters,
  -performance-enum-size
 
WarningsAsErrors: '*'
HeaderFilterRegex: '.*/(src|include|frontends|tests)/.*'
ExcludeHeaderFilterRegex: '.*/(build|_deps|third_party)/.*'
SystemHeaders: false
FormatStyle: file

Clang-Tidy must analyse only project translation units and project headers. Dependencies may still be parsed when required to understand project code, but diagnostics from system headers, generated files, fetched dependencies, and third-party code must not be treated as project findings.

The check list may be refined when a check is demonstrably unsuitable for C99 or conflicts with an explicit project rule. Disabling a check requires a short recorded reason.

5. Archived releases

Completed v0.1.0 PBIs are archived in release v0.1.0. That archive holds PBI-001 through PBI-034 with their outcomes, included work, acceptance criteria, and dependencies, grouped by epic E01 through E07.

PBI identifiers continue after PBI-034. They are permanent and are not reused, so a future release never restarts the sequence.

6. Release v0.2.0 PBIs

The release goal and expected capabilities are recorded in milestones. The epics are recorded in epics. PBI identifiers continue from PBI-035.

A new PBI is added under its epic heading and follows the structure in section 2, the shared Definition of Done in section 3, and the quality tooling policy in section 4.

E08 v0.2.0 architecture and compatibility contracts

PBI-035 Write the v0.2.0 version architecture [+]

Epic: E08 v0.2.0 architecture and compatibility contracts

Outcome: The v0.2.0 release has an accepted architecture document that defines the desktop reference app, SDL frontend, composition model, asset contract, and verification scope before implementation begins.

Included work:

  • create docs/arch/arch-v0.2.0.md
  • follow the required arc42 top level structure
  • define the release scope and exclusions
  • define app, frontend, asset, presentation role, and verification boundaries
  • record Linux, Windows, and embedded support claim limits
  • link the relevant specification, milestone, epic, ADR, and PBI records

Acceptance criteria:

  • every required architecture section exists
  • the document states that SDL, assets, platform clocks, and input devices stay outside the Core
  • the desktop app and SDL frontend ownership boundaries are explicit
  • host support and frontend support libraries are deferred
  • the architecture records how v0.2.0 preserves later embedded frontend options
  • the document names the verification evidence required before release completion

Dependencies: None

PBI-036 Record the SDL desktop frontend decision [+]

Epic: E08 v0.2.0 architecture and compatibility contracts

Outcome: The project has an ADR explaining why v0.2.0 uses SDL for the desktop reference frontend and how the dependency is kept out of the Core.

Included work:

  • create the next ADR under docs/adr/
  • compare SDL with relevant alternatives
  • record the selected SDL version policy
  • record whether SDL3 built-in PNG loading or an image loading dependency is used
  • record dependency override and offline rebuild expectations
  • link the ADR from arch-v0.2.0.md

Acceptance criteria:

  • the ADR uses the repository ADR format
  • the decision keeps SDL as a frontend dependency only
  • the dependency pinning rule is explicit
  • Windows and embedded support are not implied by the SDL decision
  • alternatives and consequences are recorded

Dependencies: PBI-035

PBI-037 Record the canonical visual asset and manifest decision [+]

Epic: E08 v0.2.0 architecture and compatibility contracts

Outcome: The project has a recorded decision for canonical visual assets, manifest-based loading, generated frontend artefacts, and fallback behaviour.

Included work:

  • create an ADR or architecture decision section, as appropriate
  • choose the canonical raster source format
  • define generated artefacts as build outputs rather than source of truth
  • define the manifest role in mapping assets and animations
  • record what is deferred from the asset pipeline
  • link the decision from arch-v0.2.0.md

Acceptance criteria:

  • the decision does not describe the asset contract as pixel-art-only
  • the Core remains unaware of asset identifiers, file paths, and image formats
  • generated desktop or embedded asset formats are explicitly non-canonical
  • missing or invalid external assets have a guaranteed fallback path
  • deferred asset tooling is named rather than hidden

Dependencies: PBI-035

PBI-038 Define app and frontend documentation and source layout contracts [+]

Epic: E08 v0.2.0 architecture and compatibility contracts

Outcome: App and frontend components have documented directory, README, and ownership contracts that extend the existing app rules without weakening them.

Included work:

  • review apps/README.md and apps/README.template.md
  • update the app contract only if the desktop app needs a template-level rule
  • create frontends/README.md
  • create frontends/README.template.md
  • document include/, src/, and tests/ ownership for app and frontend components
  • document that each app owns exactly one executable target

Acceptance criteria:

  • existing apps/headless documentation remains valid
  • apps/desktop is required to follow the app template
  • frontend documentation has a comparable template suited to frontend libraries
  • app and frontend component headers use explicit ownership boundaries
  • private component headers do not become a public compatibility promise accidentally

Dependencies: PBI-035

E09 Composition registry and gate selection

PBI-039 Define the composition registry schema [+]

Epic: E09 Composition registry and gate selection

Outcome: Supported app and frontend combinations can be described in one declarative registry without creating an unrestricted Cartesian product.

Included work:

  • define the registry file location and schema
  • add headless and desktop app entries
  • add none and sdl frontend entries
  • define default frontend resolution
  • define incompatible pair behaviour
  • document how future apps and frontends extend the registry

Acceptance criteria:

  • headless with none is valid
  • desktop with sdl is valid
  • headless with sdl is invalid
  • the schema has an explicit version
  • the registry records directories and target names needed by workflows
  • compatibility is declared by the app rather than inferred from all frontends

Dependencies: PBI-035, PBI-038

PBI-040 Implement the composition registry tool [+]

Epic: E09 Composition registry and gate selection

Outcome: A standard-library Python tool can validate, list, and resolve app and frontend compositions for use by humans and by gate.py.

Included work:

  • add an executable tool under tools/
  • validate registry schema and references
  • list apps
  • list frontends
  • list valid compositions
  • resolve an app to its default frontend
  • resolve explicit app and frontend input
  • expose import-safe helper functions for gate.py

Acceptance criteria:

  • the tool has a shebang and a CLI help path
  • the tool is import safe
  • unknown apps and frontends fail with clear diagnostics
  • incompatible pairs fail with clear diagnostics
  • valid compositions produce stable composition names
  • the tool uses only the Python standard library

Dependencies: PBI-039

PBI-041 Add composition selection to the gate workflow [+]

Epic: E09 Composition registry and gate selection

Outcome: The existing fast, strict, and audit gates can run the default composition, a selected app composition, or every valid composition.

Included work:

  • add app and frontend options to gate.py
  • add all-compositions selection
  • keep fast, strict, and audit as the gate levels
  • reject invalid option combinations
  • select build directories by preset and composition
  • preserve existing default headless behaviour

Acceptance criteria:

  • ./gate.py strict keeps the existing default behaviour
  • ./gate.py strict --app desktop resolves to the desktop default frontend
  • ./gate.py strict --app desktop --frontend sdl resolves explicitly
  • ./gate.py strict --app headless --frontend sdl fails before configure
  • --all-compositions cannot be combined with single-composition options
  • build directories are isolated per preset and composition

Dependencies: PBI-040

PBI-042 Add CMake composition validation and selected directory loading [+]

Epic: E09 Composition registry and gate selection

Outcome: Direct CMake usage can configure a selected app and frontend pair, reject invalid combinations, and add only the directories required by that composition.

Included work:

  • add CMake cache variables for app and frontend selection
  • validate the selected pair against the registry or generated CMake metadata
  • add selected app and frontend subdirectories
  • preserve the headless default
  • keep direct CMake configure and build commands documented
  • avoid duplicating compatibility policy in independent Python and CMake lists

Acceptance criteria:

  • direct CMake configure can select headless and none
  • direct CMake configure can select desktop and sdl
  • invalid pairs fail during configuration with a clear message
  • selected composition does not change Core target properties
  • CTest registrations remain scoped to the selected composition
  • the implementation follows the CMake and Python tooling boundary

Dependencies: PBI-039, PBI-041

E10 Pinned SDL desktop frontend foundation

PBI-043 Add the pinned SDL dependency [+]

Epic: E10 Pinned SDL desktop frontend foundation

Outcome: The project can fetch or use a pinned SDL dependency for the SDL frontend without turning third-party diagnostics into project diagnostics.

Included work:

  • add the selected SDL dependency provider
  • pin the selected SDL version or commit
  • document the local override policy, adding override variables only if accepted for this release
  • isolate third-party warnings
  • treat third-party includes as system includes where practical
  • provide clear diagnostics when the dependency is unavailable

Acceptance criteria:

  • the SDL version is deterministic
  • dependency configuration is disabled when the SDL frontend is disabled
  • third-party warnings are not treated as project warnings
  • dependency download and any accepted local override behaviour are documented
  • clean configure failure explains what is missing
  • Core-only builds still configure without SDL

Dependencies: PBI-036, PBI-042

PBI-044 Create the SDL frontend target skeleton [+]

Epic: E10 Pinned SDL desktop frontend foundation

Outcome: frontends/sdl exists as a buildable frontend component with the documented include/, src/, and tests/ layout.

Included work:

  • create frontends/sdl/CMakeLists.txt
  • create public frontend headers under frontends/sdl/include
  • create implementation sources under frontends/sdl/src
  • create the frontend test directory
  • add the pet_frontend_sdl target and alias
  • link the pinned SDL dependency
  • add frontends/sdl/README.md

Acceptance criteria:

  • the frontend target builds when selected
  • the frontend target can be disabled
  • the registry sdl frontend directory and target references are verified against the created component directory and CMake target
  • public frontend headers compile in their owning target
  • implementation headers remain private unless intentionally public
  • the README follows the frontend template
  • the target does not introduce an SDL dependency into Pet Core

Dependencies: PBI-038, PBI-043

E11 Desktop app host lifecycle

PBI-045 Create the desktop app target skeleton [+]

Epic: E11 Desktop app host lifecycle

Outcome: apps/desktop exists as the pet_desktop executable component and composes the selected frontend target without owning rendering internals.

Included work:

  • create apps/desktop/CMakeLists.txt
  • create component-local headers under apps/desktop/include
  • create implementation sources under apps/desktop/src
  • create apps/desktop/tests/test_scenario.cmake
  • add the pet_desktop executable target
  • link pet::core and the selected frontend target
  • add apps/desktop/README.md

Acceptance criteria:

  • pet_desktop builds for the desktop SDL composition
  • the desktop app owns exactly one executable target
  • the registry desktop app directory and target references are verified against the created component directory and CMake target
  • the app README follows apps/README.template.md
  • the app target does not include Core internal headers
  • the app links the frontend through the selected composition
  • the headless app remains unchanged in behaviour

Dependencies: PBI-038, PBI-042, PBI-044

PBI-046 Implement desktop Core and frontend lifecycle [+]

Epic: E11 Desktop app host lifecycle

Outcome: The desktop app can initialise one Core world, create the SDL frontend, request a snapshot, and shut both down in a documented order.

Included work:

  • implement app lifecycle state
  • initialise one PetWorld
  • create the selected frontend
  • request an initial snapshot
  • destroy frontend resources
  • reset the Core world
  • handle Core and frontend status failures
  • return meaningful process exit status

Acceptance criteria:

  • normal startup reaches an initial snapshot request
  • startup failure cleans up already-created resources
  • normal shutdown resets the world and destroys frontend resources
  • Core status failures do not continue into rendering with invalid state
  • failure paths return non-zero process status
  • no product behaviour is implemented in the app lifecycle code

Dependencies: PBI-045

PBI-047 Implement desktop elapsed time policy and loop control [+]

Epic: E11 Desktop app host lifecycle

Outcome: The desktop app supplies bounded elapsed time to the Core and explicit animation time to the frontend without letting wall-clock policy enter the Core.

Included work:

  • choose the desktop monotonic time source
  • compute elapsed deltas
  • handle zero deltas
  • handle deltas above PET_TIME_DELTA_MAX_MS
  • call pet_world_update
  • pass explicit elapsed time to frontend animation
  • provide controlled time seams for tests where practical

Acceptance criteria:

  • the Core never reads a platform clock
  • the frontend animation path does not read wall-clock time directly
  • accepted deltas are passed to pet_world_update
  • large elapsed values cannot cause an uncontrolled Core update
  • loop control can run at least one update and one render path
  • time policy is documented in the desktop app README or version architecture

Dependencies: PBI-046

E12 Canonical visual assets and manifest

PBI-048 Define the manifest schema and development runtime asset layout [+]

Epic: E12 Canonical visual assets and manifest

Outcome: v0.2.0 has a small manifest schema and development runtime layout for canonical visual assets.

Included work:

  • define manifest versioning
  • define image entries
  • define animation entries
  • define state-to-animation mapping entries
  • define identifier, path, line, and count limits
  • define runtime asset copy location under the build directory
  • document generated artefacts as non-canonical
  • record menu and application chrome assets as a separate future layer

Acceptance criteria:

  • manifest version 1 is documented
  • the schema is not pixel-art-only
  • the schema is explicitly for pet presentation assets rather than menu or UI chrome assets
  • manifest paths are relative to the asset set
  • runtime asset layout does not depend on the source checkout path
  • unsupported future fields are explicitly out of scope
  • generated frontend formats are not treated as source assets
  • future UI and menu assets are not forced into the pet presentation manifest

Dependencies: PBI-037, PBI-044

PBI-049 Implement and test the bounded manifest parser [+]

Epic: E12 Canonical visual assets and manifest

Outcome: A frontend can parse and validate the manifest with bounded storage and explicit failure modes.

Included work:

  • implement manifest parsing in the shared components/manifest component, because the grammar is common to future manifest kinds rather than SDL private
  • validate manifest kind and version
  • validate directive names
  • validate identifier and path lengths
  • reject duplicates
  • reject invalid references
  • reject path traversal
  • add component tests for valid and invalid manifests

Acceptance criteria:

  • a valid minimal manifest parses successfully
  • unknown manifest versions fail
  • unknown directives fail
  • duplicate identifiers fail
  • missing image or animation references fail
  • path traversal attempts fail
  • parser work and stored entries are bounded by documented limits

Dependencies: PBI-048

PBI-050 Add canonical visual assets and guaranteed fallback presentation [+]

Epic: E12 Canonical visual assets and manifest

Outcome: The repository has a canonical visual asset set for v0.2.0, a reusable asset-set loading contract outside any single frontend, and a fallback policy that works even when files are missing or invalid.

Included work:

  • add the canonical asset directory
  • add a manifest for the initial pet states
  • add simple canonical raster assets
  • copy runtime assets into selected build directories
  • add the frontend-neutral components/assets layer for resolving an asset root, reading the manifest through an injected reader, and producing accepted manifest records or a fallback-required result
  • keep the manifest parser as the pure components/manifest text parser rather than moving file I/O into it
  • provide a desktop/runtime reader path for the development build layout without making that path the only reader model future embedded frontends can use
  • define the built-in or procedural fallback policy used when the manifest or asset set cannot be used
  • test missing manifest or missing asset fallback selection without requiring SDL resource creation

Acceptance criteria:

  • canonical assets are stored once and are not duplicated per frontend
  • runtime assets are available next to the selected build output
  • components/assets has no Core, app, frontend, or SDL dependency
  • asset-set loading can be driven through a test reader without using the host filesystem
  • missing files do not prevent fallback rendering
  • invalid files do not prevent fallback rendering
  • fallback presentation is calm and does not look like an error prompt
  • Core code does not reference asset paths or identifiers

Dependencies: PBI-047, PBI-049

PBI-051 Implement SDL image loading from the manifest [+]

Epic: E12 Canonical visual assets and manifest

Outcome: The SDL frontend can turn accepted frontend-neutral asset records into SDL image resources and report asset failures without crashing the app.

Included work:

  • consume the accepted asset set produced through components/assets and components/manifest
  • load PNG files referenced by the accepted manifest with the pinned SDL image loading path
  • create SDL-owned resources for loaded assets
  • record failed loads
  • destroy loaded asset resources cleanly
  • use the built-in or procedural fallback path when SDL image loading fails
  • test image loading where an SDL resource test can run

Acceptance criteria:

  • accepted image files load successfully in the supported runtime environment
  • failed image loads select fallback presentation
  • resource cleanup is safe after partial load failure
  • image loading happens during frontend initialisation or asset reload points, not during ordinary rendering
  • SDL types and resource ownership remain private to the SDL frontend implementation
  • no asset resource is owned by the Core or desktop app
  • image loading dependency status is recorded truthfully

Dependencies: PBI-050

E13 Presentation roles and animation model

PBI-052 Implement presentation role mapping from Core snapshots [+]

Epic: E13 Presentation roles and animation model

Outcome: A frontend-neutral presentation component maps PetSnapshot activity and expression values into presentation roles before any frontend renderer selects assets.

Included work:

  • add the shared components/presentation target, public headers, implementation, and tests
  • define role identifiers for current activities
  • define role identifiers for current expressions
  • define the initial role priority policy: happy expression overrides activity, neutral expression does not override a known activity, and unknown combinations fall back
  • map current snapshot values into roles
  • provide fallback roles for unmapped values
  • keep the mapping independent of SDL, file I/O, clocks, allocation, and asset decoding
  • let the SDL frontend consume the shared mapping output without exposing SDL types through it
  • add tests for known and unknown mapping cases

Acceptance criteria:

  • components/presentation has no app, frontend, SDL, asset reader, filesystem, or clock dependency
  • PET_ACTIVITY_IDLE maps to a documented role
  • PET_ACTIVITY_CURIOUS maps to a documented role
  • PET_ACTIVITY_ATTENTIVE maps to a documented role
  • PET_EXPRESSION_NEUTRAL maps to a documented role
  • PET_EXPRESSION_HAPPY maps to a documented role
  • the activity/expression combination policy is documented and tested
  • unmapped values use fallback roles rather than crashing
  • the SDL frontend calls the shared mapping boundary before renderer code
  • renderer code does not switch directly on Core enum values

Dependencies: PBI-047, PBI-049

PBI-053 Implement deterministic animation selection [+]

Epic: E13 Presentation roles and animation model

Outcome: The shared presentation component resolves presentation roles to manifest animations and frames using explicit elapsed time supplied by the app.

Included work:

  • extend components/presentation with a bounded, renderer-ready selection result
  • resolve role identifiers against the accepted PetManifest
  • resolve roles to animation identifiers
  • support single-frame animations
  • support multi-frame looping data
  • select frames from explicit elapsed time
  • select fallback animation when a role or animation is missing
  • return the selected manifest role, animation, frame, and image indexes without exposing SDL types
  • let the SDL frontend record or consume the selected image index without drawing yet
  • add deterministic animation tests

Acceptance criteria:

  • selection depends only on the snapshot role, accepted manifest records, and explicit animation time
  • equal roles and elapsed values select equal frames
  • single-frame animations remain stable
  • looping animations wrap predictably
  • missing role mappings select fallback animation
  • missing animation entries select fallback animation
  • animation selection does not read wall-clock time
  • no animation identifier is added to PetSnapshot
  • no SDL handle, surface, texture, renderer, or filesystem dependency enters components/presentation
  • renderer code consumes the shared selection result rather than raw Core enum values

Dependencies: PBI-052

E14 Snapshot driven SDL rendering and layout

PBI-054 Implement SDL window and guaranteed fallback rendering [+]

Epic: E14 Snapshot driven SDL rendering and layout

Outcome: The SDL frontend can create its rendering context and draw a guaranteed fallback pet representation without external assets.

Included work:

  • initialise SDL frontend rendering resources
  • create the selected window and renderer resources inside the SDL frontend
  • keep SDL window and renderer handles private to frontends/sdl
  • draw the built-in fallback presentation from pet_assets_fallback
  • use the fallback render path even when no asset set is loaded
  • clear and present the frame
  • destroy rendering resources
  • add an SDL frontend renderer status or failure path if setup can fail distinctly
  • record real window or dummy driver evidence truthfully

Acceptance criteria:

  • the fallback render path runs without external asset files
  • pet_frontend_sdl_present draws a fallback frame and does not decode or read files
  • rendering resources are destroyed cleanly
  • partial rendering setup failure cleans up safely
  • Core code contains no SDL references
  • the desktop app does not own renderer internals
  • asset-backed sprite drawing remains deferred to PBI-056
  • manual-only rendering evidence is labelled manual if automation is unavailable

Dependencies: PBI-044, PBI-047, PBI-050, PBI-053

PBI-055 Implement shared logical canvas layout and scaling [+]

Epic: E14 Snapshot driven SDL rendering and layout

Outcome: A frontend-neutral layout component defines how a logical canvas fits into an output surface, and the SDL frontend renders its fallback frame through that shared policy.

Included work:

  • add the shared components/layout target, public headers, implementation, and tests
  • define frontend-neutral size and rectangle records with no SDL or app dependency
  • select the initial logical canvas size and document it as a release choice
  • implement deterministic contain/letterbox layout calculations that preserve aspect ratio
  • define non-integer scaling behaviour and integer scaling rules where practical
  • make the SDL frontend consume the shared layout result when drawing the fallback frame
  • keep SDL window, renderer, event, texture, and surface handling private to frontends/sdl
  • add pure tests for layout and scaling calculations under the shared component

Acceptance criteria:

  • the logical canvas size is recorded in the version architecture
  • components/layout has no app, frontend, SDL, filesystem, clock, or allocation dependency
  • layout calculations are deterministic and preserve aspect ratio
  • the same logical/output sizes produce the same destination rectangle for every frontend
  • SDL fallback rendering uses the shared layout policy rather than private SDL-only layout math
  • integer scaling is used where practical
  • non-integer cases have documented behaviour
  • layout tests do not require real SDL resources, a display, or a video driver
  • asset-backed sprite drawing remains deferred to PBI-056

Dependencies: PBI-054

PBI-056 Render asset-backed presentation roles from snapshots [+]

Epic: E14 Snapshot driven SDL rendering and layout

Outcome: The SDL frontend renders the current Core snapshot through presentation role and animation mapping, using loaded assets when available and fallback otherwise.

Included work:

  • request render input as PetSnapshot or derived presentation mapping output
  • choose animation frame for the current role
  • draw loaded assets through the shared layout policy
  • draw fallback when assets are unavailable
  • convert loaded SDL image resources into renderer-owned texture resources, or otherwise provide the SDL-specific drawable resource needed by SDL_RenderTexture
  • release SDL texture and image resources before closing the renderer
  • support visible autonomous state changes
  • support visible direct interaction state changes

Acceptance criteria:

  • rendering never receives a mutable PetWorld *
  • current Core activity changes can produce different rendered roles
  • current Core expression changes can produce different rendered roles
  • missing assets continue through fallback rendering
  • renderer code consumes presentation roles or animation frames rather than raw Core world state
  • renderer code consumes components/layout results rather than duplicating logical canvas fit policy
  • no SDL handle, surface, texture, renderer, or filesystem dependency enters components/layout or components/presentation
  • partial texture conversion or draw setup failure releases resources and falls back or reports a frontend renderer error according to the frontend contract
  • visible output is produced on the supported desktop runtime path

Dependencies: PBI-051, PBI-053, PBI-055

E15 Semantic desktop input

PBI-057 Define and implement the frontend event contract [+]

Epic: E15 Semantic desktop input

Outcome: The SDL frontend distinguishes product actions, host controls, and ignored frontend events before anything reaches the Core.

Included work:

  • define frontend event kinds
  • define event payload for product actions
  • define host control events
  • classify quit, resize, and focus events
  • classify unsupported input as ignored
  • add tests for event classification

Acceptance criteria:

  • product action events can carry a supported PetAction
  • quit is a host control event
  • resize is not a product action
  • focus changes are not product actions
  • unsupported input is ignored safely
  • raw SDL events are not passed to the Core

Dependencies: PBI-044, PBI-045

PBI-058 Map keyboard and pointer input to semantic actions [+]

Epic: E15 Semantic desktop input

Outcome: The SDL frontend maps at least one keyboard input and one pointer input to a semantic Core action while keeping the mapping independent from Core state mutation.

Included work:

  • choose the initial keyboard mapping
  • choose the initial pointer mapping
  • map both to a supported PetAction
  • add mapping tests
  • document limited input assumptions
  • leave unsupported desired actions out until Core supports them

Acceptance criteria:

  • one keyboard input maps to PET_ACTION_GREET or another supported action
  • one pointer input maps to PET_ACTION_GREET or another supported action
  • unsupported keys and buttons do not mutate Core state
  • the mapping can be used without rapid repeated input
  • mapping tests cover keyboard, pointer, and ignored inputs
  • no fake Core action is invented in the frontend

Dependencies: PBI-057

PBI-059 Dispatch semantic input through the desktop app [+]

Epic: E15 Semantic desktop input

Outcome: The desktop app receives frontend events, dispatches only product actions to the Core, and produces visible interaction feedback through the normal snapshot and render path.

Included work:

  • poll frontend events from the app loop
  • dispatch product action events through pet_world_apply_action
  • handle host control events without touching Core product state
  • request a new snapshot after accepted action dispatch
  • render the updated snapshot
  • test host control separation where practical

Acceptance criteria:

  • product action events call pet_world_apply_action
  • quit events do not call pet_world_apply_action
  • unsupported or ignored events do not mutate Core state
  • an accepted direct interaction can produce visible feedback
  • Core status failures during action dispatch are handled cleanly
  • the input path uses public Core APIs only

Dependencies: PBI-047, PBI-056, PBI-058

E16 Frontend, app, and release verification

PBI-060 Add frontend, app, and asset verification scripts [+]

Epic: E16 Frontend, app, and release verification

Outcome: Automated checks can verify important app and frontend boundaries that ordinary builds do not prove, with a small project-owned verification config under tools/config/, while leaving the current CMake and composition structure unchanged for the release.

Included work:

  • add dependency verification where needed
  • add include boundary verification where needed
  • add asset manifest verification where needed
  • add a tools/config/ verification config where boundary and asset policies need declared inputs
  • integrate the checks into the existing gate.py flow where they belong
  • check that Core source does not include SDL headers
  • check that app and frontend code do not include Core internal headers
  • check that manifest references resolve in the runtime asset layout
  • make verification scripts read the project-owned config rather than copying policy lists across scripts where practical
  • record any user-facing build and CMake simplification ideas under docs/ideas/ instead of implementing them in E16
  • keep every new Python script directly executable

Out of scope:

  • CMake target layout refactoring
  • preset redesign
  • replacing gate.py
  • adding a new daily-use build wrapper
  • changing app/frontend composition semantics

Acceptance criteria:

  • Core SDL include violations are detected
  • Core SDL symbol or dependency violations are detected where practical
  • app Core internal header violations are detected
  • frontend Core internal header violations are detected
  • missing manifest asset references are detected
  • generated artefacts are not treated as canonical source assets
  • the verification config is validated and missing or malformed policy entries fail clearly
  • the new checks run through the existing gate without requiring a CMake structure change
  • the deferred simple build entrypoint and CMake UX work is captured as a non-authoritative idea
  • each script can run alone with a useful exit status

Dependencies: PBI-041, PBI-051, PBI-056, PBI-059

PBI-061 Add the desktop process scenario [+]

Epic: E16 Frontend, app, and release verification

Outcome: The desktop app has a process-level scenario that proves startup, one controlled update and render path, and clean shutdown for the desktop SDL composition.

Included work:

  • implement apps/desktop/tests/test_scenario.cmake
  • register the scenario with CTest for the selected composition
  • support a deterministic smoke mode if required
  • verify process exit status
  • verify standard error behaviour where practical
  • document any display driver requirement or accepted limitation

Acceptance criteria:

  • the scenario starts pet_desktop
  • the scenario reaches Core initialisation
  • the scenario reaches frontend initialisation
  • the scenario reaches at least one update and render path
  • the scenario shuts down cleanly
  • failures produce non-zero exit status
  • unavailable display automation is recorded honestly rather than reported as passing

Dependencies: PBI-059

PBI-062 Verify all supported v0.2.0 compositions [+]

Epic: E16 Frontend, app, and release verification

Outcome: The headless and desktop SDL compositions are verified through the required gates without overstating unsupported platform claims.

Included work:

  • run the default strict gate
  • run the desktop SDL strict gate
  • run all-composition verification where required
  • run frontend tests
  • run desktop process scenario
  • run dependency, include, and asset checks
  • review Windows and embedded status
  • update release evidence inputs

Acceptance criteria:

  • the headless composition still passes its required checks
  • the desktop SDL composition passes its required checks
  • frontend tests pass
  • dependency, include, and asset checks pass or accepted limitations are recorded
  • Linux desktop evidence is recorded with exact commands
  • Windows remains unverified unless real Windows evidence exists
  • embedded suitability remains an architectural hypothesis until a real embedded build exists

Dependencies: PBI-060, PBI-061

PBI-063 Complete the v0.2.0 release review [+]

Epic: E16 Frontend, app, and release verification

Outcome: The v0.2.0 release exits with evidence that the desktop reference app and frontend architecture claims are true.

Included work:

  • review all v0.2.0 acceptance criteria
  • run the final required release gates
  • review known bugs and limitations
  • finalise arch-v0.2.0.md
  • record release evidence
  • update progress and handover documentation

Acceptance criteria:

  • all required v0.2.0 PBIs are complete
  • the milestone exit criteria in milestones are satisfied
  • pet_desktop demonstrates the supported visual interaction loop
  • the Core builds and runs without the SDL frontend
  • desktop input reaches the Core only as semantic actions
  • rendering uses public presentation state and never mutable Core world state
  • final gates pass or accepted limitations explain unavailable checks
  • remaining limitations are explicit and linked to deferred PBIs where appropriate

Dependencies: PBI-062

7. Deferred backlog areas

The following areas remain outside the active PBI set:

  • durable saves
  • digital adapters such as Git activity
  • physical sensor adapters
  • networking and local device discovery
  • multiple pets and household relationships
  • long-term traits, marks, memories, and maturity
  • embedded platform builds
  • a Core allocator or arena without evidence from a later version requirement
  • Windows build verification without a Windows environment or runner

These areas must be introduced through a version architecture document and its PBIs rather than being added opportunistically to the current release.

A visual frontend was deferred throughout v0.1.0 and is the subject of v0.2.0, so it is no longer listed here. The list as it stood at the close of v0.1.0 is preserved in release v0.1.0.