Skip to content

Console

What the system knows, and how the agents behave. Every change applies on the next run.

Data

Every table this system writes, what is in it right now, and what put it there. Row counts are read live.

Tables
20
Rows on file
1,228Live
Foreign keys drawn
39

Every table is prefixed shepherd_ and lives in one shared Postgres project. Row level security is on with no public policies, so nothing reads this database except server code holding the service role key. The counts above are queried on each load rather than cached, which is why this page is the fastest way to tell whether a job actually wrote anything.

The data as a graph

Tables, the foreign keys between them, and what writes each one. Drag a node, click for detail, use the chips to filter.

29 nodes · 39 edges · counts live

Play 01, Signal Engine

11 tables.

  • shepherd_brokers

    Brokers450 rows

    The universe. One row per person who might place a risk with Shepherd, with the four score axes and whether we have worked with them.

    Written by
    Apollo sync, CSV import, Scoring
    Columns
    fit_score · score_axes · priority_score · relationship · engagement_count
  • shepherd_signals

    Signals89 rows

    Third-party intent. One row per trade-press item the sweep judged relevant, with its type, strength, and source.

    Written by
    Signal sweep
    Columns
    signal_type · firm · strength · detected_at · monitor_id
  • shepherd_monitors

    Monitors0 rows

    Custom signal sources: extra feeds and keyword watches, either typed in or described and drafted by a model.

    Written by
    A person
    Columns
    kind · config · active · hits
  • shepherd_sweep_rejects

    Sweep rejects400 rows

    What the sweep read and threw away, with the reason. The evidence behind 'it does not flood you with noise'.

    Written by
    Signal sweep
    Columns
    title · reason · swept_at
  • shepherd_sequences

    Cadences4 rows

    The cadence definitions themselves, so a new one is a form rather than a deploy. Four are seeded and protected.

    Written by
    Cadences
    Columns
    kind · signal_types · steps · built_in
  • shepherd_enrollments

    Enrollments38 rows

    Who is in which cadence, why they entered, what step they are on, and when the next touch is due.

    Written by
    Cadences
    Columns
    sequence · status · current_step · trigger_kind · next_due_at · reply_kind
  • shepherd_sequence_events

    Sequence events40 rows

    The story of every enrollment: enrolled, drafted, sent, replied, stopped, completed.

    Written by
    Cadences
    Columns
    kind · step · at
  • shepherd_drafts

    Drafts3 rows

    The email text itself, one row per step, with the underwriter's verdict on it.

    Written by
    Cadences
    Columns
    subject · body · status · step · sent_at
  • shepherd_engagements

    Engagements0 rows

    First-party intent. Every real touch with a broker, weighted, which is the only thing that moves the Intent axis.

    Written by
    A person
    Columns
    kind · occurred_at · source
  • shepherd_suppressions

    Do not contact0 rows

    The list the underwriters own. Checked before anyone is enrolled, not before a send.

    Written by
    A person
    Columns
    kind · value · reason
  • shepherd_briefs

    Broker briefs2 rows

    The one-pager written before a call, with the sources the research actually read.

    Written by
    Broker Brief
    Columns
    slug · payload · sources · duration_ms

Play 02, Targeting

3 tables.

  • shepherd_spend

    Spend6 rows

    Planned and actual budget by channel and play.

    Written by
    A person
    Columns
    month · play · channel · kind · amount
  • shepherd_outcomes

    Outcomes0 rows

    Replies, meetings, submissions, binds. The half of cost per submission that a human still records.

    Written by
    A person
    Columns
    month · play · metric · value
  • shepherd_readouts

    Readouts1 rows

    The written monthly read on what worked, generated from spend and outcomes together.

    Written by
    A person
    Columns
    month · payload · model

Play 03, AI visibility

3 tables.

  • shepherd_aeo_prompts

    Audit prompts24 rows

    The questions the audit asks every engine, phrased the way a broker asks them.

    Written by
    A person
    Columns
    prompt · category · persona · active
  • shepherd_aeo_runs

    Audit runs116 rows

    One row per prompt per engine per run: the answer, the carriers it named in order, and what it cited.

    Written by
    Visibility audit
    Columns
    engine · answer · carriers · citations · batch_id
  • shepherd_page_drafts

    Page drafts3 rows

    The page that would close a visibility gap, with its FAQ schema.

    Written by
    Visibility audit
    Columns
    payload · prompt_id

Shared

Used by everything.

  • shepherd_settings

    Settings5 rows

    Underwriters, appetite, voice rules, and which sources are switched on. One jsonb document per key.

    Written by
    A person
    Columns
    key · value
  • shepherd_runs

    Job runs19 rows

    Every sync, score, sweep, and audit, so a silent failure is never silent.

    Written by
    Apollo sync, Scoring, Signal sweep, Visibility audit
    Columns
    kind · ok · stats · log
  • shepherd_rate_limits

    Rate limits28 rows

    The counters behind the per-IP limits and the shared daily spend ceiling.

    Written by
    Request guards
    Columns
    key · count · window_start

How the data is handled

What is stored about a real person, and what is not.

The brokers in here are real people at real firms, so the rule I set was business contact information only: name, title, firm, office, and a public source URL. No email address was guessed. Where a firm does not publish one, the field is empty, because a wrong address on a real person is worse than a missing one.

Where the research and the record disagree, the record is annotated rather than overwritten. Twelve people at a firm that was acquired are held outside the database entirely rather than imported with an employer that no longer exists, and the rows for two other acquired firms carry a flag asking a human to verify before anyone emails them.

Everything here exports to CSV from the pipeline page, and the import that put 105 of these rows in accepts the same shape. Nothing is locked in: it is plain Postgres, and the whole schema above is twenty tables.