Skip to content

Commit b87e74c

Browse files
committed
Prepare hashavatar 1.0.0 candidate
1 parent 38e92ca commit b87e74c

10 files changed

Lines changed: 189 additions & 31 deletions

File tree

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Changelog
22

3+
## 1.0.0
4+
5+
- Bumped the crate to `1.0.0`.
6+
- Declared the first stable public API and rendering contract for
7+
`hashavatar`.
8+
- Added `docs/STABILITY.md` covering Cargo semver expectations, visual output
9+
stability, automatic-style distribution, security/resource contracts, and
10+
known residual risks.
11+
- Updated README guidance for the stable contract and controlled visual
12+
rollouts through namespace `style_version` values.
13+
- Added `docs/STABILITY.md` to release metadata/package validation so future
14+
releases keep the stability policy in the published crate.
15+
- Added 1.0 release notes.
16+
- No avatar families, backgrounds, visual layers, hash modes, output formats,
17+
or runtime dependencies were added in this release.
18+
319
## 0.13.0
420

521
- Bumped the crate to `0.13.0`.

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[package]
22
name = "hashavatar"
3-
version = "0.13.0"
3+
version = "1.0.0"
44
edition = "2024"
55
rust-version = "1.95"
6-
description = "Deterministic procedural avatars in Rust with configurable identity hashing, patterned backgrounds, WebP, optional PNG/JPEG/GIF, and SVG export"
6+
description = "Stable deterministic procedural avatars in Rust with configurable identity hashing, WebP, optional PNG/JPEG/GIF, and SVG export"
77
license = "MIT OR Apache-2.0"
88
repository = "https://github.com/valkyoth/hashavatar"
99
homepage = "https://github.com/valkyoth/hashavatar"

README.md

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The crate starts conservative: validated avatar dimensions, bounded identity inp
66

77
## Current Status
88

9-
The current crate version is `0.13.0`.
9+
The current crate version is `1.0.0`.
1010

1111
Implemented now:
1212

@@ -64,40 +64,40 @@ Planned or intentionally external:
6464
| SVG posture | Generated numeric markup only; caller input is not inserted into SVG fragments |
6565
| Release evidence | fmt, clippy, tests, docs, deny, audit, fuzz harness compile, package check, SBOM, reproducibility |
6666

67-
Security-control details live in [docs/SECURITY_CONTROLS.md](docs/SECURITY_CONTROLS.md). Dependency policy lives in [docs/DEPENDENCIES.md](docs/DEPENDENCIES.md). Panic policy lives in [docs/PANIC_POLICY.md](docs/PANIC_POLICY.md).
67+
Security-control details live in [docs/SECURITY_CONTROLS.md](docs/SECURITY_CONTROLS.md). Dependency policy lives in [docs/DEPENDENCIES.md](docs/DEPENDENCIES.md). Panic policy lives in [docs/PANIC_POLICY.md](docs/PANIC_POLICY.md). Stable API and rendering policy lives in [docs/STABILITY.md](docs/STABILITY.md).
6868

69-
Future version planning for variant expansion and 1.0 stabilization lives in
70-
[docs/VERSION_PLAN.md](docs/VERSION_PLAN.md). `hashavatar` remains a single
71-
image-generation crate; low-level core planning is kept internal unless a
72-
future release has a concrete image-generation reason to split it.
69+
Future version planning lives in [docs/VERSION_PLAN.md](docs/VERSION_PLAN.md).
70+
`hashavatar` remains a single image-generation crate; low-level core planning
71+
is kept internal unless a future release has a concrete image-generation reason
72+
to split it.
7373

7474
## Install
7575

7676
```toml
7777
[dependencies]
78-
hashavatar = "0.13.0"
78+
hashavatar = "1.0.0"
7979
```
8080

8181
Optional identity hash modes and extra raster encoders are disabled by default.
8282
Hash modes are mutually exclusive, so enable at most one of `blake3` or `xxh3`:
8383

8484
```toml
8585
[dependencies]
86-
hashavatar = { version = "0.13.0", features = ["blake3"] }
86+
hashavatar = { version = "1.0.0", features = ["blake3"] }
8787
```
8888

