Skip to content

S16 Phase 3, slice 2: griff swang expand — law 1 by construction - #119

Merged
PhysShell merged 7 commits into
mainfrom
claude/s16-phase3-expand
Jul 15, 2026
Merged

S16 Phase 3, slice 2: griff swang expand — law 1 by construction#119
PhysShell merged 7 commits into
mainfrom
claude/s16-phase3-expand

Conversation

@PhysShell

@PhysShell PhysShell commented Jul 15, 2026

Copy link
Copy Markdown
Owner

What

The second Phase 3 slice: griff swang expand runs a program's pattern pipeline up to map_rhythm and prints the canonical griff.pattern-expansion JSON to stdout (the program's export owns the only musical output; an inspection command does not get a second path to own — spec updated first).

Strict red→green per commit:

  • docs(swang): the expand contract — stdout, and expansion-time diagnostic locations by §1.5's layers.
  • test(swang): red + green — parse_with_spans: a side table with the four owning-word spans (kernel literal, unit, tail, source). Not AST fields: Program equality and the roundtrip law stay span-free; parse() becomes the span-dropping wrapper. One parser, two entry points.
  • refactor(cli): compile_pattern_flawsPatternFlaw — the pattern compiler now fails as typed data named by the vocabulary site that owns the fix (kernel / unit / score geometry / density / budget-with-NodePath / lowering / silent expansion / silent window). compile_pattern becomes its transport renderer: into_transport() reproduces today's codes, flags, and messages byte-for-byte. §1.5's "core emits pure data, frontends render" now holds where it was being violated. No behavior change — all 19 transport contract tests untouched.
  • test(cli): red + green — five laws for expand:
    • Law 1, end to end: the program equivalent of a Phase-2 CLI command produces a byte-identical artifact — proven against --emit-rhythm-expansion output, and guaranteed by construction (both frontends drive the same compile_pattern_flaws).
    • Structural = NodePath: a budget breach renders error[SWG0201] (<file>: node root): … — the whole-grid check breaks at the root; dotted child indices otherwise.
    • Score-borne at the quoted source value, time-domain at the owning value: a unit that does not divide the 7/8 bar is SWG0301 at <file>:7:<col> — the unit value's span, not a flag that no longer exists.
    • Program vocabulary: the silent bars window and the rejected tail advise bars and rest_pad — no --rhythm-*, no rest-pad.

Law status after this slice

§3.5 law Status
1 (expand byte-parity, canonical subset) covered here
2, 3, 6, 7 covered in #118
4 (code parity, layered locations) parse layer in #118; expansion layer here (NodePath / quoted source value / owning value)
5 (build parity split auto/named) next slice

Fuzz targets (ADR-0010) follow build — the last Phase 3 slice.

Known local-only failure: missing_file_golden on Russian-locale Windows (pre-existing).

After merge

Phase 3 slice 3 red: griff swang build — law 5: under strategy auto byte-parity with griff generate at the same seeds; under a named strategy, the first ranked candidate of that strategy from the unchanged ranked set, written to the program's own export.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM

Summary by CodeRabbit

  • New Features

    • Added griff swang expand to compile rhythm patterns and print the canonical expansion JSON to stdout.
    • Enhanced diagnostics with more precise source locations for kernels, units, tails, and sources.
    • Added clearer, targeted error codes/messages for expansion and validation failures (e.g., budget, silent windows, rejected tails).
  • Documentation

    • Updated the swang Phase 3 spec to precisely define check | fmt | expand | build behavior and where diagnostics point.
  • Bug Fixes

    • Improved diagnostic consistency and ensured swang expand output matches existing generation transport results.

PhysShell and others added 6 commits July 15, 2026 11:40
The program's export owns the only musical output; an inspection
command does not get a second path to own. Expansion-time diagnostics
follow $1.5: NodePath for structural (node root for the whole-grid
check), the source word's span for score-borne facts, the owning
word's span for time-domain errors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
parse_with_spans returns the Program plus the four locations $1.5's
layers render expansion-time diagnostics at: the quoted kernel
literal, the unit and tail values, the quoted source literal. A side
table, not AST fields — Program equality and the roundtrip law stay
span-free. Two failing tests: the spans slice the reference source to
the owning words, and both entry points are one parser.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
parse_with_spans threads the four owning-word spans out of the
existing descent (the tokens were already in hand and thrown away);
parse() becomes its span-dropping wrapper. 53/53.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
…rt renders them

