Skip to content

docs(swang): spec §3 — the grammar the demo earned, with an explicit strategy policy - #117

Merged
PhysShell merged 3 commits into
mainfrom
claude/s16-phase3-grammar-docs
Jul 15, 2026
Merged

docs(swang): spec §3 — the grammar the demo earned, with an explicit strategy policy#117
PhysShell merged 3 commits into
mainfrom
claude/s16-phase3-grammar-docs

Conversation

@PhysShell

@PhysShell PhysShell commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

The Phase 2 closure verdict, made normative before any parser exists — so Phase 3 starts from written law, not oral tradition.

What changed

  • Spec §3 (unstable until Phase 3 closes): the surface grammar with the verdict's reference program; every construct earned by the audible DGD demo, nothing speculative. Earned parameter sets are spelled out: fractalize depth <n> density <bps>bps seed <u64> with density/seed a visible pair (no implicit seeds — determinism was paid for in several PRs and a fair number of human nerve cells), linearize always naming its traversal, map_rhythm always writing both unit and tail.
  • §3.3 — the verdict's amendment: the strategy policy is explicit (strategy auto | rhythm_copy | motif_transpose | constrained_walk | shuffle_motifs | repeat_variation). The dense demo proved the audible result is decided between the expansion and the ear — repeat_variation held one template of a six-template palette — and a language that hides that choice under-tells. Named strategies are selection-only semantics: top-ranked candidate of that strategy from the unchanged set. Group policies (the verdict's "rotate" reading) deferred until a real program asks.
  • §3.4 — not earned: gesture (generation parameter + artifact metadata; its dense-demo cut was excellent but unisolated), thin (the proven operation is seeded density pruning, already named by fractalize density/seed — no vaguer abstraction gets pre-created), pitch/fretboard transforms, morph, DGD macros.
  • §3.5 — the seven acceptance laws: byte-identical expansion vs the Phase-2 CLI, fmt idempotence, parse(format(ast)) == ast, same SWG codes and location classes, build parity with griff generate, strategy explicit in the AST, no invented defaults.
  • Stage doc Phase 3 aligned; decisions log records the strategy amendment and thin's burial.

One deliberate deviation from the verdict text

The reference program opens with swang 1, not the verdict's illustrative swang 0.1: §1.1 froze a monotonic integer level with a byte-exact first-line grammar, and a dotted version literal would contradict it. Flagged here rather than silently normalized.

Docs only; no runtime changes. After merge: Phase 3 red — lexer/parser skeleton with failing tests for the reference program, the seven laws, and the SWG parity.

Refs #108, ADR-0029, S16 Phase 3.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM

Summary by CodeRabbit

  • Documentation
    • Defined the upcoming Swang surface grammar, including supported operators, parameters, strategy selection, and rhythm overrides.
    • Clarified parsing, formatting, validation, expansion, and build behavior requirements.
    • Documented canonical formatting and byte-identical expansion guarantees.
    • Updated the experimental syntax status and reorganized deferred research topics.
    • Recorded the decision to expose strategy policy explicitly while retaining gesture and favoring seeded density pruning over thin.

…emanded

The Phase 2 closure verdict, made normative before any parser exists:
spec §3 records the surface grammar with the reference program, the
earned parameter sets (density/seed a visible pair, both map_rhythm
boundaries always written), the explicit strategy policy — the dense
demo proved the audible result is decided between the expansion and
the ear, and a language that hides that choice under-tells — the
not-earned list (gesture, thin, pitch/fretboard), and the seven
acceptance laws under which Phase 3 adds no musical semantics. The
stage doc's Phase 3 aligns; the decisions log records the strategy
amendment and thin's burial. The reference program opens with the
frozen integer header (swang 1) — the verdict's illustrative
`swang 0.1` predates §1.1 and loses.

Co-Authored-By: Claude Opus 4.8 (1M context) <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

Warning

Review limit reached

@PhysShell, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a4a96c1b-5965-4cc8-8d7a-ddca18a5f6a4

📥 Commits

