Skip to content

Sense 14: The Signal

Sense 14 · Steady · Last touched 2026-08-20

  • last_verified: 2026-06-05

Synced from docs/design/sense_14_the_signal.md in the engine repo — that’s the source; this page is a build-time mirror.

Vocabulary note. This document uses earlier terminology (SMEbit → now Subject Matter, BitBundle / Use Case → now Dossier, Observation at Level 0 → now Statement). Internal identifiers (filenames, dbt tables, contracts) kept their legacy slugs; only the display names changed. The concept is unchanged. See terminology.yaml for canonical definitions.

Not every finding is a problem. Not every problem is financial. A signal is an observation. Its meaning depends on context.

Status: implementing Author: nuMetrix Team


The current probe framework has a fundamental bias: it only sees problems.

  • Every probe detects an “anomaly” (negative)
  • Every severity says “how bad” (never “how good”)
  • Every hypothesis asks “is this bad thing happening?”
  • money_at_risk assumes the impact is financial and negative
  • 3-level severity (high/medium/low) loses signal when aggregated
  • No concept of opportunity, improvement, or health

This shapes what the user sees, thinks, and does. A dashboard of red flags creates anxiety, not insight. The user cannot answer: “What is going well?” “Where are the opportunities?” “Is this getting better or worse?”

From anomaly detection to signal detection.

A signal is a typed, directional, multi-dimensional observation. Its meaning depends on the question being asked.

The rename is total — no legacy names survive in code, AFS, or UI.

LayerOldNewWhat it does
ObservationProbe / FindingSignalA single typed observation (polarity, score, impact)
LensAssessmentPerspectiveA named aggregation of signals into an entity-level view
QuestionHypothesisThesisA business question answered by signals and perspectives
JudgmentDiagnosisVerdictA root cause explanation with confidence and recommendation
KnowledgeSMEbitSubject MatterDisplay-only rename 2026-04-13; internal slug smebit_* preserved
NarrativeBitBundleDossierDisplay-only rename 2026-04-13; internal slug bb_* / bitbundle_* preserved
Verdict
(why + what to do)
Thesis
(is this true?)
↑ ↑
Perspective Signal
(lens) (observation)

Clean, directional, polarity-neutral. Every layer can be positive or negative. No medical, laboratory, or academic metaphors.

Old pathNew path
probes/signals/
probes/probe_*.yamlsignals/signal_*.yaml
probes/assessment_*.yamlperspectives/perspective_*.yaml
hypotheses/hyp_*.yamltheses/thesis_*.yaml
diagnoses/diag_*.yamlverdicts/verdict_*.yaml
contracts/findings_contract.v1.jsoncontracts/signal_contract.v1.json
OldNew
probecheck.pysignalcheck.py
probecompile.pysignalcompile.py
proberegistry.pysignalregistry.py
hypothesischeck.pythesischeck.py
hypothesiscompile.pythesiscompile.py
diagnosischeck.pyverdictcheck.py
diagnosiscompile.pyverdictcompile.py
OldNew
probe_findings__signal_*signal_findings__signal_*
probe_findings__assessment_*perspective_findings__perspective_*
probe_registrysignal_registry
hypothesis_verdictsthesis_verdicts
hypothesis_registrythesis_registry
diagnosis_verdictsverdict_findings
diagnosis_registryverdict_registry
platform_probe_findings(retired — the platform layer was removed 2026-05-29 with the single-tenant KLS direction)
Old fieldNew field
probe_idsignal_id
probe_versionsignal_version
probe_categorysignal_category
hypothesis_idthesis_id
diagnosis_idverdict_id
source_probessource_signals
severityseverity (kept as display label, derived from score)
money_at_riskmoney_at_risk (kept for backward compat, derived from impact_value)
Old routeNew route
/{tenant}/probes/{tenant}/signals
/{tenant}/findings/{tenant}/findings (unchanged — still the findings list)
/{tenant}/findings/{probe_id}/{tenant}/findings/{signal_id}
/{tenant}/hypotheses/{tenant}/theses
/{tenant}/hypotheses/{id}/{tenant}/theses/{id}
signal:
polarity: positive | negative | neutral
score: 0-100 # continuous intensity
direction: improving | stable | worsening | null
impact:
value: -12000 # signed number
unit: CHF # or: count, percent, days, custom
dimension: financial # financial | operational | quality | cultural | strategic
PolarityMeaningExample
negativeRisk, problem, anomalyRevenue leakage, expired catalog
positiveStrength, opportunity, healthPrice stability, complete traceability
neutralObservation, no judgmentMaterial count, classification label

