# Lights On > Lights On is a nightly check on whether teams are still shipping. Every night a watcher looks at each project's public repo, live app and onchain activity, decides a status with fixed rules, and attests it on Base with EAS. AI can explain a night afterwards; it never decides the status. Site: https://lights-on-watch.vercel.app ## Why it exists: the study 30 of 33 hackathon builds on Base showed no detected commit or deploy activity in the last 30 nights. 8 of 8 big reference apps showed detected commit or deploy activity in the last 30 nights, against 3 of 33 hackathon builds. Basis: reconstructed history (git + Wayback), not attested, nights 2026-10-08 to 2026-11-06. Quiet means no verified change seen, nothing more. Full study (Vibeathon 01 finalists, commit graphs vs shipping, method): https://lights-on-watch.vercel.app/study ## Statuses shipped, building, quiet, down, unavailable. ## Rules 1. Each night covers the 24 hours ending at the shift time, and only verified evidence (what we observed ourselves) decides the status. 2. 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). 3. 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). 4. 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). 5. Quiet: none of the above - the app is not known to be down and no verified change was seen (none). 6. 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). 7. Precedence is shipped, then building, then down, then quiet; unavailable applies only when none of repo, live app or chain answered. 8. 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. 9. A source that fails while others succeed is noted as source..failed and the status is decided from the rest. 10. 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. 11. 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. 12. 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. 13. An AI model may explain a night afterwards but can never change its status. ## Ask about a project (read-only, no auth) - MCP (Streamable HTTP): https://lights-on-watch.vercel.app/api/mcp Tools: list_projects, get_project, get_night, is_still_shipping, get_briefing, watch_project. Start with is_still_shipping { "slug": "revoke-cash" }. - REST (JSON, CORS open, cached 5 minutes), spec at https://lights-on-watch.vercel.app/api/openapi.json: - GET https://lights-on-watch.vercel.app/api/v1/projects?with=lastNight,history history = the last 90 nights as a 90-letter string, oldest first: S shipped, B building, Q quiet, D down, U unavailable, . no night - GET https://lights-on-watch.vercel.app/api/v1/projects/{slug} - GET https://lights-on-watch.vercel.app/api/v1/projects/{slug}/nights?from=yyyymmdd&to=yyyymmdd - GET https://lights-on-watch.vercel.app/api/v1/evidence/{hash} the canonical evidence bundle for a night - GET https://lights-on-watch.vercel.app/api/v1/manifest/{hash} the night manifest: every project-night of a nightly root attestation - GET https://lights-on-watch.vercel.app/api/v1/briefing/{address} backer briefing for a wallet or .eth name - POST https://lights-on-watch.vercel.app/api/v1/watch { "liveUrl": "...", "repo": "owner/name", "contract": "0x..." } rate-limited; after its first check succeeds the project is reachable by slug (unlisted) - Agent registration (ERC-8004): https://lights-on-watch.vercel.app/.well-known/agent-registration.json ## Verify a night yourself 1. Read the night: GET https://lights-on-watch.vercel.app/api/v1/projects/{slug}/nights. Each night has evidenceHash, attestationUid and, once attested, attestProof, attestLit30 and attestRoot. 2. Fetch the evidence: GET https://lights-on-watch.vercel.app/api/v1/evidence/{evidenceHash}. Hashing the canonical bundle gives evidenceHash. 3. Re-run the published rules (https://lights-on-watch.vercel.app/methodology) over that bundle: you get the same status. 4. One transaction per night: a Merkle root of every project's verdict. Look up attestationUid on Base (EAS 0x4200000000000000000000000000000000000021, for example base.easscan.org/attestation/view/{uid}); it is made by the watcher's registered agent and carries the root. Rebuild the leaf keccak256(abi.encode(bytes32 keccak256(slug), uint32 night, uint8 0, uint8 status 1-5, uint16 attestLit30, bytes32 evidenceHash)) and hash it up with attestProof (each step: keccak256 of the two hashes concatenated in ascending order): you land on the attested root. The manifestURI in the attestation lists every leaf of the night. 5. Live runs are attested one by one under the per-project schema: there the attestation's own fields carry the status, lit30 and evidenceHash. Nightly root schema (not revocable): bytes32 root,uint32 night,uint16 count,uint256 agentId,string manifestURI Root schema uid: 0xfe6c6dba61a36a6fbdf682e0d8bf3903a289ebb186e172c59aa9c578b673e726 Per-project schema, live runs (not revocable): bytes32 projectKey,uint32 night,uint8 kind,uint8 status,uint16 lit30,bytes32 evidenceHash,uint256 agentId,string evidenceURI Schema uid: 0x18fe45e82c5c9b1a176794774f023536a12794a76ee877ebfb0d713166e65d8b ## Notes - Night = UTC date yyyymmdd of the shift start; the nightly window is the 24 hours before 05:00 UTC. - Summaries are short plain text for people; use status and reasons for decisions.