Skip to content

SG-6: BoundedLattice instance completeness gate in 04_infer - #4085

Merged
briansrls merged 17 commits into
mainfrom
session/lively-eagle-677
May 31, 2026
Merged

briansrls merged 17 commits into
mainfrom
session/lively-eagle-677

Conversation

@briansrls

@briansrls briansrls commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds the SG-6 BoundedLattice instance completeness gate per PR #3938 §10.3b:

  • src/v4/std/algebra.dag: substrate helpers (bounded_lattice_instance_completeness, shape detection via nested lattice.meet / lattice.join field paths) — authority for which witnesses must be populated.
  • src/v4/compiler/04_infer.dag: fail-closed gate in infer_node_facts rejecting partial instances with infer_bounded_lattice_partial_instance; exported infer_bounded_lattice_consumer_gate for consumer-site diagnostics (infer_bounded_lattice_consumer_partial).
  • src/v4/test/claim/manual/infer_bounded_lattice_completeness_anchor.dag: falsification probe — complete instance passes, missing-meet instance rejected, consumer reference rejected.

Emit is untouched (Compiler Spine lane only); incomplete instances surface typed infer diagnostics instead of relying on silent compile_error! stubs downstream.

Test plan

  • cargo test -p v3-compiler v4_std_model_core_dag_smoke — algebra.dag parses and structural receipts pass (9/9)
  • cargo build -p v2-compiler --release — bootstrap compiler builds
  • Compile anchor: infer_bounded_lattice_completeness_anchor.dag (T-22 runner execution deferred; compile-only receipts per sibling infer anchors)

@briansrls briansrls changed the title SG-6 BoundedLattice instance completeness gate per PR #3938 §10.3b: add 04_infer instance-completeness check requiring BoundedLattice instances to populate meet/join witnesses OR surface a typed partial-instance diagnostic at consumer sites. NO silent compile_error! stubs in emit (P3 fail-closed; CO SG-6: BoundedLattice instance completeness gate in 04_infer May 31, 2026
@briansrls
briansrls marked this pull request as ready for review May 31, 2026 04:31
@briansrls

Copy link
Copy Markdown
Contributor Author

Review response (24bc463)

Addressed all raised findings in the latest push:

Consumer gate wired through infer() (cursor + claude)

  • partial_bounded_lattice_instances_in_tree pre-collects partial BL instances across the full ResolvedTree.
  • infer_node_facts(n, partials) now runs infer_bounded_lattice_consumer_gate before descent/constraints — consumer references to a partial instance reject at the consumer locus with infer_bounded_lattice_consumer_partial.
  • Declaration-site rejection removed from the main path; partial instances are tagged via collection, consumers fail closed.

Falsification probe end-to-end (cursor)

  • Anchor adds anchor_module_with_partial_and_consumer and anchor_infer_rejects_consumer_tree = infer(tree: …) plus anchor_infer_consumer_tree_rejects receipt.

Diagnostic payloads (claude)

  • infer_bounded_lattice_missing_reason maps MissingMeet / MissingJoin / MissingLatticeField to distinct reason symbols (witness threaded into the diagnostic reason, not dropped).
  • Consumer diagnostic embeds the referenced instance via Suggested { node: instance }.

Algebra trichotomy + tags (cursor + claude)

  • BoundedLatticeInstanceCompleteness now has NotBoundedLatticeInstance | BoundedLatticeComplete | BoundedLatticePartial — non-BL nodes no longer masquerade as complete.
  • Added 🟢 dissolution tags on new coproducts; 🟡 tag on conj_has_unique_named_child.
  • bounded_lattice_instance_is_partial retained and used by the partial-instance collection fold.

Tests

  • cargo test -p v3-compiler v4_std_model_core_dag_smoke — 9/9 pass (algebra.dag parses cleanly).

— sent from lively-eagle-677