Replaces the 3-level severity as the source of truth for signal strength.

ScoreDisplayMeaning (negative)Meaning (positive)
0-20lowNegligible riskMarginal strength
20-50mediumModerate riskNotable strength
50-80highSignificant riskStrong signal
80-100criticalUrgent action neededExceptional

Thresholds are configurable per tenant via the config engine:

display:
signal:
thresholds: [20, 50, 80]
labels:
negative: [negligible, moderate, significant, critical]
positive: [marginal, notable, strong, exceptional]

Severity labels are a display concern, not a data concern.

DirectionMeaning
improvingScore decreasing (negative) or increasing (positive) over time
stableScore within ±5% over 3+ periods
worseningScore increasing (negative) or decreasing (positive) over time
nullNo temporal data or first observation

Impact is not money. It is a typed value with a dimension:

DimensionUnit examplesWhat it measures
financialCHF, EUR, USDRevenue, cost, savings
operationalcount, hours, daysProcess disruptions, delays
qualitypercent, scoreError rates, completeness
culturalcount, scoreWorkarounds, compliance fatigue
strategiccount, scoreSupplier dependency, market exposure

The value is signed: negative = cost/risk, positive = opportunity/savings.

A Perspective is a named lens — not a rigid bundle.

  • Selects signals (does not own them)
  • Produces a continuous score per entity (0-100)
  • Reports polarity balance (positive vs negative signal count)
  • The same signal can appear in multiple perspectives with different weights
perspective:
id: material_health
entity: Material
score: 62
polarity_balance:
positive_signals: 4
negative_signals: 3
net: positive

A Thesis is a free composition of signals and perspectives.

  • Can reference signals directly, perspectives, or both
  • Can ask positive questions (“is this entity thriving?”)
  • Supports polarity inversion (a negative signal as counter-evidence for a positive thesis)
  • Verdict labels configurable: [confirmed, promising, inconclusive, not_observed]
thesis_id: thesis_material_excellence
category: opportunity
evidence:
- signal: signal_price_stability
role: primary
weight: 3
- perspective: material_health
role: supporting
weight: 2
polarity: inverted
- signal: signal_negative_margin
role: counter
weight: 2

Signals are independent of perspectives. A thesis composes freely from both. The hierarchy is a network, not a chain.

Thesis
(free question)
╱ | ╲
Signal Perspective Signal
╱ | ╲
Signal Signal Signal (same signal can appear directly AND through a perspective)

A Verdict is a root cause judgment attached to a confirmed thesis.

  • diagnosis_idverdict_id
  • hypothesis_idthesis_id
  • root_cause_category stays (process_failure, system_failure, etc.)
  • Can now explain positive outcomes (“why is this working well?”)
