Methodology · rules r1
How a night is decided
Every status on this site comes from fixed rules applied to evidence we observed ourselves. The same rules run every night, the evidence is published, and each verdict is attested on Base so anyone can check it.
The rules
Quoted verbatim from the code that decides (rules version r1):
- Each night covers the 24 hours ending at the shift time, and only verified evidence (what we observed ourselves) decides the status.
- Shipped: the live app has a new deployment (liveapp.new_deploy), or the repo published a release or tag in the window (repo.release), or a listed deployer created a contract (chain.new_deployment).
- Building: not shipped, and at least one commit by a non-bot author touched code rather than only docs, styling or config (repo.code_commits).
- Down: the live app failed twice in a row (a non-2xx/3xx response or a timeout) and nothing else shipped that night (liveapp.down).
- Quiet: none of the above - the app is not known to be down and no verified change was seen (none).
- Unavailable: none of the repo, live app or chain answered, or none of them applies to the project, so we make no claim either way (all.unavailable).
- Precedence is shipped, then building, then down, then quiet; unavailable applies only when none of repo, live app or chain answered.
- A site that answers 401, 403 or 429 is blocking our check, not down; we note it as liveapp.blocked and it never counts as down.
- A source that fails while others succeed is noted as source.<name>.failed and the status is decided from the rest.
- Vibestarter records never count toward any status; founder updates, Vibestarter activity feeds and contract usage counts are reported or informational and never make a night shipped or building.
- Streak is the run of consecutive shipped or building nights ending at the latest night; unavailable or missing nights neither extend nor break it, while quiet and down nights end it.
- Lit30 is the number of shipped or building nights among the 30 calendar nights ending today, and last ship is the latest night with status shipped.
- An AI model may explain a night afterwards but can never change its status.
Evidence tiers
VERIFIED
What we observed ourselves: the public repo (commits, releases, tags), the live app (answers, deploy fingerprint from hashed asset paths), and the chain (contract creations by listed deployers). Only this tier decides a status.
REPORTED
What others tell us: Vibestarter raise and tranche data, founder updates, activity feeds, founder notes. Shown with every night, never counted toward a status.
Reconstructed history
The watch started with 90 nights of history rebuilt after the fact, so a window is not empty on day one. Those nights are labelled reconstructed, hatched wherever they appear, and never attested.
- Git: each public repo is cloned and its commits are bucketed into nights by author date, with the same code-versus-cosmetic path rules as the live shift. No rows exist before a repo's first commit.
- Wayback: archived captures of the live app give a deploy fingerprint per capture. A changed fingerprint between two captures counts as a deploy on the later night. For a project without a repo, quiet nights are filled in only between two captures with the same fingerprint; anywhere else the night stays unknown.
- Live nights win: once the nightly shift has observed a night, its reading replaces the reconstructed one everywhere on the site; the reconstructed row is kept and shown in the night drawer.
Attestation on Base
One transaction per night: a Merkle root of every project's verdict. Each observed night of a project becomes one leaf, keccak256 of its project key, night, status, lit30 and evidence hash. The leaves are sorted and hashed pairwise up to a single root, and the nightly shift attests that root once, with EAS on Base mainnet. Every project-night gets the same attestation uid and its own proof: the few sibling hashes that lead from its leaf to the root. A shift of up to 500 projects is exactly one transaction, so the cost stays flat however many projects are watched. The root attestation points at the night manifest, served byte for byte at /api/v1/manifest/<hash>, which lists every leaf. Its schema (non-revocable, no resolver):
bytes32 root, uint32 night, uint16 count, uint256 agentId, string manifestURI
The evidence hash is keccak256 of the bundle's canonical JSON (sorted keys, no whitespace), and the bundle is served byte for byte at /api/v1/evidence/<hash>. A live run is attested on its own, one attest per run, under the per-project schema:
bytes32 projectKey, uint32 night, uint8 kind, uint8 status, uint16 lit30, bytes32 evidenceHash, uint256 agentId, string evidenceURI
Gas is capped per day. Over the cap a run still finishes and says attestation: skipped; it never shows an attestation that does not exist.
Verify a night
In the browser: open any project, click a night, then Verify in this browser. It re-hashes the published bundle, reads the attestation from Base, and checks the schema, the attester, that it is not revoked or expired, and its night. Then it rebuilds this night's leaf from the bundle and the night's status and lit30, and checks that the proof leads from that leaf to the attested root. A wrong status, a wrong lit30 or one changed byte of evidence and the proof no longer reaches the root.
From a terminal, with the repo checked out:
curl -s <site>/api/v1/evidence/<hash> > evidence.json pnpm tsx scripts/verify-night.ts --network base \ --uid <attestation uid> --bundle evidence.json --site <site> --attester <watcher address>
It prints PASS or FAIL per check and exits 0 only on a full match. More in the docs.
Honest limits
- Private repos are invisible to us. A team that ships from a private repo shows only its deploys and contracts, so it can read quiet while it is busy.
- Projects without a repo have only the live app and the chain, and their reconstructed history is sparse: Wayback archived some of them once or never, so most of their history is unknown, not quiet.
- Contract creations by a deployer come from Blockscout; when Blockscout does not answer, new deployments can be missed for that night and the chain source is marked as failed.
- The AI explains, it never decides. A model writes the one-line summary after the rules have decided; if it fails or runs out of budget the night says "explanation unavailable" and the status is unchanged.
- Social signals are not read. Posts on X, Discord or Farcaster, and announcements anywhere, never count: only work that reached users does.
- A deploy is not a feature. A new deploy fingerprint means new code reached users, not that it was big; the evidence shows what changed so you can judge.