From 7b746f735d1cd9851bc49bb2e7c6e3618b80ed12 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 18:44:36 +0000 Subject: [PATCH 01/23] =?UTF-8?q?WIP:=20Analyses=20Finding=20#9=20?= =?UTF-8?q?=E2=80=94=20implement=20formatter=20ConfigPatch=20monoid=20(T-4?= =?UTF-8?q?.16=20fol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v4/extdeps/formatters/gofmt.dag | 10 ++++++---- src/v4/std/patch.dag | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/v4/std/patch.dag diff --git a/src/v4/extdeps/formatters/gofmt.dag b/src/v4/extdeps/formatters/gofmt.dag index f1bfd3c9b7a..6bd837cae78 100644 --- a/src/v4/extdeps/formatters/gofmt.dag +++ b/src/v4/extdeps/formatters/gofmt.dag @@ -1,6 +1,6 @@ // src/v4/extdeps/formatters/gofmt.dag // Scope: gofmt configuration carrier (no project config file; no configurable style options). -// Owns: GofmtConfig, gofmt_defaults, gofmt_layer. +// Owns: GofmtConfig, gofmt_defaults, GofmtConfigPatch, gofmt_layer. // Consumes: none. // Status: T-4.16 scaffold โ€” gofmt doc.go (no style configuration surface). // Anchor: https://go.dev/src/cmd/gofmt/doc.go @@ -13,7 +13,9 @@ type GofmtConfig {} data gofmt_defaults: GofmtConfig = GofmtConfig {} -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: GofmtConfigPatch type with per-field Override/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed. -fn gofmt_layer(base: GofmtConfig, outer: GofmtConfig) -> GofmtConfig { - outer +type GofmtConfigPatch {} + + +fn gofmt_layer(base: GofmtConfig, patch: GofmtConfigPatch) -> GofmtConfig { + base } diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag new file mode 100644 index 00000000000..1ff817f0c7a --- /dev/null +++ b/src/v4/std/patch.dag @@ -0,0 +1,25 @@ +// src/v4/std/patch.dag +// Scope: field-level overlay patch substrate โ€” per-field Override/Inherit coproduct for hierarchical config layering. +// Owns: FieldPatch, apply_field_patch. +// Consumes: none (language primitives only). +// Status: T-4.16 follow-on โ€” formatter ConfigPatch monoid substrate. +// External authority: two-element lattice per field (Override = top, Inherit = bottom); +// standard layered-config pattern (NixOS module system, Home Manager override/inherit). + +module v4.std.patch + + +// ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. +// Per-field patch coproduct for hierarchical config layering. +// Override carries the replacement value for this field; Inherit defers to the base. +type FieldPatch + = Override { value: T } + | Inherit + + +fn apply_field_patch(base: T, patch: FieldPatch) -> T { + match patch { + Override { value: v } => v + Inherit => base + } +} From 83c54555fb30c07d3343463ec6471b92b75e3ed6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 18:51:14 +0000 Subject: [PATCH 02/23] =?UTF-8?q?T-4.16=20follow-on:=20dissolve=20formatte?= =?UTF-8?q?r-config-patch=20gate=20=E2=80=94=20add=20FieldPatch=20monoi?= =?UTF-8?q?d=20and=20*ConfigPatch=20types=20for=20all=20formatters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements ConfigPatch monoid for all 9 formatter files, dissolving the feature:formatter-config-patch gate. Adds v4.std.patch { FieldPatch, apply_field_patch } (two-element Override/Inherit lattice per field) and introduces *ConfigPatch record types + updated *_layer signatures for: black, clang_format, google_java_format, ktfmt, lean4_format, prettier, rustfmt, swift_format (gofmt trivially empty โ€” no fields). Co-Authored-By: Claude Sonnet 4.6 --- src/v4/extdeps/formatters/black.dag | 47 +- src/v4/extdeps/formatters/clang_format.dag | 402 +++++++++++++++++- .../extdeps/formatters/google_java_format.dag | 18 +- src/v4/extdeps/formatters/ktfmt.dag | 53 ++- src/v4/extdeps/formatters/lean4_format.dag | 25 +- src/v4/extdeps/formatters/prettier.dag | 19 +- src/v4/extdeps/formatters/rustfmt.dag | 172 +++++++- src/v4/extdeps/formatters/swift_format.dag | 62 ++- 8 files changed, 758 insertions(+), 40 deletions(-) diff --git a/src/v4/extdeps/formatters/black.dag b/src/v4/extdeps/formatters/black.dag index 0a9365b0a03..3554a2ffee0 100644 --- a/src/v4/extdeps/formatters/black.dag +++ b/src/v4/extdeps/formatters/black.dag @@ -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. @@ -92,7 +93,43 @@ 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/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 +type BlackConfigPatch { + line_length: FieldPatch + target_version: FieldPatch + required_version: FieldPatch + pyi: FieldPatch + ipynb: FieldPatch + python_cell_magics: FieldPatch> + skip_source_first_line: FieldPatch + skip_string_normalization: FieldPatch + skip_magic_trailing_comma: FieldPatch + preview: FieldPatch + unstable: FieldPatch + enable_unstable_feature: FieldPatch> + include: FieldPatch + exclude: FieldPatch + extend_exclude: FieldPatch + force_exclude: FieldPatch +} + + +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), + } } diff --git a/src/v4/extdeps/formatters/clang_format.dag b/src/v4/extdeps/formatters/clang_format.dag index 53b5cfebea7..a48cf60e205 100644 --- a/src/v4/extdeps/formatters/clang_format.dag +++ b/src/v4/extdeps/formatters/clang_format.dag @@ -1,12 +1,14 @@ // src/v4/extdeps/formatters/clang_format.dag // Scope: clang-format configuration model โ€” option space grounded in clang-format 23.0.0git. -// Owns: ClangFormatQualifierAlignmentStyle, ClangFormatConfig, clang_format_defaults, clang_format_layer. -// Consumes: none (String, Bool, Int, List are language-level primitives; no compiler dependency). +// Owns: ClangFormatQualifierAlignmentStyle, ClangFormatConfig, clang_format_defaults, ClangFormatConfigPatch, clang_format_layer. +// Consumes: v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” full top-level option space grounded in clang-format 23.0.0git style reference. // Anchor: https://clang.llvm.org/docs/ClangFormatStyleOptions.html module v4.extdeps.formatters.clang_format +import v4.std.patch { FieldPatch, apply_field_patch } + // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. type ClangFormatStyle @@ -1029,7 +1031,397 @@ data clang_format_defaults: ClangFormatConfig = ClangFormatConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: ClangFormatConfigPatch type with per-field Override/Inherit arms replaces full-config layering. -fn clang_format_layer(base: ClangFormatConfig, outer: ClangFormatConfig) -> ClangFormatConfig { - outer +type ClangFormatConfigPatch { + access_modifier_offset: FieldPatch + align_after_open_bracket: FieldPatch + align_array_of_structures: FieldPatch + align_consecutive_assignments: FieldPatch + align_consecutive_bit_fields: FieldPatch + align_consecutive_declarations: FieldPatch + align_consecutive_macros: FieldPatch + align_consecutive_short_case_statements: FieldPatch + align_consecutive_table_gen_breaking_dag_arg_colons: FieldPatch + align_consecutive_table_gen_cond_operator_colons: FieldPatch + align_consecutive_table_gen_definition_colons: FieldPatch + align_escaped_newlines: FieldPatch + align_operands: FieldPatch + align_trailing_comments: FieldPatch + allow_all_arguments_on_next_line: FieldPatch + allow_all_constructor_initializers_on_next_line: FieldPatch + allow_all_parameters_of_declaration_on_next_line: FieldPatch + allow_break_before_noexcept_specifier: FieldPatch + allow_break_before_qt_property: FieldPatch + allow_short_blocks_on_a_single_line: FieldPatch + allow_short_case_expression_on_a_single_line: FieldPatch + allow_short_case_labels_on_a_single_line: FieldPatch + allow_short_compound_requirement_on_a_single_line: FieldPatch + allow_short_enums_on_a_single_line: FieldPatch + allow_short_functions_on_a_single_line: FieldPatch + allow_short_if_statements_on_a_single_line: FieldPatch + allow_short_lambdas_on_a_single_line: FieldPatch + allow_short_loops_on_a_single_line: FieldPatch + allow_short_namespaces_on_a_single_line: FieldPatch + allow_short_record_on_a_single_line: FieldPatch + always_break_after_definition_return_type: FieldPatch + always_break_after_return_type: FieldPatch + always_break_before_multiline_strings: FieldPatch + always_break_template_declarations: FieldPatch + based_on_style: FieldPatch + bin_pack_arguments: FieldPatch + bin_pack_long_braced_list: FieldPatch + bin_pack_parameters: FieldPatch + bit_field_colon_spacing: FieldPatch + braced_initializer_indent_width: FieldPatch + brace_wrapping: FieldPatch + break_adjacent_string_literals: FieldPatch + break_after_attributes: FieldPatch + break_after_java_field_annotations: FieldPatch + break_after_open_bracket_braced_list: FieldPatch + break_after_open_bracket_function: FieldPatch + break_after_open_bracket_if: FieldPatch + break_after_open_bracket_loop: FieldPatch + break_after_open_bracket_switch: FieldPatch + break_after_return_type: FieldPatch + break_arrays: FieldPatch + break_before_binary_operators: FieldPatch + break_before_braces: FieldPatch + break_before_close_bracket_braced_list: FieldPatch + break_before_close_bracket_function: FieldPatch + break_before_close_bracket_if: FieldPatch + break_before_close_bracket_loop: FieldPatch + break_before_close_bracket_switch: FieldPatch + break_before_concept_declarations: FieldPatch + break_before_inline_asm_colon: FieldPatch + break_before_return_type: FieldPatch + break_before_template_closer: FieldPatch + break_before_ternary_operators: FieldPatch + break_binary_operations: FieldPatch + break_constructor_initializers: FieldPatch + break_function_declaration_parameters: FieldPatch + break_function_definition_parameters: FieldPatch + break_inheritance_list: FieldPatch + break_string_literals: FieldPatch + break_template_declarations: FieldPatch + column_limit: FieldPatch + comment_pragmas: FieldPatch + compact_namespaces: FieldPatch + constructor_initializer_all_on_one_line_or_one_per_line: FieldPatch + constructor_initializer_indent_width: FieldPatch + continuation_indent_width: FieldPatch + cpp11_braced_list_style: FieldPatch + derive_line_ending: FieldPatch + derive_pointer_alignment: FieldPatch + disable_format: FieldPatch + empty_line_after_access_modifier: FieldPatch + empty_line_before_access_modifier: FieldPatch + enum_trailing_comma: FieldPatch + experimental_auto_detect_bin_packing: FieldPatch + fix_namespace_comments: FieldPatch + include_blocks: FieldPatch + include_is_main_regex: FieldPatch + include_is_main_source_regex: FieldPatch + indent_access_modifiers: FieldPatch + indent_case_blocks: FieldPatch + indent_case_labels: FieldPatch + indent_export_block: FieldPatch + indent_extern_block: FieldPatch + indent_goto_labels: FieldPatch + indent_pp_directives: FieldPatch + indent_requires_clause: FieldPatch + indent_width: FieldPatch + indent_wrapped_function_names: FieldPatch + insert_braces: FieldPatch + insert_newline_at_eof: FieldPatch + insert_trailing_commas: FieldPatch + integer_literal_separator: FieldPatch + java_script_quotes: FieldPatch + java_script_wrap_imports: FieldPatch + keep_empty_lines: FieldPatch + keep_empty_lines_at_eof: FieldPatch + keep_empty_lines_at_the_start_of_blocks: FieldPatch + keep_form_feed: FieldPatch + lambda_body_indentation: FieldPatch + language: FieldPatch + line_ending: FieldPatch + macro_block_begin: FieldPatch + macro_block_end: FieldPatch + main_include_char: FieldPatch + max_empty_lines_to_keep: FieldPatch + namespace_indentation: FieldPatch + numeric_literal_case: FieldPatch + obj_c_bin_pack_protocol_list: FieldPatch + obj_c_block_indent_width: FieldPatch + obj_c_break_before_nested_block_param: FieldPatch + obj_c_space_after_method_declaration_prefix: FieldPatch + obj_c_space_after_property: FieldPatch + obj_c_space_before_protocol_list: FieldPatch + one_line_format_off_regex: FieldPatch + pack_arguments: FieldPatch + pack_constructor_initializers: FieldPatch + pack_parameters: FieldPatch + penalty_break_assignment: FieldPatch + penalty_break_before_first_call_parameter: FieldPatch + penalty_break_before_member_access: FieldPatch + penalty_break_comment: FieldPatch + penalty_break_first_less_less: FieldPatch + penalty_break_open_parenthesis: FieldPatch + penalty_break_scope_resolution: FieldPatch + penalty_break_string: FieldPatch + penalty_break_template_declaration: FieldPatch + penalty_excess_character: FieldPatch + penalty_indented_whitespace: FieldPatch + penalty_return_type_on_its_own_line: FieldPatch + pointer_alignment: FieldPatch + pp_indent_width: FieldPatch + qualifier_alignment: FieldPatch + qualifier_order: FieldPatch> + reference_alignment: FieldPatch + reflow_comments: FieldPatch + remove_braces_llvm: FieldPatch + remove_empty_lines_in_unwrapped_lines: FieldPatch + remove_parentheses: FieldPatch + remove_semicolon: FieldPatch + requires_clause_position: FieldPatch + requires_expression_indentation: FieldPatch + separate_definition_blocks: FieldPatch + short_namespace_lines: FieldPatch + skip_macro_definition_body: FieldPatch + sort_includes: FieldPatch + sort_java_static_import: FieldPatch + sort_using_declarations: FieldPatch + space_after_c_style_cast: FieldPatch + space_after_logical_not: FieldPatch + space_after_operator_keyword: FieldPatch + space_after_template_keyword: FieldPatch + space_around_pointer_qualifiers: FieldPatch + space_before_assignment_operators: FieldPatch + space_before_case_colon: FieldPatch + space_before_cpp11_braced_list: FieldPatch + space_before_ctor_initializer_colon: FieldPatch + space_before_enum_underlying_type_colon: FieldPatch + space_before_inheritance_colon: FieldPatch + space_before_json_colon: FieldPatch + space_before_parens: FieldPatch + space_before_parens_options: FieldPatch + space_before_range_based_for_loop_colon: FieldPatch + space_before_square_brackets: FieldPatch + space_in_empty_block: FieldPatch + space_in_empty_braces: FieldPatch + space_in_empty_parentheses: FieldPatch + spaces_before_trailing_comments: FieldPatch + spaces_in_angles: FieldPatch + spaces_in_conditional_statement: FieldPatch + spaces_in_container_literals: FieldPatch + spaces_in_c_style_cast_parentheses: FieldPatch + spaces_in_line_comment_prefix: FieldPatch + spaces_in_parens: FieldPatch + spaces_in_parens_options: FieldPatch + spaces_in_parentheses: FieldPatch + spaces_in_square_brackets: FieldPatch + standard: FieldPatch + table_gen_break_inside_dag_arg: FieldPatch + tab_width: FieldPatch + use_crlf: FieldPatch + use_tab: FieldPatch + verilog_break_between_instance_ports: FieldPatch + wrap_namespace_body_with_empty_lines: FieldPatch +} + + +fn clang_format_layer(base: ClangFormatConfig, patch: ClangFormatConfigPatch) -> ClangFormatConfig { + ClangFormatConfig { + access_modifier_offset: apply_field_patch(base: base.access_modifier_offset, patch: patch.access_modifier_offset), + align_after_open_bracket: apply_field_patch(base: base.align_after_open_bracket, patch: patch.align_after_open_bracket), + align_array_of_structures: apply_field_patch(base: base.align_array_of_structures, patch: patch.align_array_of_structures), + align_consecutive_assignments: apply_field_patch(base: base.align_consecutive_assignments, patch: patch.align_consecutive_assignments), + align_consecutive_bit_fields: apply_field_patch(base: base.align_consecutive_bit_fields, patch: patch.align_consecutive_bit_fields), + align_consecutive_declarations: apply_field_patch(base: base.align_consecutive_declarations, patch: patch.align_consecutive_declarations), + align_consecutive_macros: apply_field_patch(base: base.align_consecutive_macros, patch: patch.align_consecutive_macros), + align_consecutive_short_case_statements: apply_field_patch(base: base.align_consecutive_short_case_statements, patch: patch.align_consecutive_short_case_statements), + align_consecutive_table_gen_breaking_dag_arg_colons: apply_field_patch(base: base.align_consecutive_table_gen_breaking_dag_arg_colons, patch: patch.align_consecutive_table_gen_breaking_dag_arg_colons), + align_consecutive_table_gen_cond_operator_colons: apply_field_patch(base: base.align_consecutive_table_gen_cond_operator_colons, patch: patch.align_consecutive_table_gen_cond_operator_colons), + align_consecutive_table_gen_definition_colons: apply_field_patch(base: base.align_consecutive_table_gen_definition_colons, patch: patch.align_consecutive_table_gen_definition_colons), + align_escaped_newlines: apply_field_patch(base: base.align_escaped_newlines, patch: patch.align_escaped_newlines), + align_operands: apply_field_patch(base: base.align_operands, patch: patch.align_operands), + align_trailing_comments: apply_field_patch(base: base.align_trailing_comments, patch: patch.align_trailing_comments), + allow_all_arguments_on_next_line: apply_field_patch(base: base.allow_all_arguments_on_next_line, patch: patch.allow_all_arguments_on_next_line), + allow_all_constructor_initializers_on_next_line: apply_field_patch(base: base.allow_all_constructor_initializers_on_next_line, patch: patch.allow_all_constructor_initializers_on_next_line), + allow_all_parameters_of_declaration_on_next_line: apply_field_patch(base: base.allow_all_parameters_of_declaration_on_next_line, patch: patch.allow_all_parameters_of_declaration_on_next_line), + allow_break_before_noexcept_specifier: apply_field_patch(base: base.allow_break_before_noexcept_specifier, patch: patch.allow_break_before_noexcept_specifier), + allow_break_before_qt_property: apply_field_patch(base: base.allow_break_before_qt_property, patch: patch.allow_break_before_qt_property), + allow_short_blocks_on_a_single_line: apply_field_patch(base: base.allow_short_blocks_on_a_single_line, patch: patch.allow_short_blocks_on_a_single_line), + allow_short_case_expression_on_a_single_line: apply_field_patch(base: base.allow_short_case_expression_on_a_single_line, patch: patch.allow_short_case_expression_on_a_single_line), + allow_short_case_labels_on_a_single_line: apply_field_patch(base: base.allow_short_case_labels_on_a_single_line, patch: patch.allow_short_case_labels_on_a_single_line), + allow_short_compound_requirement_on_a_single_line: apply_field_patch(base: base.allow_short_compound_requirement_on_a_single_line, patch: patch.allow_short_compound_requirement_on_a_single_line), + allow_short_enums_on_a_single_line: apply_field_patch(base: base.allow_short_enums_on_a_single_line, patch: patch.allow_short_enums_on_a_single_line), + allow_short_functions_on_a_single_line: apply_field_patch(base: base.allow_short_functions_on_a_single_line, patch: patch.allow_short_functions_on_a_single_line), + allow_short_if_statements_on_a_single_line: apply_field_patch(base: base.allow_short_if_statements_on_a_single_line, patch: patch.allow_short_if_statements_on_a_single_line), + allow_short_lambdas_on_a_single_line: apply_field_patch(base: base.allow_short_lambdas_on_a_single_line, patch: patch.allow_short_lambdas_on_a_single_line), + allow_short_loops_on_a_single_line: apply_field_patch(base: base.allow_short_loops_on_a_single_line, patch: patch.allow_short_loops_on_a_single_line), + allow_short_namespaces_on_a_single_line: apply_field_patch(base: base.allow_short_namespaces_on_a_single_line, patch: patch.allow_short_namespaces_on_a_single_line), + allow_short_record_on_a_single_line: apply_field_patch(base: base.allow_short_record_on_a_single_line, patch: patch.allow_short_record_on_a_single_line), + always_break_after_definition_return_type: apply_field_patch(base: base.always_break_after_definition_return_type, patch: patch.always_break_after_definition_return_type), + always_break_after_return_type: apply_field_patch(base: base.always_break_after_return_type, patch: patch.always_break_after_return_type), + always_break_before_multiline_strings: apply_field_patch(base: base.always_break_before_multiline_strings, patch: patch.always_break_before_multiline_strings), + always_break_template_declarations: apply_field_patch(base: base.always_break_template_declarations, patch: patch.always_break_template_declarations), + based_on_style: apply_field_patch(base: base.based_on_style, patch: patch.based_on_style), + bin_pack_arguments: apply_field_patch(base: base.bin_pack_arguments, patch: patch.bin_pack_arguments), + bin_pack_long_braced_list: apply_field_patch(base: base.bin_pack_long_braced_list, patch: patch.bin_pack_long_braced_list), + bin_pack_parameters: apply_field_patch(base: base.bin_pack_parameters, patch: patch.bin_pack_parameters), + bit_field_colon_spacing: apply_field_patch(base: base.bit_field_colon_spacing, patch: patch.bit_field_colon_spacing), + braced_initializer_indent_width: apply_field_patch(base: base.braced_initializer_indent_width, patch: patch.braced_initializer_indent_width), + brace_wrapping: apply_field_patch(base: base.brace_wrapping, patch: patch.brace_wrapping), + break_adjacent_string_literals: apply_field_patch(base: base.break_adjacent_string_literals, patch: patch.break_adjacent_string_literals), + break_after_attributes: apply_field_patch(base: base.break_after_attributes, patch: patch.break_after_attributes), + break_after_java_field_annotations: apply_field_patch(base: base.break_after_java_field_annotations, patch: patch.break_after_java_field_annotations), + break_after_open_bracket_braced_list: apply_field_patch(base: base.break_after_open_bracket_braced_list, patch: patch.break_after_open_bracket_braced_list), + break_after_open_bracket_function: apply_field_patch(base: base.break_after_open_bracket_function, patch: patch.break_after_open_bracket_function), + break_after_open_bracket_if: apply_field_patch(base: base.break_after_open_bracket_if, patch: patch.break_after_open_bracket_if), + break_after_open_bracket_loop: apply_field_patch(base: base.break_after_open_bracket_loop, patch: patch.break_after_open_bracket_loop), + break_after_open_bracket_switch: apply_field_patch(base: base.break_after_open_bracket_switch, patch: patch.break_after_open_bracket_switch), + break_after_return_type: apply_field_patch(base: base.break_after_return_type, patch: patch.break_after_return_type), + break_arrays: apply_field_patch(base: base.break_arrays, patch: patch.break_arrays), + break_before_binary_operators: apply_field_patch(base: base.break_before_binary_operators, patch: patch.break_before_binary_operators), + break_before_braces: apply_field_patch(base: base.break_before_braces, patch: patch.break_before_braces), + break_before_close_bracket_braced_list: apply_field_patch(base: base.break_before_close_bracket_braced_list, patch: patch.break_before_close_bracket_braced_list), + break_before_close_bracket_function: apply_field_patch(base: base.break_before_close_bracket_function, patch: patch.break_before_close_bracket_function), + break_before_close_bracket_if: apply_field_patch(base: base.break_before_close_bracket_if, patch: patch.break_before_close_bracket_if), + break_before_close_bracket_loop: apply_field_patch(base: base.break_before_close_bracket_loop, patch: patch.break_before_close_bracket_loop), + break_before_close_bracket_switch: apply_field_patch(base: base.break_before_close_bracket_switch, patch: patch.break_before_close_bracket_switch), + break_before_concept_declarations: apply_field_patch(base: base.break_before_concept_declarations, patch: patch.break_before_concept_declarations), + break_before_inline_asm_colon: apply_field_patch(base: base.break_before_inline_asm_colon, patch: patch.break_before_inline_asm_colon), + break_before_return_type: apply_field_patch(base: base.break_before_return_type, patch: patch.break_before_return_type), + break_before_template_closer: apply_field_patch(base: base.break_before_template_closer, patch: patch.break_before_template_closer), + break_before_ternary_operators: apply_field_patch(base: base.break_before_ternary_operators, patch: patch.break_before_ternary_operators), + break_binary_operations: apply_field_patch(base: base.break_binary_operations, patch: patch.break_binary_operations), + break_constructor_initializers: apply_field_patch(base: base.break_constructor_initializers, patch: patch.break_constructor_initializers), + break_function_declaration_parameters: apply_field_patch(base: base.break_function_declaration_parameters, patch: patch.break_function_declaration_parameters), + break_function_definition_parameters: apply_field_patch(base: base.break_function_definition_parameters, patch: patch.break_function_definition_parameters), + break_inheritance_list: apply_field_patch(base: base.break_inheritance_list, patch: patch.break_inheritance_list), + break_string_literals: apply_field_patch(base: base.break_string_literals, patch: patch.break_string_literals), + break_template_declarations: apply_field_patch(base: base.break_template_declarations, patch: patch.break_template_declarations), + column_limit: apply_field_patch(base: base.column_limit, patch: patch.column_limit), + comment_pragmas: apply_field_patch(base: base.comment_pragmas, patch: patch.comment_pragmas), + compact_namespaces: apply_field_patch(base: base.compact_namespaces, patch: patch.compact_namespaces), + constructor_initializer_all_on_one_line_or_one_per_line: apply_field_patch(base: base.constructor_initializer_all_on_one_line_or_one_per_line, patch: patch.constructor_initializer_all_on_one_line_or_one_per_line), + constructor_initializer_indent_width: apply_field_patch(base: base.constructor_initializer_indent_width, patch: patch.constructor_initializer_indent_width), + continuation_indent_width: apply_field_patch(base: base.continuation_indent_width, patch: patch.continuation_indent_width), + cpp11_braced_list_style: apply_field_patch(base: base.cpp11_braced_list_style, patch: patch.cpp11_braced_list_style), + derive_line_ending: apply_field_patch(base: base.derive_line_ending, patch: patch.derive_line_ending), + derive_pointer_alignment: apply_field_patch(base: base.derive_pointer_alignment, patch: patch.derive_pointer_alignment), + disable_format: apply_field_patch(base: base.disable_format, patch: patch.disable_format), + empty_line_after_access_modifier: apply_field_patch(base: base.empty_line_after_access_modifier, patch: patch.empty_line_after_access_modifier), + empty_line_before_access_modifier: apply_field_patch(base: base.empty_line_before_access_modifier, patch: patch.empty_line_before_access_modifier), + enum_trailing_comma: apply_field_patch(base: base.enum_trailing_comma, patch: patch.enum_trailing_comma), + experimental_auto_detect_bin_packing: apply_field_patch(base: base.experimental_auto_detect_bin_packing, patch: patch.experimental_auto_detect_bin_packing), + fix_namespace_comments: apply_field_patch(base: base.fix_namespace_comments, patch: patch.fix_namespace_comments), + include_blocks: apply_field_patch(base: base.include_blocks, patch: patch.include_blocks), + include_is_main_regex: apply_field_patch(base: base.include_is_main_regex, patch: patch.include_is_main_regex), + include_is_main_source_regex: apply_field_patch(base: base.include_is_main_source_regex, patch: patch.include_is_main_source_regex), + indent_access_modifiers: apply_field_patch(base: base.indent_access_modifiers, patch: patch.indent_access_modifiers), + indent_case_blocks: apply_field_patch(base: base.indent_case_blocks, patch: patch.indent_case_blocks), + indent_case_labels: apply_field_patch(base: base.indent_case_labels, patch: patch.indent_case_labels), + indent_export_block: apply_field_patch(base: base.indent_export_block, patch: patch.indent_export_block), + indent_extern_block: apply_field_patch(base: base.indent_extern_block, patch: patch.indent_extern_block), + indent_goto_labels: apply_field_patch(base: base.indent_goto_labels, patch: patch.indent_goto_labels), + indent_pp_directives: apply_field_patch(base: base.indent_pp_directives, patch: patch.indent_pp_directives), + indent_requires_clause: apply_field_patch(base: base.indent_requires_clause, patch: patch.indent_requires_clause), + indent_width: apply_field_patch(base: base.indent_width, patch: patch.indent_width), + indent_wrapped_function_names: apply_field_patch(base: base.indent_wrapped_function_names, patch: patch.indent_wrapped_function_names), + insert_braces: apply_field_patch(base: base.insert_braces, patch: patch.insert_braces), + insert_newline_at_eof: apply_field_patch(base: base.insert_newline_at_eof, patch: patch.insert_newline_at_eof), + insert_trailing_commas: apply_field_patch(base: base.insert_trailing_commas, patch: patch.insert_trailing_commas), + integer_literal_separator: apply_field_patch(base: base.integer_literal_separator, patch: patch.integer_literal_separator), + java_script_quotes: apply_field_patch(base: base.java_script_quotes, patch: patch.java_script_quotes), + java_script_wrap_imports: apply_field_patch(base: base.java_script_wrap_imports, patch: patch.java_script_wrap_imports), + keep_empty_lines: apply_field_patch(base: base.keep_empty_lines, patch: patch.keep_empty_lines), + keep_empty_lines_at_eof: apply_field_patch(base: base.keep_empty_lines_at_eof, patch: patch.keep_empty_lines_at_eof), + keep_empty_lines_at_the_start_of_blocks: apply_field_patch(base: base.keep_empty_lines_at_the_start_of_blocks, patch: patch.keep_empty_lines_at_the_start_of_blocks), + keep_form_feed: apply_field_patch(base: base.keep_form_feed, patch: patch.keep_form_feed), + lambda_body_indentation: apply_field_patch(base: base.lambda_body_indentation, patch: patch.lambda_body_indentation), + language: apply_field_patch(base: base.language, patch: patch.language), + line_ending: apply_field_patch(base: base.line_ending, patch: patch.line_ending), + macro_block_begin: apply_field_patch(base: base.macro_block_begin, patch: patch.macro_block_begin), + macro_block_end: apply_field_patch(base: base.macro_block_end, patch: patch.macro_block_end), + main_include_char: apply_field_patch(base: base.main_include_char, patch: patch.main_include_char), + max_empty_lines_to_keep: apply_field_patch(base: base.max_empty_lines_to_keep, patch: patch.max_empty_lines_to_keep), + namespace_indentation: apply_field_patch(base: base.namespace_indentation, patch: patch.namespace_indentation), + numeric_literal_case: apply_field_patch(base: base.numeric_literal_case, patch: patch.numeric_literal_case), + obj_c_bin_pack_protocol_list: apply_field_patch(base: base.obj_c_bin_pack_protocol_list, patch: patch.obj_c_bin_pack_protocol_list), + obj_c_block_indent_width: apply_field_patch(base: base.obj_c_block_indent_width, patch: patch.obj_c_block_indent_width), + obj_c_break_before_nested_block_param: apply_field_patch(base: base.obj_c_break_before_nested_block_param, patch: patch.obj_c_break_before_nested_block_param), + obj_c_space_after_method_declaration_prefix: apply_field_patch(base: base.obj_c_space_after_method_declaration_prefix, patch: patch.obj_c_space_after_method_declaration_prefix), + obj_c_space_after_property: apply_field_patch(base: base.obj_c_space_after_property, patch: patch.obj_c_space_after_property), + obj_c_space_before_protocol_list: apply_field_patch(base: base.obj_c_space_before_protocol_list, patch: patch.obj_c_space_before_protocol_list), + one_line_format_off_regex: apply_field_patch(base: base.one_line_format_off_regex, patch: patch.one_line_format_off_regex), + pack_arguments: apply_field_patch(base: base.pack_arguments, patch: patch.pack_arguments), + pack_constructor_initializers: apply_field_patch(base: base.pack_constructor_initializers, patch: patch.pack_constructor_initializers), + pack_parameters: apply_field_patch(base: base.pack_parameters, patch: patch.pack_parameters), + penalty_break_assignment: apply_field_patch(base: base.penalty_break_assignment, patch: patch.penalty_break_assignment), + penalty_break_before_first_call_parameter: apply_field_patch(base: base.penalty_break_before_first_call_parameter, patch: patch.penalty_break_before_first_call_parameter), + penalty_break_before_member_access: apply_field_patch(base: base.penalty_break_before_member_access, patch: patch.penalty_break_before_member_access), + penalty_break_comment: apply_field_patch(base: base.penalty_break_comment, patch: patch.penalty_break_comment), + penalty_break_first_less_less: apply_field_patch(base: base.penalty_break_first_less_less, patch: patch.penalty_break_first_less_less), + penalty_break_open_parenthesis: apply_field_patch(base: base.penalty_break_open_parenthesis, patch: patch.penalty_break_open_parenthesis), + penalty_break_scope_resolution: apply_field_patch(base: base.penalty_break_scope_resolution, patch: patch.penalty_break_scope_resolution), + penalty_break_string: apply_field_patch(base: base.penalty_break_string, patch: patch.penalty_break_string), + penalty_break_template_declaration: apply_field_patch(base: base.penalty_break_template_declaration, patch: patch.penalty_break_template_declaration), + penalty_excess_character: apply_field_patch(base: base.penalty_excess_character, patch: patch.penalty_excess_character), + penalty_indented_whitespace: apply_field_patch(base: base.penalty_indented_whitespace, patch: patch.penalty_indented_whitespace), + penalty_return_type_on_its_own_line: apply_field_patch(base: base.penalty_return_type_on_its_own_line, patch: patch.penalty_return_type_on_its_own_line), + pointer_alignment: apply_field_patch(base: base.pointer_alignment, patch: patch.pointer_alignment), + pp_indent_width: apply_field_patch(base: base.pp_indent_width, patch: patch.pp_indent_width), + qualifier_alignment: apply_field_patch(base: base.qualifier_alignment, patch: patch.qualifier_alignment), + qualifier_order: apply_field_patch(base: base.qualifier_order, patch: patch.qualifier_order), + reference_alignment: apply_field_patch(base: base.reference_alignment, patch: patch.reference_alignment), + reflow_comments: apply_field_patch(base: base.reflow_comments, patch: patch.reflow_comments), + remove_braces_llvm: apply_field_patch(base: base.remove_braces_llvm, patch: patch.remove_braces_llvm), + remove_empty_lines_in_unwrapped_lines: apply_field_patch(base: base.remove_empty_lines_in_unwrapped_lines, patch: patch.remove_empty_lines_in_unwrapped_lines), + remove_parentheses: apply_field_patch(base: base.remove_parentheses, patch: patch.remove_parentheses), + remove_semicolon: apply_field_patch(base: base.remove_semicolon, patch: patch.remove_semicolon), + requires_clause_position: apply_field_patch(base: base.requires_clause_position, patch: patch.requires_clause_position), + requires_expression_indentation: apply_field_patch(base: base.requires_expression_indentation, patch: patch.requires_expression_indentation), + separate_definition_blocks: apply_field_patch(base: base.separate_definition_blocks, patch: patch.separate_definition_blocks), + short_namespace_lines: apply_field_patch(base: base.short_namespace_lines, patch: patch.short_namespace_lines), + skip_macro_definition_body: apply_field_patch(base: base.skip_macro_definition_body, patch: patch.skip_macro_definition_body), + sort_includes: apply_field_patch(base: base.sort_includes, patch: patch.sort_includes), + sort_java_static_import: apply_field_patch(base: base.sort_java_static_import, patch: patch.sort_java_static_import), + sort_using_declarations: apply_field_patch(base: base.sort_using_declarations, patch: patch.sort_using_declarations), + space_after_c_style_cast: apply_field_patch(base: base.space_after_c_style_cast, patch: patch.space_after_c_style_cast), + space_after_logical_not: apply_field_patch(base: base.space_after_logical_not, patch: patch.space_after_logical_not), + space_after_operator_keyword: apply_field_patch(base: base.space_after_operator_keyword, patch: patch.space_after_operator_keyword), + space_after_template_keyword: apply_field_patch(base: base.space_after_template_keyword, patch: patch.space_after_template_keyword), + space_around_pointer_qualifiers: apply_field_patch(base: base.space_around_pointer_qualifiers, patch: patch.space_around_pointer_qualifiers), + space_before_assignment_operators: apply_field_patch(base: base.space_before_assignment_operators, patch: patch.space_before_assignment_operators), + space_before_case_colon: apply_field_patch(base: base.space_before_case_colon, patch: patch.space_before_case_colon), + space_before_cpp11_braced_list: apply_field_patch(base: base.space_before_cpp11_braced_list, patch: patch.space_before_cpp11_braced_list), + space_before_ctor_initializer_colon: apply_field_patch(base: base.space_before_ctor_initializer_colon, patch: patch.space_before_ctor_initializer_colon), + space_before_enum_underlying_type_colon: apply_field_patch(base: base.space_before_enum_underlying_type_colon, patch: patch.space_before_enum_underlying_type_colon), + space_before_inheritance_colon: apply_field_patch(base: base.space_before_inheritance_colon, patch: patch.space_before_inheritance_colon), + space_before_json_colon: apply_field_patch(base: base.space_before_json_colon, patch: patch.space_before_json_colon), + space_before_parens: apply_field_patch(base: base.space_before_parens, patch: patch.space_before_parens), + space_before_parens_options: apply_field_patch(base: base.space_before_parens_options, patch: patch.space_before_parens_options), + space_before_range_based_for_loop_colon: apply_field_patch(base: base.space_before_range_based_for_loop_colon, patch: patch.space_before_range_based_for_loop_colon), + space_before_square_brackets: apply_field_patch(base: base.space_before_square_brackets, patch: patch.space_before_square_brackets), + space_in_empty_block: apply_field_patch(base: base.space_in_empty_block, patch: patch.space_in_empty_block), + space_in_empty_braces: apply_field_patch(base: base.space_in_empty_braces, patch: patch.space_in_empty_braces), + space_in_empty_parentheses: apply_field_patch(base: base.space_in_empty_parentheses, patch: patch.space_in_empty_parentheses), + spaces_before_trailing_comments: apply_field_patch(base: base.spaces_before_trailing_comments, patch: patch.spaces_before_trailing_comments), + spaces_in_angles: apply_field_patch(base: base.spaces_in_angles, patch: patch.spaces_in_angles), + spaces_in_conditional_statement: apply_field_patch(base: base.spaces_in_conditional_statement, patch: patch.spaces_in_conditional_statement), + spaces_in_container_literals: apply_field_patch(base: base.spaces_in_container_literals, patch: patch.spaces_in_container_literals), + spaces_in_c_style_cast_parentheses: apply_field_patch(base: base.spaces_in_c_style_cast_parentheses, patch: patch.spaces_in_c_style_cast_parentheses), + spaces_in_line_comment_prefix: apply_field_patch(base: base.spaces_in_line_comment_prefix, patch: patch.spaces_in_line_comment_prefix), + spaces_in_parens: apply_field_patch(base: base.spaces_in_parens, patch: patch.spaces_in_parens), + spaces_in_parens_options: apply_field_patch(base: base.spaces_in_parens_options, patch: patch.spaces_in_parens_options), + spaces_in_parentheses: apply_field_patch(base: base.spaces_in_parentheses, patch: patch.spaces_in_parentheses), + spaces_in_square_brackets: apply_field_patch(base: base.spaces_in_square_brackets, patch: patch.spaces_in_square_brackets), + standard: apply_field_patch(base: base.standard, patch: patch.standard), + table_gen_break_inside_dag_arg: apply_field_patch(base: base.table_gen_break_inside_dag_arg, patch: patch.table_gen_break_inside_dag_arg), + tab_width: apply_field_patch(base: base.tab_width, patch: patch.tab_width), + use_crlf: apply_field_patch(base: base.use_crlf, patch: patch.use_crlf), + use_tab: apply_field_patch(base: base.use_tab, patch: patch.use_tab), + verilog_break_between_instance_ports: apply_field_patch(base: base.verilog_break_between_instance_ports, patch: patch.verilog_break_between_instance_ports), + wrap_namespace_body_with_empty_lines: apply_field_patch(base: base.wrap_namespace_body_with_empty_lines, patch: patch.wrap_namespace_body_with_empty_lines), + } } diff --git a/src/v4/extdeps/formatters/google_java_format.dag b/src/v4/extdeps/formatters/google_java_format.dag index 00a56649d96..6a28c5b3c62 100644 --- a/src/v4/extdeps/formatters/google_java_format.dag +++ b/src/v4/extdeps/formatters/google_java_format.dag @@ -1,12 +1,14 @@ // src/v4/extdeps/formatters/google_java_format.dag // Scope: google-java-format style selection model โ€” no user-configurable algorithm options. -// Owns: GoogleJavaFormatStyle, GoogleJavaFormatConfig, google_java_format_defaults, google_java_format_layer. -// Consumes: none (String, Bool, Int, List are language-level primitives; no compiler dependency). +// Owns: GoogleJavaFormatStyle, GoogleJavaFormatConfig, google_java_format_defaults, GoogleJavaFormatConfigPatch, google_java_format_layer. +// Consumes: v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” style toggle grounded in google-java-format README. // Anchor: https://github.com/google/google-java-format module v4.extdeps.formatters.google_java_format +import v4.std.patch { FieldPatch, apply_field_patch } + // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. type GoogleJavaFormatStyle @@ -24,7 +26,13 @@ data google_java_format_defaults: GoogleJavaFormatConfig = GoogleJavaFormatConfi } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: GoogleJavaFormatConfigPatch type with per-field Override/Inherit arms replaces full-config layering. -fn google_java_format_layer(base: GoogleJavaFormatConfig, outer: GoogleJavaFormatConfig) -> GoogleJavaFormatConfig { - outer +type GoogleJavaFormatConfigPatch { + style: FieldPatch +} + + +fn google_java_format_layer(base: GoogleJavaFormatConfig, patch: GoogleJavaFormatConfigPatch) -> GoogleJavaFormatConfig { + GoogleJavaFormatConfig { + style: apply_field_patch(base: base.style, patch: patch.style), + } } diff --git a/src/v4/extdeps/formatters/ktfmt.dag b/src/v4/extdeps/formatters/ktfmt.dag index 2754dc23366..84acc05b66e 100644 --- a/src/v4/extdeps/formatters/ktfmt.dag +++ b/src/v4/extdeps/formatters/ktfmt.dag @@ -1,7 +1,7 @@ // src/v4/extdeps/formatters/ktfmt.dag // Scope: ktfmt configuration model โ€” option space grounded in ktfmt latest README/options and CLI help. -// Owns: KtfmtStyle, KtfmtTrailingCommaManagementStrategy, KtfmtPositiveInt, ktfmt_positive_int_validation, make_ktfmt_positive_int, KtfmtConfig, ktfmt_defaults, ktfmt_layer. -// Consumes: Locus, Outcome, Symbol, Refined, Validation. +// Owns: KtfmtStyle, KtfmtTrailingCommaManagementStrategy, KtfmtPositiveInt, ktfmt_positive_int_validation, make_ktfmt_positive_int, KtfmtConfig, ktfmt_defaults, KtfmtConfigPatch, ktfmt_layer. +// Consumes: Locus, Outcome, Symbol, Refined, Validation, FieldPatch, apply_field_patch. // Status: T-4.16 scaffold โ€” full documented ktfmt option surface. // Anchor: https://github.com/facebook/ktfmt#options @@ -11,6 +11,7 @@ module v4.extdeps.formatters.ktfmt import v4.std.diagnostic { Locus, Outcome } import v4.std.node { Symbol } import v4.std.refinement { Refined, Validation, refine } +import v4.std.patch { FieldPatch, apply_field_patch } // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. @@ -100,7 +101,49 @@ data ktfmt_defaults: KtfmtConfig = KtfmtConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: KtfmtConfigPatch type with per-field Override/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed. -fn ktfmt_layer(base: KtfmtConfig, outer: KtfmtConfig) -> KtfmtConfig { - outer +type KtfmtConfigPatch { + style: FieldPatch + max_width: FieldPatch + block_indent: FieldPatch + continuation_indent: FieldPatch + trailing_comma_management_strategy: FieldPatch + remove_unused_imports: FieldPatch + debugging_print_ops_after_formatting: FieldPatch + dry_run: FieldPatch + set_exit_if_changed: FieldPatch + stdin_name: FieldPatch + enable_editorconfig: FieldPatch + quiet: FieldPatch + editorconfig_max_line_length: FieldPatch + editorconfig_indent_size: FieldPatch + editorconfig_tab_width: FieldPatch + editorconfig_ij_kotlin_indent_size: FieldPatch + editorconfig_ij_continuation_indent_size: FieldPatch + editorconfig_ij_kotlin_continuation_indent_size: FieldPatch + editorconfig_ktfmt_trailing_comma_management_strategy: FieldPatch +} + + +fn ktfmt_layer(base: KtfmtConfig, patch: KtfmtConfigPatch) -> KtfmtConfig { + KtfmtConfig { + style: apply_field_patch(base: base.style, patch: patch.style), + max_width: apply_field_patch(base: base.max_width, patch: patch.max_width), + block_indent: apply_field_patch(base: base.block_indent, patch: patch.block_indent), + continuation_indent: apply_field_patch(base: base.continuation_indent, patch: patch.continuation_indent), + trailing_comma_management_strategy: apply_field_patch(base: base.trailing_comma_management_strategy, patch: patch.trailing_comma_management_strategy), + remove_unused_imports: apply_field_patch(base: base.remove_unused_imports, patch: patch.remove_unused_imports), + debugging_print_ops_after_formatting: apply_field_patch(base: base.debugging_print_ops_after_formatting, patch: patch.debugging_print_ops_after_formatting), + dry_run: apply_field_patch(base: base.dry_run, patch: patch.dry_run), + set_exit_if_changed: apply_field_patch(base: base.set_exit_if_changed, patch: patch.set_exit_if_changed), + stdin_name: apply_field_patch(base: base.stdin_name, patch: patch.stdin_name), + enable_editorconfig: apply_field_patch(base: base.enable_editorconfig, patch: patch.enable_editorconfig), + quiet: apply_field_patch(base: base.quiet, patch: patch.quiet), + editorconfig_max_line_length: apply_field_patch(base: base.editorconfig_max_line_length, patch: patch.editorconfig_max_line_length), + editorconfig_indent_size: apply_field_patch(base: base.editorconfig_indent_size, patch: patch.editorconfig_indent_size), + editorconfig_tab_width: apply_field_patch(base: base.editorconfig_tab_width, patch: patch.editorconfig_tab_width), + editorconfig_ij_kotlin_indent_size: apply_field_patch(base: base.editorconfig_ij_kotlin_indent_size, patch: patch.editorconfig_ij_kotlin_indent_size), + editorconfig_ij_continuation_indent_size: apply_field_patch(base: base.editorconfig_ij_continuation_indent_size, patch: patch.editorconfig_ij_continuation_indent_size), + editorconfig_ij_kotlin_continuation_indent_size: apply_field_patch(base: base.editorconfig_ij_kotlin_continuation_indent_size, patch: patch.editorconfig_ij_kotlin_continuation_indent_size), + editorconfig_ktfmt_trailing_comma_management_strategy: apply_field_patch(base: base.editorconfig_ktfmt_trailing_comma_management_strategy, patch: patch.editorconfig_ktfmt_trailing_comma_management_strategy), + } } diff --git a/src/v4/extdeps/formatters/lean4_format.dag b/src/v4/extdeps/formatters/lean4_format.dag index ef471f1de80..e0c5cb1f3fa 100644 --- a/src/v4/extdeps/formatters/lean4_format.dag +++ b/src/v4/extdeps/formatters/lean4_format.dag @@ -1,8 +1,8 @@ // src/v4/extdeps/formatters/lean4_format.dag // Scope: Lean 4 formatter configuration model โ€” option space grounded in Lean 4 formatter/Lake option surfaces. // Owns: Lean4NameValue, Lean4SyntaxValue, Lean4NatValue, lean4_nat_value_validation, make_lean4_nat_value, Lean4OptionValue, Lean4OptionAssignment, -// Lean4FormatConfig, lean4_format_defaults, lean4_format_layer. -// Consumes: Locus, Outcome, Symbol, Refined, Validation. +// Lean4FormatConfig, lean4_format_defaults, Lean4FormatConfigPatch, lean4_format_layer. +// Consumes: Locus, Outcome, Symbol, Refined, Validation, FieldPatch, apply_field_patch. // Status: T-4.16 scaffold โ€” full documented Lean formatter-facing option surface. // Anchor: https://github.com/leanprover/lean4/blob/master/src/Lean/Data/Format.lean // https://github.com/leanprover/lean4/blob/master/src/Lean/Data/Options.lean @@ -13,6 +13,7 @@ module v4.extdeps.formatters.lean4_format import v4.std.diagnostic { Locus, Outcome } import v4.std.node { Symbol } import v4.std.refinement { Refined, Validation, refine } +import v4.std.patch { FieldPatch, apply_field_patch } type Lean4NameValue @@ -75,7 +76,21 @@ data lean4_format_defaults: Lean4FormatConfig = Lean4FormatConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: Lean4FormatConfigPatch type with per-field Override/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed. -fn lean4_format_layer(base: Lean4FormatConfig, outer: Lean4FormatConfig) -> Lean4FormatConfig { - outer +type Lean4FormatConfigPatch { + format_width: FieldPatch + format_indent: FieldPatch + format_unicode: FieldPatch + pp_oneline: FieldPatch + lake_lean_options: FieldPatch> +} + + +fn lean4_format_layer(base: Lean4FormatConfig, patch: Lean4FormatConfigPatch) -> Lean4FormatConfig { + Lean4FormatConfig { + format_width: apply_field_patch(base: base.format_width, patch: patch.format_width), + format_indent: apply_field_patch(base: base.format_indent, patch: patch.format_indent), + format_unicode: apply_field_patch(base: base.format_unicode, patch: patch.format_unicode), + pp_oneline: apply_field_patch(base: base.pp_oneline, patch: patch.pp_oneline), + lake_lean_options: apply_field_patch(base: base.lake_lean_options, patch: patch.lake_lean_options), + } } diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index a96ce5ced05..75946ff073a 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -1,7 +1,7 @@ // src/v4/extdeps/formatters/prettier.dag // Scope: Prettier configuration file model (.prettierrc / package.json "prettier"). -// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierIntPatch, PrettierBoolPatch, PrettierTrailingCommaPatch, PrettierQuotePropsPatch, PrettierArrowParensPatch, PrettierProseWrapPatch, PrettierHtmlWhitespaceSensitivityPatch, PrettierEndOfLinePatch, PrettierEmbeddedLanguageFormattingPatch, PrettierObjectWrapPatch, PrettierExperimentalOperatorPositionPatch, PrettierParserPatch, PrettierFormattingOptions, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, prettier_layer. -// Consumes: v4.std.collection { List }. +// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierIntPatch, PrettierBoolPatch, PrettierTrailingCommaPatch, PrettierQuotePropsPatch, PrettierArrowParensPatch, PrettierProseWrapPatch, PrettierHtmlWhitespaceSensitivityPatch, PrettierEndOfLinePatch, PrettierEmbeddedLanguageFormattingPatch, PrettierObjectWrapPatch, PrettierExperimentalOperatorPositionPatch, PrettierParserPatch, PrettierFormattingOptions, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, PrettierConfigPatch, prettier_layer. +// Consumes: v4.std.collection { List }, v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” Prettier stable config/options docs (v3 defaults). // Anchor: https://prettier.io/docs/configuration // https://prettier.io/docs/options @@ -9,6 +9,7 @@ module v4.extdeps.formatters.prettier import v4.std.collection { List } +import v4.std.patch { FieldPatch, apply_field_patch } // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. @@ -272,7 +273,15 @@ data prettier_defaults: PrettierConfig = PrettierConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: PrettierConfigPatch type with per-field Override/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed. -fn prettier_layer(base: PrettierConfig, outer: PrettierConfig) -> PrettierConfig { - outer +type PrettierConfigPatch { + options: FieldPatch + overrides: FieldPatch> +} + + +fn prettier_layer(base: PrettierConfig, patch: PrettierConfigPatch) -> PrettierConfig { + PrettierConfig { + options: apply_field_patch(base: base.options, patch: patch.options), + overrides: apply_field_patch(base: base.overrides, patch: patch.overrides), + } } diff --git a/src/v4/extdeps/formatters/rustfmt.dag b/src/v4/extdeps/formatters/rustfmt.dag index acb94da4a2e..0b6fe7be77a 100644 --- a/src/v4/extdeps/formatters/rustfmt.dag +++ b/src/v4/extdeps/formatters/rustfmt.dag @@ -1,12 +1,14 @@ // src/v4/extdeps/formatters/rustfmt.dag // Scope: rustfmt configuration model โ€” option space grounded in rustfmt v1.6.0 toml reference. -// Owns: RustfmtIndentStyle, RustfmtBraceStyle, RustfmtControlBraceStyle, RustfmtTrailingComma, RustfmtMatchArmLeadingPipes, RustfmtImportsGranularity, RustfmtGroupImports, RustfmtImportsLayout, RustfmtFnParamsLayout, RustfmtNewlineStyle, RustfmtEdition, RustfmtSmallHeuristics, RustfmtHexLiteralCase, RustfmtVersion, RustfmtBinopSeparator, RustfmtColor, RustfmtTypePunctuationDensity, RustfmtMacroSelector, RustfmtRequiredVersion, RustfmtConfig, rustfmt_defaults, rustfmt_layer. -// Consumes: none (String, Bool, Int, List are language-level primitives; no compiler dependency). +// Owns: RustfmtIndentStyle, RustfmtBraceStyle, RustfmtControlBraceStyle, RustfmtTrailingComma, RustfmtMatchArmLeadingPipes, RustfmtImportsGranularity, RustfmtGroupImports, RustfmtImportsLayout, RustfmtFnParamsLayout, RustfmtNewlineStyle, RustfmtEdition, RustfmtSmallHeuristics, RustfmtHexLiteralCase, RustfmtVersion, RustfmtBinopSeparator, RustfmtColor, RustfmtTypePunctuationDensity, RustfmtMacroSelector, RustfmtRequiredVersion, RustfmtConfig, rustfmt_defaults, RustfmtConfigPatch, rustfmt_layer. +// Consumes: v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” full option space grounded in rustfmt v1.6.0 toml reference. // Anchor: https://rust-lang.github.io/rustfmt/?version=v1.6.0 module v4.extdeps.formatters.rustfmt +import v4.std.patch { FieldPatch, apply_field_patch } + // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. type RustfmtIndentStyle @@ -330,7 +332,167 @@ data rustfmt_defaults: RustfmtConfig = RustfmtConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: RustfmtConfigPatch type with per-field Override/Inherit arms replaces full-config layering; forbidden: full-config replacement where partial field override is needed. -fn rustfmt_layer(base: RustfmtConfig, outer: RustfmtConfig) -> RustfmtConfig { - outer +type RustfmtConfigPatch { + indent_style: FieldPatch + tab_spaces: FieldPatch + hard_tabs: FieldPatch + max_width: FieldPatch + comment_width: FieldPatch + chain_width: FieldPatch + single_line_if_else_max_width: FieldPatch + single_line_let_else_max_width: FieldPatch + fn_call_width: FieldPatch + attr_fn_like_width: FieldPatch + struct_lit_width: FieldPatch + struct_variant_width: FieldPatch + array_width: FieldPatch + short_array_element_width_threshold: FieldPatch + brace_style: FieldPatch + control_brace_style: FieldPatch + where_single_line: FieldPatch + trailing_comma: FieldPatch + trailing_semicolon: FieldPatch + match_arm_leading_pipes: FieldPatch + match_arm_blocks: FieldPatch + match_block_trailing_comma: FieldPatch + imports_granularity: FieldPatch + group_imports: FieldPatch + imports_layout: FieldPatch + imports_indent: FieldPatch + reorder_imports: FieldPatch + merge_imports: FieldPatch + fn_params_layout: FieldPatch + fn_args_layout: FieldPatch + fn_single_line: FieldPatch + inline_attribute_width: FieldPatch + reorder_modules: FieldPatch + reorder_impl_items: FieldPatch + newline_style: FieldPatch + blank_lines_upper_bound: FieldPatch + blank_lines_lower_bound: FieldPatch + wrap_comments: FieldPatch + normalize_comments: FieldPatch + normalize_doc_attributes: FieldPatch + format_strings: FieldPatch + format_code_in_doc_comments: FieldPatch + doc_comment_code_block_width: FieldPatch + format_generated_files: FieldPatch + hide_parse_errors: FieldPatch + merge_derives: FieldPatch + use_field_init_shorthand: FieldPatch + use_try_shorthand: FieldPatch + force_explicit_abi: FieldPatch + format_macro_matchers: FieldPatch + format_macro_bodies: FieldPatch + binop_separator: FieldPatch + use_small_heuristics: FieldPatch + overflow_delimited_expr: FieldPatch + remove_nested_parens: FieldPatch + combine_control_expr: FieldPatch + hex_literal_case: FieldPatch + enum_discrim_align_threshold: FieldPatch + struct_field_align_threshold: FieldPatch + spaces_around_ranges: FieldPatch + space_after_colon: FieldPatch + space_before_colon: FieldPatch + empty_item_single_line: FieldPatch + struct_lit_single_line: FieldPatch + condense_wildcard_suffixes: FieldPatch + force_multiline_blocks: FieldPatch + error_on_line_overflow: FieldPatch + error_on_unformatted: FieldPatch + skip_children: FieldPatch + skip_macro_invocations: FieldPatch> + type_punctuation_density: FieldPatch + disable_all_formatting: FieldPatch + color: FieldPatch + edition: FieldPatch + version: FieldPatch + unstable_features: FieldPatch + required_version: FieldPatch + ignore: FieldPatch> +} + + +fn rustfmt_layer(base: RustfmtConfig, patch: RustfmtConfigPatch) -> RustfmtConfig { + RustfmtConfig { + indent_style: apply_field_patch(base: base.indent_style, patch: patch.indent_style), + tab_spaces: apply_field_patch(base: base.tab_spaces, patch: patch.tab_spaces), + hard_tabs: apply_field_patch(base: base.hard_tabs, patch: patch.hard_tabs), + max_width: apply_field_patch(base: base.max_width, patch: patch.max_width), + comment_width: apply_field_patch(base: base.comment_width, patch: patch.comment_width), + chain_width: apply_field_patch(base: base.chain_width, patch: patch.chain_width), + single_line_if_else_max_width: apply_field_patch(base: base.single_line_if_else_max_width, patch: patch.single_line_if_else_max_width), + single_line_let_else_max_width: apply_field_patch(base: base.single_line_let_else_max_width, patch: patch.single_line_let_else_max_width), + fn_call_width: apply_field_patch(base: base.fn_call_width, patch: patch.fn_call_width), + attr_fn_like_width: apply_field_patch(base: base.attr_fn_like_width, patch: patch.attr_fn_like_width), + struct_lit_width: apply_field_patch(base: base.struct_lit_width, patch: patch.struct_lit_width), + struct_variant_width: apply_field_patch(base: base.struct_variant_width, patch: patch.struct_variant_width), + array_width: apply_field_patch(base: base.array_width, patch: patch.array_width), + short_array_element_width_threshold: apply_field_patch(base: base.short_array_element_width_threshold, patch: patch.short_array_element_width_threshold), + brace_style: apply_field_patch(base: base.brace_style, patch: patch.brace_style), + control_brace_style: apply_field_patch(base: base.control_brace_style, patch: patch.control_brace_style), + where_single_line: apply_field_patch(base: base.where_single_line, patch: patch.where_single_line), + trailing_comma: apply_field_patch(base: base.trailing_comma, patch: patch.trailing_comma), + trailing_semicolon: apply_field_patch(base: base.trailing_semicolon, patch: patch.trailing_semicolon), + match_arm_leading_pipes: apply_field_patch(base: base.match_arm_leading_pipes, patch: patch.match_arm_leading_pipes), + match_arm_blocks: apply_field_patch(base: base.match_arm_blocks, patch: patch.match_arm_blocks), + match_block_trailing_comma: apply_field_patch(base: base.match_block_trailing_comma, patch: patch.match_block_trailing_comma), + imports_granularity: apply_field_patch(base: base.imports_granularity, patch: patch.imports_granularity), + group_imports: apply_field_patch(base: base.group_imports, patch: patch.group_imports), + imports_layout: apply_field_patch(base: base.imports_layout, patch: patch.imports_layout), + imports_indent: apply_field_patch(base: base.imports_indent, patch: patch.imports_indent), + reorder_imports: apply_field_patch(base: base.reorder_imports, patch: patch.reorder_imports), + merge_imports: apply_field_patch(base: base.merge_imports, patch: patch.merge_imports), + fn_params_layout: apply_field_patch(base: base.fn_params_layout, patch: patch.fn_params_layout), + fn_args_layout: apply_field_patch(base: base.fn_args_layout, patch: patch.fn_args_layout), + fn_single_line: apply_field_patch(base: base.fn_single_line, patch: patch.fn_single_line), + inline_attribute_width: apply_field_patch(base: base.inline_attribute_width, patch: patch.inline_attribute_width), + reorder_modules: apply_field_patch(base: base.reorder_modules, patch: patch.reorder_modules), + reorder_impl_items: apply_field_patch(base: base.reorder_impl_items, patch: patch.reorder_impl_items), + newline_style: apply_field_patch(base: base.newline_style, patch: patch.newline_style), + blank_lines_upper_bound: apply_field_patch(base: base.blank_lines_upper_bound, patch: patch.blank_lines_upper_bound), + blank_lines_lower_bound: apply_field_patch(base: base.blank_lines_lower_bound, patch: patch.blank_lines_lower_bound), + wrap_comments: apply_field_patch(base: base.wrap_comments, patch: patch.wrap_comments), + normalize_comments: apply_field_patch(base: base.normalize_comments, patch: patch.normalize_comments), + normalize_doc_attributes: apply_field_patch(base: base.normalize_doc_attributes, patch: patch.normalize_doc_attributes), + format_strings: apply_field_patch(base: base.format_strings, patch: patch.format_strings), + format_code_in_doc_comments: apply_field_patch(base: base.format_code_in_doc_comments, patch: patch.format_code_in_doc_comments), + doc_comment_code_block_width: apply_field_patch(base: base.doc_comment_code_block_width, patch: patch.doc_comment_code_block_width), + format_generated_files: apply_field_patch(base: base.format_generated_files, patch: patch.format_generated_files), + hide_parse_errors: apply_field_patch(base: base.hide_parse_errors, patch: patch.hide_parse_errors), + merge_derives: apply_field_patch(base: base.merge_derives, patch: patch.merge_derives), + use_field_init_shorthand: apply_field_patch(base: base.use_field_init_shorthand, patch: patch.use_field_init_shorthand), + use_try_shorthand: apply_field_patch(base: base.use_try_shorthand, patch: patch.use_try_shorthand), + force_explicit_abi: apply_field_patch(base: base.force_explicit_abi, patch: patch.force_explicit_abi), + format_macro_matchers: apply_field_patch(base: base.format_macro_matchers, patch: patch.format_macro_matchers), + format_macro_bodies: apply_field_patch(base: base.format_macro_bodies, patch: patch.format_macro_bodies), + binop_separator: apply_field_patch(base: base.binop_separator, patch: patch.binop_separator), + use_small_heuristics: apply_field_patch(base: base.use_small_heuristics, patch: patch.use_small_heuristics), + overflow_delimited_expr: apply_field_patch(base: base.overflow_delimited_expr, patch: patch.overflow_delimited_expr), + remove_nested_parens: apply_field_patch(base: base.remove_nested_parens, patch: patch.remove_nested_parens), + combine_control_expr: apply_field_patch(base: base.combine_control_expr, patch: patch.combine_control_expr), + hex_literal_case: apply_field_patch(base: base.hex_literal_case, patch: patch.hex_literal_case), + enum_discrim_align_threshold: apply_field_patch(base: base.enum_discrim_align_threshold, patch: patch.enum_discrim_align_threshold), + struct_field_align_threshold: apply_field_patch(base: base.struct_field_align_threshold, patch: patch.struct_field_align_threshold), + spaces_around_ranges: apply_field_patch(base: base.spaces_around_ranges, patch: patch.spaces_around_ranges), + space_after_colon: apply_field_patch(base: base.space_after_colon, patch: patch.space_after_colon), + space_before_colon: apply_field_patch(base: base.space_before_colon, patch: patch.space_before_colon), + empty_item_single_line: apply_field_patch(base: base.empty_item_single_line, patch: patch.empty_item_single_line), + struct_lit_single_line: apply_field_patch(base: base.struct_lit_single_line, patch: patch.struct_lit_single_line), + condense_wildcard_suffixes: apply_field_patch(base: base.condense_wildcard_suffixes, patch: patch.condense_wildcard_suffixes), + force_multiline_blocks: apply_field_patch(base: base.force_multiline_blocks, patch: patch.force_multiline_blocks), + error_on_line_overflow: apply_field_patch(base: base.error_on_line_overflow, patch: patch.error_on_line_overflow), + error_on_unformatted: apply_field_patch(base: base.error_on_unformatted, patch: patch.error_on_unformatted), + skip_children: apply_field_patch(base: base.skip_children, patch: patch.skip_children), + skip_macro_invocations: apply_field_patch(base: base.skip_macro_invocations, patch: patch.skip_macro_invocations), + type_punctuation_density: apply_field_patch(base: base.type_punctuation_density, patch: patch.type_punctuation_density), + disable_all_formatting: apply_field_patch(base: base.disable_all_formatting, patch: patch.disable_all_formatting), + color: apply_field_patch(base: base.color, patch: patch.color), + edition: apply_field_patch(base: base.edition, patch: patch.edition), + version: apply_field_patch(base: base.version, patch: patch.version), + unstable_features: apply_field_patch(base: base.unstable_features, patch: patch.unstable_features), + required_version: apply_field_patch(base: base.required_version, patch: patch.required_version), + ignore: apply_field_patch(base: base.ignore, patch: patch.ignore), + } } diff --git a/src/v4/extdeps/formatters/swift_format.dag b/src/v4/extdeps/formatters/swift_format.dag index d91b03e7709..6d450152a75 100644 --- a/src/v4/extdeps/formatters/swift_format.dag +++ b/src/v4/extdeps/formatters/swift_format.dag @@ -1,12 +1,14 @@ // src/v4/extdeps/formatters/swift_format.dag // Scope: swift-format formatting configuration model โ€” formatting knobs only; rules carrier excluded (see gate below). -// Owns: SwiftFormatIndentation, SwiftFormatPrivacy, SwiftFormatTrailingCommaBehavior, SwiftFormatStringReflow, SwiftFormatOrderedImports, SwiftFormatConfig, swift_format_defaults, swift_format_layer. -// Consumes: none (String, Bool, Int, List are language-level primitives; no compiler dependency). +// Owns: SwiftFormatIndentation, SwiftFormatPrivacy, SwiftFormatTrailingCommaBehavior, SwiftFormatStringReflow, SwiftFormatOrderedImports, SwiftFormatConfig, swift_format_defaults, SwiftFormatConfigPatch, swift_format_layer. +// Consumes: v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” formatting-knob option space grounded in swift-format Configuration.md; rules field gated pending Map primitive availability. // Anchor: https://github.com/apple/swift-format/blob/main/Documentation/Configuration.md module v4.extdeps.formatters.swift_format +import v4.std.patch { FieldPatch, apply_field_patch } + // ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. type SwiftFormatIndentation @@ -113,7 +115,57 @@ data swift_format_defaults: SwiftFormatConfig = SwiftFormatConfig { } -// ๐ŸŸก gated โ€” feature: formatter-config-patch โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: SwiftFormatConfigPatch type with per-field Override/Inherit arms replaces full-config layering. -fn swift_format_layer(base: SwiftFormatConfig, outer: SwiftFormatConfig) -> SwiftFormatConfig { - outer +type SwiftFormatConfigPatch { + version: FieldPatch + line_length: FieldPatch + indentation: FieldPatch + tab_width: FieldPatch + maximum_blank_lines: FieldPatch + spaces_before_end_of_line_comments: FieldPatch + respects_existing_line_breaks: FieldPatch + line_break_before_control_flow_keywords: FieldPatch + line_break_before_each_argument: FieldPatch + line_break_before_each_generic_requirement: FieldPatch + line_break_between_declaration_attributes: FieldPatch + prioritize_keeping_function_output_together: FieldPatch + indent_conditional_compilation_blocks: FieldPatch + line_break_around_multiline_expression_chain_components: FieldPatch + file_scoped_declaration_privacy: FieldPatch + indent_switch_case_labels: FieldPatch + spaces_around_range_formation_operators: FieldPatch + no_assignment_in_expressions: FieldPatch + multiline_trailing_comma_behavior: FieldPatch + multi_element_collection_trailing_commas: FieldPatch + reflow_multiline_string_literals: FieldPatch + indent_blank_lines: FieldPatch + ordered_imports: FieldPatch +} + + +fn swift_format_layer(base: SwiftFormatConfig, patch: SwiftFormatConfigPatch) -> SwiftFormatConfig { + SwiftFormatConfig { + version: apply_field_patch(base: base.version, patch: patch.version), + line_length: apply_field_patch(base: base.line_length, patch: patch.line_length), + indentation: apply_field_patch(base: base.indentation, patch: patch.indentation), + tab_width: apply_field_patch(base: base.tab_width, patch: patch.tab_width), + maximum_blank_lines: apply_field_patch(base: base.maximum_blank_lines, patch: patch.maximum_blank_lines), + spaces_before_end_of_line_comments: apply_field_patch(base: base.spaces_before_end_of_line_comments, patch: patch.spaces_before_end_of_line_comments), + respects_existing_line_breaks: apply_field_patch(base: base.respects_existing_line_breaks, patch: patch.respects_existing_line_breaks), + line_break_before_control_flow_keywords: apply_field_patch(base: base.line_break_before_control_flow_keywords, patch: patch.line_break_before_control_flow_keywords), + line_break_before_each_argument: apply_field_patch(base: base.line_break_before_each_argument, patch: patch.line_break_before_each_argument), + line_break_before_each_generic_requirement: apply_field_patch(base: base.line_break_before_each_generic_requirement, patch: patch.line_break_before_each_generic_requirement), + line_break_between_declaration_attributes: apply_field_patch(base: base.line_break_between_declaration_attributes, patch: patch.line_break_between_declaration_attributes), + prioritize_keeping_function_output_together: apply_field_patch(base: base.prioritize_keeping_function_output_together, patch: patch.prioritize_keeping_function_output_together), + indent_conditional_compilation_blocks: apply_field_patch(base: base.indent_conditional_compilation_blocks, patch: patch.indent_conditional_compilation_blocks), + line_break_around_multiline_expression_chain_components: apply_field_patch(base: base.line_break_around_multiline_expression_chain_components, patch: patch.line_break_around_multiline_expression_chain_components), + file_scoped_declaration_privacy: apply_field_patch(base: base.file_scoped_declaration_privacy, patch: patch.file_scoped_declaration_privacy), + indent_switch_case_labels: apply_field_patch(base: base.indent_switch_case_labels, patch: patch.indent_switch_case_labels), + spaces_around_range_formation_operators: apply_field_patch(base: base.spaces_around_range_formation_operators, patch: patch.spaces_around_range_formation_operators), + no_assignment_in_expressions: apply_field_patch(base: base.no_assignment_in_expressions, patch: patch.no_assignment_in_expressions), + multiline_trailing_comma_behavior: apply_field_patch(base: base.multiline_trailing_comma_behavior, patch: patch.multiline_trailing_comma_behavior), + multi_element_collection_trailing_commas: apply_field_patch(base: base.multi_element_collection_trailing_commas, patch: patch.multi_element_collection_trailing_commas), + reflow_multiline_string_literals: apply_field_patch(base: base.reflow_multiline_string_literals, patch: patch.reflow_multiline_string_literals), + indent_blank_lines: apply_field_patch(base: base.indent_blank_lines, patch: patch.indent_blank_lines), + ordered_imports: apply_field_patch(base: base.ordered_imports, patch: patch.ordered_imports), + } } From 92b04c5a0a65417bf1c19a9575bfcfc1373ec12f Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 18:57:28 +0000 Subject: [PATCH 03/23] prettier.dag: replace bespoke Prettier*Patch coproducts with FieldPatch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete the 12 formatter-local patch coproducts (PrettierIntPatch, PrettierBoolPatch, and the ten enum-specific variants) and migrate PrettierOverrideOptions to FieldPatch โ€” eliminating the parallel authority that violated INVARIANTS.md P2/P5. Co-Authored-By: Claude Sonnet 4.6 --- src/v4/extdeps/formatters/prettier.dag | 121 +++++-------------------- 1 file changed, 25 insertions(+), 96 deletions(-) diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index 75946ff073a..48ef09fb7b3 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -1,6 +1,6 @@ // src/v4/extdeps/formatters/prettier.dag // Scope: Prettier configuration file model (.prettierrc / package.json "prettier"). -// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierIntPatch, PrettierBoolPatch, PrettierTrailingCommaPatch, PrettierQuotePropsPatch, PrettierArrowParensPatch, PrettierProseWrapPatch, PrettierHtmlWhitespaceSensitivityPatch, PrettierEndOfLinePatch, PrettierEmbeddedLanguageFormattingPatch, PrettierObjectWrapPatch, PrettierExperimentalOperatorPositionPatch, PrettierParserPatch, PrettierFormattingOptions, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, PrettierConfigPatch, prettier_layer. +// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierFormattingOptions, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, PrettierConfigPatch, prettier_layer. // Consumes: v4.std.collection { List }, v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” Prettier stable config/options docs (v3 defaults). // Anchor: https://prettier.io/docs/configuration @@ -100,77 +100,6 @@ type PrettierParser | PrettierParserYaml -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierIntPatch - = PrettierIntPatchInherit - | PrettierIntPatchOverride { value: Int } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierBoolPatch - = PrettierBoolPatchInherit - | PrettierBoolPatchOverride { value: Bool } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierTrailingCommaPatch - = PrettierTrailingCommaPatchInherit - | PrettierTrailingCommaPatchOverride { value: PrettierTrailingComma } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierQuotePropsPatch - = PrettierQuotePropsPatchInherit - | PrettierQuotePropsPatchOverride { value: PrettierQuoteProps } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierArrowParensPatch - = PrettierArrowParensPatchInherit - | PrettierArrowParensPatchOverride { value: PrettierArrowParens } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierProseWrapPatch - = PrettierProseWrapPatchInherit - | PrettierProseWrapPatchOverride { value: PrettierProseWrap } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierHtmlWhitespaceSensitivityPatch - = PrettierHtmlWhitespaceSensitivityPatchInherit - | PrettierHtmlWhitespaceSensitivityPatchOverride { value: PrettierHtmlWhitespaceSensitivity } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierEndOfLinePatch - = PrettierEndOfLinePatchInherit - | PrettierEndOfLinePatchOverride { value: PrettierEndOfLine } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierEmbeddedLanguageFormattingPatch - = PrettierEmbeddedLanguageFormattingPatchInherit - | PrettierEmbeddedLanguageFormattingPatchOverride { value: PrettierEmbeddedLanguageFormatting } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierObjectWrapPatch - = PrettierObjectWrapPatchInherit - | PrettierObjectWrapPatchOverride { value: PrettierObjectWrap } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierExperimentalOperatorPositionPatch - = PrettierExperimentalOperatorPositionPatchInherit - | PrettierExperimentalOperatorPositionPatchOverride { value: PrettierExperimentalOperatorPosition } - - -// ๐ŸŸข coproduct dissolution โ€” CP-3229-GREEN-TERMINAL. -type PrettierParserPatch - = PrettierParserPatchInherit - | PrettierParserPatchOverride { value: PrettierParser } - type PrettierFormattingOptions { print_width: Int // ๐ŸŸก gated: formatter-int-refinement โ€” must be โ‰ฅ1 @@ -200,30 +129,30 @@ type PrettierFormattingOptions { type PrettierOverrideOptions { - parser: PrettierParserPatch - print_width: PrettierIntPatch - tab_width: PrettierIntPatch - use_tabs: PrettierBoolPatch - semi: PrettierBoolPatch - single_quote: PrettierBoolPatch - quote_props: PrettierQuotePropsPatch - jsx_single_quote: PrettierBoolPatch - trailing_comma: PrettierTrailingCommaPatch - bracket_spacing: PrettierBoolPatch - object_wrap: PrettierObjectWrapPatch - bracket_same_line: PrettierBoolPatch - arrow_parens: PrettierArrowParensPatch - require_pragma: PrettierBoolPatch - insert_pragma: PrettierBoolPatch - check_ignore_pragma: PrettierBoolPatch - prose_wrap: PrettierProseWrapPatch - html_whitespace_sensitivity: PrettierHtmlWhitespaceSensitivityPatch - vue_indent_script_and_style: PrettierBoolPatch - single_attribute_per_line: PrettierBoolPatch - end_of_line: PrettierEndOfLinePatch - embedded_language_formatting: PrettierEmbeddedLanguageFormattingPatch - experimental_ternaries: PrettierBoolPatch - experimental_operator_position: PrettierExperimentalOperatorPositionPatch + parser: FieldPatch + print_width: FieldPatch + tab_width: FieldPatch + use_tabs: FieldPatch + semi: FieldPatch + single_quote: FieldPatch + quote_props: FieldPatch + jsx_single_quote: FieldPatch + trailing_comma: FieldPatch + bracket_spacing: FieldPatch + object_wrap: FieldPatch + bracket_same_line: FieldPatch + arrow_parens: FieldPatch + require_pragma: FieldPatch + insert_pragma: FieldPatch + check_ignore_pragma: FieldPatch + prose_wrap: FieldPatch + html_whitespace_sensitivity: FieldPatch + vue_indent_script_and_style: FieldPatch + single_attribute_per_line: FieldPatch + end_of_line: FieldPatch + embedded_language_formatting: FieldPatch + experimental_ternaries: FieldPatch + experimental_operator_position: FieldPatch } From ff27e84897269fd729a0fadc762f7f6f19c3c590 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 19:25:54 +0000 Subject: [PATCH 04/23] patch.dag: add compose_field_patch + field_patch_monoid witness (M9/P1) Grounds the declared monoid substrate against std/algebra: adds compose_field_patch (right-biased semigroup op, later layer wins) and field_patch_monoid -> Monoid> that assembles the Magma/Semigroup/Monoid chain. Identity is Inherit. Resolves the blocking inline review comment on PR #3705. Co-Authored-By: Claude Sonnet 4.6 --- src/v4/std/patch.dag | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index 1ff817f0c7a..5d6353fe00b 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -1,13 +1,15 @@ // src/v4/std/patch.dag // Scope: field-level overlay patch substrate โ€” per-field Override/Inherit coproduct for hierarchical config layering. -// Owns: FieldPatch, apply_field_patch. -// Consumes: none (language primitives only). +// Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid. +// Consumes: v4.std.algebra { Magma, Semigroup, Monoid }. // Status: T-4.16 follow-on โ€” formatter ConfigPatch monoid substrate. // External authority: two-element lattice per field (Override = top, Inherit = bottom); // standard layered-config pattern (NixOS module system, Home Manager override/inherit). +// Monoid: right-biased composition (later layer wins); identity = Inherit. module v4.std.patch +import v4.std.algebra { Magma, Semigroup, Monoid } // ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. // Per-field patch coproduct for hierarchical config layering. @@ -23,3 +25,26 @@ fn apply_field_patch(base: T, patch: FieldPatch) -> T { Inherit => base } } + + +// Right-biased semigroup composition: later layer wins. +// compose(left, Override{v}) = Override{v}; compose(left, Inherit) = left. +// Identity: Inherit (compose(Inherit, p) = p and compose(p, Inherit) = p). +fn compose_field_patch(left: FieldPatch, right: FieldPatch) -> FieldPatch { + match right { + Override { value: v } => Override { value: v } + Inherit => left + } +} + + +fn field_patch_monoid() -> Monoid> { + Monoid { + semigroup: Semigroup { + magma: Magma { + op: fn(left, right) { compose_field_patch(left: left, right: right) } + } + }, + identity: Inherit, + } +} From 3957e3931aaec4bc79139db158ce6de7a3dce657 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 19:26:52 +0000 Subject: [PATCH 05/23] prettier.dag: expand PrettierConfigPatch to per-field FieldPatch Replace coarse FieldPatch with 23 per-field patches mirroring PrettierFormattingOptions, so a layer can express a single option override without full-record replacement. Update prettier_layer to thread apply_field_patch per field via base.options.* projection. Matches the per-field granularity of every other formatter ConfigPatch. Co-Authored-By: Claude Sonnet 4.6 --- src/v4/extdeps/formatters/prettier.dag | 50 ++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index 48ef09fb7b3..c36a3143673 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -203,14 +203,60 @@ data prettier_defaults: PrettierConfig = PrettierConfig { type PrettierConfigPatch { - options: FieldPatch + print_width: FieldPatch + tab_width: FieldPatch + use_tabs: FieldPatch + semi: FieldPatch + single_quote: FieldPatch + quote_props: FieldPatch + jsx_single_quote: FieldPatch + trailing_comma: FieldPatch + bracket_spacing: FieldPatch + object_wrap: FieldPatch + bracket_same_line: FieldPatch + arrow_parens: FieldPatch + require_pragma: FieldPatch + insert_pragma: FieldPatch + check_ignore_pragma: FieldPatch + prose_wrap: FieldPatch + html_whitespace_sensitivity: FieldPatch + vue_indent_script_and_style: FieldPatch + single_attribute_per_line: FieldPatch + end_of_line: FieldPatch + embedded_language_formatting: FieldPatch + experimental_ternaries: FieldPatch + experimental_operator_position: FieldPatch overrides: FieldPatch> } fn prettier_layer(base: PrettierConfig, patch: PrettierConfigPatch) -> PrettierConfig { PrettierConfig { - options: apply_field_patch(base: base.options, patch: patch.options), + options: PrettierFormattingOptions { + print_width: apply_field_patch(base: base.options.print_width, patch: patch.print_width), + tab_width: apply_field_patch(base: base.options.tab_width, patch: patch.tab_width), + use_tabs: apply_field_patch(base: base.options.use_tabs, patch: patch.use_tabs), + semi: apply_field_patch(base: base.options.semi, patch: patch.semi), + single_quote: apply_field_patch(base: base.options.single_quote, patch: patch.single_quote), + quote_props: apply_field_patch(base: base.options.quote_props, patch: patch.quote_props), + jsx_single_quote: apply_field_patch(base: base.options.jsx_single_quote, patch: patch.jsx_single_quote), + trailing_comma: apply_field_patch(base: base.options.trailing_comma, patch: patch.trailing_comma), + bracket_spacing: apply_field_patch(base: base.options.bracket_spacing, patch: patch.bracket_spacing), + object_wrap: apply_field_patch(base: base.options.object_wrap, patch: patch.object_wrap), + bracket_same_line: apply_field_patch(base: base.options.bracket_same_line, patch: patch.bracket_same_line), + arrow_parens: apply_field_patch(base: base.options.arrow_parens, patch: patch.arrow_parens), + require_pragma: apply_field_patch(base: base.options.require_pragma, patch: patch.require_pragma), + insert_pragma: apply_field_patch(base: base.options.insert_pragma, patch: patch.insert_pragma), + check_ignore_pragma: apply_field_patch(base: base.options.check_ignore_pragma, patch: patch.check_ignore_pragma), + prose_wrap: apply_field_patch(base: base.options.prose_wrap, patch: patch.prose_wrap), + html_whitespace_sensitivity: apply_field_patch(base: base.options.html_whitespace_sensitivity, patch: patch.html_whitespace_sensitivity), + vue_indent_script_and_style: apply_field_patch(base: base.options.vue_indent_script_and_style, patch: patch.vue_indent_script_and_style), + single_attribute_per_line: apply_field_patch(base: base.options.single_attribute_per_line, patch: patch.single_attribute_per_line), + end_of_line: apply_field_patch(base: base.options.end_of_line, patch: patch.end_of_line), + embedded_language_formatting: apply_field_patch(base: base.options.embedded_language_formatting, patch: patch.embedded_language_formatting), + experimental_ternaries: apply_field_patch(base: base.options.experimental_ternaries, patch: patch.experimental_ternaries), + experimental_operator_position: apply_field_patch(base: base.options.experimental_operator_position, patch: patch.experimental_operator_position), + }, overrides: apply_field_patch(base: base.overrides, patch: patch.overrides), } } From fec18cd2e35dbdad1c6d3c4d0dadd990ebe2bb7a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 23:30:48 +0000 Subject: [PATCH 06/23] =?UTF-8?q?WIP:=20Analyses=20Finding=20#9=20?= =?UTF-8?q?=E2=80=94=20implement=20formatter=20ConfigPatch=20monoid=20(T-4?= =?UTF-8?q?.16=20fol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v4/std/patch.dag | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index 5d6353fe00b..b428bf65002 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -3,9 +3,11 @@ // Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid. // Consumes: v4.std.algebra { Magma, Semigroup, Monoid }. // Status: T-4.16 follow-on โ€” formatter ConfigPatch monoid substrate. -// External authority: two-element lattice per field (Override = top, Inherit = bottom); -// standard layered-config pattern (NixOS module system, Home Manager override/inherit). -// Monoid: right-biased composition (later layer wins); identity = Inherit. +// External authority: right-biased optional-value patch monoid โ€” FieldPatch is 1 + T +// (Inherit = absent/identity, Override { value } = present/payload). Not a two-element +// lattice: for non-singleton T, distinct Override values are distinct patches, not a +// shared top. Monoid op is right-biased (later layer wins); identity is Inherit. +// Standard layered-config pattern: NixOS module system, Home Manager mkOverride. module v4.std.patch From 3ac471c33a9a5f27731fb6187389f1a1a0bae0dd Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 23:30:56 +0000 Subject: [PATCH 07/23] =?UTF-8?q?patch.dag:=20correct=20grounding=20?= =?UTF-8?q?=E2=80=94=20right-biased=20optional-value=20monoid,=20not=20two?= =?UTF-8?q?-element=20lattice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FieldPatch is 1 + T: for non-singleton T, distinct Override values are distinct patches, so there is no single lattice top. Reframe the external authority comment as the right-biased optional-value patch monoid (Inherit = identity, Override = payload) โ€” matching what the compose/monoid witness actually implements. Co-Authored-By: Claude Sonnet 4.6 --- src/v4/std/patch.dag | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index b428bf65002..9779f438bde 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -14,8 +14,7 @@ module v4.std.patch import v4.std.algebra { Magma, Semigroup, Monoid } // ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. -// Per-field patch coproduct for hierarchical config layering. -// Override carries the replacement value for this field; Inherit defers to the base. +// Per-field optional-value patch: Inherit = no opinion (identity), Override = explicit replacement. type FieldPatch = Override { value: T } | Inherit From db7ef8cd2d4bcba14198cc33735ac0ba9ddf11f2 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Tue, 26 May 2026 23:53:34 +0000 Subject: [PATCH 08/23] =?UTF-8?q?WIP:=20Analyses=20Finding=20#9=20?= =?UTF-8?q?=E2=80=94=20implement=20formatter=20ConfigPatch=20monoid=20(T-4?= =?UTF-8?q?.16=20fol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v4/std/patch.dag | 11 +- .../claim/algebra_laws/field_patch_monoid.dag | 129 ++++++++++++++++++ 2 files changed, 131 insertions(+), 9 deletions(-) create mode 100644 src/v4/test/claim/algebra_laws/field_patch_monoid.dag diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index 9779f438bde..566a444ee90 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -3,18 +3,14 @@ // Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid. // Consumes: v4.std.algebra { Magma, Semigroup, Monoid }. // Status: T-4.16 follow-on โ€” formatter ConfigPatch monoid substrate. -// External authority: right-biased optional-value patch monoid โ€” FieldPatch is 1 + T -// (Inherit = absent/identity, Override { value } = present/payload). Not a two-element -// lattice: for non-singleton T, distinct Override values are distinct patches, not a -// shared top. Monoid op is right-biased (later layer wins); identity is Inherit. -// Standard layered-config pattern: NixOS module system, Home Manager mkOverride. +// Anchor: https://en.wikipedia.org/wiki/Monoid (NixOS module system / Home Manager override/inherit pattern) module v4.std.patch import v4.std.algebra { Magma, Semigroup, Monoid } // ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. -// Per-field optional-value patch: Inherit = no opinion (identity), Override = explicit replacement. +// FieldPatch = 1 + T: Inherit = absent/identity, Override = present payload. type FieldPatch = Override { value: T } | Inherit @@ -28,9 +24,6 @@ fn apply_field_patch(base: T, patch: FieldPatch) -> T { } -// Right-biased semigroup composition: later layer wins. -// compose(left, Override{v}) = Override{v}; compose(left, Inherit) = left. -// Identity: Inherit (compose(Inherit, p) = p and compose(p, Inherit) = p). fn compose_field_patch(left: FieldPatch, right: FieldPatch) -> FieldPatch { match right { Override { value: v } => Override { value: v } diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag new file mode 100644 index 00000000000..d9de2aa87ea --- /dev/null +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -0,0 +1,129 @@ +// src/v4/test/claim/algebra_laws/field_patch_monoid.dag +// Scope: TestClaim corpus for FieldPatch right-biased optional-value patch monoid laws. +// Owns: claim rows for compose_field_patch left/right identity, associativity; apply_field_patch behavior. +// Consumes: v4.std.patch v4.std.node v4.std.verification. +// Status: T-4.16 follow-on behavior receipts; execution deferred to T-22 runner bridge. +// Discovery: T-22 runner enumerates src/v4/test/claim/** recursively. + +module v4.test.claim.algebra_laws.field_patch_monoid + +import v4.std.patch { FieldPatch, Override, Inherit, compose_field_patch, apply_field_patch } +import v4.std.node { Atom, Node, Symbol, TypeNode } +import v4.std.verification { + CompilesClaim, + ManualAnchorAbsent, + TestClaim, + TestClassification, + Tier1, + Unit, + manual_claim_anchor +} + + +data fp_pass_sym: Symbol = fp_pass_sym +data fp_fail_sym: Symbol = fp_fail_sym + + +fn fp_pass_node() -> Node { + Node { kind: TypeNode { connective: Atom { identity: fp_pass_sym } }, children: [] } +} +fn fp_fail_node() -> Node { + Node { kind: TypeNode { connective: Atom { identity: fp_fail_sym } }, children: [] } +} +fn fp_ok(b: Bool) -> Node { + if b { fp_pass_node() } else { fp_fail_node() } +} + + +fn field_patch_bool_eq(a: FieldPatch, b: FieldPatch) -> Bool { + match a { + Override { value: va } => match b { + Override { value: vb } => va == vb + Inherit => false + } + Inherit => match b { + Override { value: _ } => false + Inherit => true + } + } +} + + +// Monoid left identity: compose(Inherit, p) == p +data witness_left_identity: Bool = field_patch_bool_eq( + a: compose_field_patch(left: Inherit, right: Override { value: true }), + b: Override { value: true } +) + + +// Monoid right identity: compose(p, Inherit) == p +data witness_right_identity: Bool = field_patch_bool_eq( + a: compose_field_patch(left: Override { value: true }, right: Inherit), + b: Override { value: true } +) + + +// Associativity: (a โˆ˜ b) โˆ˜ c == a โˆ˜ (b โˆ˜ c) for a=Override{true}, b=Override{false}, c=Inherit +data witness_associativity: Bool = field_patch_bool_eq( + a: compose_field_patch( + left: compose_field_patch(left: Override { value: true }, right: Override { value: false }), + right: Inherit + ), + b: compose_field_patch( + left: Override { value: true }, + right: compose_field_patch(left: Override { value: false }, right: Inherit) + ) +) + + +// apply: Inherit defers to base +data witness_inherit_preserves: Bool = apply_field_patch(base: true, patch: Inherit) == true + + +// apply: Override replaces base +data witness_override_replaces: Bool = apply_field_patch(base: true, patch: Override { value: false }) == false + + +data claim_left_identity: TestClaim = CompilesClaim { + label: "field_patch/compose: Inherit is left identity", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_left_identity), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_right_identity: TestClaim = CompilesClaim { + label: "field_patch/compose: Inherit is right identity", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_right_identity), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_associativity: TestClaim = CompilesClaim { + label: "field_patch/compose: right-biased composition is associative", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_associativity), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_inherit_preserves: TestClaim = CompilesClaim { + label: "field_patch/apply: Inherit preserves base field value", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_inherit_preserves), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_override_replaces: TestClaim = CompilesClaim { + label: "field_patch/apply: Override replaces base field value", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_override_replaces), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} From 7878f59a5b56ca3b482f659cf56ad8b9c64de4ef Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 00:01:24 +0000 Subject: [PATCH 09/23] field_patch_monoid.dag: remove hand-rolled field_patch_bool_eq (Practice 10) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the local field_patch_bool_eq match-over-storage-shape with law witnesses expressed purely through apply_field_patch (canonical eliminator) and Bool == Bool equality โ€” no new derived operation over the FieldPatch coproduct. Each monoid law is now proven by applying the composed patch to a concrete base and checking the Bool result. Co-Authored-By: Claude Sonnet 4.6 --- .../claim/algebra_laws/field_patch_monoid.dag | 71 ++++++++----------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index d9de2aa87ea..60838145991 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -35,52 +35,43 @@ fn fp_ok(b: Bool) -> Node { } -fn field_patch_bool_eq(a: FieldPatch, b: FieldPatch) -> Bool { - match a { - Override { value: va } => match b { - Override { value: vb } => va == vb - Inherit => false - } - Inherit => match b { - Override { value: _ } => false - Inherit => true - } - } -} - - -// Monoid left identity: compose(Inherit, p) == p -data witness_left_identity: Bool = field_patch_bool_eq( - a: compose_field_patch(left: Inherit, right: Override { value: true }), - b: Override { value: true } -) - - -// Monoid right identity: compose(p, Inherit) == p -data witness_right_identity: Bool = field_patch_bool_eq( - a: compose_field_patch(left: Override { value: true }, right: Inherit), - b: Override { value: true } -) - - -// Associativity: (a โˆ˜ b) โˆ˜ c == a โˆ˜ (b โˆ˜ c) for a=Override{true}, b=Override{false}, c=Inherit -data witness_associativity: Bool = field_patch_bool_eq( - a: compose_field_patch( - left: compose_field_patch(left: Override { value: true }, right: Override { value: false }), - right: Inherit - ), - b: compose_field_patch( - left: Override { value: true }, - right: compose_field_patch(left: Override { value: false }, right: Inherit) +// Left identity: compose(Inherit, Override{v}) applies as Override{v}. +// Witness: base=false, patch=compose(Inherit, Override{true}) โ†’ result must be true. +data witness_left_identity: Bool = + apply_field_patch(base: false, patch: compose_field_patch(left: Inherit, right: Override { value: true })) == true + + +// Right identity: compose(Override{v}, Inherit) applies as Override{v}. +// Witness: base=false, patch=compose(Override{true}, Inherit) โ†’ result must be true. +data witness_right_identity: Bool = + apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true + + +// Associativity: apply((aโˆ˜b)โˆ˜c, base) == apply(aโˆ˜(bโˆ˜c), base). +// a=Override{true}, b=Override{false}, c=Inherit โ†’ both sides yield false from base=true. +data witness_associativity: Bool = + apply_field_patch( + base: true, + patch: compose_field_patch( + left: compose_field_patch(left: Override { value: true }, right: Override { value: false }), + right: Inherit + ) + ) + == + apply_field_patch( + base: true, + patch: compose_field_patch( + left: Override { value: true }, + right: compose_field_patch(left: Override { value: false }, right: Inherit) + ) ) -) -// apply: Inherit defers to base +// apply: Inherit defers to base. data witness_inherit_preserves: Bool = apply_field_patch(base: true, patch: Inherit) == true -// apply: Override replaces base +// apply: Override replaces base. data witness_override_replaces: Bool = apply_field_patch(base: true, patch: Override { value: false }) == false From bd6406ad67759f827ff8ce0c1da4ea7c281dadbe Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 00:16:48 +0000 Subject: [PATCH 10/23] =?UTF-8?q?field=5Fpatch=5Fmonoid.dag:=20fix=20parse?= =?UTF-8?q?=20error=20=E2=80=94=20data=20initializer=20must=20start=20on?= =?UTF-8?q?=20same=20line=20as=20=3D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move multi-line data initializers onto one line; extract associativity witness into compose_assoc_lhs/rhs helper functions to keep line length reasonable. Parser requires expression to begin on the same line as the = token in a data declaration. Co-Authored-By: Claude Sonnet 4.6 --- .../claim/algebra_laws/field_patch_monoid.dag | 31 ++++++------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index 60838145991..fbc90ef09ca 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -36,35 +36,22 @@ fn fp_ok(b: Bool) -> Node { // Left identity: compose(Inherit, Override{v}) applies as Override{v}. -// Witness: base=false, patch=compose(Inherit, Override{true}) โ†’ result must be true. -data witness_left_identity: Bool = - apply_field_patch(base: false, patch: compose_field_patch(left: Inherit, right: Override { value: true })) == true +data witness_left_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Inherit, right: Override { value: true })) == true // Right identity: compose(Override{v}, Inherit) applies as Override{v}. -// Witness: base=false, patch=compose(Override{true}, Inherit) โ†’ result must be true. -data witness_right_identity: Bool = - apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true +data witness_right_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true // Associativity: apply((aโˆ˜b)โˆ˜c, base) == apply(aโˆ˜(bโˆ˜c), base). // a=Override{true}, b=Override{false}, c=Inherit โ†’ both sides yield false from base=true. -data witness_associativity: Bool = - apply_field_patch( - base: true, - patch: compose_field_patch( - left: compose_field_patch(left: Override { value: true }, right: Override { value: false }), - right: Inherit - ) - ) - == - apply_field_patch( - base: true, - patch: compose_field_patch( - left: Override { value: true }, - right: compose_field_patch(left: Override { value: false }, right: Inherit) - ) - ) +fn compose_assoc_lhs() -> Bool { + apply_field_patch(base: true, patch: compose_field_patch(left: compose_field_patch(left: Override { value: true }, right: Override { value: false }), right: Inherit)) +} +fn compose_assoc_rhs() -> Bool { + apply_field_patch(base: true, patch: compose_field_patch(left: Override { value: true }, right: compose_field_patch(left: Override { value: false }, right: Inherit))) +} +data witness_associativity: Bool = compose_assoc_lhs() == compose_assoc_rhs() // apply: Inherit defers to base. From 7c36463b99585e6409f470fd1d2abada7e72769d Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 00:37:54 +0000 Subject: [PATCH 11/23] test: wire monoid witness consumer claims in field_patch_monoid.dag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add fp_monoid_op/fp_monoid_identity helpers that extract from field_patch_monoid() and three new TestClaims that route through the Monoid witness surface rather than the raw helpers directly โ€” so a bad wiring of .identity or .semigroup.magma.op inside the Monoid record would be detected. Co-Authored-By: Claude Sonnet 4.6 --- .../claim/algebra_laws/field_patch_monoid.dag | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index fbc90ef09ca..53c050fd908 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -1,13 +1,14 @@ // src/v4/test/claim/algebra_laws/field_patch_monoid.dag // Scope: TestClaim corpus for FieldPatch right-biased optional-value patch monoid laws. -// Owns: claim rows for compose_field_patch left/right identity, associativity; apply_field_patch behavior. +// Owns: claim rows for compose_field_patch left/right identity, associativity; apply_field_patch +// behavior; field_patch_monoid witness identity and op consumption. // Consumes: v4.std.patch v4.std.node v4.std.verification. // Status: T-4.16 follow-on behavior receipts; execution deferred to T-22 runner bridge. // Discovery: T-22 runner enumerates src/v4/test/claim/** recursively. module v4.test.claim.algebra_laws.field_patch_monoid -import v4.std.patch { FieldPatch, Override, Inherit, compose_field_patch, apply_field_patch } +import v4.std.patch { FieldPatch, Override, Inherit, compose_field_patch, apply_field_patch, field_patch_monoid } import v4.std.node { Atom, Node, Symbol, TypeNode } import v4.std.verification { CompilesClaim, @@ -35,14 +36,24 @@ fn fp_ok(b: Bool) -> Node { } +// Helpers that route through the monoid witness surface, not the raw helpers. +fn fp_monoid_op(left: FieldPatch, right: FieldPatch) -> FieldPatch { + let m = field_patch_monoid() + m.semigroup.magma.op(left, right) +} +fn fp_monoid_identity() -> FieldPatch { + field_patch_monoid().identity +} + + +// โ”€โ”€ Helper-level law witnesses (apply/compose directly) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + // Left identity: compose(Inherit, Override{v}) applies as Override{v}. data witness_left_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Inherit, right: Override { value: true })) == true - // Right identity: compose(Override{v}, Inherit) applies as Override{v}. data witness_right_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true - // Associativity: apply((aโˆ˜b)โˆ˜c, base) == apply(aโˆ˜(bโˆ˜c), base). // a=Override{true}, b=Override{false}, c=Inherit โ†’ both sides yield false from base=true. fn compose_assoc_lhs() -> Bool { @@ -53,15 +64,27 @@ fn compose_assoc_rhs() -> Bool { } data witness_associativity: Bool = compose_assoc_lhs() == compose_assoc_rhs() - // apply: Inherit defers to base. data witness_inherit_preserves: Bool = apply_field_patch(base: true, patch: Inherit) == true - // apply: Override replaces base. data witness_override_replaces: Bool = apply_field_patch(base: true, patch: Override { value: false }) == false +// โ”€โ”€ Monoid witness consumers (via field_patch_monoid().identity / .op) โ”€โ”€โ”€โ”€โ”€ + +// Witness: monoid identity element preserves base (identity == Inherit semantically). +data witness_monoid_identity_preserves: Bool = apply_field_patch(base: true, patch: fp_monoid_identity()) == true + +// Witness: monoid op left identity โ€” op(identity, Override{v}) applies as Override{v}. +data witness_monoid_left_identity: Bool = apply_field_patch(base: false, patch: fp_monoid_op(left: fp_monoid_identity(), right: Override { value: true })) == true + +// Witness: monoid op right identity โ€” op(Override{v}, identity) applies as Override{v}. +data witness_monoid_right_identity: Bool = apply_field_patch(base: false, patch: fp_monoid_op(left: Override { value: true }, right: fp_monoid_identity())) == true + + +// โ”€โ”€ Claims โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + data claim_left_identity: TestClaim = CompilesClaim { label: "field_patch/compose: Inherit is left identity", anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), @@ -105,3 +128,30 @@ data claim_override_replaces: TestClaim = CompilesClaim { expected_value: fp_pass_node(), classification: TestClassification { tier: Tier1, layer: Unit } } + + +data claim_monoid_identity_preserves: TestClaim = CompilesClaim { + label: "field_patch/monoid: identity element preserves base (Monoid witness)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_monoid_identity_preserves), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_monoid_left_identity: TestClaim = CompilesClaim { + label: "field_patch/monoid: op(identity, p) == p (Monoid witness left identity)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_monoid_left_identity), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + +data claim_monoid_right_identity: TestClaim = CompilesClaim { + label: "field_patch/monoid: op(p, identity) == p (Monoid witness right identity)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_monoid_right_identity), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} From d953a42e074b8a728a8d9f5f31e9950223462e9a Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 01:05:24 +0000 Subject: [PATCH 12/23] fix: remove explicit type args from field_patch_monoid calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DAG parser treats `f()` as a comparison expression, not a generic type application โ€” `Bool` is undefined as a variable. Drop the explicit type arguments; inference resolves T=Bool from the declared return types of fp_monoid_op and fp_monoid_identity. Co-Authored-By: Claude Sonnet 4.6 --- src/v4/test/claim/algebra_laws/field_patch_monoid.dag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index 53c050fd908..e3a9d6cc31c 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -38,11 +38,11 @@ fn fp_ok(b: Bool) -> Node { // Helpers that route through the monoid witness surface, not the raw helpers. fn fp_monoid_op(left: FieldPatch, right: FieldPatch) -> FieldPatch { - let m = field_patch_monoid() + let m = field_patch_monoid() m.semigroup.magma.op(left, right) } fn fp_monoid_identity() -> FieldPatch { - field_patch_monoid().identity + field_patch_monoid().identity } From 45e01ec37bab3affd70521b6f16d8bb3ba2cb05b Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:01:50 +0000 Subject: [PATCH 13/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../claim/algebra_laws/field_patch_monoid.dag | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index e3a9d6cc31c..de55ee70e08 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -1,7 +1,7 @@ // src/v4/test/claim/algebra_laws/field_patch_monoid.dag // Scope: TestClaim corpus for FieldPatch right-biased optional-value patch monoid laws. -// Owns: claim rows for compose_field_patch left/right identity, associativity; apply_field_patch -// behavior; field_patch_monoid witness identity and op consumption. +// Owns: claim rows for compose_field_patch left/right identity, right-bias (later Override wins), +// associativity; apply_field_patch behavior; field_patch_monoid witness identity and op consumption. // Consumes: v4.std.patch v4.std.node v4.std.verification. // Status: T-4.16 follow-on behavior receipts; execution deferred to T-22 runner bridge. // Discovery: T-22 runner enumerates src/v4/test/claim/** recursively. @@ -54,6 +54,9 @@ data witness_left_identity: Bool = apply_field_patch(base: false, patch: compose // Right identity: compose(Override{v}, Inherit) applies as Override{v}. data witness_right_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true +// Right-bias: compose(Override{left}, Override{right}) applies as Override{right} (later layer wins). +data witness_right_bias: Bool = apply_field_patch(base: true, patch: compose_field_patch(left: Override { value: true }, right: Override { value: false })) == false + // Associativity: apply((aโˆ˜b)โˆ˜c, base) == apply(aโˆ˜(bโˆ˜c), base). // a=Override{true}, b=Override{false}, c=Inherit โ†’ both sides yield false from base=true. fn compose_assoc_lhs() -> Bool { @@ -103,6 +106,15 @@ data claim_right_identity: TestClaim = CompilesClaim { } +data claim_right_bias: TestClaim = CompilesClaim { + label: "field_patch/compose: right Override wins over left Override (later layer)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_right_bias), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + data claim_associativity: TestClaim = CompilesClaim { label: "field_patch/compose: right-biased composition is associative", anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), From aee2ef22e9f216825fe66836dab9138d19f95cde Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:02:46 +0000 Subject: [PATCH 14/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/claim/algebra_laws/field_patch_monoid.dag | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index de55ee70e08..f6adbfe568b 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -85,6 +85,9 @@ data witness_monoid_left_identity: Bool = apply_field_patch(base: false, patch: // Witness: monoid op right identity โ€” op(Override{v}, identity) applies as Override{v}. data witness_monoid_right_identity: Bool = apply_field_patch(base: false, patch: fp_monoid_op(left: Override { value: true }, right: fp_monoid_identity())) == true +// Witness: monoid op right-bias โ€” op(Override{left}, Override{right}) applies as Override{right}. +data witness_monoid_right_bias: Bool = apply_field_patch(base: true, patch: fp_monoid_op(left: Override { value: true }, right: Override { value: false })) == false + // โ”€โ”€ Claims โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ @@ -167,3 +170,12 @@ data claim_monoid_right_identity: TestClaim = CompilesClaim { expected_value: fp_pass_node(), classification: TestClassification { tier: Tier1, layer: Unit } } + + +data claim_monoid_right_bias: TestClaim = CompilesClaim { + label: "field_patch/monoid: op(Override, Override) right-biased (later layer wins)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_monoid_right_bias), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} From 446f5924493dc16c27f896453abf71e5f86c4e10 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:01:50 +0000 Subject: [PATCH 15/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../claim/algebra_laws/field_patch_monoid.dag | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index e3a9d6cc31c..de55ee70e08 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -1,7 +1,7 @@ // src/v4/test/claim/algebra_laws/field_patch_monoid.dag // Scope: TestClaim corpus for FieldPatch right-biased optional-value patch monoid laws. -// Owns: claim rows for compose_field_patch left/right identity, associativity; apply_field_patch -// behavior; field_patch_monoid witness identity and op consumption. +// Owns: claim rows for compose_field_patch left/right identity, right-bias (later Override wins), +// associativity; apply_field_patch behavior; field_patch_monoid witness identity and op consumption. // Consumes: v4.std.patch v4.std.node v4.std.verification. // Status: T-4.16 follow-on behavior receipts; execution deferred to T-22 runner bridge. // Discovery: T-22 runner enumerates src/v4/test/claim/** recursively. @@ -54,6 +54,9 @@ data witness_left_identity: Bool = apply_field_patch(base: false, patch: compose // Right identity: compose(Override{v}, Inherit) applies as Override{v}. data witness_right_identity: Bool = apply_field_patch(base: false, patch: compose_field_patch(left: Override { value: true }, right: Inherit)) == true +// Right-bias: compose(Override{left}, Override{right}) applies as Override{right} (later layer wins). +data witness_right_bias: Bool = apply_field_patch(base: true, patch: compose_field_patch(left: Override { value: true }, right: Override { value: false })) == false + // Associativity: apply((aโˆ˜b)โˆ˜c, base) == apply(aโˆ˜(bโˆ˜c), base). // a=Override{true}, b=Override{false}, c=Inherit โ†’ both sides yield false from base=true. fn compose_assoc_lhs() -> Bool { @@ -103,6 +106,15 @@ data claim_right_identity: TestClaim = CompilesClaim { } +data claim_right_bias: TestClaim = CompilesClaim { + label: "field_patch/compose: right Override wins over left Override (later layer)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_right_bias), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} + + data claim_associativity: TestClaim = CompilesClaim { label: "field_patch/compose: right-biased composition is associative", anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), From 9c119e5d2e3630a97fbc39461231b9e26a0f89ce Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:02:46 +0000 Subject: [PATCH 16/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/claim/algebra_laws/field_patch_monoid.dag | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag index de55ee70e08..f6adbfe568b 100644 --- a/src/v4/test/claim/algebra_laws/field_patch_monoid.dag +++ b/src/v4/test/claim/algebra_laws/field_patch_monoid.dag @@ -85,6 +85,9 @@ data witness_monoid_left_identity: Bool = apply_field_patch(base: false, patch: // Witness: monoid op right identity โ€” op(Override{v}, identity) applies as Override{v}. data witness_monoid_right_identity: Bool = apply_field_patch(base: false, patch: fp_monoid_op(left: Override { value: true }, right: fp_monoid_identity())) == true +// Witness: monoid op right-bias โ€” op(Override{left}, Override{right}) applies as Override{right}. +data witness_monoid_right_bias: Bool = apply_field_patch(base: true, patch: fp_monoid_op(left: Override { value: true }, right: Override { value: false })) == false + // โ”€โ”€ Claims โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ @@ -167,3 +170,12 @@ data claim_monoid_right_identity: TestClaim = CompilesClaim { expected_value: fp_pass_node(), classification: TestClassification { tier: Tier1, layer: Unit } } + + +data claim_monoid_right_bias: TestClaim = CompilesClaim { + label: "field_patch/monoid: op(Override, Override) right-biased (later layer wins)", + anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), + input: fp_ok(b: witness_monoid_right_bias), + expected_value: fp_pass_node(), + classification: TestClassification { tier: Tier1, layer: Unit } +} From 58b93ed1cd107b83dc19ff6602c2d6c0e2d9c21e Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:16:33 +0000 Subject: [PATCH 17/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v4/extdeps/formatters/black.dag | 1 + src/v4/extdeps/formatters/gofmt.dag | 1 + src/v4/extdeps/formatters/google_java_format.dag | 1 + src/v4/std/patch.dag | 10 ++++++++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/v4/extdeps/formatters/black.dag b/src/v4/extdeps/formatters/black.dag index 3554a2ffee0..46503dfd261 100644 --- a/src/v4/extdeps/formatters/black.dag +++ b/src/v4/extdeps/formatters/black.dag @@ -93,6 +93,7 @@ data black_defaults: BlackConfig = BlackConfig { } +// ๐ŸŸก 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 target_version: FieldPatch diff --git a/src/v4/extdeps/formatters/gofmt.dag b/src/v4/extdeps/formatters/gofmt.dag index 6bd837cae78..1fbecba5ad8 100644 --- a/src/v4/extdeps/formatters/gofmt.dag +++ b/src/v4/extdeps/formatters/gofmt.dag @@ -13,6 +13,7 @@ type GofmtConfig {} data gofmt_defaults: GofmtConfig = GofmtConfig {} +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: GofmtConfigPatch projected from GofmtConfig field set. type GofmtConfigPatch {} diff --git a/src/v4/extdeps/formatters/google_java_format.dag b/src/v4/extdeps/formatters/google_java_format.dag index 6a28c5b3c62..530734afd5c 100644 --- a/src/v4/extdeps/formatters/google_java_format.dag +++ b/src/v4/extdeps/formatters/google_java_format.dag @@ -26,6 +26,7 @@ data google_java_format_defaults: GoogleJavaFormatConfig = GoogleJavaFormatConfi } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: GoogleJavaFormatConfigPatch projected from GoogleJavaFormatConfig field set. type GoogleJavaFormatConfigPatch { style: FieldPatch } diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index 566a444ee90..43a29fdd417 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -1,14 +1,15 @@ // src/v4/std/patch.dag // Scope: field-level overlay patch substrate โ€” per-field Override/Inherit coproduct for hierarchical config layering. -// Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid. +// Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid, field_patch_inherit. // Consumes: v4.std.algebra { Magma, Semigroup, Monoid }. -// Status: T-4.16 follow-on โ€” formatter ConfigPatch monoid substrate. +// Status: T-4.16 follow-on โ€” scalar FieldPatch monoid landed; per-record *ConfigPatch projection is ๐ŸŸก below. // Anchor: https://en.wikipedia.org/wiki/Monoid (NixOS module system / Home Manager override/inherit pattern) module v4.std.patch import v4.std.algebra { Magma, Semigroup, Monoid } +// ๐ŸŸก gated โ€” feature:config-patch-record-projection โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: record-field map derives each formatter *ConfigPatch and *_layer from *Config without hand-maintained parallel field lists; forbidden: ConfigPatch mirrors that can drift when Config gains a field. // ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. // FieldPatch = 1 + T: Inherit = absent/identity, Override = present payload. type FieldPatch @@ -16,6 +17,11 @@ type FieldPatch | Inherit +fn field_patch_inherit() -> FieldPatch { + Inherit +} + + fn apply_field_patch(base: T, patch: FieldPatch) -> T { match patch { Override { value: v } => v From fb9a2741c3630ce7cd499aa7bab56fbc38fae1e6 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:17:05 +0000 Subject: [PATCH 18/23] fix: gate ConfigPatch record mirrors under config-patch-record-projection Codex BLOCKING on PR #3761: scalar FieldPatch is sound but per-formatter *ConfigPatch types are hand-maintained mirrors of *Config. Add the owning feature gate in v4.std.patch (T-4.16 follow-on dissolve-on) and consumer tags on every formatter ConfigPatch until record-field projection lands. Co-authored-by: Cursor --- src/v4/extdeps/formatters/clang_format.dag | 1 + src/v4/extdeps/formatters/ktfmt.dag | 1 + src/v4/extdeps/formatters/lean4_format.dag | 1 + src/v4/extdeps/formatters/prettier.dag | 1 + src/v4/extdeps/formatters/rustfmt.dag | 1 + src/v4/extdeps/formatters/swift_format.dag | 1 + 6 files changed, 6 insertions(+) diff --git a/src/v4/extdeps/formatters/clang_format.dag b/src/v4/extdeps/formatters/clang_format.dag index a48cf60e205..9233ad915c9 100644 --- a/src/v4/extdeps/formatters/clang_format.dag +++ b/src/v4/extdeps/formatters/clang_format.dag @@ -1031,6 +1031,7 @@ data clang_format_defaults: ClangFormatConfig = ClangFormatConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: ClangFormatConfigPatch projected from ClangFormatConfig field set. type ClangFormatConfigPatch { access_modifier_offset: FieldPatch align_after_open_bracket: FieldPatch diff --git a/src/v4/extdeps/formatters/ktfmt.dag b/src/v4/extdeps/formatters/ktfmt.dag index 84acc05b66e..0855709fe7e 100644 --- a/src/v4/extdeps/formatters/ktfmt.dag +++ b/src/v4/extdeps/formatters/ktfmt.dag @@ -101,6 +101,7 @@ data ktfmt_defaults: KtfmtConfig = KtfmtConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: KtfmtConfigPatch projected from KtfmtConfig field set. type KtfmtConfigPatch { style: FieldPatch max_width: FieldPatch diff --git a/src/v4/extdeps/formatters/lean4_format.dag b/src/v4/extdeps/formatters/lean4_format.dag index e0c5cb1f3fa..5fb101d86b7 100644 --- a/src/v4/extdeps/formatters/lean4_format.dag +++ b/src/v4/extdeps/formatters/lean4_format.dag @@ -76,6 +76,7 @@ data lean4_format_defaults: Lean4FormatConfig = Lean4FormatConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: Lean4FormatConfigPatch projected from Lean4FormatConfig field set. type Lean4FormatConfigPatch { format_width: FieldPatch format_indent: FieldPatch diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index c36a3143673..a991308c540 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -202,6 +202,7 @@ data prettier_defaults: PrettierConfig = PrettierConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: PrettierConfigPatch projected from PrettierConfig field set. type PrettierConfigPatch { print_width: FieldPatch tab_width: FieldPatch diff --git a/src/v4/extdeps/formatters/rustfmt.dag b/src/v4/extdeps/formatters/rustfmt.dag index 0b6fe7be77a..0fa76d1028b 100644 --- a/src/v4/extdeps/formatters/rustfmt.dag +++ b/src/v4/extdeps/formatters/rustfmt.dag @@ -332,6 +332,7 @@ data rustfmt_defaults: RustfmtConfig = RustfmtConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: RustfmtConfigPatch projected from RustfmtConfig field set. type RustfmtConfigPatch { indent_style: FieldPatch tab_spaces: FieldPatch diff --git a/src/v4/extdeps/formatters/swift_format.dag b/src/v4/extdeps/formatters/swift_format.dag index 6d450152a75..3db6c546cfa 100644 --- a/src/v4/extdeps/formatters/swift_format.dag +++ b/src/v4/extdeps/formatters/swift_format.dag @@ -115,6 +115,7 @@ data swift_format_defaults: SwiftFormatConfig = SwiftFormatConfig { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: SwiftFormatConfigPatch projected from SwiftFormatConfig field set. type SwiftFormatConfigPatch { version: FieldPatch line_length: FieldPatch From b158710bf35a65c198b1e1543eca1c85601345a9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:35:54 +0000 Subject: [PATCH 19/23] fix: clarify patch anchor and config-patch-record-projection owner Claude REQUEST_CHANGES on #3761: drop misleading NixOS/Home Manager anchor (implementation is right-biased optional-value monoid, not commutative mkForce/mkDefault). Tighten feature gate wording and add T-4.16 TASKS.md owner row for interim *ConfigPatch hand mirrors. Co-authored-by: Cursor --- src/v4/TASKS.md | 1 + src/v4/std/patch.dag | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/v4/TASKS.md b/src/v4/TASKS.md index 2e273a438b9..bab05b679d4 100644 --- a/src/v4/TASKS.md +++ b/src/v4/TASKS.md @@ -1824,6 +1824,7 @@ are already landed on main โ€” see PRs #3650, #3651, #3652.) types (per-field `Override/Inherit` coproduct) are ๐ŸŸก gated โ€” feature: `formatter-config-patch` โ€” dissolve when consumers need partial override without full-config specification. +- **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 diff --git a/src/v4/std/patch.dag b/src/v4/std/patch.dag index 43a29fdd417..b08c977e9b2 100644 --- a/src/v4/std/patch.dag +++ b/src/v4/std/patch.dag @@ -3,13 +3,13 @@ // Owns: FieldPatch, apply_field_patch, compose_field_patch, field_patch_monoid, field_patch_inherit. // Consumes: v4.std.algebra { Magma, Semigroup, Monoid }. // Status: T-4.16 follow-on โ€” scalar FieldPatch monoid landed; per-record *ConfigPatch projection is ๐ŸŸก below. -// Anchor: https://en.wikipedia.org/wiki/Monoid (NixOS module system / Home Manager override/inherit pattern) +// Anchor: https://en.wikipedia.org/wiki/Monoid module v4.std.patch import v4.std.algebra { Magma, Semigroup, Monoid } -// ๐ŸŸก gated โ€” feature:config-patch-record-projection โ€” bind T-4.16 follow-on โ€” dissolve-on-arrival: record-field map derives each formatter *ConfigPatch and *_layer from *Config without hand-maintained parallel field lists; forbidden: ConfigPatch mirrors that can drift when Config gains a field. +// ๐ŸŸก gated โ€” feature:config-patch-record-projection โ€” bind src/v4/TASKS.md ยงT-4.16 โ€” dissolve-on-arrival: record-field map derives *ConfigPatch and *_layer from *Config; interim consumer-tagged hand mirrors only while this feature is open; forbidden: untagged mirrors after projection lands. // ๐ŸŸข coproduct dissolution โ€” CP-T416-FPATCH-TERMINAL. // FieldPatch = 1 + T: Inherit = absent/identity, Override = present payload. type FieldPatch From 81db78f5b42f181bc2c6b4493fa1cb34609ebe55 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:40:28 +0000 Subject: [PATCH 20/23] =?UTF-8?q?WIP:=20PR=20#3705:=20add=20right-bias=20T?= =?UTF-8?q?estClaim=20to=20field=5Fpatch=5Fmonoid=20=E2=80=94=20openai-pro?= =?UTF-8?q?=20RC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/v4/TASKS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v4/TASKS.md b/src/v4/TASKS.md index bab05b679d4..68c077f00b8 100644 --- a/src/v4/TASKS.md +++ b/src/v4/TASKS.md @@ -1809,7 +1809,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` 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.) From 69dd5d8e2c10f3d87d6fcc065b0c69e378f40ff0 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 17:40:35 +0000 Subject: [PATCH 21/23] fix(T-4.16): align TASKS.md layering contract with ConfigPatch model Codex REQUEST_CHANGES on #3705: TASKS.md still described superseded *_layer(base, outer) full-config replacement while formatter files now use *_layer(base, patch: *ConfigPatch) with v4.std.patch FieldPatch. Co-authored-by: Cursor --- src/v4/TASKS.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/v4/TASKS.md b/src/v4/TASKS.md index 68c077f00b8..2e3ef77aab4 100644 --- a/src/v4/TASKS.md +++ b/src/v4/TASKS.md @@ -1819,12 +1819,14 @@ 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 From 0f2f896c22abc48ea0d0c71cf3675c8727728795 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Wed, 27 May 2026 18:00:59 +0000 Subject: [PATCH 22/23] fix(prettier): align PrettierConfigPatch with PrettierConfig shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex REQUEST_CHANGES #3761: stop flattening PrettierFormattingOptions fields into PrettierConfigPatch. Introduce PrettierFormattingOptionsPatch nested under options; overrides stays FieldPatch> โ€” matches PrettierConfig { options, overrides } for P2 / projection contract. Co-authored-by: Cursor --- src/v4/extdeps/formatters/prettier.dag | 67 +++++++++++++++----------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index a991308c540..2a32d9960bd 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -1,6 +1,6 @@ // src/v4/extdeps/formatters/prettier.dag // Scope: Prettier configuration file model (.prettierrc / package.json "prettier"). -// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierFormattingOptions, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, PrettierConfigPatch, prettier_layer. +// Owns: PrettierTrailingComma, PrettierQuoteProps, PrettierArrowParens, PrettierProseWrap, PrettierHtmlWhitespaceSensitivity, PrettierEndOfLine, PrettierEmbeddedLanguageFormatting, PrettierObjectWrap, PrettierExperimentalOperatorPosition, PrettierParser, PrettierFormattingOptions, PrettierFormattingOptionsPatch, PrettierOverrideOptions, PrettierOverrideEntry, PrettierConfig, prettier_defaults, PrettierConfigPatch, prettier_layer. // Consumes: v4.std.collection { List }, v4.std.patch { FieldPatch, apply_field_patch }. // Status: T-4.16 scaffold โ€” Prettier stable config/options docs (v3 defaults). // Anchor: https://prettier.io/docs/configuration @@ -202,8 +202,8 @@ data prettier_defaults: PrettierConfig = PrettierConfig { } -// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: PrettierConfigPatch projected from PrettierConfig field set. -type PrettierConfigPatch { +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: PrettierFormattingOptionsPatch projected from PrettierFormattingOptions field set. +type PrettierFormattingOptionsPatch { print_width: FieldPatch tab_width: FieldPatch use_tabs: FieldPatch @@ -227,37 +227,48 @@ type PrettierConfigPatch { embedded_language_formatting: FieldPatch experimental_ternaries: FieldPatch experimental_operator_position: FieldPatch +} + + +fn apply_prettier_formatting_options_patch(base: PrettierFormattingOptions, patch: PrettierFormattingOptionsPatch) -> PrettierFormattingOptions { + PrettierFormattingOptions { + print_width: apply_field_patch(base: base.print_width, patch: patch.print_width), + tab_width: apply_field_patch(base: base.tab_width, patch: patch.tab_width), + use_tabs: apply_field_patch(base: base.use_tabs, patch: patch.use_tabs), + semi: apply_field_patch(base: base.semi, patch: patch.semi), + single_quote: apply_field_patch(base: base.single_quote, patch: patch.single_quote), + quote_props: apply_field_patch(base: base.quote_props, patch: patch.quote_props), + jsx_single_quote: apply_field_patch(base: base.jsx_single_quote, patch: patch.jsx_single_quote), + trailing_comma: apply_field_patch(base: base.trailing_comma, patch: patch.trailing_comma), + bracket_spacing: apply_field_patch(base: base.bracket_spacing, patch: patch.bracket_spacing), + object_wrap: apply_field_patch(base: base.object_wrap, patch: patch.object_wrap), + bracket_same_line: apply_field_patch(base: base.bracket_same_line, patch: patch.bracket_same_line), + arrow_parens: apply_field_patch(base: base.arrow_parens, patch: patch.arrow_parens), + require_pragma: apply_field_patch(base: base.require_pragma, patch: patch.require_pragma), + insert_pragma: apply_field_patch(base: base.insert_pragma, patch: patch.insert_pragma), + check_ignore_pragma: apply_field_patch(base: base.check_ignore_pragma, patch: patch.check_ignore_pragma), + prose_wrap: apply_field_patch(base: base.prose_wrap, patch: patch.prose_wrap), + html_whitespace_sensitivity: apply_field_patch(base: base.html_whitespace_sensitivity, patch: patch.html_whitespace_sensitivity), + vue_indent_script_and_style: apply_field_patch(base: base.vue_indent_script_and_style, patch: patch.vue_indent_script_and_style), + single_attribute_per_line: apply_field_patch(base: base.single_attribute_per_line, patch: patch.single_attribute_per_line), + end_of_line: apply_field_patch(base: base.end_of_line, patch: patch.end_of_line), + embedded_language_formatting: apply_field_patch(base: base.embedded_language_formatting, patch: patch.embedded_language_formatting), + experimental_ternaries: apply_field_patch(base: base.experimental_ternaries, patch: patch.experimental_ternaries), + experimental_operator_position: apply_field_patch(base: base.experimental_operator_position, patch: patch.experimental_operator_position), + } +} + + +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: PrettierConfigPatch projected from PrettierConfig field set (options + overrides). +type PrettierConfigPatch { + options: PrettierFormattingOptionsPatch overrides: FieldPatch> } fn prettier_layer(base: PrettierConfig, patch: PrettierConfigPatch) -> PrettierConfig { PrettierConfig { - options: PrettierFormattingOptions { - print_width: apply_field_patch(base: base.options.print_width, patch: patch.print_width), - tab_width: apply_field_patch(base: base.options.tab_width, patch: patch.tab_width), - use_tabs: apply_field_patch(base: base.options.use_tabs, patch: patch.use_tabs), - semi: apply_field_patch(base: base.options.semi, patch: patch.semi), - single_quote: apply_field_patch(base: base.options.single_quote, patch: patch.single_quote), - quote_props: apply_field_patch(base: base.options.quote_props, patch: patch.quote_props), - jsx_single_quote: apply_field_patch(base: base.options.jsx_single_quote, patch: patch.jsx_single_quote), - trailing_comma: apply_field_patch(base: base.options.trailing_comma, patch: patch.trailing_comma), - bracket_spacing: apply_field_patch(base: base.options.bracket_spacing, patch: patch.bracket_spacing), - object_wrap: apply_field_patch(base: base.options.object_wrap, patch: patch.object_wrap), - bracket_same_line: apply_field_patch(base: base.options.bracket_same_line, patch: patch.bracket_same_line), - arrow_parens: apply_field_patch(base: base.options.arrow_parens, patch: patch.arrow_parens), - require_pragma: apply_field_patch(base: base.options.require_pragma, patch: patch.require_pragma), - insert_pragma: apply_field_patch(base: base.options.insert_pragma, patch: patch.insert_pragma), - check_ignore_pragma: apply_field_patch(base: base.options.check_ignore_pragma, patch: patch.check_ignore_pragma), - prose_wrap: apply_field_patch(base: base.options.prose_wrap, patch: patch.prose_wrap), - html_whitespace_sensitivity: apply_field_patch(base: base.options.html_whitespace_sensitivity, patch: patch.html_whitespace_sensitivity), - vue_indent_script_and_style: apply_field_patch(base: base.options.vue_indent_script_and_style, patch: patch.vue_indent_script_and_style), - single_attribute_per_line: apply_field_patch(base: base.options.single_attribute_per_line, patch: patch.single_attribute_per_line), - end_of_line: apply_field_patch(base: base.options.end_of_line, patch: patch.end_of_line), - embedded_language_formatting: apply_field_patch(base: base.options.embedded_language_formatting, patch: patch.embedded_language_formatting), - experimental_ternaries: apply_field_patch(base: base.options.experimental_ternaries, patch: patch.experimental_ternaries), - experimental_operator_position: apply_field_patch(base: base.options.experimental_operator_position, patch: patch.experimental_operator_position), - }, + options: apply_prettier_formatting_options_patch(base: base.options, patch: patch.options), overrides: apply_field_patch(base: base.overrides, patch: patch.overrides), } } From 23c0b83b65991c22af7eef45877e6f525d8a63c9 Mon Sep 17 00:00:00 2001 From: Brian Searls Date: Thu, 28 May 2026 01:29:47 +0000 Subject: [PATCH 23/23] WIP: PR #3761 cursor RC fix: T-4.16 formatter ConfigPatch monoid + right-bias --- src/v4/extdeps/formatters/prettier.dag | 1 + 1 file changed, 1 insertion(+) diff --git a/src/v4/extdeps/formatters/prettier.dag b/src/v4/extdeps/formatters/prettier.dag index 2a32d9960bd..a400fd6193e 100644 --- a/src/v4/extdeps/formatters/prettier.dag +++ b/src/v4/extdeps/formatters/prettier.dag @@ -128,6 +128,7 @@ type PrettierFormattingOptions { } +// ๐ŸŸก gated โ€” consumer:config-patch-record-projection โ€” bind v4.std.patch feature:config-patch-record-projection โ€” dissolve-on-arrival: PrettierOverrideOptions projected from PrettierFormattingOptions field set plus parser override field. type PrettierOverrideOptions { parser: FieldPatch print_width: FieldPatch