Reviewing files that changed from the base of the PR and between 79d0c23 and 7e051c4.

📒 Files selected for processing (1)
  • docs/stages/S16-swang-language-and-verified-lifting.md
📝 Walkthrough

Walkthrough

The PR documents the Swang Phase 3 surface grammar, exposes strategy policy in the AST, clarifies operator parameters and CLI behavior, and defines stronger expansion, formatting, diagnostics, and build equivalence acceptance laws.

Changes

Swang Phase 3 grammar

Layer / File(s) Summary
Surface grammar and strategy policy
docs/swang/spec.md, docs/decisions.log.md
The specification defines the earned surface grammar, operator parameters, explicit strategy syntax, Phase 3 acceptance laws, and supersession of the experimental transport syntax. The decision log records the strategy policy and seeded density pruning decisions.
Phase 3 scope and acceptance
docs/stages/S16-swang-language-and-verified-lifting.md
Phase 3 scope now includes the specified operators and AST strategy policy, updates the build example, and defines expansion, formatting, diagnostics, and build equivalence requirements.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • PhysShell/griff#111: Establishes the normative Swang semantic core and Phase 2 transport syntax referenced by these Phase 3 documentation updates.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the documentation update to Swang spec §3 and the explicit strategy policy change.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/s16-phase3-grammar-docs

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: 31145d22f1

ℹ️ 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 docs/swang/spec.md Outdated
Comment thread docs/swang/spec.md Outdated

Copy link
Copy Markdown
Owner Author

Арбитраж Phase 3 grammar docs — changes required

Общее направление принято: swang 1 правильно следует замороженному integer-level header; явная named-strategy policy нужна; selection-only трактовка лучше, чем изменение генератора/реранкера; групповой rotate действительно следует отложить до реального запроса. Но текущий текст ещё не является исполнимым контрактом. До parser red нужно закрыть следующие границы.

P1 — в программе отсутствует source score

Существующий griff generate INPUT OUTPUT извлекает из INPUT scale/pitch range, PPQN, meter и tempo; corpus заменяет rhythm/novelty/gesture inputs, но не источник этих базовых generation constraints. Эталонная Swang-программа не объявляет INPUT, а griff swang build riff.swg --output ... также его не принимает. Поэтому acceptance law о parity с griff generate сейчас физически невыполним.

Добавить source dependency в AST, например source "seed.gp5" либо generate from "seed.gp5" { ... }. Не прятать её только во frontend flag: ADR-0029 требует явных semantic dependencies, а law 6 уже требует strategy в AST по той же причине.

Заодно нормативно определить resolution относительных source/corpus/export paths (предпочтительно относительно .swg, не process CWD) и поправить determinism law: одинаковы должны быть source text и bytes/fingerprints declared dependencies, а не только text/level/seeds.

P1 — скрыты два значения, влияющие на обещанный parity

  1. Phase-2 expansion artifact содержит max_cells, CLI допускает --rhythm-max-cells и использует frontend default 4096. В §3 fractalize не несёт budget и не фиксирует profile value. Byte-identical artifact поэтому недоопределён. Либо сделать max_cells обязательным синтаксисом, либо явно и нормативно определить значение профиля swang 1; первый вариант лучше соответствует law 7.
  2. Named-strategy selection означает «лучший кандидат этой стратегии», но кандидатный set зависит от --candidates / variants_per_strategy. В grammar этого параметра нет. Добавить явный candidates <n>/variants <n> либо нормативно закрепить profile value. Иначе одна и та же программа не определяет, из какого множества выбирает.

P1 — два владельца output path

Программа содержит |> export midi "...", а stage CLI одновременно обещает griff swang build riff.swg --output riff.mid. Сейчас не определены precedence, provenance и поведение при конфликте. Выбрать один контракт:

  • предпочтительно build riff.swg, где output принадлежит export; либо
  • оставить --output как явный override и нормативно описать precedence и то, что именно форматирует/хеширует fmt.

Молчаливое наличие двух output edges несовместимо с law 7.

P2 — acceptance law 4 смешивает location layers

