operad: data-driven port colors + fail-closed §12.2 gate (closes #50)#51
Merged
Conversation
Port→color mapping moves from the hardcoded portColorFromName switch to
Registry.PortColors: DefaultPortColors() (complete over every pair declared
in ontology v4.0.1, grounded in the authored declared_pairs_by_wf intent
rows) merged with an optional ontology port_color_compatibility.
port_color_map override, so later ontology rounds can add or recolor ports
without a kernel release. Unknown color names fail the load loudly.
The §12.2 gate flips from permissive-skip to FAIL-CLOSED for WFs with
declared pairs: a declared pair whose port lacks a color is rejected,
matching the doctrine the ontology prose authored (4.0.1 parity note:
"fail-closed pending kernel#50"). Spec-absent WFs keep the legacy
permissive skip, mirroring the pair-declaration gate. A port explicitly
mapped to the empty color (bound-to — ambiguous compute-or-storage
crossing) is a documented exemption that skips the matrix check, replacing
the silent fallthrough. Newly covered: the WF19 PRIMARY opens-on/
occupied-by pair (never color-checked before), caused-by, owned-by,
delegates-to/delegated-by, has-purpose/purpose-of-session, presents-as/
presented-by, promotes/promoted-from, composes/composed-by,
spans/spanned-by, and WF15's {semantic} → ColorSemantic (making the
matrix's wf15_only cells reachable).
Verification: full suite green; hermetic canonical-pairs invariant
(TestDefaultPortColors_CoverCanonicalOntologyPairs) proves no declared
4.0.1 pair is rejected by the flip; MOOS_INTEGRATION mirror against the
real sibling ontology passes; live throwaway-kernel gate run (real
ontology, in-memory log): R2 spine LINKs (has-occupant, governs,
opens-on) + 4.0.1 presents-as/spans accepted, phantom claims-session and
typo'd pairs still rejected by the declaration gate. parseColorMatrix
value-kind parsing (bool/wf15_only/sink_only/junk) gains its first tests.
Kept as-is, documented: Relation.SrcColor/TgtColor stay (never set, never
read — dropping them would churn serialized state shape for external
readers; candidate for a separate cleanup). resolvePortColors' stale
doc-comment corrected.
Closes #50.
authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / color-gate-data-driven
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review round (3 lenses, refute-first verify; live-fleet lens independently
recomputed the pair table: zero accept->reject flips, replay untouched):
- port_color_map: JSON null no longer aliases onto the "" exemption —
map values are *string; null is a load error pointing at the "" syntax
(confirmed repro: {"opens-on": null} silently exempted the WF19 primary
pair from the matrix check).
- canonicalPairs hermetic table: WF14 (implements, implemented-by) row was
missing — table now matches the ontology's 31 declared pairs, so plain
`go test ./...` catches a dropped/recolored WF14 port without needing
MOOS_INTEGRATION.
- GET /operad/port-colors now serves {"matrix", "port_colors"} — both
halves of the gate are introspectable; a fail-closed rejection can be
diagnosed against the running kernel's merged map. (Response shape
change: was the bare matrix.)
- Load-time coverage check (soft): loader warns loudly, listing WF:port,
when a declared pair's port has no color — boot proceeds, the gate
rejects at LINK time (soft-first; no boot-brick on ontology evolution).
- Phantom-pair rejection (claims-session/session-claimed-by via the
declaration gate, not color) now a unit test, not just the live run.
- Doc notes for the produces/emits authored-row conflicts (mirror of
connects-to). Correction to the previous commit's message: coloring
{semantic} does NOT make wf15_only matrix cells reachable via declared
pairs — those sit on non-semantic->semantic crossings; {semantic}->
{semantic} rides the diagonal.
Named follow-ups (not this PR): ontology prose true-up ("fail-closed
pending kernel#50" goes stale at merge) + port_color_map adoption ride the
next collected ontology round; pre-existing WF11 tagged/tagged-in
declaration-gate gap filed separately.
authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / color-gate-data-driven
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates the operad §12 port color system to be data-driven (defaults + ontology override) and makes the §12.2 color gate fail-closed for rewrite categories that declare port pairs, aligning runtime validation with ontology doctrine and improving diagnostics.
Changes:
- Introduces
Registry.PortColors(defaulted byDefaultPortColors()and optionally overridden byport_color_compatibility.port_color_mapduring load), plus a soft boot-time coverage warning for declared-but-uncolored ports. - Flips §12.2 validation to fail-closed for WFs with declared port pairs; keeps legacy permissive skip only for spec-absent WFs.
- Expands introspection and adds tests covering fail-closed behavior, override parsing, and canonical-pair coverage invariants.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| internal/transport/server.go | Changes /operad/port-colors to return both the matrix and merged port→color map for diagnostics. |
| internal/operad/validate.go | Resolves port colors via Registry.PortColors and enforces fail-closed color validation for declared-pair WFs. |
| internal/operad/validate_color_gate_test.go | Adds unit + integration tests for fail-closed semantics, exemptions, and canonical-pair coverage. |
| internal/operad/registry.go | Adds Registry.PortColors field and seeds it in EmptyRegistry(). |
| internal/operad/port_colors.go | Adds DefaultPortColors() mapping (kernel-side default vocabulary). |
| internal/operad/loader.go | Loads/merges port_color_map, validates override values, and logs soft coverage warnings. |
| internal/operad/loader_test.go | Adds tests for matrix value parsing, port_color_map merging/errors, and coverage warning behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Wolfram lane, revived per Sam's t249 /goal — executed from the Zappa seat. Implements the #50 fix sketch in its stated order: data-driven map → identity-spine coverage → then fail-closed.
What changes
internal/operad/port_colors.go):Registry.PortColors=DefaultPortColors()— complete over every pair declared in ontology v4.0.1 (31 pairs, 60 ports) — merged with an optionalport_color_compatibility.port_color_mapoverride object, so later ontology rounds add/recolor ports without a kernel release. Color choices grounded in the authoreddeclared_pairs_by_wfintent rows where they exist; family-consistent for the 20 previously-uncovered ports (WF19 primaryopens-on/occupied-by— never color-checked before —caused-by,owned-by,delegates-to,has-purpose,presents-as,spans,promotes, …).{semantic}→ semantic. Unknown color names and JSONnullin the override are load errors.validate.go): a declared pair whose port lacks a color is rejected, matching the 4.0.1 prose ("fail-closed pending kernel#50"). Spec-absent WFs keep the legacy permissive skip (mirrors the pair-declaration gate; keeps partial fixtures/registries working).bound-tobecomes an explicit, documented exemption (""= matrix-skip) instead of a silent fallthrough — the ontology declares its crossing both compute→topology and storage→topology.loader.go): boot warns loudly (listingWF:port) if any declared pair is uncovered; no boot-brick on ontology evolution.transport/server.go):GET /operad/port-colorsnow serves{"matrix", "port_colors"}(⚠ response-shape change: was the bare matrix) so a fail-closed rejection can be diagnosed against the running kernel's merged map.resolvePortColors' stale doc-comment fixed.Relation.SrcColor/TgtColorkept as-is (never set/read; dropping would churn serialized state shape — separate cleanup candidate).Verification
go build && go vet && go test ./...TestDefaultPortColors_CoverCanonicalOntologyPairs)MOOS_INTEGRATION=1)has-occupant,governs,opens-on) + 4.0.1presents-as/spansaccept; phantomclaims-session+ typo'd pairs reject at the declaration gateNamed follow-ups (deliberately not this PR)
port_color_compatibility.description("fail-closed pending kernel#50") goes stale at merge; prose true-up + optionalport_color_mapadoption ride the next collected ontology round (ontology.json touched once, reviewed once).tagged/tagged-inunder WF11) is silently dropped by the declaration gate today — separate issue, filed next.Closes #50.
authored-by: agent:claude-cowork.hp-z440 / session:sam.z440-cowork-workspace / color-gate-data-driven
🤖 Generated with Claude Code