Two minutes for this screen · ten for the rest
Your trackers already carry the commercial consequence of every change: the money, the deadline, who it lands on. It sits inside the summary paragraph. This proposes holding it as structure instead.
A schema and a set of rendering rules. A first version is a week of design and a week of extraction work — not a quarter, and not a rewrite of what you have.
A vocabulary, not a redesign, built against a law you publish. Every term is up for correction.
Three kinds of content, marked wherever they appear
Yours, reproduced as written, source and verified date given.
The vocabulary. This is what I am proposing.
Dashed frames. Not your screens, and no attempt to match your interface.
Proposed This is the deliverable. Everything after it is the same vocabulary applied to one of your laws. The full spec has ten fact types, nine event types and six derivations; this is the short version.
A priority or importance score fails the first test, which is why nothing like it is in here.
Closed sets are what make the query work, and what stops the vocabulary drifting one tracker at a time. Every value came out of your published pages. None were invented to fill a row.
| Candidate term | Citable | Compressible | Queryable | Quiet in prose | Verdict |
|---|---|---|---|---|---|
| Obligation type | ✓ | ✓ | ✓ | ✓ | in |
| Amount — kind and route | ✓ | ✓ | ✓ | ✓ | in |
| Clock — type and mode | ✓ | ✓ | ✓ | ✓ | in |
| Affected party — direct or downstream | ✓ | ✓ | ✓ | ✓ | in |
| Summary paragraph | ✓ | ✗ | ✗ | ✓ | out |
| Priority score | ✗ | ✓ | ✓ | ✓ | out |
| Business impact: high / medium / low | ✗ | ✓ | ✓ | ✓ | out |
| Regulator's posture or tone | ✗ | ✓ | ✗ | ✗ | out |
The rejections are the useful part. Summary paragraph is what you hold today. It cites cleanly and fails the two tests that would let a machine use it. Priority score is what several competitors ship. It cannot be traced to a line of text, so I left it out — though you may have a reason to carry one that I cannot see.
Everything below changes when you switch. The facts do not. Proposed — both are composites built from customer types you name publicly, not real companies.
The order is part of the proposal. Today a reader works out their own standing from the tracker.
Recomputed for whoever is looking, never written onto the item. Nothing in the facts changed between the two readers — only the profile did. Cannot determine is a result, not a blank, and it names what would settle it.
California · Health & Safety Code §§ 38532–38533, as your tracker cites them
Eleven values are yours, quoted from the tracker. The twelfth is inferred, and marked. Every field name is mine — your tracker holds all of it as prose.
Source: Regbase, SB 253 & SB 261: California Climate Disclosure Law Tracker, verified 2 September 2026.
Every surface gets a budget: how many terms it can carry and stay readable. The vocabulary stays the same, the budget changes. Dropping is the design work — a surface that carries everything carries nothing. The standing block above is a fourth. Two more are not mocked: a tracker page carries every term, because it is where someone goes to check; an analysis piece carries the facts as a header and leaves the prose exactly as your writer wrote it.
Mock-up A dashed frame means I invented the rendering. These are not your screens. The law inside them is still yours.
In the inbox — subject line, 2 slots: standing and nearest clock
Opened — the standing block rendered as prose, in the same order
Manage this tracker · Change what you receive · Unsubscribe
Two budgets. The subject line gets two terms, standing and the nearest clock, because that decides whether it gets opened. The body runs the standing block in the same order: what changed, where you stand, what it costs. Both come off the record. Neither is written by hand.
| Name · stage · force | Standing | Obligation | Next clock | Amount |
|---|
Standing is a reading, so it gets its own column. Stage and force stay with the instrument — an injunction is a fact about the law, not about the reader. SB 261 shows two things: "not yet set" as a value rather than an empty cell, and one suspended statute reading differently for each reader.
Invented syntax, standing in for whatever you would actually build. The point is not how it gets typed. The point is that the reader is an argument to every query, so "nothing applies to you" can run a second pass instead of returning nothing.
I have not seen your stack. This is how I would build it, not a description of what you have.
{
"item": "ca-sb-253",
"instrument": "statute",
"stage": "final",
"force": "in_force",
"jurisdiction": { "level": "state", "name": "California" },
"obligation_type": ["obligation", "exposure"],
"amounts": [
{ "kind": "threshold", "value": 1000000000, "currency": "USD",
"party": "reporting_entity", "route": "none", "basis": "stated",
"source": { "doc": "hsc-38532", "locator": "§ 38532(b)" } },
{ "kind": "penalty_ceiling", "value": 500000, "currency": "USD",
"party": "reporting_entity", "route": "none", "basis": "stated",
"source": { "doc": "hsc-38532", "locator": "§ 38532(e)" } },
{ "kind": "fee", "value": 3106, "currency": "USD",
"party": "reporting_entity", "route": "none", "basis": "proposed",
"source": null, "status": "held_for_review" } // ← no locator, so it does not ship
],
"clocks": [
{ "type": "reporting_due", "mode": "fixed", "value": "2026-11-10",
"granularity": "day", "basis": "proposed", "revisions": 0,
"source": { "doc": "carb-96076", "locator": "§ 96076(c)" } },
{ "type": "fee_due", "mode": "relative", "offset_days": 60,
"anchor_event": "fee_determination_notice", "value": null,
"source": null, "status": "held_for_review" },
{ "type": "phase_in", "mode": "fixed", "value": "2027",
"granularity": "year", "basis": "stated",
"source": { "doc": "hsc-38532", "locator": "§ 38532(c)(2)" } }
],
"affected": [
{ "party": "p_over_threshold", "degree": "direct",
"condition": "us_organized AND ca_nexus AND revenue > amount:threshold",
"source": { "doc": "hsc-38532", "locator": "§ 38532(b)" } },
{ "party": "p_assurance_providers", "degree": "downstream",
"condition": "sells_to(p_over_threshold)",
"source": null, "basis": "inferred" }
],
"relations": [
{ "type": "parallel_to", "item": "ca-sb-261" },
{ "type": "implemented_by", "item": "carb-96076" }
]
}
Two things. No standing, no direction, no urgency anywhere in the record — keeping them out is what lets one record serve every reader. And two facts carry "source": null, so they sit at held_for_review instead of rendering. I could not find a locator for the fee schedule or the fee clock. That is the case the rule exists for.
What I would most want to be wrong about: whether extraction can assign obligation type and affected-party conditions reliably at your coverage. If it cannot, the vocabulary still holds, but the write path needs a person in it and the economics change.
Take one tracker end to end — facts with locators, the standing block, one alert — and find out whether extraction holds at your coverage. That answers the only question that decides whether the rest is worth building.
Twenty minutes, or one sentence telling me which term is wrong. Either one is useful, and the second is faster.