LearnNewsExamplesServices
Frontmatter
id14446
titleBusiness-engine schema: BUSINESS_GOAL/METRIC nodes + read-only probe
stateClosed
labels
enhancementaiarchitecture
assigneesneo-fable-clio
createdAtJul 2, 2026, 8:45 AM
updatedAtJul 2, 2026, 11:23 AM
githubUrlhttps://github.com/neomjs/neo/issues/14446
authorneo-fable-clio
commentsCount3
parentIssue14442
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 2, 2026, 11:23 AM

Business-engine schema: BUSINESS_GOAL/METRIC nodes + read-only probe

Closed v13.1.0/archive-v13-1-0-chunk-8 enhancementaiarchitecture
neo-fable-clio
neo-fable-clio commented on Jul 2, 2026, 8:45 AM

Leaf 1 of Epic #14442 (Business engine), created-at-claim per the epic's one-feature-one-ticket pattern. Claimed by @neo-fable-clio; epic review (Greenlight) posted at IC_kwDODSospM8AAAABIdpLJw before this pickup.

Context

Epic #14442 graduated tonight from Discussion #14430 (§6.2 family-keyed quorum MET; operator prio-1, 2026-07-02) — extend the Native Edge Graph from reasoning over the codebase to reasoning over the business. Everything downstream (sandman CEO-slice, Social-MCP, attribution) stands on this leaf: the node/edge schema and the first read-only ingestion path. The epic mandates leaves in dependency order; this is the only unblocked one (Leaf 2 is sequenced behind the #14422 Golden-Path structural-reach work; Leaf 3 behind OQ2's social guardrails).

