Determinism Rules
APS is designed for deterministic, reproducible validation. This page explains how.
What is Determinism?
Determinism means: same inputs → same outputs.
For APS:
- Same plan content → same hash
- Same plan → same validation result
- Same task → same success criteria
Hash Stability
How Hashes Work
Each APS document has a content hash:
---
format: aps
version: 1.0
hash: sha256:a1b2c3d4e5f6...
---
The hash is computed from the semantic content, not the raw text.
What Changes the Hash
Content changes:
# Before
Outcome: Users can log in
# After (hash changes)
Outcome: Users can log in with SSO
What Doesn't Change the Hash
Whitespace normalisation:
# These produce the same hash:
Outcome: Users can log in
Outcome: Users can log in
Outcome: Users can log in
Comment changes:
# These produce the same hash:
Outcome: Users can log in
<!-- This is a comment -->
Outcome: Users can log in
<!-- Different comment -->
Computing Hashes
# Compute hash for a plan
anvil plan hash plans/index.aps.md
# Output:
# sha256:a1b2c3d4e5f6...
Normalisation Rules
Text Normalisation
- Trim leading/trailing whitespace
- Collapse multiple spaces to single space
- Normalise line endings to LF
- Remove trailing whitespace from lines
Structural Normalisation
- Order frontmatter fields alphabetically
- Order list items by appearance
- Preserve heading hierarchy
What's Preserved
- Heading text and level
- Task IDs and titles
- Outcome text
- Validation commands
- Step text and order
- Dependencies
What's Ignored
- Comments (HTML-style)
- Extra blank lines
- Trailing whitespace
- Frontmatter order
Reproducibility
Validation Reproducibility
Given:
- Same plan (by hash)
- Same configuration
- Same codebase state
Result:
- Same validation outcome
- Same evidence produced
Caching
Hash stability enables caching:
Plan hash: abc123
Config hash: def456
Files hash: ghi789
Combined: xyz...
Cache hit? Use cached result.
Cache miss? Run validation.
Audit Trail
Reproducibility enables auditing:
Q: "Was this code validated?"
A: Evidence shows plan abc123 passed at timestamp T
Same plan today produces same hash
Therefore: same validation criteria applied
Implementation Details
Hash Algorithm
APS uses SHA-256:
- Widely supported
- Collision resistant
- Fast computation
Content Extraction
Before hashing:
- Parse Markdown to AST
- Extract semantic nodes
- Normalise text content
- Serialise to canonical form
- Compute SHA-256
Canonical Form
The canonical form is JSON:
{
"format": "aps",
"version": "1.0",
"title": "My Project",
"modules": [
{
"id": "auth",
"tasks": [
{
"id": "AUTH-001",
"title": "Login endpoint",
"outcome": "Users can log in"
}
]
}
]
}
This JSON is then hashed.
Edge Cases
Empty Content
Empty or whitespace-only content has a defined hash:
sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
(This is the SHA-256 of empty string.)
Unicode
Unicode is normalised (NFC) before hashing:
# These produce the same hash:
café (composed) café (decomposed: e + combining accent)
Ordering
Task order matters (affects hash). Step order matters.
# Different hashes:
## Tasks
- AUTH-001
- AUTH-002
## Tasks
- AUTH-002
- AUTH-001
Verification
Manual Verification
# Compute expected hash
anvil plan hash plans/index.aps.md
# Compare with stored hash
cat plans/index.aps.md | grep "hash:"
Automated Verification
# Verify all plans
anvil plan verify
# Output:
# plans/index.aps.md: ✓ valid
# plans/modules/auth.aps.md: ✗ hash mismatch
Next: JSON Schema →