Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7b746f7
WIP: Analyses Finding #9 — implement formatter ConfigPatch monoid (T-…
briansrls May 26, 2026
83c5455
T-4.16 follow-on: dissolve formatter-config-patch gate — add FieldPat…
briansrls May 26, 2026
92b04c5
prettier.dag: replace bespoke Prettier*Patch coproducts with FieldPat…
briansrls May 26, 2026
ff27e84
patch.dag: add compose_field_patch + field_patch_monoid<T> witness (M…
briansrls May 26, 2026
3957e39
prettier.dag: expand PrettierConfigPatch to per-field FieldPatch<T>
briansrls May 26, 2026
764924d
Merge remote-tracking branch 'origin/main' into session/vivid-wren-215
briansrls May 26, 2026
fec18cd
WIP: Analyses Finding #9 — implement formatter ConfigPatch monoid (T-…
briansrls May 26, 2026
3ac471c
patch.dag: correct grounding — right-biased optional-value monoid, no…
briansrls May 26, 2026
db7ef8c
WIP: Analyses Finding #9 — implement formatter ConfigPatch monoid (T-…
briansrls May 26, 2026
7878f59
field_patch_monoid.dag: remove hand-rolled field_patch_bool_eq (Pract…
briansrls May 27, 2026
bd6406a
field_patch_monoid.dag: fix parse error — data initializer must start…
briansrls May 27, 2026
7c36463
test: wire monoid witness consumer claims in field_patch_monoid.dag
briansrls May 27, 2026
6293218
Merge remote-tracking branch 'origin/main' into session/vivid-wren-215
briansrls May 27, 2026
d953a42
fix: remove explicit <Bool> type args from field_patch_monoid calls
briansrls May 27, 2026
f2e425e
Merge remote-tracking branch 'origin/main' into session/cool-newt-327
briansrls May 27, 2026
45e01ec
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
aee2ef2
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
446f592
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
9c119e5
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
59ee7e6
sync: merge vivid-wren-215 right-bias RC fix into cool-newt-327
briansrls May 27, 2026
58b93ed
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
fb9a274
fix: gate ConfigPatch record mirrors under config-patch-record-projec…
briansrls May 27, 2026
b158710
fix: clarify patch anchor and config-patch-record-projection owner
briansrls May 27, 2026
81db78f
WIP: PR #3705: add right-bias TestClaim to field_patch_monoid — opena…
briansrls May 27, 2026
69dd5d8
fix(T-4.16): align TASKS.md layering contract with ConfigPatch model
briansrls May 27, 2026
0f2f896
fix(prettier): align PrettierConfigPatch with PrettierConfig shape
briansrls May 27, 2026
23c0b83
WIP: PR #3761 cursor RC fix: T-4.16 formatter ConfigPatch monoid + ri…
briansrls May 28, 2026
19d9d12
Merge remote-tracking branch 'origin/main' into session/bold-gull-35-…
briansrls May 28, 2026
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
18 changes: 11 additions & 7 deletions src/v4/TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1840,7 +1840,8 @@ facts.

`rustfmt.dag` established the pattern the sibling files follow:
option coproducts → full config type → defaults data node →
`*_layer` function for hierarchical override composition.
`*ConfigPatch` (per-field `FieldPatch<T>` from `v4.std.patch`) →
`*_layer(base, patch)` applying `apply_field_patch` per field.
(Sibling files black.dag, gofmt.dag, prettier.dag, clang_format.dag,
google_java_format.dag, swift_format.dag, ktfmt.dag, lean4_format.dag
are already landed on main — see PRs #3650, #3651, #3652.)
Expand All @@ -1849,12 +1850,15 @@ are already landed on main — see PRs #3650, #3651, #3652.)
- Each formatter file is **pure config substrate** — no dependency on
`std/node.dag` or any compiler module. This keeps the formatter layer
independent of the compiler pipeline and usable as a standalone fact bundle.
- **Hierarchical override**: `*_layer(base: Config, outer: Config) ->
Config` where outer wins unconditionally. Layering is
`fold(layers, init: *_defaults, f: *_layer)`. Field-granularity patch
types (per-field `Override/Inherit` coproduct) are 🟡 gated —
feature: `formatter-config-patch` — dissolve when consumers need
partial override without full-config specification.
- **Hierarchical override (per-field patches):** `*_layer(base: Config,
patch: *ConfigPatch) -> Config` rebuilds the config by applying
`apply_field_patch` on each field. Patches compose with right-biased
`compose_field_patch` / `field_patch_monoid` from `v4.std.patch`
(`Override { value }` replaces; `Inherit` defers to base). Layering is
`fold(layers, init: *_defaults, f: *_layer)` with one patch per layer.
The prior full-config `*_layer(base, outer) { outer }` scaffold and
`feature:formatter-config-patch` gate are dissolved in the T-4.16 follow-on.
- **ConfigPatch record projection (interim mirrors):** `feature:config-patch-record-projection` in `v4.std.patch` — formatter `*ConfigPatch` records and `*_layer` bodies are hand mirrors until record-field projection derives them from `*Config`; owner **T-4.16 follow-on** (same lane as formatter-config-patch dissolution); consumers carry `consumer:config-patch-record-projection` tags until projection lands.
- **Real options, not abstract axes**: each file models the actual
formatter's documented option space (e.g., `rustfmt.toml` flags, not
a synthetic `IndentWidth` abstraction shared across languages). A
Expand Down
48 changes: 43 additions & 5 deletions src/v4/extdeps/formatters/black.dag
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// src/v4/extdeps/formatters/black.dag
// Scope: Black 26.5.1 pyproject [tool.black] configuration model.
// Owns: BlackTargetVersion, BlackTargetVersionPolicy, BlackRequiredVersionPolicy, BlackUnstableFeature, BlackConfig, black_defaults, black_layer.
// Consumes: v4.std.collection { List }.
// Owns: BlackTargetVersion, BlackTargetVersionPolicy, BlackRequiredVersionPolicy, BlackUnstableFeature, BlackConfig, black_defaults, BlackConfigPatch, black_layer.
// Consumes: v4.std.collection { List }, v4.std.patch { FieldPatch, apply_field_patch }.
// Status: T-4.16 scaffold — Black 26.5.1 pyproject schema.
// Anchor: https://github.com/psf/black/blob/26.5.1/src/black/resources/black.schema.json

module v4.extdeps.formatters.black

import v4.std.collection { List }
import v4.std.patch { FieldPatch, apply_field_patch }


// 🟢 coproduct dissolution — CP-3229-GREEN-TERMINAL.
Expand Down Expand Up @@ -92,7 +93,44 @@ data black_defaults: BlackConfig = BlackConfig {
}


// 🟡 gated — feature: formatter-config-patch — bind T-4.16 follow-on — dissolve-on-arrival: BlackConfigPatch type with per-field Override<T>/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed.
fn black_layer(base: BlackConfig, outer: BlackConfig) -> BlackConfig {
outer
// 🟡 gated — consumer:config-patch-record-projection — bind v4.std.patch feature:config-patch-record-projection — dissolve-on-arrival: BlackConfigPatch projected from BlackConfig field set.
type BlackConfigPatch {
line_length: FieldPatch<Int>
target_version: FieldPatch<BlackTargetVersionPolicy>
required_version: FieldPatch<BlackRequiredVersionPolicy>
pyi: FieldPatch<Bool>
ipynb: FieldPatch<Bool>
python_cell_magics: FieldPatch<List<String>>
skip_source_first_line: FieldPatch<Bool>
skip_string_normalization: FieldPatch<Bool>
skip_magic_trailing_comma: FieldPatch<Bool>
preview: FieldPatch<Bool>
unstable: FieldPatch<Bool>
enable_unstable_feature: FieldPatch<List<BlackUnstableFeature>>
include: FieldPatch<String>
exclude: FieldPatch<String>
extend_exclude: FieldPatch<String>
force_exclude: FieldPatch<String>
}


fn black_layer(base: BlackConfig, patch: BlackConfigPatch) -> BlackConfig {
BlackConfig {
line_length: apply_field_patch(base: base.line_length, patch: patch.line_length),
target_version: apply_field_patch(base: base.target_version, patch: patch.target_version),
required_version: apply_field_patch(base: base.required_version, patch: patch.required_version),
pyi: apply_field_patch(base: base.pyi, patch: patch.pyi),
ipynb: apply_field_patch(base: base.ipynb, patch: patch.ipynb),
python_cell_magics: apply_field_patch(base: base.python_cell_magics, patch: patch.python_cell_magics),
skip_source_first_line: apply_field_patch(base: base.skip_source_first_line, patch: patch.skip_source_first_line),
skip_string_normalization: apply_field_patch(base: base.skip_string_normalization, patch: patch.skip_string_normalization),
skip_magic_trailing_comma: apply_field_patch(base: base.skip_magic_trailing_comma, patch: patch.skip_magic_trailing_comma),
preview: apply_field_patch(base: base.preview, patch: patch.preview),
unstable: apply_field_patch(base: base.unstable, patch: patch.unstable),
enable_unstable_feature: apply_field_patch(base: base.enable_unstable_feature, patch: patch.enable_unstable_feature),
include: apply_field_patch(base: base.include, patch: patch.include),
exclude: apply_field_patch(base: base.exclude, patch: patch.exclude),
extend_exclude: apply_field_patch(base: base.extend_exclude, patch: patch.extend_exclude),
force_exclude: apply_field_patch(base: base.force_exclude, patch: patch.force_exclude),
}
}
Loading
Loading