Skip to content

Merge Orchestration runtime · sensory layer: Sensor (classify → context → sense)#492

Merged
hyperpolymath merged 2 commits into
mainfrom
claude/peaceful-pascal-IRlgq
Jun 14, 2026
Merged

Merge Orchestration runtime · sensory layer: Sensor (classify → context → sense)#492
hyperpolymath merged 2 commits into
mainfrom
claude/peaceful-pascal-IRlgq

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

The sense half of sense → deliberate → actuate

Dispatcher/Strategist/KinCouncil already deliberate and actuate; this adds the organ that builds their input. lib/merge_orchestration/sensor.ex turns a token-free per-PR observation into the decision ctx.

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-farm hand) and written to the shared store as an observation%{"repo","number","branch","title","files","labels"}. The brain only ever reads: observation + the repo's RepoPoolPolicy (artifact-5 bot_directive label) + 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, or standards contractiles ⇒ :meta ⇒ the Strategist forces :flag. The actuator may propose oracle changes, never self-approve them.
    • license_touch: a LICENSE/COPYING/*.spdx/licenses/ path ⇒ the owner-only symbolic veto upstream.
    • No confidence here — confidence is the council's job, downstream. The sensor reports what changed, not how sure we are.
  • to_context/3 — assemble the ctx, mapping RepoPoolPolicy ("P2":p2, unlabelled→conservative :p1) and normalising on-disk attestations onto the council shape.
  • sense/3 + sense_and_decide/3 — batch observations into the Dispatcher.
  • store_resolvers / file_pool_resolver / dir_attestation_resolver — read pools + signed attestations off the shared flat-file store. The JSON decoder is injectable (Jason in prod; the unit suite stays dependency-free).

Testing (actual, not looks-right)

39 ExUnit, 0 failures (was 22) under Elixir 1.14:

39 tests, 0 failures
  • Exhaustive classifier coverage: bump (branch + title), proof, security (file + label), docs vs mixed, chore/refactor/feature fallthrough, the three meta triggers, standards-contractiles-vs-elsewhere, the LICENSE family.
  • Shape normalisers: string-keyed (disk) and atom-keyed (memory) attestations both land on the council shape; pool_atom over enum/string/map/nil.
  • sense_and_decide integration — runs a mixed batch all the way through classify → to_context → Strategist → KinCouncil → Dispatcher.decide_all and asserts the exact outcome distribution: bump@P2 → auto_execute/squash, docs@P1 → clamped review, workflow-edit → meta→flag, LICENSE → owner-veto→flag (%{total: 4, auto_execute: 1, review: 1, report_only: 2}).
  • Disk-resolver plumbing tested with an injected decoder; and a Jason-guarded test parses the real on-disk a3/a5 fixtures (signed-valid.json, valid-p2-standard.json) — runs in CI, self-skips locally where the dep isn't resolvable.

Scope / safety

  • Not auto-armed — core-tier lib/, routes to your review (the dogfooded pool rule).
  • Additive: one new module + its test + a LEDGER refresh (workstream 0.3.0). No change to Strategist/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

…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).
Comment thread lib/merge_orchestration/sensor.ex Fixed
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 43 issues detected

Severity Count
🔴 Critical 0
🟠 High 1
🟡 Medium 42
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

@hyperpolymath hyperpolymath enabled auto-merge (squash) June 14, 2026 04:27
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 04:27
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 14, 2026 04:27
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 04:28
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 14, 2026 04:28
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.
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 42 issues detected

Severity Count
🔴 Critical 0
🟠 High 0
🟡 Medium 42
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

@hyperpolymath hyperpolymath merged commit b98acbf into main Jun 14, 2026
36 checks passed
@hyperpolymath hyperpolymath deleted the claude/peaceful-pascal-IRlgq branch June 14, 2026 04:30
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.

3 participants