briansrls and others added 2 commits May 31, 2026 04:43
Inline bounded-lattice shape checks into bounded_lattice_instance_completeness,
match completeness directly in infer partial collection, and simplify
partial_bounded_lattice_reference with any().

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Review response (8c7ecfd)

bounded_lattice_instance_is_partial (claude + cursor) — fixed

Deleted the helper. infer_partial_bounded_lattice_instances_fold_init now matches directly on bounded_lattice_instance_completeness, returning [n] only for BoundedLatticePartial.

bounded_lattice_instance_shape (cursor) — fixed

Deleted the composite Bool predicate. Shape checks are inlined into bounded_lattice_instance_completeness via the existing 🟡-gated conj_has_unique_named_child calls inside the completeness match path — no parallel exported Bool authority.

partial_bounded_lattice_reference nested fold (claude) — fixed

Replaced inner fold with any(xs: partials, predicate: fn(p) { e.target == p }).

Anchor updated: anchor_bounded_lattice_completeness_classifies_instances replaces the removed shape helper receipt.

Tests: cargo test -p v3-compiler v4_std_model_core_dag_smoke — 9/9 pass.

— sent from lively-eagle-677

briansrls and others added 4 commits May 31, 2026 04:49
v2 bootstrap maps Optional to Some/None; Absent/Present from
collection.dag collided with LoopMeasureTargetLookup during lens-ci
semantic compile. Consumer gate now folds directly to Outcome.

Co-authored-by: Cursor <cursoragent@cursor.com>
Consumer-site rejection is wired in infer_node_facts; the exported
instance gate remains for falsification probes only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

claude APPROVE (22725) — verified on latest HEAD

  1. Instance gate not in main pipeline — intentional per SG-6 §10.3b (consumer-site diagnostics). Added a two-line comment above infer_bounded_lattice_instance_gate in 04_infer.dag so the export/anchor path vs infer_node_facts consumer gate is explicit.

  2. Duplicate child traversals in bounded_lattice_instance_completeness — agreed, non-blocking. The 🟡 conj_has_unique_named_child predicate already carries a named dissolve trigger (substrate-derived name_occurrences==1 projection) that collapses into conj_named_child_lookup; no separate refactor in this PR.

— sent from lively-eagle-677

When a consumer references multiple partial BoundedLattice instances,
append each rejection via non_empty_diagnostics_append instead of
pinning the first partial edge only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

claude APPROVE (22728) + cursor APPROVE (22729) — verified on e1263e419

22728 observations (non-blocking, no code change):

  1. NamedChildAmbiguous → MissingMeet/MissingJoin — intentional for SG-6 gate classification: any inner meet/join field that is not uniquely present counts as partial (same accept/reject bucket as absence). Outer-field ambiguity is filtered to NotBoundedLatticeInstance by the shape pre-check; inner ambiguity only arises on duplicate meet/join edges inside lattice, which are incomplete instances for consumer-gate purposes. A distinct Ambiguous* witness variant would be a follow-on if we want finer diagnostic copy, not required for this gate.

  2. Two-pass shape check + lookup — acknowledged; covered by the 🟡 conj_has_unique_named_child dissolve trigger (substrate-derived name_occurrences==1 projection → dispatch on conj_named_child_lookup only).

  3. 🟡 predicate disposition — confirmed: feature/bind/dissolve-on-arrival/forbidden-parallel clause present at algebra.dag:631.

22729: No findings; Empty import left as-is per no-nit rule.

Diagnostic coalescing across multiple partial consumer edges landed in e1263e419.

— sent from lively-eagle-677

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-pro
  • Commit: e1263e41 · Trigger: manual
  • Comparison: main @ 78b9698a ... session/lively-eagle-677 @ e1263e41
  • Conversation: View conversation

1. Story of the diff

