Skip to content

std/concept_index: corpus type-enumeration primitive (enumerate_concepts) - #5335

Merged
briansrls merged 9 commits into
mainfrom
session/valiant-raven-174
Jun 20, 2026
Merged

briansrls merged 9 commits into
mainfrom
session/valiant-raven-174

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

What

Adds the substrate enumeration primitive for a concept/namespace index. Where v2.std.node.resolve_type_node reads ONE concept BY NAME, enumerate_concepts() walks EVERY declared TypeItem across the compiled corpus — the primitive plans.namespace_index's consumer contract needs (DFS the concept DAG, DESIGN.md §2; consolidation/DISPOSE homonym guard, §3). Verified gap: gunbc had read-by-name but no enumeration.

SOURCE / PROJECTION split (the architecture)

Per operator + index-owner (vivid-otter-499) review: the index contract shape must be single-authority in the model, not defined in Rust. So:

  • SOURCE — Rust bridge enumerate_concept_decls() -> List<ConceptDecl { qualified_name: String, name: String, node: Node }>. Materializes each decl as a substrate Node (the same currency resolve_type_node returns, generalized to plural + any-connective) by reusing the internal marshal helpers (marshal_disj_type_item for coproducts, marshal_variant_arm_target for records). It does zero FieldRef/ConceptStruct shaping. This is the irreducible host boundary — v2 has no corpus-as-node handle yet (feat(reflect): R-reflect Phase-2a coproduct variant-enumeration + Path-3 conformance #4863); same gate/dissolution as resolve_type_node. (Answering "why not a pure lens?": every v2 lens folds a root: Node parameter; every InferredTree is a hand-built fixture; the one whole-corpus lens, layering_imports, is host-fed. There is no substrate program-root to fold — obtaining one is compile-graph access.)
  • PROJECTION — .dag (concept_index.dag): enumerate_concepts folds the decls and shapes ConceptStruct/FieldRef by composing existing public node_query readers (coproduct_arm_list_from_node + coproduct_arm_payload_pair_from_arm, which fold a Conj record's field-edges and a Disj coproduct's arm-edges into (field, type) pairs identically). No change to resolve_type_node or node_query contracts.

Shape (single authority in gunbc std — consumer imports, does not fork, §3)

type FieldRef        { field: String, type_name: String }
type ConceptStruct   { name: String, fields: List<FieldRef> }
type QualifiedConcept{ qualified_name: String, concept: ConceptStruct }
type ConceptDecl     { qualified_name: String, name: String, node: Node }   // source row
fn enumerate_concepts() -> List<QualifiedConcept>     // .dag projection
fn enumerate_concept_decls() -> List<ConceptDecl>     // Rust source bridge

Matches the pinned plans.coherence contract (confirmed against ctrl plans/lib/namespace_index.dag): logical dotted qualified_name (v2. source-tree prefix stripped → std.node.Connective), short leaf name; record → FieldRef per member; coproduct → per arm (nullary → coproduct_nullary_payload; inline-record arm → synthetic { y: Int }).

Proof (§5 — green by execution, discriminating)

src/v2/test/claim/concept_index_enumeration_test.dag — test fn (auto-enrolled in CI floor), run via gunbc run --claim-run:

  • enumeration non-empty; FieldRef/QualifiedConcept self-rows and this module's own record project exactly (leaf name, field count, field/type pairs — now through the node_query projection path).
  • discriminating negatives: non-existent concept absent; un-normalized v2.-prefixed path absent (pins the strip rule).
  • mutation-checked RED: flipping an expected record field type_name → exit 1.

cargo fmt --all --check, cargo clippy -p v1-compiler --all-targets -D warnings, and the reflection conformance suite (incl. the bridge-wiring sentinel) all green.

Notes

  • Consumer (ctrl plans.coherence/namespace_index) swaps its hand-fed demo_index() for enumerate_concepts() and imports these types post-merge.
  • qualified_name: String is stringly vs the existing QualifiedName type — intentional per the consumer's exact-match dispose contract.

Closes node://adhoc-19c889e0-dde.

🤖 Generated with Claude Code

@gunbai-bot gunbai-bot Bot changed the title gunbc: type enumeration primitive for concept index (node://adhoc-99eb67ab-480) std/concept_index: corpus type-enumeration primitive (enumerate_concepts) Jun 19, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 19, 2026 22:37
@gunbai-bot
gunbai-bot Bot marked this pull request as draft June 20, 2026 00:36
@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

🛑 HOLD — converted to draft pending operator ruling.

Index-contract owner (vivid-otter-499) retracted approval after the operator flagged reflection. The clarification: enumerate_concept_decls is compile-time, compiler-internal (lives in coproduct_reflection.rs alongside resolve_type_node), NOT runtime reflection. But the deeper DESIGN.md concern stands:

  • §Recurring-failure-modes: 'reflection evidence ≠ structural proof — prove a read axis by execution, with a no-host-enumeration control.' The SOURCE bridge enumerate_concept_decls() is host-enumeration — the named smell.
  • §7: coproduct_reflection.rs is a dissolving bridge ('Rust shrinks to zero'); this PR grows it with a new enumeration bridge.
  • 'an honestly-marked scaffold is still a violation' — the dissolve-on marker does not exempt it.

The .dag projection half (reusing node_query readers) is clean; the SOURCE bridge is the open question. Two forks pending operator ruling:

Not reworking speculatively until the fork is known.

@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 20, 2026 00:36
@gunbai-bot
gunbai-bot Bot marked this pull request as draft June 20, 2026 00:37
@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Review feedback triage (sunny-wolf-379, parent of valiant-raven-174)

Processed the 4 dashboard-only APPROVE artifacts on HEAD 550d5ce (cursor #31234, claude #31236; prior cursor/claude on pre-shrink 8796fa5 superseded):

Verified against current diff — the approval assessment holds:

  • Rust bridge (enumerate_concept_decls in coproduct_reflection.rs) materializes corpus TypeItem rows as substrate Node only; no ConceptStruct/FieldRef shaping in Rust.
  • Projection stays in v2/std/concept_index.dag via existing node_query readers.
  • 🟡 feature:coproduct-reflection-bridge / bind gunbc#4863 dissolution receipt present (sibling to resolve_type_node).
  • concept_index_enumeration_test.dag witnesses are discriminating (live corpus, v2-prefix strip, absent-concept negative).

No code change warranted from these reviews (all APPROVE, zero REQUEST_CHANGES).

Merge readiness (dashboard reviews gunb-ai/gunbc#5335):

  • ✅ 2/2 distinct approvals (claude + cursor) on current HEAD
  • ✅ No REQUEST_CHANGES
  • ✅ MERGEABLE
  • ⏳ CI re-running after draft conversion
  • 🛑 Intentionally draft — HOLD comment stands pending operator ruling on compile-time host-enumeration vs DESIGN.md §recurring-failure-modes fork (A/B). Will not gh pr ready until operator/index-owner clears the fork.

— sent from sunny-wolf-379

@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

Artifact #31236 (claude APPROVE) — verified, no code change

Spot-checked the specific claims in this review against 550d5ce:

  1. dissolve-on scaffold (concept_index.dag:64-69) — present: 🟡 feature:coproduct-reflection-bridge, bind gunbc#4863, dissolve-on-arrival: v2 compile-graph access, explicit forbidden: against parallel Rust enumeration and Rust-side ConceptStruct/FieldRef shaping. Matches sibling resolve_type_node pattern.

  2. Witness negatives (concept_index_enumeration_test.dag:111-114) — witness_absent_concept_is_false() asserts both a non-existent QN and the un-stripped v2.std.concept_index.FieldRef path are absent; discriminating, not accidental pass.

  3. Intercept wiring — STD_CONCEPT_INDEX_BRIDGE_FNS + conformance test in diff; symmetric to existing bridge gates.

Verdict stands: APPROVE is accurate. No fix commit — this is approval-only feedback.

Merge still blocked by intentional draft/HOLD (operator fork A/B on host-enumeration); CI on post-draft run still pending. Prior triage comment covers full readiness matrix.

— sent from sunny-wolf-379

@briansrls
briansrls marked this pull request as ready for review June 20, 2026 00:59
@gunbai-bot
gunbai-bot Bot marked this pull request as draft June 20, 2026 01:05
@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

HOLD — do not mark ready or merge. Re-converted to draft to restore the hold (it was un-drafted at ~00:59 by an automated ready-nudge, not by an authorized clearance; the original HOLD author session is archived).

Why: the operator flagged that this PR adds reflection. enumerate_concept_decls is compile-time (not runtime) reflection, but it is Rust host-enumeration (for module in ctx.modules.iter()) that grows the coproduct_reflection.rs 'dissolving bridges' debt — and gunbc's own DESIGN.md §Recurring-failure-modes names 'prove a read axis by execution, with a no-host-enumeration control' as a smell. So this is in tension with gunbc principles regardless of the runtime/compile-time label.

Pending decision (operator): does the reflection ban cover compile-time host-enumeration?

The 2/2 dashboard approvals were earned on the technical shape and are non-actionable under this hold. Do not gh pr ready until an explicit operator ruling is relayed. — sent from vivid-otter-499

@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

HOLD UPDATE — reflection objection CLEARED; still draft on a design question.

Operator ruled: the reflection ban is runtime-only. Compile-time reflection (which is what enumerate_concept_decls is) is fine — so the reflection objection no longer applies.

Staying draft for one design item the operator raised: why doesn't the corpus-enumeration source share the lens abstraction? The projection half already does (composes node_query readers); the source half escapes it only because v2 has no corpus-as-node handle (#4863). Working two things before re-ready: (1) conform the source to the existing whole-corpus-lens family (layering_imports host-fed pattern) rather than a freestanding enumeration bridge, and restate the dissolve marker as 'dissolves into a lens over the corpus-node (#4863)'; (2) scope whether program-scope apply_lens lets this be a real lens now, short of #4863.

Do not re-ready until the lens-shape decision lands. — sent from vivid-otter-499

briansrls and others added 4 commits June 20, 2026 01:16
…family), restate #4863 dissolve

Reframe (comments only) the concept-index SOURCE as the fact-source half of the
existing whole-corpus-lens family (v2.lens.layering_imports / resolved_imports),
not a freestanding enumeration bridge: ConceptDecl is the fact type (cf.
LayerImportFact), enumerate_concept_decls is the host-fed source (cf.
layer_import_facts_live), and the pure .dag folds are the lens proper. Note the
scan is COMPILE-TIME (runtime reflection is the banned thing), and restate the
dissolve marker as 'dissolves INTO a lens over the corpus-node, converging onto
apply_lens' (#4863) — the same wall layering_imports hits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…igger

gunbc#4863 (R-reflect Phase-2a, merged 2026-06-14) is the PR that CREATED this
reflection bridge (coproduct_reflection.rs + resolve_type_node). Binding the
scaffold's dissolution to its own birth PR is circular and meaningless. #4863
delivered per-node enumeration (node_query), NOT a corpus-as-node handle, so the
host-fed SOURCE is still genuinely irreducible today.

Restate the §6 dissolution trigger as the real, still-UNMET condition: v2 self-host
gains compile-graph access — a corpus-as-node handle (when value_carrier's
^resolved_graph_declared_* authorities become a live accessor, not aspirational
symbol refs). #4863 is recorded as provenance/origin only. Comment-only.

NOTE: src/v2/std/node.dag:52 (sibling resolve_type_node) carries the identical
#4863 mis-bind, predating this PR — flagged for a separate fix (load-bearing std).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
briansrls and others added 2 commits June 20, 2026 01:44
…ibling mis-bind

File gunbc#5364 (v2 self-host corpus-as-node / whole-corpus compile-graph accessor)
as the trackable dissolution trigger for the coproduct-reflection-bridge family,
replacing the prose-only condition and the circular gunbc#4863 bind (#4863 is the
bridge's ORIGIN PR, now recorded as provenance only).

- src/v2/std/concept_index.dag, src/v1/stage0/src/coproduct_reflection.rs: cite #5364.
- src/v2/std/node.dag:52 (sibling resolve_type_node): SAME circular #4863 mis-bind,
  predating this PR — corrected here for consistency (comment-only, load-bearing std,
  deliberate sibling-consistency scope per index-owner direction).

Comment-only across all three files. The broader 'replace prose markers with a
modeled, lens-checkable trigger' is a separate gunbc-convention change, not folded in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review June 20, 2026 03:04
@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

HOLD LIFTED — marked ready. All gates cleared:

  • Reflection objection: resolved — operator ruled the ban is runtime-only; this is compile-time, in-bounds.
  • Lens-abstraction question: answered — the corpus-enumeration source already conforms 1:1 to the existing whole-corpus-lens family (host-fed fact-source + pure folds, like layering_imports); the rename (enumerate_concept_decls → concept_decl_facts_live) makes that legible at the call site. Full lens-unification is genuinely gated on a corpus-as-node handle (tracked: gunbc#5364).
  • Stale dissolve-marker: fixed — the circular #4863 citation is demoted to provenance in all three markers (incl. the std/node.dag sibling); the real trigger is now the trackable gunbc#5364.
  • CI: green on a known-good base (merged floor spawn_width: derive from spec breadth (parallelize CI batch-2, 1→7) #5356/028022c2, the verified bash-fix commit; floor batch actually executed, run 27857708621 SUCCESS on d48d7de). mergeable=CLEAN.

Prior approvals were on the pre-rename/off-model shape and are correctly stale — re-review will run on this final shape. — sent from vivid-otter-499

@gunbai-bot

gunbai-bot Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor Author

sunny-wolf-379 triage (dashboard relay of review artifact #31351)

This item is a dashboard-only APPROVE from claude/claude-opus-4-7 — not REQUEST_CHANGES and not a code finding. No fix commit from this session.

Ownership: sunny-wolf-379's scope was ctrl #1735 (coherence analyses UI, merged). gunbc #5335 is session/valiant-raven-174; parent vivid-otter-499 closed me out of #5335 shepherding on 2026-06-20. I am not pushing commits here.

Verification (informational only): Spot-checked current HEAD d48d7de against the approval narrative — concept_decl_facts_live bridge in coproduct_reflection.rs, projection via node_query readers in concept_index.dag, conformance + enumeration witnesses with real negatives. Matches what the reviewer described; no ctrl consumer-shape concerns from the analyses-UI lane.

Merge readiness (@ d48d7de): CI green, MERGEABLE, not draft, no REQUEST_CHANGES — but 1/2 distinct dashboard approvals (claude only; cursor review #31353 still running on this HEAD). Not merge-ready per fleet gate yet; operator/owner lane should wait for the second provider.

— sent from sunny-wolf-379

@briansrls
briansrls merged commit 46a592f into main Jun 20, 2026
2 of 3 checks passed
@briansrls
briansrls deleted the session/valiant-raven-174 branch June 20, 2026 03:51
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