# Version Plan
This plan describes the intended post-`0.6.0` direction for `hashavatar`.
Each version has a concrete finish line so the project can stop, review, and
release without letting exploratory work blur into the release criteria.
## Guiding Principles
- Keep the default path conservative and deterministic.
- Prefer explicit opt-in features over broad default dependency growth.
- Do not add custom unsafe SIMD code to this crate.
- Use vetted dependencies for optimized algorithms when they have a clear
security and maintenance story.
- Prefer latest compatible stable crate releases; check crates.io, docs.rs,
upstream repositories, and RustSec advisories before adding or upgrading
dependencies.
- Keep web/API concerns in `hashavatar-api`; keep this crate focused on
reusable avatar generation.
- Treat self-testing as part of implementation, not a follow-up task.
- Keep GitHub CodeQL on the repository default setup unless there is a
documented reason to move to advanced setup.
- Treat visual-output changes as compatibility events and document them in
release notes.
- Derive enum-based choices from a single variant list instead of hard-coded
modulo counts.
## 0.7.0: Pluggable Identity Hashing
Status: implemented in `0.7.0`.
Goal: make identity hashing explicit and extensible while keeping SHA-512 as
the stable default.
### Scope
- Keep SHA-512 as the default crate-wide identity hash mode.
- Add optional `BLAKE3` support behind an explicit Cargo feature.
- Add optional `XXH3-128` support behind an explicit Cargo feature.
- Keep optional hash modes mutually exclusive so feature unification cannot
silently mix identity derivation algorithms.
- Include the active non-default hash mode in the length-prefixed hash domain
input.
- Preserve existing default SHA-512 output unless the crate is built with a
different hash-mode feature.
- Document that `XXH3-128` is non-cryptographic and intended only for
non-adversarial identity distribution.
### API Shape
Hash choice is not a runtime public API. `AvatarIdentityOptions` carries
namespace configuration only; the active identity hash is selected for the
whole crate by Cargo features.
### Dependency Policy
- `sha2` remains the default dependency.
- `blake3` is optional.
- `xxhash-rust` or another reviewed XXH3 provider is optional.
- Optional hash dependencies must pass `cargo deny`, `cargo audit`, license
checks, and package-size review.
- Do not enable optional hash dependencies by default unless there is a clear
project decision and release-note justification.
### SIMD Policy
- SIMD may be used only through admitted dependency implementations such as
`blake3`.
- No custom AVX2, AVX-512, NEON, or wasm SIMD implementation is added to
`hashavatar`.
- README/docs must explain that hardware acceleration, when available, comes
from the selected hash dependency and platform support.
### Finish Line
`0.7.0` is done when:
- Default SHA-512 fingerprints are unchanged from `0.6.0`.
- BLAKE3 and XXH3 identity modes have dedicated tests.
- Oversized identity and namespace inputs are rejected for the active hash mode.
- Optional hash-mode tests prove non-default modes add an explicit algorithm
domain component.
- README, release notes, dependency docs, and security controls document the
default and optional crate-wide hash modes.
- `scripts/stable_release_gate.sh check` passes.
- crates.io publish dry run passes.
## 0.8.0: Core Boundary Preparation
Status: implemented in `0.8.0`.
Goal: separate deterministic avatar decisions from encoding/integration
concerns internally so later visual-layer work can stay organized.
### Scope
- Identify the minimum deterministic core:
- validated avatar specs
- identity and namespace validation
- crate-wide hash mode
- avatar genome derivation
- geometry/layout primitives
- color values
- Reduce direct coupling between that core and `image::RgbaImage`.
- Introduce an internal drawing target trait if it makes the core boundary
cleaner.
- Normalize public enum variant lists and byte-to-variant helpers before new
visual layers are added.
- Keep the public crate behavior stable unless a breaking change is explicitly
worth making before `1.0`.
- Keep raster encoding in the main crate.
### Non-Goals
- Do not split the crate unless the internal boundary is already clean enough
to maintain.
- Do not add custom SIMD code.
### Finish Line
`0.8.0` is done when:
- The code has a clear internal boundary between deterministic avatar planning
and output encoding.
- Raster and SVG outputs still pass golden fingerprint and safety tests.
- The dependency graph is no larger than `0.7.0` unless explicitly justified.
- Public enum derivation does not rely on duplicated magic counts such as
`value % 23`; it uses `ALL.len()` or an equivalent single source of truth.
- Tests fail if public enum variant lists drift from parser/display behavior.
- The README explains that `hashavatar` remains a focused image-generation
crate.
- `docs/DEPENDENCIES.md` explains the single-crate dependency boundary.
- `scripts/stable_release_gate.sh check` passes.
- crates.io publish dry run passes.
### Implementation Notes
- Public enum variant lists use `ALL` slices rather than array constants with
duplicated lengths.
- `from_byte` helpers derive variants from `ALL.len()` for avatar kinds,
backgrounds, and output formats.
- Tests cover parser/display drift and byte-to-variant behavior for public
enums.
- Raster and SVG rendering now share an internal render plan before output
encoding.
- `0.9.0` later rejected a public core crate split because the project goal is
avatar image generation.
## 0.9.0: Single-Crate Boundary Decision
Status: implemented in `0.9.0`.
Goal: keep `hashavatar` focused as one image-generation crate and avoid a
separate public core crate until there is a concrete image-generation use case
for that split.
### Scope
- Keep deterministic identity hashing, public options, raster rendering, SVG
rendering, and encoders in the `hashavatar` crate.
- Keep lower-level planning helpers internal.
- Remove `hashavatar-core` / `no_std + alloc` from the near-term release plan.
- Preserve all 0.8.0 rendering output and security posture.
### Finish Line
`0.9.0` is done when:
- The published package is still only `hashavatar`.
- README and dependency docs describe the single-crate boundary.
- Release notes explain why the separate core crate was not adopted.
- Golden fingerprints prove the release did not accidentally change default
output.
- `scripts/stable_release_gate.sh check` passes.
## 0.10.0: Visual Layer Model
Status: implemented in `0.10.0`.
Goal: expand avatar variety with explicit, deterministic visual layers before
the public API is frozen.
### Scope
- Add new option enums for visual layers:
- `AvatarAccessory`
- `AvatarColor`
- `AvatarExpression`
- `AvatarShape`
- Add a higher-level options type, for example `AvatarStyleOptions`, that can
carry kind, background, accessory, color palette, expression, and frame
shape together.
- Keep existing `AvatarOptions` working during the transition if practical.
- Define a deterministic derivation path for each layer from identity bytes
when the caller chooses an automatic/default mode.
- Reserve distinct identity digest offsets for top-level automatic choices so
kind, background, accessory, palette, expression, and frame shape do not all
depend on the same byte.
- Make every new enum parseable and displayable like the existing public
enums.
- Derive automatic layer choices from each enum's variant list rather than
hard-coded modulo counts.
- Document how layer choices affect the deterministic output tuple.
### Candidate API Shape
```rust
pub enum AvatarAccessory {
None,
Glasses,
Hat,
Headphones,
Crown,
Bowtie,
Eyepatch,
Scarf,
Halo,
Horns,
}
pub enum AvatarColor {
Default,
NeonMint,
PastelPink,
Crimson,
Gold,
DeepSeaBlue,
}
pub enum AvatarExpression {
Default,
Happy,
Grumpy,
Surprised,
Sleepy,
Winking,
Cool,
Crying,
}
pub enum AvatarShape {
Square,
Circle,
Squircle,
Hexagon,
Octagon,
}
```
The exact enum names can change during design review. The important contract is
that visual layers are typed, deterministic, documented, and covered by golden
tests.
### Compatibility Policy
- Existing callers should either keep the old default visual behavior or get a
clearly documented migration path.
- If default output changes, release notes must state that `0.10.0` is a
visual-output compatibility release.
- The `style_version` guidance in `VERSIONING.md` must be updated so services
can roll out layered avatars deliberately.
### Enum Derivation Policy
- Prefer small hand-maintained `ALL` lists or `all()` accessors as the single
source of truth for public enum variants.
- Avoid `strum` or other enum-reflection dependencies unless the boilerplate
becomes large enough to justify the additional dependency and audit surface.
- Any byte-to-variant helper should index through the variant list, for
example `Self::ALL[(value as usize) % Self::ALL.len()]`, so adding a variant
cannot silently leave it unreachable.
### Automatic Derivation Schedule
Automatic layer choices must use an explicit schedule of identity digest bytes
or domain-separated sub-derivations. The simple baseline is one distinct digest
byte per top-level choice:
```rust
let kind = AvatarKind::from_byte(identity.byte(0));
let background = AvatarBackground::from_byte(identity.byte(1));
let accessory = AvatarAccessory::from_byte(identity.byte(2));
let color = AvatarColor::from_byte(identity.byte(3));
let expression = AvatarExpression::from_byte(identity.byte(4));
let shape = AvatarShape::from_byte(identity.byte(5));
```
The exact offsets can change during implementation, but the schedule must be
documented and covered by tests. Reusing a byte for unrelated top-level traits
is avoided because it creates visible correlation, such as one background being
overrepresented with one accessory.
### Finish Line
`0.10.0` is done when:
- [x] Every visual layer enum has `ALL`, `as_str`, `Display`, and `FromStr`.
- [x] Every automatic public enum choice uses the enum's variant list instead of a
duplicated literal count.
- [x] Top-level automatic traits use distinct identity digest offsets or explicit
domain-separated derivations.
- [x] Tests prove changing the digest byte reserved for one top-level trait does
not alter the other automatic trait selections.
- [x] Automatic layer derivation is deterministic and covered by tests.
- [x] Manual layer selection is covered by tests.
- [x] Raster and SVG renderers support all selected baseline layers.
- [x] Unsupported accessory/expression combinations skip deterministically
instead of drawing in arbitrary positions.
- [x] Golden fingerprints cover representative combinations of kind, background,
accessory, color palette, expression, and frame shape.
- [x] README includes examples for automatic and manual visual layers.
- [x] Release notes clearly state whether default visuals changed.
- [x] `scripts/stable_release_gate.sh check` passes.
- [x] crates.io publish dry run passes.
## 0.11.0: Visual Layer Coverage And Polish
Status: implemented in `0.11.0`.
Goal: make the visual layer system feel complete across avatar families rather
than merely supported by the API.
### Scope
- Expand accessory rendering across all avatar families where the accessory
makes visual sense.
- Define fallback behavior for combinations that do not make sense, such as
accessories that conflict with a particular family shape.
- Refine color palettes so they are accessible and readable on all supported
backgrounds.
- Refine expression support so the common expressions are visually distinct
across face-like families.
- Ensure frame shapes clip or mask raster and SVG output consistently.
- Add documentation for recommended layer combinations and public endpoint
query mapping.
### Non-Goals
- Do not add user-supplied SVG fragments, arbitrary colors, arbitrary paths,
or external assets.
- Do not make the crate responsible for HTTP query parsing.
- Do not add an unbounded combinatorial golden test matrix; use representative
coverage plus targeted unit tests.
### Finish Line
`0.11.0` is done when:
- Every avatar family has reviewed behavior for every visual layer.
- Unsupported or awkward layer/family combinations have deterministic,
documented fallback behavior.
- Raster and SVG outputs are visually consistent for frame shapes.
- Tests cover fallback behavior and representative cross-family combinations.
- README and docs explain the full layer model.
- `hashavatar-api` has enough documented guidance to expose the new layers
safely when that project is ready.
- `scripts/stable_release_gate.sh check` passes.
- crates.io publish dry run passes.
## 0.12.0: Variant Expansion
Status: implemented in `0.12.0` for the accepted avatar-family set.
Candidate background variants remain deferred.
Goal: broaden the built-in avatar and background catalog once the visual layer
model is in place and tested.
### Scope
- Add new `AvatarKind` families where they can be rendered with the same
deterministic, asset-free approach as the existing variants.
- Candidate animal variants:
- `Bear` (accepted)
- `Monkey` (deferred)
- `Penguin` (accepted)
- `Dinosaur`
- `Unicorn`
- `Bat`
- `Turtle`
- Candidate fantasy and sci-fi variants:
- `Dragon` (accepted)
- `Ninja` (accepted)
- `Vampire`
- `Cyborg`
- `Astronaut` (accepted)
- Candidate object variants:
- `Diamond` (accepted)
- `Gemstone`
- `CoffeeCup` (accepted)
- `Sword`
- `Shield` (accepted)
- `Crown`
- Add new `AvatarBackground` modes where they do not require external assets
or unbounded procedural work.
- Candidate pattern backgrounds:
- `PolkaDot`
- `Striped`
- `Checkerboard`
- `Grid`
- `Wavy`
- Candidate gradient backgrounds:
- `Sunrise`
- `Synthwave`
- `Ocean`
- Candidate environment backgrounds:
- `Starry`
- `Pixel`
- `Cloudy`
Accepted `0.12.0` families are `Bear`, `Penguin`, `Dragon`, `Ninja`,
`Astronaut`, `Diamond`, `CoffeeCup`, and `Shield`. Pattern, gradient, and
environment backgrounds are deferred because they need a separate bounded
raster/SVG texture implementation and contrast review before they are safe
public API.
### Admission Policy
- Each new variant must be visually distinct at small sizes such as 64x64 and
128x128.
- Each new variant must work in raster and SVG output.
- New backgrounds must be bounded, deterministic, and safe for untrusted
identities.
- Pattern and environment backgrounds must not make foreground avatars hard to
read; use contrast tests or reviewed golden outputs where practical.
- Variant expansion must update enum `ALL` lists, parser/display tests,
README examples, and release notes together.
- Adding variants may change automatic distribution only in a documented
visual-output compatibility release. Services that need stable old output
should pin the older `style_version` until they intentionally migrate.
### Finish Line
`0.12.0` is done when:
- The accepted `AvatarKind` and `AvatarBackground` variants are implemented in
both raster and SVG paths.
- Every new public variant has `as_str`, `Display`, `FromStr`, and `ALL`
coverage.
- Automatic selection uses the enum variant lists, not duplicated literal
counts.
- Golden fingerprints cover representative new avatar families and
backgrounds.
- Small-size visual review confirms each accepted variant is recognizable.
- README and docs describe the expanded catalog without promising variants
that were rejected or deferred.
- Release notes clearly state any deterministic output impact.
- `scripts/stable_release_gate.sh check` passes.
- crates.io publish dry run passes.
## 0.13.0: Background Expansion And Determinism Hardening
Status: implemented in `0.13.0`.
Goal: improve the background catalog without adding new avatar families, and
reduce platform-sensitive geometry in frame-shape masking before `1.0`.
### Scope
- Add a small accepted background set:
- `PolkaDot`
- `Striped`
- `Checkerboard`
- `Grid`
- `Sunrise`
- `Ocean`
- `Starry`
- Keep background rendering deterministic, bounded, asset-free, and represented
in both raster and SVG output.
- Avoid admitting busier backgrounds such as `Wavy`, `Synthwave`, `Pixel`, and
`Cloudy` until they have a clearer contrast and readability story.
- Replace selected float-based frame-shape raster hit-testing with integer
arithmetic.
- Fix stale documentation around feature-combination testing and fuzz encoder
coverage.
### Finish Line
`0.13.0` is done when:
- Every accepted background has `as_str`, `Display`, `FromStr`, and `ALL`
coverage.
- Raster tests prove the new background canvases are distinct and bounded.
- SVG tests parse every new background as well-formed XML.
- Golden fingerprints document the automatic-output impact from expanding
`AvatarBackground::ALL`.
- README, dependency docs, changelog, and release notes describe the new
background catalog and the feature-testing policy.
- `scripts/stable_release_gate.sh check` passes.
- crates.io publish dry run passes.
## 1.0.0: Stability Contract
Status: implemented in `1.0.0`.
Goal: freeze a professional, security-oriented public API and rendering
contract.
### Scope
- Freeze default hash algorithm and default visual style version.
- Freeze the visual layer option model.
- Freeze the baseline avatar kind and background catalog intended for `1.0`.
- Freeze error types and constructor behavior.
- Define a stable policy for when visual output may change.
- Define semver rules for adding avatar families, visual layers, hash
algorithms, and output formats.
### Finish Line
`1.0.0` is done when:
- The public API has no known avoidable breaking changes left.
- Security controls, dependency policy, panic policy, and release process are
complete and current.
- README and docs.rs examples compile and reflect the final API.
- Release notes clearly state the stability contract.
- `scripts/stable_release_gate.sh release` passes.
- crates.io publish dry run passes.
## Deferred Until Evidence Exists
These are intentionally not committed to a specific version:
- Custom SIMD inside `hashavatar`.
- Async APIs in this crate.
- HTTP server or demo code in this crate.
- AVIF/JPEG XL output.
- Enabling BLAKE3 or XXH3 by default.
- Raising identity length limits.
Each item needs concrete use cases, dependency review, tests, and release-note
justification before admission.