This PR adds a BoundedLattice completeness classifier in src/v4/std/algebra.dag, then threads that classifier into src/v4/compiler/04_infer.dag so inference can collect partial BoundedLattice instance nodes across the resolved tree and reject nodes that consume one of those partial instances. The load-bearing path is: bounded_lattice_instance_completeness classifies a Node as non-instance, complete, or partial; partial_bounded_lattice_instances_in_tree folds the resolved tree to collect partials; infer_node_facts calls infer_bounded_lattice_consumer_gate before descent/constraint solving; and the new manual anchor constructs complete/partial examples plus a consumer tree to keep the surfaces compile-visible. chatgpt-review-b22839cf-30b6-4c…

chatgpt-review-b22839cf-30b6-4c…

The intended shape is good: the algebra module owns the BoundedLattice field-path interpretation, while infer owns the diagnostic gate. The implementation has two semantic holes, though: the consumer gate currently treats any parent edge to a partial instance as a consumer edge, and the MissingLatticeField partial case introduced by the PR is unreachable because the top-level classifier requires a unique lattice field before entering the branch that could report it.

2. Invariant categories

1. LAYER MODEL substrate vs implementation

Finding — BLOCKING. src/v4/std/algebra.dag:688-699: bounded_lattice_instance_completeness introduces substrate-visible completeness states, including MissingLatticeField, but the top-level guard at src/v4/std/algebra.dag:689 requires conj_has_unique_named_child(... bounded_lattice_field_lattice) before the function can reach the NamedChildMissing => BoundedLatticePartial { missing: MissingLatticeField } arm at src/v4/std/algebra.dag:695. If the lattice field is absent or ambiguous, the function falls to NotBoundedLatticeInstance at src/v4/std/algebra.dag:699, so a declared partial instance with missing lattice witness is silently removed from the partial-instance gate rather than failing closed with the diagnostic family this PR adds at src/v4/compiler/04_infer.dag:127. This is substrate modeling, not local implementation detail: the classifier is the single authority consumed by infer. chatgpt-review-b22839cf-30b6-4c…

2. INVARIANTS.md + modeling-discipline.md

Finding — BLOCKING. src/v4/compiler/04_infer.dag:222-241: the comment at src/v4/compiler/04_infer.dag:208 states “consumer-site gate only — partial declarations are tagged, not rejected here,” but the gate rejects whenever any consumer.children edge has a target equal to a partial instance. That uses raw child containment as the consumer relation, so a module/declaration container that merely has a named declaration edge to a partial instance is treated as a consumer. The anchor itself demonstrates the ambiguous shape: src/v4/test/claim/manual/infer_bounded_lattice_completeness_anchor.dag:117-119 adds a declaration edge directly to anchor_partial_bounded_lattice_instance, and src/v4/test/claim/manual/infer_bounded_lattice_completeness_anchor.dag:168 only asserts the whole tree rejects, not that the rejection comes from the actual consumer edge. This violates Boundary Discipline / API-level enforcement: the code needs a typed “consumes algebra instance” relation, or at least must filter out declaration/containment edges, instead of using all child edges as a proxy. chatgpt-review-b22839cf-30b6-4c…

chatgpt-review-b22839cf-30b6-4c…

3. CODING.md

Compliant. The new production code is data + free functions over explicit inputs (instance, consumer, partials, tree), with typed result carriers (Outcome<Node>, BoundedLatticeInstanceCompleteness) rather than booleans or sentinel strings; the comments that remain on the new gate are narrow boundary comments explaining SG-6 scope.

4. TESTING.md

Finding — BLOCKING as regression coverage for the two bugs above. The added anchor only covers the “missing meet” happy-negative path (src/v4/test/claim/manual/infer_bounded_lattice_completeness_anchor.dag:142-148) and a whole-tree rejection (src/v4/test/claim/manual/infer_bounded_lattice_completeness_anchor.dag:168-179). It does not assert that a top/bottom-only BoundedLattice-shaped declaration is classified as BoundedLatticePartial { missing: MissingLatticeField }, and it does not assert that a tree containing a partial declaration but no consumer remains accepted/tagged. Because this PR’s purpose is a fail-closed completeness gate, those are behavior-level regression claims that should land with the fix. chatgpt-review-b22839cf-30b6-4c…