8989
Enable additional raster formats explicitly:
9090

9191
```toml
9292
[dependencies]
93-
hashavatar = { version = "0.13.0", features = ["png", "jpeg", "gif"] }
93+
hashavatar = { version = "1.0.0", features = ["png", "jpeg", "gif"] }
9494
```
9595

9696
Or enable every optional raster encoder at once:
9797

9898
```toml
9999
[dependencies]
100-
hashavatar = { version = "0.13.0", features = ["all-formats"] }
100+
hashavatar = { version = "1.0.0", features = ["all-formats"] }
101101
```
102102

103103
Combine these as needed, for example `features = ["blake3", "png"]`.
@@ -115,6 +115,20 @@ The crate is dual-licensed:
115115
license = "MIT OR Apache-2.0"
116116
```
117117

118+
## Stable Contract
119+
120+
`1.0.0` freezes the crate's public API shape and documented rendering contract.
121+
Patch releases should not intentionally change output for the same explicit
122+
rendering tuple except for correctness or security fixes. Minor releases may
123+
add opt-in features, output formats, avatar families, backgrounds, or visual
124+
layer variants when they are documented and tested. Automatic style rendering
125+
can change distribution when public enum `ALL` lists grow, so services that
126+
need precise visual rollout control should use namespace `style_version`
127+
values deliberately.
128+
129+
See [docs/STABILITY.md](docs/STABILITY.md) for the full semver and rendering
130+
policy.
131+
118132
## Limits
119133

120134
| Limit | Value |
@@ -381,7 +395,7 @@ your namespace style version when intentionally migrating output.
381395

382396
```toml
383397
[dependencies]
384-
hashavatar = { version = "0.13.0", features = ["blake3"] }
398+
hashavatar = { version = "1.0.0", features = ["blake3"] }
385399
```
386400

387401
```rust
@@ -409,7 +423,7 @@ assert!(svg.contains("alien avatar"));
409423

410424
```toml
411425
[dependencies]
412-
hashavatar = { version = "0.13.0", features = ["xxh3"] }
426+
hashavatar = { version = "1.0.0", features = ["xxh3"] }
413427
```
414428