CREATE TABLE signal_findings (
finding_id VARCHAR NOT NULL,
tenant_id VARCHAR NOT NULL,
signal_id VARCHAR NOT NULL,
signal_version VARCHAR NOT NULL,
-- Signal properties (Sense 14)
polarity VARCHAR NOT NULL DEFAULT 'negative',
score DOUBLE NOT NULL DEFAULT 45.0,
direction VARCHAR,
-- Impact (multi-dimensional)
impact_value DOUBLE,
impact_unit VARCHAR DEFAULT 'CHF',
impact_dimension VARCHAR DEFAULT 'financial',
-- Entity
entity_type VARCHAR NOT NULL,
entity_id VARCHAR NOT NULL,
time_bucket VARCHAR,
-- Evidence
evidence VARCHAR,
-- Backward compatibility (computed)
severity VARCHAR, -- derived from score + thresholds
money_at_risk DOUBLE, -- abs(impact_value) when unit is currency
health_score DOUBLE, -- perspectives only
PRIMARY KEY (finding_id)
);

money_at_risk summed naively across duplicated findings → billions.

Rules:

  1. Deduplicate before aggregating: one entity × one signal × one time_bucket = one observation
  2. Aggregate scores, not impact: maps show average score, not summed CHF
  3. Show net impact: positive + negative = net, not just “total risk”
  4. Configurable aggregation: sum, weighted avg, worst-of, best-of — per context
ChannelMaps to
xtime_bucket, entity_type, perspective
yscore (0-100), impact_value, signal_count
colorpolarity (red/green/amber), score (gradient), direction
sizeabsolute impact, finding count

The zero line on y-axis separates opportunity (above) from risk (below).

Full rename across:

  • Scripts (compilers, validators, registries)
  • YAML artifacts (signals/, perspectives/, theses/, verdicts/)
  • Contracts
  • dbt models
  • JinDesk routes and pages
  • CLI commands
  • Documentation

No new functionality — just the vocabulary change. Everything compiles and builds exactly as before, with new names.

  • Add polarity, score, direction, impact_* to signal findings schema
  • Existing signals: auto-populate from severity + money_at_risk
  • Signal compiler: accept new YAML fields, emit new columns
  • JinDesk: read new fields when present, fall back gracefully
  • Findings pages show score + polarity
  • Map Salon uses continuous score
  • Color scale: polarity-aware (red ← 0 → green)

Phase 4: Positive signals + Perspectives (Day 3)

Section titled “Phase 4: Positive signals + Perspectives (Day 3)”
  • First positive signals (price_stability, catalogue_completeness)
  • Reform one assessment → perspective
  • First opportunity thesis
  • Green dots on the map
  • Remove redundant signals (I/O weekly variants, stale duplicate)
  • Fix billion-dollar aggregation
  • Migration script for packs and live tenants
  • Update synthetic data generator
SenseRelationship
Sense 7 (Price Lab)Price stability = positive signal
Sense 10 (Computed Aggregates)Score aggregation replaces naive SUM
Sense 11 (The Veil)Signal visibility per identity
Sense 12 (The Mirror)User preferences for signal display
Sense 13 (The Canvas)Signal panels as building blocks

Every signal you author lives as a YAML file in your tenant AFS at signals/signal_*.yaml, compiles to a dbt model via jin make, and produces a findings table JinDesk reads. The Val d’Oria demo runs the full pipeline on 16 active signals against 104K persons + 13K assignments — every finding you see is a real output of the chain this sense describes.

Status: shipped. The Signal / Perspective / Thesis / Verdict chain is the engine’s analytical spine and runs in every pack today.

  1. Score computation: Signal YAML defines score_expression (SQL), compiler wraps it.

  2. Impact units: Standardized base units (CHF, count, percent, days) with free-form display label.

  3. Perspective membership: Declarative in the perspective YAML — the lens chooses its signals, not the other way around. A signal doesn’t need to know who’s looking at it.

  4. Historical scores: Compute from KLS snapshots (time machine from Sense 5).

  5. Thesis ↔ Perspective independence: A thesis can reference signals that belong to NO perspective. Perspectives and theses are independent composition axes over the same signal pool.


Numerical neighbors:Sense 13: The Canvas · Sense 14.2 — Typed Signals

jazzisnow jinflow is a jazzisnow product
v0.64.7 · built 2026-09-20 19:48 UTC