5. LOCKED DESIGN DECISIONS

N/A — the diff does not alter a locked design doc or change a locked substrate shape such as the six type connectives / five behavior substrate; it adds a classifier and infer gate within existing Node/Conj modeling.

6. TRACKED vs UNTRACKED DEBT

Compliant. The visible new scaffold is the predicate-dissolution tag on conj_has_unique_named_child at src/v4/std/algebra.dag:631, which names the gate as feature:conj-has-unique-named-child-predicate, binds it to node://sg6-bl-completeness, and gives a dissolve-on-arrival trigger. The manual claim file also labels itself as compile-only with execution deferred to T-22, so the temporary test-runner limitation is at least explicitly bounded in-file. chatgpt-review-b22839cf-30b6-4c…

chatgpt-review-b22839cf-30b6-4c…

2.5. Top-down PM intent review

Finding — BLOCKING. The PR’s own in-diff intent says the SG-6 gate is “consumer-site gate only” and that partial declarations are “tagged, not rejected here” at src/v4/compiler/04_infer.dag:208, but the implementation at src/v4/compiler/04_infer.dag:222-241 rejects any node whose child edge target is in partials, regardless of whether that edge is a declaration/containment edge or an actual consuming reference. That semantic dilution matters at PM level: a worker following this implementation faithfully would make “declaring a partial BoundedLattice instance inside a tree” operationally equivalent to “consuming a partial BoundedLattice instance,” which is not the contract the PR states. chatgpt-review-b22839cf-30b6-4c…

3. Verdict

REQUEST_CHANGES. The direction is right, but the merge would ship a gate that both over-rejects declaration containers and under-detects the missing-lattice-field case it explicitly models. Both issues sit on substrate/infer boundary semantics, so they should be fixed before landing.

@briansrls

Copy link
Copy Markdown
Contributor Author

openai-pro REQUEST_CHANGES (22732) — addressed in latest push

  1. MissingLatticeField unreachable — fixed. bounded_lattice_instance_completeness now keys the BL shell on unique top/bottom, then dispatches on lattice lookup; absent/ambiguous lattice yields BoundedLatticePartial { missing: MissingLatticeField } instead of NotBoundedLatticeInstance.

  2. Consumer gate over-rejects declaration containers — fixed. infer_edge_consumes_bounded_lattice_partial filters to algebra-use edge labels (inhabitant_edge, algebra_edge, lattice_field_meet/join, boolean_algebra_field_bounded_lattice); module declaration siblings no longer trigger rejection. Anchor consumer now uses inhabitant_edge (typed use reference).

  3. Anchor regression gaps — fixed. Added anchor_partial_missing_lattice_field_instance, anchor_module_with_partial_only, anchor_module_partial_only_consumer_gate_accepts, and anchor_partials_collected_from_partial_only_module.

v4 bootstrap compile verified locally.

— sent from lively-eagle-677

@briansrls
briansrls merged commit 2ac52f2 into main May 31, 2026
briansrls added a commit that referenced this pull request May 31, 2026
… split + dispatch board + watchlist

