CRM Hypothesis Ledger
Implements:
commons:hypothesis-ledger-pattern— shared append-only ledger schema, status lifecycle, and scoring operations. This skill configures the pattern for the CRM domain (C-### prefix, 14-day default window, CRM metric whitelist).
Append-only ledger of every CRM and sales action. The single source of truth for what we tried with leads, what we predicted, and what actually happened. Every other CRM skill writes to it.
Dependencies
Load crm-identity first (for C-### format, metric whitelist, and pipeline stage definitions).
Storage
/var/www/html/systemprompt-web/reports/crm/data/hypothesis-ledger.md
Single markdown file. One table, append-only. Newest rows at the bottom. Never rewrite history — failed predictions are the most valuable data in the ledger.
Schema
| id | logged | channel | action | hypothesis | metric | baseline | window_end | result | status | notes |
Fields:
- id:
C-###sequential, zero-padded to 3 digits, allocated by this skill. - logged: YYYY-MM-DD the action was taken.
- channel: one of
email,linkedin,github,call,demo,website,conference,other. - action: one-line past-tense description. Full draft/context goes in
data/actions/C-###.md. - hypothesis: the "If ... then ... within ..." statement, trimmed to one line.
- metric: exact field name from the metric whitelist below.
- baseline: numeric value of
metricat the moment of logging (pulled from latestpipeline-trackerreport orpipeline-history.jsonl). - window_end: YYYY-MM-DD when the hypothesis matures. Default = logged + 14d (longer than marketing because sales cycles are slower).
- result: numeric value of
metricat window_end. Empty while in-flight. - status:
SEEDED|IN-FLIGHT|PASS|FAIL|INCONCLUSIVE|ABORTED. - notes: free text, max 140 chars.
Metric Whitelist
These are the only valid values for the metric column:
pipeline_value_total pipeline_deals_active
leads_new_7d leads_new_14d
leads_qualified_7d leads_converted_7d
emails_sent_7d email_reply_rate_7d
avg_days_in_stage_{name} deal_velocity_7d
interactions_7d demos_scheduled_7d
If a metric is not on this list, reject the log operation and ask the caller to pick a valid metric.
Action Text Store
Full context for each hypothesis lives in:
/var/www/html/systemprompt-web/reports/crm/data/actions/C-###.md
Each file contains:
- Timestamp and skill that logged it
- Full email draft / call notes / outreach text
- Target lead(s) and their current stage
- Expected outcome and reasoning
- Post-maturation notes (added when scored)
Operations
next-id
Read hypothesis-ledger.md, find the highest C-###, return the next sequential ID.
log
Inputs: channel, action, hypothesis, metric, window_days (default 14), full context text.
Steps:
- Allocate next
C-###. - Read latest
pipeline-history.jsonlentry to fetch the current value ofmetric->baseline. Ifpipeline-history.jsonlis empty, use 0 as baseline. - Validate
metricis in the whitelist. Reject if not. - Compute
window_end= logged + window_days. - Append row to ledger with
status=SEEDED(becomesIN-FLIGHTonce Ed confirms execution). - Write
data/actions/C-###.mdwith context. - Print the assigned ID.
in-flight
Print all rows where status is SEEDED or IN-FLIGHT.
maturing
Input: date (YYYY-MM-DD).
Print rows where window_end <= date AND status is SEEDED or IN-FLIGHT. These need scoring.
score
Inputs: id, result (numeric), status (PASS/FAIL/INCONCLUSIVE/ABORTED), note.
Steps:
- Find the row by
C-###. - Read the latest
pipeline-history.jsonlto get the current value of the metric. - Update
resultandstatuscolumns in-place (this is the one exception to append-only: scoring is an update, not a new row). - Append post-maturation notes to
data/actions/C-###.md.
stats
Print pass/fail/inconclusive tally by channel for last 7d and 30d. Include total actions logged and average window length.
Integration with Daily Brief
daily-crm-brief calls:
in-flight— to show active hypothesesmaturing {today}— to identify hypotheses that need scoring todaylog— to register new actions from today's briefscore— to close out matured hypotheses
Separation from Marketing Ledger
The CRM ledger uses C-### IDs. The marketing ledger uses H-###. The SEO ledger uses S-###. They are completely independent files in different directories. Do not cross-reference IDs across ledgers — they are separate namespaces.