Hypothesis Ledger Pattern
Every action across every domain is logged as a falsifiable hypothesis with a measurable outcome. This pattern defines the shared infrastructure. Domain ledgers (SEO, marketing, CRM) configure it with their own prefix, window, path, and metrics.
Principle
No action without a hypothesis. No hypothesis without a metric. No metric without a baseline. Every row is append-only. History is never rewritten.
Storage
Each domain stores its ledger at:
/var/www/html/systemprompt-web/reports/{domain}/data/hypothesis-ledger.md
Single markdown file. One table. Newest rows at the bottom.
Schema
| id | logged | channel | action | hypothesis | metric | baseline | window_end | result | status | notes |
| Field |
Description |
| id |
{PREFIX}-### sequential, zero-padded to 3 digits. Each domain has its own namespace. |
| logged |
YYYY-MM-DD the action was taken. |
| channel |
Domain-specific enum (see domain config below). |
| action |
One-line past-tense description. Full draft goes in data/actions/{PREFIX}-###.md. |
| hypothesis |
"If ... then ... within ..." statement, trimmed to one line. Must be falsifiable. |
| metric |
Exact field name from the domain's metric whitelist (validated on append). |
| baseline |
Numeric value of metric at the moment of logging. |
| window_end |
YYYY-MM-DD when the hypothesis matures. Uses domain default window. |
| result |
Numeric value of metric at window_end. Empty while in-flight. |
| status |
IN-FLIGHT, SEEDED, PASS, FAIL, INCONCLUSIVE, or ABORTED. |
| notes |
Free text, max 140 characters. |
Status Lifecycle
SEEDED → IN-FLIGHT → PASS | FAIL | INCONCLUSIVE
→ ABORTED (if conditions change before window_end)
- SEEDED: hypothesis logged but prerequisites not yet met (e.g., waiting for indexing)
- IN-FLIGHT: action taken, waiting for window_end
- PASS/FAIL/INCONCLUSIVE: scored at or after window_end
Action Text Store
Full context for each action lives in:
reports/{domain}/data/actions/{PREFIX}-###.md
Each file contains: timestamp, what was changed, before/after values, target URLs, measurement notes.
Operations
Every domain ledger implements these 6 operations:
| Operation |
Description |
next-id |
Allocate the next sequential {PREFIX}-### ID |
log {fields} |
Append new row + write actions/{PREFIX}-###.md |
in-flight |
Return rows where status = IN-FLIGHT |
maturing {date} |
Return rows where window_end <= date AND status = IN-FLIGHT |
score {id} {result} {status} {note} |
Close out a hypothesis row |
stats |
Pass/fail tally by channel |
Log operation
- Allocate next ID via
next-id.
- Pull current value of
metric from the domain's data source (monitor report, GSC data, analytics).
- Validate
metric is in the domain's whitelist. Reject if not.
- Append row to ledger with status = IN-FLIGHT or SEEDED.
- Write
actions/{PREFIX}-###.md with full context.
- Return the assigned ID.
Score operation
- Read the row, confirm status is IN-FLIGHT.
- Append a new row with the same ID and closed-out values. Never edit existing rows.
- If PASS, emit a diff suggestion for the strategy master's Winning Tactics section.
- If FAIL, emit a diff suggestion for the Dead Hypotheses section.
Anti-Sludge Rules
- Every hypothesis must be falsifiable: it must name a specific metric, a baseline, and a target direction.
- Every metric must come from the domain's validated whitelist. No invented metrics.
- Rows are never edited in place. Corrections are appended as new rows.
- No hypothesis without a measurable outcome. "Improve brand awareness" is not a hypothesis.
- No action without a logged hypothesis. If you take an action, log it.
Domain Configuration
| Config |
SEO |
Marketing |
CRM |
Content |
| Prefix |
S-### |
H-### |
C-### |
CT-### |
| Default window |
14 days |
7 days |
14 days |
14 days |
| Storage path |
reports/seo/data/ |
reports/marketing/data/ |
reports/crm/data/ |
reports/content/data/ |
| Actions path |
reports/seo/data/actions/ |
reports/marketing/data/actions/ |
reports/crm/data/actions/ |
reports/content/data/actions/ |
| Metric source |
GSC + DataForSEO + daily-seo-brief |
lead-tracker + analytics |
pipeline-tracker + lead-enrichment |
daily-seo-brief |
| Strategy master |
seo-strategy-master |
marketing-strategy-master |
crm-strategy-master |
content-strategy-master |
| Channels |
seo, content, technical, linking, indexing, ctr |
reddit, linkedin, x, hn, crates, website, email, seo, ai-agent |
pipeline, email, enrichment, outreach |
optimisation, new-guide, revision, distribution, technical |
Note: Social media uses the marketing ledger (H-### prefix). Social hypotheses are a subset of marketing hypotheses, not a separate ledger.
Domain ledger skills (seo:seo-hypothesis-ledger, commons:marketing-hypothesis-ledger, crm:crm-hypothesis-ledger, content:content-hypothesis-ledger) reference this pattern and add their specific metric whitelist and channel enum.
1---2name: hypothesis-ledger-pattern3description: Shared append-only hypothesis ledger pattern. Defines schema, operations, and rules for S-###/H-###/C-###/CT-### ledgers across SEO, marketing, CRM, and content domains.4---56# Hypothesis Ledger Pattern78Every action across every domain is logged as a falsifiable hypothesis with a measurable outcome. This pattern defines the shared infrastructure. Domain ledgers (SEO, marketing, CRM) configure it with their own prefix, window, path, and metrics.910## Principle1112No action without a hypothesis. No hypothesis without a metric. No metric without a baseline. Every row is append-only. History is never rewritten.1314## Storage1516Each domain stores its ledger at:1718```19/var/www/html/systemprompt-web/reports/{domain}/data/hypothesis-ledger.md20```2122Single markdown file. One table. Newest rows at the bottom.2324## Schema2526```markdown27| id | logged | channel | action | hypothesis | metric | baseline | window_end | result | status | notes |28```2930| Field | Description |31|-------|-------------|32| id | `{PREFIX}-###` sequential, zero-padded to 3 digits. Each domain has its own namespace. |33| logged | YYYY-MM-DD the action was taken. |34| channel | Domain-specific enum (see domain config below). |35| action | One-line past-tense description. Full draft goes in `data/actions/{PREFIX}-###.md`. |36| hypothesis | "If ... then ... within ..." statement, trimmed to one line. Must be falsifiable. |37| metric | Exact field name from the domain's metric whitelist (validated on append). |38| baseline | Numeric value of metric at the moment of logging. |39| window_end | YYYY-MM-DD when the hypothesis matures. Uses domain default window. |40| result | Numeric value of metric at window_end. Empty while in-flight. |41| status | IN-FLIGHT, SEEDED, PASS, FAIL, INCONCLUSIVE, or ABORTED. |42| notes | Free text, max 140 characters. |4344## Status Lifecycle4546```47SEEDED → IN-FLIGHT → PASS | FAIL | INCONCLUSIVE48 → ABORTED (if conditions change before window_end)49```5051- **SEEDED:** hypothesis logged but prerequisites not yet met (e.g., waiting for indexing)52- **IN-FLIGHT:** action taken, waiting for window_end53- **PASS/FAIL/INCONCLUSIVE:** scored at or after window_end5455## Action Text Store5657Full context for each action lives in:5859```60reports/{domain}/data/actions/{PREFIX}-###.md61```6263Each file contains: timestamp, what was changed, before/after values, target URLs, measurement notes.6465## Operations6667Every domain ledger implements these 6 operations:6869| Operation | Description |70|-----------|-------------|71| `next-id` | Allocate the next sequential {PREFIX}-### ID |72| `log {fields}` | Append new row + write actions/{PREFIX}-###.md |73| `in-flight` | Return rows where status = IN-FLIGHT |74| `maturing {date}` | Return rows where window_end <= date AND status = IN-FLIGHT |75| `score {id} {result} {status} {note}` | Close out a hypothesis row |76| `stats` | Pass/fail tally by channel |7778### Log operation79801. Allocate next ID via `next-id`.812. Pull current value of `metric` from the domain's data source (monitor report, GSC data, analytics).823. Validate `metric` is in the domain's whitelist. Reject if not.834. Append row to ledger with status = IN-FLIGHT or SEEDED.845. Write `actions/{PREFIX}-###.md` with full context.856. Return the assigned ID.8687### Score operation88891. Read the row, confirm status is IN-FLIGHT.902. Append a **new row** with the same ID and closed-out values. **Never edit existing rows.**913. If PASS, emit a diff suggestion for the strategy master's Winning Tactics section.924. If FAIL, emit a diff suggestion for the Dead Hypotheses section.9394## Anti-Sludge Rules9596- Every hypothesis must be falsifiable: it must name a specific metric, a baseline, and a target direction.97- Every metric must come from the domain's validated whitelist. No invented metrics.98- Rows are never edited in place. Corrections are appended as new rows.99- No hypothesis without a measurable outcome. "Improve brand awareness" is not a hypothesis.100- No action without a logged hypothesis. If you take an action, log it.101102## Domain Configuration103104| Config | SEO | Marketing | CRM | Content |105|--------|-----|-----------|-----|---------|106| Prefix | S-### | H-### | C-### | CT-### |107| Default window | 14 days | 7 days | 14 days | 14 days |108| Storage path | reports/seo/data/ | reports/marketing/data/ | reports/crm/data/ | reports/content/data/ |109| Actions path | reports/seo/data/actions/ | reports/marketing/data/actions/ | reports/crm/data/actions/ | reports/content/data/actions/ |110| Metric source | GSC + DataForSEO + daily-seo-brief | lead-tracker + analytics | pipeline-tracker + lead-enrichment | daily-seo-brief |111| Strategy master | seo-strategy-master | marketing-strategy-master | crm-strategy-master | content-strategy-master |112| Channels | seo, content, technical, linking, indexing, ctr | reddit, linkedin, x, hn, crates, website, email, seo, ai-agent | pipeline, email, enrichment, outreach | optimisation, new-guide, revision, distribution, technical |113114Note: Social media uses the marketing ledger (H-### prefix). Social hypotheses are a subset of marketing hypotheses, not a separate ledger.115116Domain ledger skills (seo:seo-hypothesis-ledger, commons:marketing-hypothesis-ledger, crm:crm-hypothesis-ledger, content:content-hypothesis-ledger) reference this pattern and add their specific metric whitelist and channel enum.