202 lines
5.8 KiB
Markdown
202 lines
5.8 KiB
Markdown
# Incremental Build, Cache, and Watch Model Decision
|
|
|
|
## Status
|
|
|
|
Accepted
|
|
|
|
## Date
|
|
|
|
2026-03-11
|
|
|
|
## Context
|
|
|
|
This decision closes the architectural questions raised in [`01.5. Incremental Build, Cache, and Watch Model Agenda`](../agendas/01.5.%20Incremental%20Build,%20Cache,%20and%20Watch%20Model%20Agenda.md).
|
|
|
|
The packer should support incremental work and future watch-driven workflows, but only under a strict rule:
|
|
|
|
- optimization must never redefine build semantics.
|
|
|
|
Incremental behavior, cache reuse, and watch mode must remain subordinate to deterministic artifact production.
|
|
|
|
## Decision
|
|
|
|
The packer adopts a `determinism-first, cache-as-optimization, watch-as-optional-trigger` model.
|
|
|
|
### 1. Fingerprint model
|
|
|
|
Input tracking uses three levels of signal:
|
|
|
|
- `size`
|
|
- `mtime`
|
|
- `strong_hash`
|
|
|
|
Roles:
|
|
|
|
- `size` and `mtime` are fast-change hints;
|
|
- `strong_hash` is the authoritative content identity signal.
|
|
|
|
### 2. Authority of fingerprint signals
|
|
|
|
`size` and `mtime` are not sufficient as final truth for cache reuse.
|
|
|
|
Rules:
|
|
|
|
- they may be used to avoid unnecessary hashing in the fast path;
|
|
- they may indicate that a strong hash check is required;
|
|
- when reuse affects emitted output, strong hash is the authoritative content check.
|
|
|
|
### 3. Cache reuse rule
|
|
|
|
Cached work may be reused only when the full effective build inputs remain equivalent.
|
|
|
|
This includes, at minimum:
|
|
|
|
- source inputs;
|
|
- selected output format;
|
|
- codec;
|
|
- runtime-facing metadata;
|
|
- build configuration that affects emitted bytes;
|
|
- materialized defaults or effective derived configuration.
|
|
|
|
If any of these change, the relevant output must be rebuilt.
|
|
|
|
### 4. Incremental equivalence
|
|
|
|
Incremental build is an execution optimization only.
|
|
|
|
Rules:
|
|
|
|
- full build and incremental build must produce the same observable results;
|
|
- byte output, header content, offsets, preload data, and other runtime-facing artifacts must match;
|
|
- any semantic difference between full and incremental build is a bug.
|
|
|
|
### 5. Cache scope
|
|
|
|
The packer may persist:
|
|
|
|
- fingerprint data;
|
|
- derived build results;
|
|
- internal cache metadata.
|
|
|
|
But:
|
|
|
|
- cache internals are not the source of truth;
|
|
- runtime-facing artifacts remain authoritative;
|
|
- cache structure is not frozen as a normative external contract in the current baseline.
|
|
|
|
### 6. Cache explainability
|
|
|
|
The packer must be able to explain reuse and rebuild decisions.
|
|
|
|
At minimum, the model should support reasons equivalent to:
|
|
|
|
- cache hit;
|
|
- rebuild because input changed;
|
|
- rebuild because config changed;
|
|
- rebuild because format or schema contract changed;
|
|
- rebuild because cache state is missing or invalid.
|
|
|
|
This does not require always-on verbosity, but the capability must exist for diagnostics and Studio tooling.
|
|
|
|
### 7. Watch mode
|
|
|
|
Watch mode is optional in the current baseline contract.
|
|
|
|
Rules:
|
|
|
|
- watch may exist as a supported capability;
|
|
- watch must trigger rebuild and/or revalidation behavior equivalent to normal packer execution;
|
|
- watch is not the place to freeze detailed UI, timing, or orchestration policy yet.
|
|
|
|
### 8. Watch safety
|
|
|
|
Watch mode must not become a silent mutation engine.
|
|
|
|
Rules:
|
|
|
|
- baseline watch behavior is observe, detect, validate, and rebuild;
|
|
- watch does not imply auto-fix, quarantine, adoption, or destructive cleanup;
|
|
- any broader mutation policy requires explicit later design.
|
|
|
|
### 9. Strong hash timing
|
|
|
|
Strong hash calculation is performed pragmatically, but remains authoritative.
|
|
|
|
Rules:
|
|
|
|
- fast hints may be checked first;
|
|
- when hints indicate possible change, strong hash resolves the question;
|
|
- when cache trust is insufficient, strong hash may be recomputed even if hints appear unchanged.
|
|
|
|
### 10. Cache portability
|
|
|
|
Cross-machine cache portability is not part of the current baseline contract.
|
|
|
|
Rules:
|
|
|
|
- cache is treated as local to the workspace/runtime environment by default;
|
|
- portability, remote reuse, or shareable cache semantics require later explicit design.
|
|
|
|
## Invariants and Constraints
|
|
|
|
The following invariants now apply:
|
|
|
|
1. Deterministic output has priority over cache reuse.
|
|
2. `size` and `mtime` are hints, not final truth.
|
|
3. Strong hash is the authoritative content identity signal for reuse decisions.
|
|
4. Cache reuse is allowed only when effective build inputs are equivalent.
|
|
5. Full and incremental builds must be observably equivalent.
|
|
6. Cache is an optimization layer, not a semantic authority.
|
|
7. The packer must be able to explain rebuild/reuse decisions.
|
|
8. Watch mode is optional in the baseline contract.
|
|
9. Watch mode does not imply silent mutation of authoring content.
|
|
10. Cache portability is deferred.
|
|
|
|
## Explicit Non-Decisions
|
|
|
|
This decision does not yet define:
|
|
|
|
- the exact on-disk schema of every cache file;
|
|
- detailed watch UX or scheduling behavior;
|
|
- remote/shared cache design;
|
|
- background worker orchestration;
|
|
- policy for multi-user cache coordination.
|
|
|
|
Those belong to later decisions and specs.
|
|
|
|
## Propagation Targets
|
|
|
|
This decision must propagate to:
|
|
|
|
- packer cache and fingerprint specs;
|
|
- incremental build guarantees spec;
|
|
- watch mode spec or deferred capability note;
|
|
- Studio diagnostics for build-reason visibility;
|
|
- future implementation of fingerprint persistence and cache invalidation.
|
|
|
|
## Validation Notes
|
|
|
|
Example: changed input
|
|
|
|
- source file timestamp changed
|
|
- strong hash also changed
|
|
- cached derived result must be invalidated
|
|
|
|
Example: misleading timestamp
|
|
|
|
- `mtime` changed
|
|
- strong hash remains identical
|
|
- packer may treat the content as unchanged after authoritative hash confirmation
|
|
|
|
Example: config change
|
|
|
|
- source inputs are identical
|
|
- `output.format` or runtime-facing metadata changed
|
|
- cached result must be invalidated because emitted bytes may differ
|
|
|
|
Example: watch behavior
|
|
|
|
- file changes while watch is active
|
|
- packer revalidates or rebuilds
|
|
- watch does not automatically move, delete, or adopt workspace content
|