compile_pattern_flaws is the same pipeline returning PatternFlaw —
each variant named by the vocabulary site that owns the fix (kernel,
unit, score geometry, density, the budget with its NodePath intact,
the lowering, the silent expansion and window). compile_pattern
becomes its transport renderer: into_transport() reproduces today's
codes, flags, and messages byte-for-byte, so $1.5's 'core emits pure
data, frontends render' finally holds where it was being violated.
No behavior change; all 19 transport contract tests untouched and
green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
…cations

Five failing tests: the program equivalent to a Phase-2 CLI command
produces a byte-identical expansion JSON (one compiler, one artifact);
a structural budget breach is SWG0201 at 'node root' — the NodePath is
the location; a unit that does not divide the 7/8 bar is SWG0301 at
the unit word on line 7, not at a flag that no longer exists; the
silent --bars window and the rejected tail speak program vocabulary —
'bars' and 'rest_pad', no retired flags, no transport spellings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
expand parses with the span table, loads the program's own source
score, and drives the same compile_pattern_flaws the transport drives
— so law 1's byte parity is a property of construction, and the test
proves it end to end against --emit-rhythm-expansion. The artifact
goes to stdout: export owns the only musical output.

Flaws render at $1.5's layers: SWG0201/0202 carry their NodePath
('node root' for the whole-grid check, dotted indices otherwise);
SWG0304/0305 sit at the source word; unit flaws at the unit value;
the rejected tail at the tail value, advising the program's own
rest_pad; the silent window speaks 'bars' — no retired flags, no
transport spellings. 11/11 CLI, the wall clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Swang gains span-aware parsing, typed rhythm compilation failures, and a new griff swang expand command that emits canonical expansion JSON with stable source-located diagnostics. Integration tests cover output parity, budget failures, and program-specific error vocabulary.

Changes

Swang expansion flow

Layer / File(s) Summary
Span-aware program parsing
swang/src/syntax.rs
Adds ProgramSpans and parse_with_spans, capturing kernel, unit, tail, and source locations while preserving parse.
Typed rhythm compilation failures
cli/src/rhythm_pattern.rs
Introduces PatternFlaw and compile_pattern_flaws, deferring conversion to transport diagnostics for rhythm, budget, lowering, and silent-expansion failures.
Swang expand command and rendering
cli/src/main.rs
Adds griff swang expand, compiles through map_rhythm, renders stable SWG____ diagnostics, and prints expansion JSON.
Expansion parity and acceptance coverage
cli/tests/swang_cmd.rs, docs/swang/spec.md
Tests byte-level output parity and source-located diagnostics, and documents expand output ownership and diagnostic span rules.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: enhancement

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is specific and accurately summarizes the main change: the Phase 3 slice for griff swang expand.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/s16-phase3-expand

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 49b6e7b439

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread swang/src/syntax.rs
…executable

The spec said 'the source word's span' while the implementation stored
the value's — the review resolved the ambiguity in the value's favor:
the path literal identifies the offending score, and the keyword never
changes (unit and tail already point at values). The spec now says
'the quoted source value's span', and the one uncovered branch of the
expansion layer gets its executable verdict: a meter-change MIDI (4/4
to 7/8 at bar 1, encoded independently in the test) drives SWG0304 to
exactly <file>:9:16 — the opening quote of the source path — with no
INPUT and no transport flags in sight. The rhythm_pattern module doc
also stops claiming errors leave only as PatternDiagnostics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
@PhysShell

Copy link
Copy Markdown
Owner Author

Blocker closed at head 40fe6c3, one docs+test commit as prescribed:

  1. Spec disambiguated in the value's favor: 'score-borne facts sit at the quoted source value's span — the path literal identifies the offending score, and the keyword never changes.'
  2. Executable verdict for the uncovered branch: a meter-change MIDI (4/4 → 7/8 at bar 1, encoded independently in the test) drives SWG0304 to exactly <file>:9:16 — the opening quote of the source path literal — asserting the code, the precise line:column, and the absence of INPUT and transport flags. 12/12.
  3. Codex thread answered (ambiguity accepted, keyword-span rejected per the arbiter's resolution) and resolved.
  4. rhythm_pattern module doc no longer claims errors leave only as PatternDiagnostics — it now names the PatternFlaw core and both renderers.

No other changes: no path-resolution semantics, no fuzzing, no generation integration. Gate: fmt/clippy clean, the only local failure remains the known locale golden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant