Loop signals
The OPEN: convention captures loose ends you noticed. Loop signals catch the ones you didn't.
The problem
Most operational decay happens slowly. A vendor's lead time creeps up by a day every month. Your card decline rate ticks from 1% to 1.5% to 2%. A VIP customer hasn't been in for 47 days, then 58, then 78.
Nothing in your daily attention surfaces these. By the time you notice, the problem is already an emergency.
Loop signals fix this. A loop signal is an automated monitor that watches one specific metric and surfaces it when it crosses a threshold.
The model
Each domain in your vault has a _loop/ subfolder. Inside _loop/ are three subdirectories:
The continuous improvement cycle is: collect → measure → improve.
Loop signals plug into measure/. They watch the metrics and post alerts when something crosses a threshold.
The signal table
A central loop_signals table (or JSONL file, or Markdown ledger) holds active signals. Each signal has:
- signal_id — stable identifier (e.g.,
OPS-VENDOR-LEAD-TIME-DRIFT) - severity — INFO / WATCH / ESCALATE / CRITICAL
- status — ACTIVE / RESOLVED
- title — one-line description
- finding — sentence-or-two explanation of what triggered
- resolve_condition — what would close this signal
- created_at / updated_at — timestamps
When a monitoring script detects a threshold crossing, it upserts a row into this table. When the metric returns to safe range, the script marks the signal RESOLVED.
The morning brief reads the active signals (status != RESOLVED) and surfaces them in the daily synthesis.
Severity levels
Four levels. Each implies a different response:
BRAIN.md priorities.
CRITICALAction needed today. Demands immediate response.
The threshold for each level depends on the metric. Setting thresholds is the hard part — too aggressive and you get alert fatigue, too lax and signals don't fire until it's too late.
A worked example
You run a restaurant. Card decline rate is one of your key metrics. Most days it sits at 0.5-1.5%. Occasionally it spikes for an hour and recovers.
You write a script that runs daily at 6 AM and computes the rolling 7-day decline rate:
What this gives you: tomorrow's morning brief tells you "Card decline rate 1.86% over last 7 days (threshold 3.0%)" if it has spiked. If it hasn't, the brief stays quiet.
Without the signal, you would notice the decline spike only when a customer complained, or when monthly P&L showed an unexpected chargeback hit.
Examples of signals worth building
Different operations have different signals. Some that apply broadly:
Finance
- Bank balance trending toward a danger zone
- AR aging exceeding 60 days
- Recurring subscription charge from a vendor you canceled
- Expense category outlier vs. last 90 days
Operations
- Vendor lead time drift (rolling 90-day average vs. baseline)
- Service quality scores trending down
- Specific SOP not executed (last touched > N days)
People
- Employee tenure milestones approaching (90 days, 1 year)
- Certification renewals 30 days from expiration
- Performance review overdue
Customers / relationships
- VIP customer not seen in 60+ days
- High-touch client not contacted in 30+ days
- New customer cohort retention dropping
Marketing
- Content cadence broken (no posts in N days)
- Email list growth flat for N weeks
Tech / tools
- Cron job hasn't reported success in 25+ hours
- Backup not run in 7+ days
- SSL certificate within 14 days of expiration
The list is not prescriptive. Build signals for metrics YOU watch. If you don't watch a metric, don't build a signal for it.
Where signals live
Pick one source of truth and stick to it. Three patterns work:
A loop_signals table with the columns above. Scripts UPSERT signals. The morning brief queries WHERE status = 'ACTIVE'.
A _AI/loop-signals/active.jsonl file. One signal per line. Scripts append/rewrite.
A _AI/loop-signals/active.md file with a table. Humans and scripts both append.
Most operators start with Pattern C, then move to A or B when signal count exceeds ~30.
Threshold tuning
The hardest part. Too tight and you get noise; too loose and you miss real problems.
Start with conservative thresholds (high noise tolerance, only fire on clear issues). After 60 days, review which signals fired and which didn't:
- Signals that fired and were real problems → keep
- Signals that fired but weren't real problems → raise threshold or kill
- Things that became problems but didn't fire → lower threshold or add a new signal
This calibration is ongoing. Plan to revisit signals quarterly.
Anti-patterns
Building signals for things you don't care about
If you wouldn't act on the signal, don't build it. The morning brief getting cluttered with informational noise reduces its value.
Signals that fire constantly
A signal that's been active for 30+ days has become wallpaper. Either the threshold is wrong, or the underlying issue is structural and needs to be solved (not monitored). Re-evaluate.
Signals without a resolve condition
If you can't define what would close the signal, you can't tell when the problem is solved. Always define resolve_condition before deploying a signal.
Hiding the signals
If signals only exist in a database and never surface in your daily brain, they aren't doing their job. The morning brief or the BRAIN.md "Blockers" section is where they have to show up.
The first three signals to build
Don't try to build 20 signals on day 1. Start with three:
- A financial signal — bank balance, AR aging, or category spend
- An operational signal — something that breaks visibly when it does (cron health, backup status, vendor delivery)
- A relationship signal — VIP customer lapse, key vendor not heard from in N days
Run those three for 30 days. See how the morning brief integrates them. Then add more.
Loop signals are how the harness watches what you don't have time to watch. Build them slowly, calibrate them honestly, and let them compound.
Next chapter: AI integration — how the harness uses local and cloud models without becoming dependent on any one provider.