Merge Orchestration runtime · sensory layer: Sensor (classify → context → sense)#492
Merged
Merged
Conversation
…xt + sense + store resolvers
The sense half of sense->deliberate->actuate. Turns a token-free per-PR
observation (deposited in the shared store by a scanning bot) into the
decision ctx the Strategist/Dispatcher consume:
* classify/1 (pure): branch/title/files/labels -> change_class (route),
change_level (the object/meta reflexivity guard), license_touch (the
owner-only symbolic veto). No confidence here -- that is the council's job.
* to_context/3: assemble the ctx, mapping RepoPoolPolicy -> pool atom and
normalising on-disk attestations onto the council shape.
* sense/3 + sense_and_decide/3: batch over observations into Dispatcher.
* store_resolvers/file_pool_resolver/dir_attestation_resolver: read pools +
signed attestations off the shared flat-file store (brain stays token-free;
Jason decoder injectable so the logic tests run dep-free).
39 ExUnit (was 22), 0 failures, elixir 1.14. sense_and_decide integration
asserts the full arm/clamp/meta-flag/license-veto-flag distribution end to end.
Real on-disk a3/a5 fixtures parsed under a Jason guard (runs in CI).
🔍 Hypatia Security ScanFindings: 43 issues detected
View findings[
{
"reason": "String.to_existing_atom with user input exhausts atom table -- use to_existing_atom (1 occurrences, CWE-400)",
"type": "elixir_atom_from_user",
"file": "/home/runner/work/hypatia/hypatia/lib/merge_orchestration/sensor.ex",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Repository has 5 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "src/ui/gossamer/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/ci-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/bench-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "ffi/zig/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/reports/audit/audit-2026-04-15-post.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/a2ml-k9.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
Hypatia's own code_safety/elixir_atom_from_user rule (the regex String.to_atom\() flagged the dual-key helper as atom-table exhaustion. The keys pick/2 ever sees are a fixed, small set, so replace the dynamic String.to_atom with a bounded compile-time lookup (known_atom/1) — no atom is ever minted from data, and unlike to_existing_atom it cannot raise on a not-yet-interned atom (e.g. :subject). Behaviour-preserving: 39 ExUnit, 0 failures.
🔍 Hypatia Security ScanFindings: 42 issues detected
View findings[
{
"reason": "Repository has 5 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "src/ui/gossamer/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/ci-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/bench-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "ffi/zig/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/reports/audit/audit-2026-04-15-post.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/a2ml-k9.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/architecture/system-integration.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
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.
The sense half of sense → deliberate → actuate
Dispatcher/Strategist/KinCouncilalready deliberate and actuate; this adds the organ that builds their input.lib/merge_orchestration/sensor.exturns a token-free per-PR observation into the decisionctx.Why the brain stays token-free
The fetch (gh/API) is done by a token-bearing scanning bot (or a CI job, or the
.git-private-farmhand) and written to the shared store as an observation —%{"repo","number","branch","title","files","labels"}. The brain only ever reads: observation + the repo'sRepoPoolPolicy(artifact-5bot_directivelabel) + the bots' signed attestations (artifact-3). No PAT in hypatia. That's the same separation as the actuator: the hand holds the token, the brain holds the judgment.What it does
classify/1(pure) — branch/title/files/labels →{change_class, change_level, license_touch}:change_class(the route axis): license → bump → proof → security → docs → chore → refactor → feature, most-guarded first.change_level(the meta reflexivity guard): touching.github/workflows/,lib/rules/,bot_directives/, the orchestrator's own schemas, orstandardscontractiles ⇒:meta⇒ the Strategist forces:flag. The actuator may propose oracle changes, never self-approve them.license_touch: aLICENSE/COPYING/*.spdx/licenses/path ⇒ the owner-only symbolic veto upstream.to_context/3— assemble thectx, mappingRepoPoolPolicy("P2"→:p2, unlabelled→conservative:p1) and normalising on-disk attestations onto the council shape.sense/3+sense_and_decide/3— batch observations into theDispatcher.store_resolvers/file_pool_resolver/dir_attestation_resolver— read pools + signed attestations off the shared flat-file store. The JSON decoder is injectable (Jasonin prod; the unit suite stays dependency-free).Testing (actual, not looks-right)
39 ExUnit, 0 failures (was 22) under Elixir 1.14:
pool_atomover enum/string/map/nil.sense_and_decideintegration — runs a mixed batch all the way throughclassify → to_context → Strategist → KinCouncil → Dispatcher.decide_alland asserts the exact outcome distribution: bump@P2 →auto_execute/squash, docs@P1 → clampedreview, workflow-edit →meta→flag, LICENSE → owner-veto→flag (%{total: 4, auto_execute: 1, review: 1, report_only: 2}).signed-valid.json,valid-p2-standard.json) — runs in CI, self-skips locally where the dep isn't resolvable.Scope / safety
lib/, routes to your review (the dogfooded pool rule).0.3.0). No change toStrategist/KinCouncil/Dispatcher.Where this leaves the runtime
sense → deliberate → actuate is now wired end-to-end. The remaining piece is operationalisation, not the brain: the observation producer (the token-bearing job that deposits observations + signed attestations into the store), real central Kin.Gate lease storage, and feeding the GoT/MoE competence weights into
KinCouncil(currently uniform).Generated by Claude Code