feat(admin): buildGraphModel, the graph's edge-honesty fold (issue #54) - #167
Merged
Conversation
One pure function assembles the model every graph consumer renders from, and the derivation rules are the design: four evidence classes (config, observed, potential, cron-rearm) from a closed test-pinned vocabulary, the two OQ-009 structural prohibitions (no forge-parent chain edges, no cross-folder chain edges: the harness makes both unrepresentable, so drawing either would draw a lie), precise dangling (no-skill only where enumeration succeeded; unverified is not dangling; charset-invalid is its own flag because deny proves nothing about existence), three-way orphanhood (orphan vs ai-reachable-no-trigger vs injected-ai-trigger), the OQ-020 pr-spend-loop badge, and caps plus honesty counters (unattributed runs, refusals, truncation, dropped edges) on every model. Gate eligibility is a node badge, never an all-pairs edge fabric; a mention is the edge, labelled strong/eligible. An observed edge that cannot hang on exactly one enumerated folder is dropped and counted, never guessed onto a basename that merely matches. An unenumerated cron folder still draws its trigger and config edge on a group that says not-enumerated, so the folder cap cannot silently lose an edge. Specs: NEW DES-GRAPH-EDGE-DERIVATION with the rejected alternatives recorded. DES-JOB-OUTBOX-CHAINING UNCHANGED, checked. DES-COST-FOLD-BY-SCAN UNCHANGED, checked (same scan, second consumer). Suite in the CI posture: 2115 pass, 0 skipped; admin bundle builds. Signed-off-by: Rob Boerman <robboerman@live.nl>
This was referenced Aug 11, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third slice of issue #54: the pure assembler every graph consumer renders from. Stacked on #166 (merged).
What
buildGraphModel(admin/src/graph-model.mjs) folds the read-model's outputs into one model, and the derivation rules are the design (DES-GRAPH-EDGE-DERIVATION, new):config(every trigger naming a flow gets one, always — dangling, unverifiable and charset-invalid included),observed(records only, with count + last occurrence),potential(a text mention, labelledstrong/eligible),cron-rearm(the one self-edge every cron trigger carries by definition).no-skillonly where enumeration succeeded and the path is absent at HEAD; an unreachable or remote folder renders unverified, never dangling; arun.flowfailingSKILL_NAME_REis its owncharset-invalidflag (the gate answersdenyfor it, and deny proves nothing about existence).orphan,ai-reachable-no-trigger,injected-ai-trigger(the OQ-022 silent no-op, badged loudly). Sub-skills are never orphan candidates.meta.droppedObservedEdges), never guessed onto a basename that merely matches.not-enumerated— the cap must not silently lose an edge.pr-spend-loop-riskbadge: apull_requesttrigger onopened/synchronizeis the static signature of the cross-actor spend loop.Specs (same PR)
NEW
DES-GRAPH-EDGE-DERIVATIONwith the rejected alternatives recorded (declared chain topology; the all-pairs eligibility fabric; deny-as-dangling; first-match target resolution).DES-JOB-OUTBOX-CHAININGUNCHANGED, checked.DES-COST-FOLD-BY-SCANUNCHANGED, checked (same scan, second consumer).Tests
21 new assembler tests over one canned deployment: the closed-vocabulary literal pin, per-rule positives, and the negative claims as their own assertions (unreachable folder → zero dangling flags; a potential edge never carries a count; eligibility alone draws no edge; the dropped edge is counted). Suite in the CI posture: 2115 pass, 0 skipped; admin bundle builds.