Существующий открытый thread прав: сохраняется SWG-code parity, но CLI flag/INPUT location нельзя требовать от .swg grammar boundary. Structural core по-прежнему может вернуть NodePath; syntax/transport facts в Phase 3 должны указывать source span. Переписать law как «same SWG semantic code, layer-appropriate §1.5 location» и дать явные примеры.

P2 — build parity применим только к strategy auto

Второй открытый thread также корректен. Текущий griff generate не имеет strategy selector. Поэтому:

  • strategy auto обязан быть byte/semantic parity с существующим CLI;
  • named strategy обязана выбрать первый ranked candidate с соответствующим GenerationStrategy из того же уже отранжированного set, не меняя generation/rerank.

Это два разных acceptance закона, не один.

P2 — seed-only transport нужно решить явно

Phase 2 допускает --rhythm-seed без density и сериализует этот seed в expansion artifact, хотя pruning не включается. §3 теперь запрещает seed без density. Это допустимое canonical-language сужение только если оно названо сознательно и law 1 ограничен canonical Phase-2 subset; иначе byte-identical parity для такого transport invocation невозможен. Либо разрешить seed-only ради полного artifact parity, либо явно исключить его из parity domain и назначить source diagnostic для orphan seed.

CI на 31145d2 зелёный, но это docs-only gate и логические противоречия он, к сожалению, читать пока не научился. Merge удержан до уточнения контракта.

…didates

The #117 review (comment 4976245608) caught the grammar hiding three
semantic dependencies the language was built to expose:

- `source` joins the generate block as a required word: the seed score
  supplies pitch material, range, PPQN, meter, and tempo, and a corpus
  supplements but never replaces it — without it, build parity was
  unimplementable even in theory;
- `max_cells` joins fractalize and `candidates` joins generate, both
  required: the artifact serializes the budget and the candidate count
  shapes the set a named strategy selects from, so neither may hide
  behind a frontend courtesy default;
- the program is the output's single owner — `griff swang build` takes
  no output flag, so a path can never have two masters.

The seven laws sharpen accordingly: parity law 1 is scoped to the
canonical subset (the transport's inert seed-without-density is
deliberately unexpressible and claims no parity); law 4 keeps SWG-code
parity but assigns locations by §1.5 layer — source spans for
syntax/transport, NodePath for structural, the flag class retiring
with the transport; law 5 splits by policy — auto matches griff
generate, a named strategy selects the first ranked candidate of that
strategy from the unchanged, already-ranked set.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM
@PhysShell

Copy link
Copy Markdown
Owner Author

Review fixes landed — point by point against comment 4976245608:

Blockers:

  1. source in the AST — a required word in the generate block (source "…gp5"): the seed score supplies pitch material, range, PPQN, meter, and tempo; corpus supplements, never replaces. §3.1 now states the principle outright: the language was built against hidden dependencies; it does not get to keep one for itself.
  2. max_cells + candidates explicit and requiredfractalize depth 1 max_cells 4096 density 9500bps seed 4; candidates 2 in generate. The Phase-2 CLI's 4096 was a frontend courtesy the grammar does not inherit (law 7 names all three required words).
  3. Output single-owner — the program's export owns the path; griff swang build riff.swg takes no output flag (spec §3.2, §3.5 CLI note, stage doc CLI block updated).