415429
```rust
@@ -614,32 +628,39 @@ AVIF and JPEG XL are not exposed because they add dependency or encoder maturity
614628

615629
## Determinism
616630

617-
The output is deterministic for the tuple:
631+
For a concrete crate release, the output is deterministic for the tuple:
618632

619633
```text
620634
crate identity hash mode + namespace tenant + namespace style version + identity bytes + avatar kind + background + dimensions + seed
621635
```
622636

623-
This makes the crate suitable for stable CDN-backed avatar URLs and golden regression tests. Namespace hashing uses length-prefixed components, so embedded separator bytes cannot create tenant/style-version ambiguity. The default SHA-512 path keeps the pre-0.7 identity preimage stable; optional crate-wide hash modes are domain-separated.
637+
Within the `1.x` series, explicit output for that tuple should remain stable
638+
except for documented correctness or security fixes. This makes the crate
639+
suitable for stable CDN-backed avatar URLs and golden regression tests.
640+
Namespace hashing uses length-prefixed components, so embedded separator bytes
641+
cannot create tenant/style-version ambiguity. The default SHA-512 path keeps the
642+
pre-0.7 identity preimage stable; optional crate-wide hash modes are
643+
domain-separated.
624644

625645
For style-aware rendering, the deterministic tuple also includes
626646
`accessory`, `color`, `expression`, and `shape`. Existing `AvatarOptions`
627647
entry points keep those extra layer choices at `none`, `default`, `default`,
628648
and `square`, so explicitly selected `AvatarOptions` output remains stable
629-
unless the selected family renderer changes. `0.13.0` adds new
630-
`AvatarBackground` values, so automatic style derivation can map some
631-
identities to different backgrounds than `0.12.0`; services that need the old
632-
automatic distribution should keep their existing namespace style version until
633-
they intentionally migrate. Some family/layer combinations are deterministic
634-
no-ops when the layer has no sensible anchor for that family.
649+
within a major release unless a documented correctness or security fix requires
650+
new output. Automatic style rendering derives choices through public `ALL`
651+
variant lists, so adding variants in a future minor release can change
652+
automatic distribution. Services that need controlled rollouts should keep
653+
their existing namespace style version until they intentionally migrate. Some
654+
family/layer combinations are deterministic no-ops when the layer has no
655+
sensible anchor for that family.
635656

636657
Frame shapes are applied as masks in raster output and as SVG clip paths in SVG
637658
output. Non-square shapes therefore trim the background, avatar body, color
638659
accent, accessory layer, and expression layer consistently before drawing the
639660
frame border.
640661

641662
The renderer still uses floating-point geometry in family-specific drawing
642-
paths. Frame-shape raster hit-testing uses integer arithmetic as of `0.13.0`,
663+
paths. Frame-shape raster hit-testing uses integer arithmetic as of `1.0.0`,
643664
which reduces one source of platform rounding variance. The project tests
644665
golden fingerprints on the release platform, but it does not yet claim formal
645666
bit-identical raster output across every CPU architecture, compiler backend,

docs/STABILITY.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Stability Policy
2+
3+
`hashavatar` 1.0.0 is the first stable release of the public crate API and the
4+
documented rendering contract.
5+
6+
## Public API
7+
8+
The crate follows Cargo semver for exported Rust API items:
9+
10+
- Removing or renaming public items requires a major version.
11+
- Changing public function signatures, error types, constructor behavior, or
12+
feature names requires a major version unless the change is strictly
13+
additive and source-compatible.
14+
- Adding new enum variants to public non-exhaustive-style option enums such as
15+
`AvatarKind`, `AvatarBackground`, `AvatarAccessory`, `AvatarColor`,
16+
`AvatarExpression`, `AvatarShape`, or `AvatarOutputFormat` is allowed in a
17+
minor release. Callers should include wildcard arms when matching these
18+
enums if they want minor-version compatibility.
19+
- New optional Cargo features may be added in minor releases when they are
20+
disabled by default and documented.
21+
22+
## Rendering Contract
23+
24+
For a concrete crate release and explicitly selected options, the intended
25+
stable rendering tuple is:
26+
27+
```text
28+
crate identity hash mode + namespace tenant + namespace style version + identity bytes + avatar kind + background + accessory + color + expression + shape + dimensions + seed
29+
```
30+
31+
Within a major release, patch releases should not intentionally change output
32+
for the same tuple except to fix a correctness or security bug. Minor releases
33+
may add variants or visual capabilities, and release notes must state whether
34+
automatic style distribution changes.
35+
36+
`AvatarOptions` keeps `accessory = none`, `color = default`,
37+
`expression = default`, and `shape = square`. `AvatarStyleOptions` includes the
38+
full visual-layer tuple.
39+
40+
Automatic style rendering derives options from public enum `ALL` lists. Adding
41+
a variant can change automatic distribution. Services that need controlled
42+
rollouts should use `AvatarNamespace::new(tenant, style_version)` and only bump
43+
`style_version` when they are ready for a new visual distribution.
44+
45+
## Security And Resource Contract
46+
47+
- Public dimensions remain bounded by `AvatarSpec`.
48+
- Identity and namespace input lengths remain bounded before hashing.
49+
- Public rendering APIs return typed errors for invalid inputs instead of
50+
panicking.
51+
- The crate remains a pure library crate with no HTTP server, CLI, filesystem
52+
writing API, async runtime, or network dependency.
53+
- The default build keeps SHA-512 identity hashing and WebP encoding.
54+
- Optional hash modes and extra raster encoders remain explicit Cargo feature
55+
choices.
56+
57+
## Known Residuals
58+
59+
The renderer still uses floating-point arithmetic in family-specific geometry.
60+
Frame-shape hit-testing uses integer arithmetic, and golden fingerprints protect
61+
the release-platform output, but the crate does not claim formal bit-identical
62+
raster output across every CPU architecture and compiler backend.
63+
64+
Rendering time, SVG size, and encoded raster size are not constant-time with
65+
respect to the identity digest. High-assurance services should use stable cache
66+
keys, CDN caching, rate limits, concurrency limits, and fixed-minimum-latency
67+
wrappers when their threat model requires it.

docs/VERSION_PLAN.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@ reduce platform-sensitive geometry in frame-shape masking before `1.0`.
489489

490490
## 1.0.0: Stability Contract
491491

492+
Status: release candidate.
493+
492494
Goal: freeze a professional, security-oriented public API and rendering
493495
contract.
494496

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# hashavatar 1.0.0
2+
3+
`1.0.0` is the first stable release of `hashavatar`.
4+
5+
This release does not add new avatar families, backgrounds, visual layers,
6+
hash modes, output formats, or runtime dependencies. It freezes the public API
7+
shape and documents the rendering stability contract built through the 0.x
8+
series.
9+
10+
## Stable Contract
11+
12+
- Public Rust API changes now follow Cargo semver expectations.
13+
- Explicit rendering output is intended to remain stable within the `1.x`
14+
series for the same active identity hash mode, namespace, identity, avatar
15+
options, dimensions, and seed, except for documented correctness or security
16+
fixes.
17+
- Automatic style rendering remains deterministic, but future minor releases
18+
may change automatic distribution when public enum `ALL` lists gain new
19+
variants.
20+
- Services that need deliberate visual rollouts should use
21+
`AvatarNamespace::new(tenant, style_version)` and bump `style_version` only
22+
when they are ready for a new visual distribution.
23+
24+
## Documentation
25+
26+
- Added `docs/STABILITY.md` with the stable API, rendering, security/resource,
27+
and residual-risk policies.
28+
- Updated README guidance for the 1.0 stable contract.
29+
- Added the stability policy to release metadata validation so it remains part
30+
of the published crate package.
31+
32+
## Security Posture
33+
34+
- The crate remains a pure library crate with no HTTP server, CLI, filesystem
35+
writing API, async runtime, or network dependency.
36+
- Public dimensions, identity inputs, and namespace components remain bounded.
37+
- Public render APIs return typed errors for invalid inputs instead of
38+
panicking.
39+
- The default build remains SHA-512 identity hashing plus WebP encoding.
40+
- Optional BLAKE3, XXH3-128, PNG, JPEG, and GIF support remain explicit Cargo
41+
features.
42+
43+
## Compatibility Notes
44+
45+
- No visual variants were added in this release.
46+
- No intentional golden fingerprint changes were made for `1.0.0`.
47+
- The known residuals documented in `docs/STABILITY.md` and
48+
`docs/SECURITY_CONTROLS.md` still apply: family-specific geometry uses some
49+
floating-point arithmetic, rendering is not constant-time, and service-level
50+
concurrency/rate limiting belongs in callers such as `hashavatar-api`.

fuzz/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fuzz/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ publish = false
88
cargo-fuzz = true
99

1010
[dependencies]
11-
hashavatar = { path = "..", version = "0.13.0", features = ["fuzzing"] }
11+
hashavatar = { path = "..", version = "1.0.0", features = ["fuzzing"] }
1212
libfuzzer-sys = "0.4"
1313
roxmltree = "0.21.1"
1414

scripts/validate-release-metadata.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ test -s docs/DEPENDENCIES.md
6060
test -s docs/PANIC_POLICY.md
6161
test -s docs/RELEASE.md
6262
test -s docs/SECURITY_CONTROLS.md
63+
test -s docs/STABILITY.md
6364
test -s "docs/release-notes/RELEASE_NOTES_${cargo_version}.md"
6465

6566
for required_script in \
@@ -113,6 +114,7 @@ for required_package_file in \
113114
"docs/PANIC_POLICY.md" \
114115
"docs/RELEASE.md" \
115116
"docs/SECURITY_CONTROLS.md" \
117+
"docs/STABILITY.md" \
116118
"LICENSE-APACHE" \
117119
"LICENSE-MIT" \
118120
"README.md" \

0 commit comments

Comments
 (0)