Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["core", "ui-core", "cockpit", "cli", "plugin", "preview"]
members = ["core", "pattern", "ui-core", "cockpit", "cli", "plugin", "preview"]
# `fuzz/` is an isolated nightly cargo-fuzz crate (ADR-0010); it is
# deliberately not a workspace member so stable `--workspace` builds,
# clippy, and tests never touch it.
Expand Down
7 changes: 5 additions & 2 deletions docs/adr/0029-swang-authoring-and-verified-lifting.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ in [`../swang/spec.md`](../swang/spec.md); the delivery plan in

2. **Two crates, one dependency direction.** `griff-pattern` is the pure
structural algebra — **std-only: zero external dependencies, no
`griff-core`, no MIDI, no serde, no time types** — holding `Pattern`,
`PatternTree`, traversals, budgets, and deterministic pruning.
`griff-core`, no MIDI, no serde, no time types** — holding `Kernel`,
`Expansion`, `NodePath`, traversals, budgets, and deterministic pruning.
No materialized pattern tree exists: the expansion is answered per cell
from coordinate digits, and the tree stays implicit in the `NodePath`
addressing; the pruning semantics are unaffected.
`griff-swang` holds the AST, parser/formatter (later phases), and the
lowering into `griff-core` types. Serialization of artifacts lives in
`griff-swang` or an adapter, never in `griff-pattern`.
Expand Down
13 changes: 13 additions & 0 deletions docs/decisions.log.md
Original file line number Diff line number Diff line change
Expand Up @@ -1688,3 +1688,16 @@ Architectural decisions go to [`adr/`](adr/) instead.
Verus toolchain in CI, to achieve verification effort proportional to
frozen semantics, accepting that no machine-checked functional proofs
exist for v0.1. Logged in `process-backlog.md`.

- 2026-07-14 — In the context of the `griff-pattern` Phase 1 review (#113),
facing a stage plan that promised a materialized `PatternTree` while the
implementation answers each cell of the final `Expansion` grid from its
coordinate digits, we decided for **recognizing the coordinate-digit
evaluator as the v0.1 representation** — the tree stays implicit in the
`NodePath` addressing — and against building the intermediate tree to match
the document, to achieve the same normative pruning semantics without the
exponential intermediate allocation, accepting that a future phase needing
the explicit tree (recognizers, lifting) must introduce it then. `thin` is
likewise deferred out of Phase 1: spec §1.10 fixes its type contract, but
its cell-selection rule is unspecified, and inventing one to satisfy an
acceptance checkbox would freeze semantics nobody designed.
26 changes: 18 additions & 8 deletions docs/stages/S16-swang-language-and-verified-lifting.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,13 @@ Specified and scheduled, with semantics in the spec:
fractalize
linearize
map_rhythm
thin
```

`thin` sits between the tiers: its **type contract** is fixed (spec §1.10 —
it may only flip `X -> .`, preserving dimensions and sequence length), but
its cell-selection rule is deliberately unspecified and it ships in no phase
until that rule earns its own spec section.

Candidate roster — names under consideration, with **no promised semantics
and no assigned delivery phase** until each earns its spec section:

Expand Down Expand Up @@ -279,23 +283,29 @@ No generation behavior changes.
Add domain-neutral primitives, std-only:

```text
Pattern / Cell
PatternTree / NodePath
Kernel / NodePath
Expansion
Traversal (row_major | snake)
ActivitySequence
FractalSpec / ExpansionBudget
PruneSpec / DensityBps / ExpansionBudget
```

There is deliberately **no materialized `PatternTree`**: `fractalize`
answers each cell of the final `Expansion` grid from its coordinate digits
(most-significant first — the digits *are* the implicit tree path), so the
tree exists in the addressing scheme rather than in memory. The normative
pruning semantics are unchanged; the intermediate representation of the
first draft is simply not needed (decisions log 2026-07-14).

Implement deterministic `fractalize`, traversal, and path-addressed pruning
without MIDI, tonal, fretboard, UI, serde, or generator dependencies.

Acceptance:

- empty parents produce empty descendants;
- expansion never exceeds the declared budget, and the breach error carries
the offending `NodePath`;
- transforms are deterministic and compositional; `thin` preserves cell
count and sequence length;
- expansion never exceeds the declared budget, and every breach error —
depth or cells — carries the offending `NodePath`;
- transforms are deterministic and compositional;
- two-dimensional kernels require explicit traversal; ragged kernels are
rejected before allocation;
- golden coordinate/activity vectors for both traversals; golden
Expand Down
6 changes: 5 additions & 1 deletion docs/swang/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ Consequences, all normative:

- `thin : Pattern2D -> Pattern2D` may only flip `X -> .`. It preserves
dimensions, cell count, coordinates, and post-`linearize` sequence length.
Only this type contract is fixed: the cell-selection rule is deliberately
unspecified, and `thin` ships in no phase until that rule earns its own
spec section.
- Compaction (removing cells, shortening the sequence) is a **separate,
deferred operator with a distinct output type** — returning a plain
`ActivitySequence` from it would be a type-system lie.
Expand Down Expand Up @@ -403,7 +406,8 @@ griff generate seed.gp5 out.mid \
3. A ragged kernel is rejected before expansion.
4. `.` creates a gap in offsets; it does not disappear.
5. Two adjacent `X` create two short notes.
6. `thin` preserves cell count and sequence duration.
6. The expansion artifact records the bar geometry (PPQN, meter,
`bar_duration`, `slots_per_bar`).
7. `rest-pad` pads only the tail of the final bar.
8. `reject` refuses an incomplete final bar.
9. Pattern rhythm overrides corpus rhythm but not corpus novelty/gesture.
Expand Down
22 changes: 22 additions & 0 deletions pattern/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "griff-pattern"
description = "Pure structural pattern algebra: kernels, bounded fractal expansion, traversals (S16)"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true
categories.workspace = true

# Deliberately empty: this crate is std-only by contract (ADR-0029 §2).
# No serde, no griff-core, no time types — serialization and musical meaning
# live in griff-swang and the frontends.
[dependencies]

[dev-dependencies]
proptest = { workspace = true }

[lints]
workspace = true
8 changes: 8 additions & 0 deletions pattern/proptest-regressions/lib.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 975a4af0b66d5bc280058fe9e6c7f192816380e212a17c8e32537190aad9940a # shrinks to rows = ["."]
cc d13b8e3f8aba50341518bb0ff7f35717169e6da72df7093017acd585b05f4325 # shrinks to rows = ["."], depth = 0
Loading
Loading