Clarifications:
4. Law 4 keeps SWG-code parity with locations assigned by §1.5 layer: source spans for syntax/transport-class errors (the flag class retires with the transport), NodePath for structural.
5. Law 5 splits by policy: auto matches griff generate byte-for-byte under the same seeds; a named strategy selects the first ranked candidate of that strategy from the unchanged, already-ranked set — selection only, never a re-generation.
6. Law 1 is scoped to the canonical subset: the transport's inert --rhythm-seed-without-density is deliberately unexpressible in the grammar and claims no parity.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NkqJUU6d1sW1RAfvyHrqVM

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/stages/S16-swang-language-and-verified-lifting.md`:
- Around line 383-384: The acceptance bullet in the Swang expansion parity
section is too broad; revise it to limit byte-identical expansion JSON parity to
Phase-2 CLI commands within the canonical transport subset, explicitly excluding
seed-without-density transport. Preserve the existing expand/map_rhythm
qualification.
- Around line 387-388: Update the diagnostic-location statement in the
build/check compatibility bullet to explicitly distinguish source spans for
syntax and transport errors from NodePath for structural errors, reflecting the
§3.5 rule rather than implying all transport location classes remain unchanged.
- Around line 361-366: Update the Phase 3 grammar summary near the listed
constructs to include the required fractalize max_cells parameter and generate
source and candidates parameters, matching the required signatures in
docs/swang/spec.md. Make clear these parameters are mandatory and must not be
replaced with implicit defaults.
- Around line 388-389: Update the build parity statement in the specification to
distinguish strategy policies: require auto to match griff generate, while named
strategies select the first candidate from the unchanged ranked set without
regeneration. Replace the existing broad parity wording near the transport
boundary/build description, preserving the stated ranked-candidate behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: caf9e4f1-439b-45d5-b41f-e2bb4b647b60

📥 Commits

Reviewing files that changed from the base of the PR and between 554a746 and 79d0c23.

📒 Files selected for processing (3)
  • docs/decisions.log.md
  • docs/stages/S16-swang-language-and-verified-lifting.md
  • docs/swang/spec.md

Comment thread docs/stages/S16-swang-language-and-verified-lifting.md
Comment thread docs/stages/S16-swang-language-and-verified-lifting.md Outdated
Comment thread docs/stages/S16-swang-language-and-verified-lifting.md Outdated
Comment thread docs/stages/S16-swang-language-and-verified-lifting.md Outdated

Copy link
Copy Markdown
Owner Author

Повторная сверка головы 79d0c23:

Шесть исходных пунктов в docs/swang/spec.md закрыты корректно: source, max_cells, candidates, единственный владелец output, layered locations, split parity и canonical-subset scope теперь зафиксированы без скрытых defaults.

Остаётся один блокер перед merge: docs/stages/S16-swang-language-and-verified-lifting.md не синхронизирован со спецификацией. В нём по-прежнему перечислены старые сигнатуры без обязательных max_cells, source, candidates, а acceptance всё ещё формулирует безусловный transport parity, старые location classes и общий build parity. Это уже пород

The stage summary still described the pre-verdict contract: fractalize
without its required max_cells, generate without source and candidates,
an unconditional expansion parity, the retired flag location class, and
one undivided build parity. spec.md §3 had already moved on; the stage
doc now mirrors it — canonical-subset parity, layered locations,
auto/named parity split, and the three required words named as such.
The L1 sketch also stops pairing density with no seed.

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

Copy link
Copy Markdown
Owner Author

Re-review addressed at head 7e051c4 (docs-only).

The one remaining blocker — the stage doc contradicting its own spec — is closed. docs/stages/S16-swang-language-and-verified-lifting.md Phase 3 now mirrors §3:

  • Grammar summary: fractalize(depth, max_cells, density, seed) and generate(source, bars, seed, candidates, strategy, corpus)max_cells, source, candidates named as required words, no invented defaults; export named the output's single owner.
  • Expansion parity scoped to the canonical transport subset: the inert --rhythm-seed-without-density form is unexpressible and claims no parity.
  • Locations layered per §1.5: source spans for syntax/transport-class errors (flag class retires with the transport), NodePath for structural.
  • Build parity split: auto matches griff generate; a named strategy selects the first ranked candidate of that strategy from the unchanged, already-ranked set — selection only, never re-generation.
  • Bonus consistency fix: the L1 sketch no longer pairs density with no seed and says max_cells, not budget.

All six open threads (2 Codex on the spec — already fixed by 79d0c23, now answered; 4 CodeRabbit on the stage doc — fixed by 7e051c4) are replied to and resolved. CI should stay green: prose only, no code paths touched.

@PhysShell
PhysShell merged commit 849cc18 into main Jul 15, 2026
3 checks passed
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