Live latest-open sweep: checked latest 20 open issues at 2026-07-02T06:39Z + latest 10 re-checked at 06:43Z; no equivalent found. A2A in-flight claim sweep degraded (mailbox read-path bug #14426 — list_messages returns empty); GitHub-side sweep is the operative collision substrate, per the two-substrate rule.

The Problem

The graph has no business-layer vocabulary: no goal nodes, no metric time-series, no attribution edges. Without a schema whose validity rules are mechanical, a business layer degrades into unfalsifiable numbers — the exact failure V-B-A exists to prevent. The graduated design (#14430 OQ1 [RESOLVED_TO_AC]) resolves this by making verify-before-assert a schema property: a metric that cannot name its falsifying query is invalid by construction.

The Architectural Reality

  • Node/edge class surface: ai/graph/NodeModel.mjs, ai/graph/EdgeModel.mjs, ai/graph/identityRoots.mjs — the owning siblings for new class definitions (structure-map consulted at claim).
  • Decay/protection: ai/services/memory-core/GraphService.mjs protects only IMPLEMENTS / EXTENDS / SYSTEM_TENET / RESOLVES today (live-verified in the graduation's V-B-A). New semantic classes are NOT durable by default — that claim-class error is explicitly warned against in the epic.
  • Ranking type-gate: ai/services/graph/computedGoldenPathRouting.mjs gates actionable ranking to type ∈ {ISSUE, DISCUSSION} — so BUSINESS_GOAL/METRIC cannot be prioritization substrate yet. This leaf ships honestly as a reporting layer.
  • Ingestion precedent: ai/scripts/maintenance/ingestTenant.mjs (#14404) is the tenant-scale bulk-ingestion path to reuse; auditGraphIntegrity.mjs sits beside it as the integrity-check precedent.
  • Recency/rollup machinery: #12671/#12672 shipped the decay/rollup substrate to reuse for time-series disposition.

The Fix

  1. Define BUSINESS_GOAL + METRIC node classes and ADVANCED_BY (goal→work) edge class in the ai/graph/ schema surface, each node carrying {claimClass, falsifyingQuery, windowSemantics, confoundDisclaimer, publicFlag} as first-class properties, with write-time rejection of a METRIC lacking falsifyingQuery.
  2. Author the ADR-0024 amendment: named decay/protection disposition for the new classes — raw high-cadence signals decay, rollups persist — implemented via the #12671/#12672 machinery (named reuse, no parallel build).
  3. Wire metric-source configuration (endpoints, cadences, redaction allowlists) as AiConfig subtree refs read at use-site (ADR-0019; no env-reads, no pass-through, no hidden defaults).
  4. Build the read-only ingestion probe on the ingestTenant.mjs path shape, ingesting ≥1 public metric category (Ring 0/Ring 1 categories only) into idempotent METRIC nodes.
  5. Attach the #14426 post-sync integrity canary: after a probe run + sync window, assert ingested node IDs/counts survived.

structural-pre-flight fires for each new .mjs at implementation time (sibling fast-path expected for both locations above).

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
BUSINESS_GOAL node class (new) #14430 OQ1 [RESOLVED_TO_AC] + ADR-0024 amendment (this leaf) Stable operator-slug identity; lifecycle active/achieved/retired; retirement triggers ADVANCED_BY reweight Absent class = no business layer (today's behavior) ADR amendment + Anchor & Echo JSDoc Unit: lifecycle + reweight
METRIC node class (new) same Deterministic ID (source, metricName, windowSemantics, periodStart); append-only periods; falsifyingQuery-or-invalid Rejected write logs + skips (fail-closed, never partial node) same Unit: idempotent double-ingest = 1 node; closed-period write rejected; missing-falsifyingQuery rejected
ADVANCED_BY edge class (new) same Goal→work attribution; carries provenance fields; binds the #14422 OQ6 lattice when attribution leaves land (no rival scalar minted here) Edge absent = goal renders unlinked (visible, honest) same Unit: edge create/reweight
AiConfig metric-source subtree (new config) ADR-0019 Endpoints/cadences/redaction allowlists as subtree refs, read at use-site Missing subtree = probe refuses to run (fail-closed) ADR-0019 boundary note in JSDoc Probe run without config → clean refusal
Ingestion probe script (new, read-only) ingestTenant.mjs precedent (#14404) Reuses tenant-ingestion path shape; writes only METRIC nodes; publicFlag=false never serialized to public outputs No probe = schema still ships (schema is independently landable) script header JSDoc Probe run + #14426 canary assertion

Rows naming existing surfaces (GraphService protected set, computedGoldenPathRouting type-gate, ingestTenant.mjs) were live-verified this cycle per the Surface-Anchor discipline.

Decision Record impact

amends ADR 0024 (decay/protection disposition for the new semantic classes) · depends-on ADR 0019 (AiConfig SSOT for metric-source config) · aligned-with ADR 0020 lineage via Epic #14442.

Decision Record (Discussion-origin)

Required: carried from #14430 graduation — the ADR-0024 amendment is a named first-leaf Decision Record; OQ1's schema contract is [RESOLVED_TO_AC] and binds this leaf verbatim.

Acceptance Criteria

  • BUSINESS_GOAL/METRIC node classes + ADVANCED_BY edge class defined beside the ai/graph/ siblings, each node carrying {claimClass, falsifyingQuery, windowSemantics, confoundDisclaimer, publicFlag}; a METRIC without falsifyingQuery is rejected at write time (unit-proven).
  • METRIC identity is deterministic from (source, metricName, windowSemantics, periodStart): double-ingest lands on the same node (idempotent upsert test). BUSINESS_GOAL identity = stable operator slug.
  • Mutability enforced: closed METRIC periods immutable (rejected-write test); current period mutable-until-close; BUSINESS_GOAL lifecycle + retired-goal ADVANCED_BY reweighting (zombie-priority test).
  • ADR-0024 amendment authored + merged in this leaf: decay/protection disposition (raw decays / rollups persist) via #12671/#12672 reuse — no parallel rollup implementation introduced.
  • Metric-source config lives as AiConfig subtree refs read at use-site; zero env-reads/pass-throughs/hidden defaults (ADR-0019 review checklist applied).
  • Read-only probe reuses the ingestTenant.mjs path shape and ingests ≥1 public metric category; publicFlag=false content never reaches public serialization (mechanical check).
  • #14426 integrity canary: post-probe + post-sync assertion that ingested METRIC IDs/counts survive; canary failure is loud, not silent.
  • Reporting-layer honesty: no prioritization claim in code/docs/JSDoc; the Golden-Path-v2 dependency is stated in-body with the Discussion #14422 anchor; native blocked_by edge added when #14422 graduates to a ticket.
  • Public/private boundary: metric categories only — no targets, revenue figures, strategy, or client names in any artifact of this leaf.
  • Anchor & Echo JSDoc (@summary + intent) on every new class/method (Gate 2).

Out of Scope

Leaf 2 (sandman CEO-slice — sequenced behind #14422), Leaf 3 (Social-MCP + any posting capability), any computedGoldenPathRouting ranking change, any HOME/#13444 rendering, attribution-edge trust-lattice implementation (binds at Leaf 2), and all private business-repo content.

Avoided Traps

  • Metadata-tags instead of nodes (Matrix A2) — rejected at graduation: metadata can't carry edges/metrics or be walked; the falsifier is recorded in #14430.
  • Durable-by-default claimPROTECTED_EDGE_TYPES does not auto-cover new classes; durability must be an authored ADR-0024 disposition, not an assumption.
  • Parallel ingestion walkeringestTenant.mjs reuse is mandated; a second FileSystemIngestor-style walker is the named anti-pattern.
  • Scalar-flattened trust — this leaf mints no confidence scalar; attribution trust binds the shared #14422 OQ6 lattice when Leaf 2 lands.
  • Vanity-metric ingestion — Ring-1 sources enter only as attributable-action categories; raw engagement counts stay out of the graph.

Related

Epic #14442 (parent) · Discussion #14430 (design anchor) · Discussion #14422 (Golden-Path-v2 type-gate dependency) · #14426 (integrity canary rationale — live datums this session) · #14404 (tenant-ingestion path) · #12671/#12672 (recency machinery) · ADR 0019 · ADR 0024 · #14418/#14428 (OQ6 lattice co-consumers).

Origin Session ID: c82afc7d-dffe-400e-984d-c670b62f39dc Retrieval Hint: query_summaries("business engine Leaf 1 schema falsifyingQuery METRIC BUSINESS_GOAL probe"); grep ADVANCED_BY ai/graph/

tobiu referenced in commit c279a0c - "feat(ai): business-engine schema, decay shield + metric probe (#14446) (#14455) on Jul 2, 2026, 11:23 AM
tobiu closed this issue on Jul 2, 2026, 11:23 AM