Applies operator feedback on the dep graph refresh:
- §1 top table: P2 row renamed "TECHNICAL-PROVEN / AUTHORITY-BLOCKED" so the split between technical proof and authority deletion is visible at the top; P5 row reframed as two-bundle ("fixture/law" + "authority gate") to prevent "Wa-2 LANDED → P5 GREEN" misreads.
- §3.2 P2: explicit Layer 1 / Layer 2 framing matching the top table; P2-B authorization listed as decision-node.
- §3.3 P3 table: adds `state` column (routed / worksheet-needed / authoring / in-review / route-pending) + explanatory note on the 9-rows-for-8-classes structure cursor flagged on the prior commit.
- §3.5 P5: Layer 1 fixture/law bundle 3/3 CLOSED (Wa-2 #4080 dca5ce7 LANDED while operator was writing feedback); Layer 2 authority gate OPEN; explicit anti-misread sentence.
- §4 Path A: step 1 marked complete; structural-bridge step references #4091 §3.
- §6.5 NEW Current Dispatch Board: priority-ordered table per operator suggestion (Wa-2 done; structural-bridge DFS unstaffed; P2-B operator-gated; SG-RC-LAYERING authoring; SG-6 #4085 in cursor RC; SG-1b routed; #4091 ratification posture).
- §7: inverted "no dispatches needed" framing to name the two authoring blockers (SG-RC-LAYERING + structural-bridge replacement) as active items to monitor/escalate; operator-gated decisions surfaced.
- §8: removed Wa-2 risk (closed); added explicit "first concrete CiUpsertStep replacement under #4091" framing for the structural bridge.
- §10 renamed "Forecast (pre-bed read)" → "Watchlist (receipt-state, not time-based)" per operator's no-timeline discipline; consolidated PM-actionables into "decisions blocking forward progress" so it reads as receipt-state rather than time-adjacent.

No code paths changed; docs-only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 31, 2026
… snapshot + #4091 anchor (#4094)

* docs(planning): v4 dep graph refresh 2026-05-31T06:30Z — post-cascade snapshot + #4091 anchor

Forward-projection update to docs/planning/v4-predicate-dependency-graph-2026-05-30.md (#4058) for the
2026-05-31 wave-collapse window. Captures: P2 scope (a) PROVEN via P2-A probe (44-source compiler
closure, 0 diagnostics, no bridge); P3 7951→6991 rustc with 8 receipt-producing classes routed per
#4086 catalog; P5-PROVEN 2/3 gates closed (Wa-1 #4079 + P5-D tranche-2 #4089 LANDED); Wave 1 EXIT
achieved via #4082. Names Path A (P5 final-flip) as shortest critical path forward; identifies P2-B
bridge deletion + structural-bridge replacement as latent operator gates. References #4091 elastic
CI redesign exploration at §3.5 / §6 / §8 / §9 / §10 so any structural-bridge replacement authoring
aligns with the in-flight design rather than being re-shaped post-ratification.

Definitions cited per src/v4/TASKS.md:806-817. Authoritative state defers to merry-badger burn-down,
sharp-otter MW-D8 ledger + P1 roster + post-SG-1 catalog (#4086), and quick-tern's tranche state.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(planning): #4094 tightening per operator feedback — P5 two-layer split + dispatch board + watchlist

Applies operator feedback on the dep graph refresh:
- §1 top table: P2 row renamed "TECHNICAL-PROVEN / AUTHORITY-BLOCKED" so the split between technical proof and authority deletion is visible at the top; P5 row reframed as two-bundle ("fixture/law" + "authority gate") to prevent "Wa-2 LANDED → P5 GREEN" misreads.
- §3.2 P2: explicit Layer 1 / Layer 2 framing matching the top table; P2-B authorization listed as decision-node.
- §3.3 P3 table: adds `state` column (routed / worksheet-needed / authoring / in-review / route-pending) + explanatory note on the 9-rows-for-8-classes structure cursor flagged on the prior commit.
- §3.5 P5: Layer 1 fixture/law bundle 3/3 CLOSED (Wa-2 #4080 dca5ce7 LANDED while operator was writing feedback); Layer 2 authority gate OPEN; explicit anti-misread sentence.
- §4 Path A: step 1 marked complete; structural-bridge step references #4091 §3.
- §6.5 NEW Current Dispatch Board: priority-ordered table per operator suggestion (Wa-2 done; structural-bridge DFS unstaffed; P2-B operator-gated; SG-RC-LAYERING authoring; SG-6 #4085 in cursor RC; SG-1b routed; #4091 ratification posture).
- §7: inverted "no dispatches needed" framing to name the two authoring blockers (SG-RC-LAYERING + structural-bridge replacement) as active items to monitor/escalate; operator-gated decisions surfaced.
- §8: removed Wa-2 risk (closed); added explicit "first concrete CiUpsertStep replacement under #4091" framing for the structural bridge.
- §10 renamed "Forecast (pre-bed read)" → "Watchlist (receipt-state, not time-based)" per operator's no-timeline discipline; consolidated PM-actionables into "decisions blocking forward progress" so it reads as receipt-state rather than time-adjacent.

No code paths changed; docs-only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 31, 2026
… graph refresh (#4096)

Reflects two state changes from 2026-05-31T06:28-07:04Z:

1. **#4091 elastic CI redesign MERGED** (squash c05a5a8, 07:04Z) — flips from "draft / exploration" to ratified substrate authority across §3.5 (P5 Layer 2 framing), §6 (blockers table), §6.5 (dispatch board priority 7), §7 (operator-gated decisions list), §8 (risk section), §9 (cross-refs), §10 (watchlist).

2. **Wave 2 TR-lane COMPLETE** — SG-6 #4085 MERGED 06:28Z (squash 2ac52f2); lively-eagle archived. Updates §6.5 priority 5 from "cursor RC" to "LANDED ✓ + Wave 2 TR-lane COMPLETE".

3. **proud-pike scope clarification (msg_6287177d)**: #4095 elastic compute fabric DFS worksheet is scoped to `dsl/std` + `v4.std` substrate vocabulary only (per #4091 §4.0f/§4.0g); explicitly out-of-scope for `ci.dag`/`ci.yml`/shell bridge deletion. Separate downstream §10.0 worksheet still required for structural-bridge replacement — the "first concrete CiUpsertStep replacement under #4091" per operator framing. §3.5 + §6 + §6.5 updated to reflect.

4. **Operator decisions resolved per #4094 review**: D3 (SG-RC vs SG-1b prioritization) = PARALLEL (proud-pike confirms separate sibling worksheet, not amendment); D5 (CI risk posture) = operational nuisance NOT merge-blocker until ci_v4 fail-rate climbs above ~1-in-3.

5. **sharp-otter M2 probe dispatched** as P2-B safety-net receipt (full corpus compile w/o bridge step) so operator has artifact when authorizing P2-B deletion.

No code paths changed; docs-only.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request May 31, 2026
…isions resolved

Addresses cursor REQUEST_CHANGES on #4096:

1. §3.3 SG-6 row: in-review → merged (#4085 LANDED 06:28Z squash 2ac52f2; lively-eagle archived).
2. §5 Parallelizable workers: lively-eagle row updated to "LANDED + archived"; proud-pike row updated to reflect 3-parallel-front authoring (bridge + 2 child workers); deep-ferret marked ARCHIVED with respawn work-item adhoc-6b440f7f-6de noted.
3. §6 blockers table: removed stale "#4085 SG-6 cursor RC" row; SG-RC-LAYERING row updated to note PM-override-spawned child workers.
4. §3.3 state legend: added `merged` enum value.
5. §10 watchlist: split "decisions blocking" into "blocking" + "resolved this snapshot"; moved #4095-scope clarification, SG-RC-vs-SG-1b prioritization, CI risk posture, and #4091 ratification into resolved. Only P2-B authorization remains as blocking (with M2 probe receipt path in flight).

INVARIANTS.md P2 single-authority discipline restored: SG-6 receipt has one authority statement (LANDED) across all sections.

Per PM override (msg_9640253b) + proud-pike ack (msg_cdbe1925): 2 child §10.0 workers spawned (sharp-lark-878 SG-RC, sleek-badger-874 SG-1b) parallel with proud-pike's own bridge authoring + sharp-wolf #4095 review.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@briansrls
briansrls deleted the session/lively-eagle-677 branch June 1, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant