Skip to content

[New Skill]: monitoring/business_diagnostic — deterministic scenario ledger and calibration (companion to kpi_gate) #338

Description

@mrmasa88

Skill ID

monitoring/business_diagnostic

Category

monitoring

What should this skill do?

What it does. A deterministic scenario ledger and calibration skill that sits next to monitoring/kpi_gate. Given an operator-maintained, versioned framework — an exhaustive set of scenarios with an adjudication date, leading indicators with per-scenario weights, and the operator's probability marks — plus dated indicator observations, the skill returns the model-implied probability of each scenario under the declared weights, the delta from the operator's marks, which indicators fired, the next re-mark due date, days to adjudication, and — once the outcome is resolved — Brier scores per mark date. Where kpi_gate answers "did this period breach a rule?", this skill answers "across periods, which way has the balance of plausibility shifted, and how well calibrated were the operator's marks?"

Proposed short_description (brief mode, ~80 chars): Scenario ledger: declared-weight odds vs operator marks, re-mark dates, Brier.

The problem. Tracking several named scenarios with assigned probabilities is common practice — investment decisions, business planning, project risk — but the ledger usually lives in a spreadsheet or a table inside a document. Three things are then missing: (i) it is not traceable which observation moved which probability by how much; (ii) re-mark deadlines are not enforced; (iii) calibration (how right the marks turned out to be) is never computed after the fact. This skill mechanizes those three things without replacing any operator judgment.

Design split (same philosophy as kpi_gate).

  • The framework is operator-owned, versioned, and strict-schema. Scenario ids and indicator ids are a closed set declared by the framework; the skill ships no scenarios or indicators of its own.
  • The skill's closed error registry covers contract violations only: schema failures, undeclared weights, unknown indicators, marks that do not sum to 1, malformed dates.
  • Operator marks are never overwritten. The output shows marks and model-implied values side by side, with deltas. "Model-implied" means "what the declared weights imply" — not a forecast and not a recommendation; instructions.md states this and asks hosts to present it that way.
  • Unobserved indicators contribute 0; nothing is estimated. Missing required inputs return insufficient_data with reason codes (the honest third state).
  • Renormalization happens only when exhaustive: true; otherwise each scenario updates independently.

Arithmetic (v0.1). For each scenario s: logit(p_s') = logit(p_s) + Σ_i w_{i,s} · o_i, where o_i ∈ {+1, 0, −1} (observed / unobserved / observed-negative) and the weights w are declared in the framework (default ±1.0). Given an outcome, Brier = Σ(p_s − y_s)² per mark date. Pure Python, standard library only, no network calls; identical input returns identical output.

Chaining and context (SkillContext / chains:).

  • The skill never calls another skill; the host owns ordering (per docs/usage/skill_chaining.md).
  • Stateless. SkillContext reuses skill instances across calls, so all ledger state — marks history, observations, outcome — travels in the input and comes back in the output. Nothing is kept on the instance.
  • Position in chains. v0.1 is a terminal step: the host (or an upstream step) records indicator observations, adjudicate computes, the host presents. From v0.2 it is the natural step after kpi_gate — same policy / metrics vocabulary, findings and metrics mapped straight in:
chains:
  period_review:
    description: Gate this period's metrics, then update projections and the scenario ledger.
    when: A period snapshot has been recorded.
    steps:
      - id: gate
        skill: monitoring/kpi_gate
        input_from:
          metrics: host.metrics
          policy: host.policy
        map_out:
          findings: next.findings
      - skill: monitoring/work_diagnostic
        params:
          action: diagnose
        input_from:
          snapshots: host.snapshots
          policy: host.policy
  • when: gates. Top-level booleans for chain conditions: fired_any (at least one indicator moved a scenario), marks_stale (re-mark overdue), insufficient (required input missing). calibration.* fields remain reachable by dot path.
  • Relation to office/outreach_manager (proposed separately by the same issuer, filed alongside this one): the two skills are never adjacent steps in a chain. From v0.2 they connect only through data — outreach_manager.advance emits period aggregates in kpi_gate's metrics schema, which period_review above consumes.
  • Brief mode. instructions.md is kept short (it is injected on prepare() / execute()): how to present deltas next to marks, when to prompt for re-marking, never to backfill insufficient_data.

Agent-loop contract. Hosts (a) surface deltas and fired indicators to the operator; (b) prompt for re-marking when marks_stale is true; (c) never backfill insufficient_data; (d) never present model-implied values on their own — always alongside the operator's marks.

Bundle. skill.py (Effect) · instructions.md (Directive, brief-mode sized) · schemas/ (JSON Schemas for framework, observations, and outcome — documentation; runtime uses explicit stdlib checks) · kb/demo_scenarios.json (synthetic example framework, timestamped and sourced) · test_skill.py (synthetic fixtures only) · card.json. The manifest declares named outputs: (scenarios, calibration, fired_any, marks_stale, insufficient, insufficient_data, contract_errors).

Roadmap (to be proposed as Skill Upgrades on the same ID). v0.2 — readiness / diagnose: a coverage scan of an operator-declared policy (N areas with targets, deadlines, and thresholds) and trend/projection from period snapshots using kpi_gate's metrics schema (default 90-day horizon; reach-by-deadline where a target has one) — this is where the period_review chain above becomes live. v0.3 — skeleton: an alert-first report skeleton assembled from those outputs (prose stays with the host). v0.1 is deliberately limited to the ledger and calibration to keep the first PR small.

Why monitoring. Business-side monitoring alongside kpi_gate (single-period gate) and token_limiter (resource gate); this skill adds the multi-period, calibrated layer.

Ideal Inputs & Outputs

Input (action: "adjudicate"):

{
  "action": "adjudicate",
  "framework": {
    "schema_version": 1,
    "framework_id": "demo_launch_2026",
    "adjudication_date": "2027-12-31",
    "exhaustive": true,
    "scenarios": [
      {"id": "A", "label": "wired launch",   "criterion": "..."},
      {"id": "B", "label": "branded launch", "criterion": "..."},
      {"id": "C", "label": "no launch",      "criterion": "..."},
      {"id": "D", "label": "residual",       "criterion": "..."}
    ],
    "indicators": [
      {"id": "I01", "label": "design document published",            "strengthens": {"A": 1.0, "B": -0.5}},
      {"id": "I07", "label": "timing synchronized with market window", "strengthens": {"B": 1.0, "A": -0.5}}
    ]
  },
  "marks": {"marked_on": "2026-07-18", "remark_every_days": 90,
            "values": {"A": 0.15, "B": 0.45, "C": 0.30, "D": 0.10}},
  "observations": [
    {"indicator": "I01", "observed": "yes", "on": "2026-08-20", "source": "ref-12"}
  ],
  "outcome": null
}

Output:

{
  "scenarios": [
    {"id": "A", "operator_mark": 0.15, "model_implied": 0.307, "delta":  0.157, "fired": ["I01"]},
    {"id": "B", "operator_mark": 0.45, "model_implied": 0.314, "delta": -0.136, "fired": ["I01"]},
    {"id": "C", "operator_mark": 0.30, "model_implied": 0.284, "delta": -0.016, "fired": []},
    {"id": "D", "operator_mark": 0.10, "model_implied": 0.095, "delta": -0.005, "fired": []}
  ],
  "calibration": {"next_remark_due": "2026-10-16", "days_to_adjudication": 485, "brier": null},
  "fired_any": true,
  "marks_stale": false,
  "insufficient": false,
  "insufficient_data": [],
  "contract_errors": []
}

action: "calibrate" takes outcome: {"resolved_on": "...", "scenario": "B"} and returns the Brier score for each mark date and its trend across re-marks.

Target runtime

Model agnostic (all supported adapters)

External APIs & env vars (if any)

None. No network calls; no environment variables.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

cat: monitoringRegistry skill category — monitoring (`skills/monitoring/`).enhancementNew feature or request.skill requestRequest for a new capability to be added to the registry.

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions