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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module gunbc.recurring_failure_mode.service_interface_member_has_no_carrier

import std.types { NonEmptyStr }
import std.decl_ref { DeclarationRef, WholeDeclaration }
import gunbc.recurring_failure_mode { RecurringFailureMode }

data service_interface_member_has_no_carrier: RecurringFailureMode = RecurringFailureMode {
identity: "service_interface_member_has_no_carrier" as NonEmptyStr,

receipts: [
"INVALID STATE: an interface fact of a v2 service declaration has no typed carrier, so the declaration-grade lowering (`v2.compiler.body_lowering_fold` `body_lower_service_decl`) cannot lower it with the interface. The members are the operation modifiers `readonly` / `idempotent` / `hermetic` and an io field's `from \"key\"` wire-key and `= default` tails. They are set aside as `body_lowering_reason_interface_member_unmodeled`, typed, located and counted apart from the realization members (`body_lowering_reason_realization_member_set_aside`: transport, config, exit, response, mock_response), which are realization per DESIGN section 3 and are never part of the interface.",
"HARM: these are safety-relevant interface facts, not decoration. `idempotent` decides whether an automatic retry is admissible (DESIGN section 4b names a non-idempotent effect under retry as a class the ladder must reach), and a `from` key decides which wire field fills a declared output. A consumer that read the lowered interface without them would retry what it must not, or read a field it was not given.",
"CONTAINED, NOT SILENT: a set-aside member is unreachable as lowered, by construction. The lowering builds the set-aside population as a typed list (`ServiceSetAside`), and only census grade (`v2.compiler.normalize` `normalize_census`, whose carrier has no route past the symbol index) admits it as located advisories. Every other route refuses the service as `body_lowering_reason_service_realization_unreachable`, with each member's own located diagnostic pending, so no stage that would act on a service can assume a modifier's absence or a default transport.",
"RELATED FRONTIER ON THE SAME LOWERING: a service's name is lowered as ONE label with the whole declared spelling (`shell.Find`) rather than a per-segment spine, because sixteen services in `dag/extdeps/shell.dag` share the `shell` prefix and a spine needs a prefix merge in `v2.compiler.namespace_graft`. The dotted label hides named parts (DESIGN section 2) and a dotted reference to it does not resolve. TRIGGER: v2 resolving service CALLS; then the spine plus a graft prefix merge is the required shape, and the label migrates in one transition.",
"RUNG FOUND AT: mitigated (typed, located, counted set-aside; full normalize refuses). CEILING: structurally impossible -- each modifier and wire-key is a field of a typed operation carrier, so a lowered operation cannot exist without them. NEXT-RUNG TRIGGER, NAMING THE CAPABILITY: a typed operation-modifier carrier (and io wire-key / default carrier) in the v2 interface model that `body_lower_service_decl` lowers onto, so that every interface member of every service in the corpus lowers with the interface and `body_lowering_reason_interface_member_unmodeled` has no producer.",
],

evidence: [
DeclarationRef { module_path: "v2.test.claim.normalize.service_declaration_lowering", decl_name: "census_counts_realization_and_unmodeled_interface_apart_holds", field: WholeDeclaration },
DeclarationRef { module_path: "v2.test.claim.normalize.service_declaration_lowering", decl_name: "full_door_refuses_a_service_with_a_set_aside_realization_holds", field: WholeDeclaration },
],
}
6 changes: 6 additions & 0 deletions src/v2/compiler/03_normalize.dag
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import v2.compiler.body_lowering_fold {
no_wrapper_retentions,
wrapper_retentions_concat,
body_lower_fn_decl_to_census_arrow,
body_lower_service_decl,
body_lower_is_deferred_lower_at_normalize,
body_lower_type_decl_record_name_optional
}
Expand Down Expand Up @@ -463,6 +464,11 @@ fn normalize_census_node(n: Node, under_fn_decl: Bool) -> Outcome<BodyLoweredTre
Present { value: emitted } =>
if (emitted == ^dag_surface_data_decl) || (emitted == ^dag_surface_test_fn_decl) {
Accepted { value: body_lowered_tree_over(node: n, retained: no_wrapper_retentions()), diagnostics: None }
} else if emitted == ^dag_surface_service_decl {
body_lowered_tree_then(
t: body_lowered_tree_over(node: n, retained: no_wrapper_retentions()),
f: fn(shell) { body_lower_service_decl(shell: shell, admit_set_aside: true) }
)
} else if emitted == ^dag_surface_fn_decl {
match normalize_census_fold_children(n: n, under_fn_decl: true) {
Rejected { diagnostics: r } => Rejected { diagnostics: r }
Expand Down
Loading