Skip to content

Latest commit

 

History

History
374 lines (328 loc) · 87.4 KB

File metadata and controls

374 lines (328 loc) · 87.4 KB

Daily run contract — Post-AGI Planning

This file is the authoritative operational contract for the scheduled daily workflow. The scheduler prompt is a short pointer to it; everything the run must do, refuse, verify and report is written here.

It lives in the repository rather than in scheduler metadata for one reason: a 60,000-character contract stored in a scheduler field is not version-controlled, not diffable, not reviewable and not mirrored, so nobody — including the run itself — can see what changed or when. Here it is all four. The project already uses this pattern for REVISE-PREDICTIONS.md, which the run reads in full.

Change it by editing this file in a reviewed change, exactly like any other gate.

Additive campaign preservation and rebuild

The 07:00 Sydney actuals-only automation for both monthly timelines is governed by TIMELINE-DAILY-RUN.md. It reuses the evidence, transport, and publication guards here but does not inherit this document's separate forecast/author/book editorial work. Do not create another daily actuals collector or schedule. Its companion snapshot stays separate from canonical NEWS and retains its original scenario dates.

The owner-approved /game campaign is additive. After authorized canonical-data work and before the derived suite, run node build-game.js --write under the same normal pipeline owner. It regenerates the complete book/tool projection from current canonical source without changing forecasts, probabilities, author data, NEWS, reference receipts, METR or weekly X. Do not automatically invent or approve gameplay adaptations for changed/new forecast records. A valid GAME-only adaptation gap emits exact pending IDs and pauses new campaigns while retaining the current original-content archive. It does not relax any NEWS partition/provenance/freshness or reference coverage/review-integrity gate; those existing failures still block publication. Broken game builds, schemas, imports, vendor hashes or budgets also block publication.

The precise eleven active base game files and unchanged base limits are in game-policy.json; three.webgpu.min.js replaces, not supplements, three.module.min.js. The user deferred the unpublished cinematic extension; preserve its sealed session archive and do not restore any of its seven material/license paths to serving or mirroring. Do not download or regenerate art. Preserve the reader-first homepage, intent-loaded news-timeline.js, optional Explore tools and the separately reviewed ai-timeline.html companion. Keep canonical book/tool/rules/save identities and NEWS/reference/METR/X channel boundaries unchanged. The approved root aggregate is 432000 bytes; all other root/base/per-file limits remain. Companion dates are not renewed by daily collection. No wildcard surface, new browser origin, collector, schedule or paid service is authorized. Use run-gates.ps1 -IsolatedPreview for the derived suite so the runner owns and cleans up its loopback preview; do not stop another owner's existing preview. Ordinary scheduled runs keep the default real both-domain live-surface checks. -CandidateSurface is an explicitly labeled pre-publication candidate check, not a production verdict, and never replaces the real postflight. The first campaign launch additionally requires complete current mapping and full gameplay proof; its helpers are invoked with -RequireGameReady. Later valid gameplay-only gaps may pause the game, but never excuse an invalid underlying forecast/reference/NEWS bundle.


Daily auto-evolution of The Hitchhiker's Guide to the Singularity / Post-AGI Planning site. Every run must: (A) refresh the live-verified news evidence layer; (B) keep EVERY individual dated prediction and Post-Superintelligence Horizon item ACCOUNTED FOR — each one either carries a live-verified news citation or is explicitly recorded as having no qualifying source inside the currency window; (C) reassess the dated 2026–2040 forecast without daily wording churn; (D) maintain the undated, dependency-gated horizon; (E) refresh Reality Signals; (F) preserve Chapter 07's thesis and the current visual system; and (G) publish the same secret-free result to peterxing.com, post-agi-planning.vercel.app, and github.com/peterxing/post-agi-planning. Work autonomously. Never fabricate a source, ID, URL, text, author, publisher, byline, date, quote, provenance, mapping, metric, event, freshness claim, clinical result, engineering demonstration, or theoretical validation.

FILES AND SAFETY

  • Source: C:\Users\peterxing\pap-deploy
  • Vercel bundle: C:\Users\peterxing\pap-site
  • Forecast source of truth: C:\Users\peterxing\pap-deploy\predictions.json
  • Public evidence output: C:\Users\peterxing\pap-deploy\signals.json
  • Credentials and any private operational data: C:\Users\peterxing\pap-secrets only. Never print, serve, copy to pap-site, or commit anything from this directory. The retired X evidence corpus must not return. The separate weekly X workflow owns its private activity cache; this daily workflow neither modifies that cache nor collects X.
  • .pipeline.lock is local coordination state only. Never serve, deploy, stage or commit it; server.js, deploy.ps1 and publish-github.ps1 all reject it, and npm run verify:interlock proves that.
  • The public deploy surface is an ALLOW-LIST, not a deny-list. .vercelignore excludes everything with * and re-includes only index.html, app.js, styles.css, signals.json, predictions.json, author.json, vercel.json and LICENSE, so any new script, corpus, cache, ledger or log is excluded BY DEFAULT instead of being published because nobody remembered to add a deny rule. Production is served by the Vercel Git integration from the GitHub mirror, so the repository copy of .vercelignore is the live gate. Never widen it to ship a new file; npm run verify:surface enforces the shape and node verify-deploy-surface.js --live proves it on both domains.
  • Keep the Clawpilot theme intact. Use only existing var(--cp-*) color tokens and preserve the current accessible responsive design, illustrations, reduced-motion behavior, escaping/sanitization and verifiers.
  1. RUN CONTINUITY AND MISSED-RUN RECOVERY — DO THIS FIRST ACQUIRE THE TREE INTERLOCK BEFORE ANY OTHER STEP. Scheduled runs, the About-the-Author guard and interactive sessions all share the pap-deploy tree, and reading a half-applied tree is exactly the failure this prevents — so claim the tree BEFORE the first read of predictions.json, signals.json or evidence-floors.json and before any write. From C:\Users\peterxing\pap-deploy choose a unique owner id for this run (for example scheduled-forecast-yyyyMMddHHmm), export it as $env:PAP_PIPELINE_OWNER in every subsequent command block so guarded tools inherit it rather than deadlocking, and run: node pipeline-lock.js acquire --owner=$env:PAP_PIPELINE_OWNER --purpose=scheduled-forecast --wait=600 Exit 0 means the tree is yours for the whole run. Exit 75 means DEFERRED: another live actor holds the tree, this run has read and written nothing, and it must stop immediately — publish nothing, change nothing, report DEFERRED plainly as a distinct outcome that is NOT a verification failure, and never retry in a loop or force-break a live lock. A stale holder (dead pid, or a lock older than 90 minutes) is reclaimed automatically; report any reclamation loudly and treat the interrupted run it belonged to as a missed run. ALWAYS release at the very end, on success, failure and abort alike: node pipeline-lock.js release --owner=$env:PAP_PIPELINE_OWNER DEFERRED AND CATCH-UP ARE LINKED. A DEFERRED run published nothing, so it counts as "did not publish" for the continuity check below and the next scheduled run must treat it as a missed run and execute an explicit CATCH-UP. The same applies when this run reclaims a stale lock: whoever held it did not finish. Then, still before any evidence work, establish whether the previous scheduled run actually completed and published. Compare today's date against the updated fields in signals.json, evidence-floors.json and predictions.json, the sourceFetchedAt in signals.json, and the latest commit date in the GitHub mirror. If the previous run failed, was skipped, errored during session creation, was DEFERRED by the interlock, or never reached publication, treat today as an explicit CATCH-UP run: say so in the report and execute the complete pipeline rather than assuming the existing outputs are current. Never silently skip work because a file looks recent. LOCK LIVENESS IS PART OF CONTINUITY. At the start of every run, before any evidence work, read the interlock state and report it explicitly as one of: free; held (owner, purpose, lock age and HEARTBEAT AGE in minutes); or reclaimed-stale (with the reclaim reason). Print the heartbeat age for any lock you encounter or hold, and print your own final lock disposition — released, still held, or reclaimed — as the last line of the run. A run that ends without an explicit lock disposition line is an incomplete run and must be reported as such. If you reclaim a stale lock, treat the run that held it as a MISSED RUN under this section, absorb its work, and say so in the report. Never infer that a previous run succeeded merely because a lock file is absent or because a process is gone; confirm success against the published artifact timestamp on both live domains. HEARTBEAT AGE IS NOT A LIVENESS SIGNAL, AND THE ORPHAN GRACE IS THINNER THAN IT LOOKS. pipeline-lock.js justifies its orphan rule on the premise that every guarded tool heartbeats on entry and then every HEARTBEAT_MS (60 seconds) while it works. Independent monitoring of a live, healthy run on 2026-08-11 sampled the lock every 45 seconds and measured heartbeat ages far beyond that cadence: repeated 5-7 minute gaps and a peak of 11.3 minutes before the next beat, meaning a live run routinely misses ten or more consecutive beats. Nothing was at risk on that run — STALE_MINUTES is 90 and the orphan path additionally requires a dead supervisorPid — but the worst observed gap is 75 percent of the 15-minute ORPHAN_MINUTES grace, leaving under 4 minutes of margin. Therefore: never treat a stale-looking heartbeat as evidence that another holder is dead. A held lock means DEFERRED exit 75 regardless of heartbeat age, and only pipeline-lock.js itself may decide a reclaim. Never lower PAP_LOCK_ORPHAN_MINUTES or PAP_LOCK_STALE_MINUTES, and treat any change that narrows the margin between the worst observed heartbeat gap and the orphan grace as a concurrency regression. Report the maximum heartbeat age observed during the run on the same line as the lock disposition, and if it exceeds 12 minutes flag it as an anomaly rather than passing over it. A false reclaim is strictly worse than a deferral: it declares a LIVE run dead, and the reclaim path then instructs the next run to treat that interrupted work as a missed run. UPDATE 2026-08-11: this was fixed in code rather than left as a rule, so do not read the 15-minute grace or the under-4-minutes margin above as current. ORPHAN_MINUTES now defaults to 30 minutes, putting 18.7 minutes of margin against the worst observed 11.3-minute silence, and PAP_LOCK_ORPHAN_MINUTES, PAP_LOCK_STALE_MINUTES and PAP_LOCK_HEARTBEAT_MS now ratchet one way only: an environment variable may make each gate stricter but can never weaken it, the same monotonic rule evidence-floors.json applies to the coverage gates. Correct the mechanism too, because the premise above understates it: the heartbeat does NOT beat every 60 seconds throughout a run. It advances when a guarded tool ENTERS, and then every HEARTBEAT_MS only for as long as that tool own process stays alive, so nothing beats at all between guarded tools and multi-minute silences are normal, healthy and expected rather than a symptom. Heartbeat age is an ACTIVITY signal, not a LIVENESS signal. verify-interlock.js now proves the grace stays at or above 30 minutes and that a narrowing environment variable is refused, so this is enforced by a gate rather than by memory. A RUN STATUS IS NOT A LIVENESS SIGNAL EITHER, AND A STUCK ONE SILENTLY DISABLES THIS AUTOMATION. On 2026-08-09 a manual run of the predictions workflow was recorded status=running with completed_at NULL and never left that state, because its workspace row had been deleted while its session row survived: the run was orphaned, not slow. A non-terminal run suppresses BOTH the scheduled tick and any manual trigger, so nextRunAt passed 4.9 hours without firing and run_workflow refused with "already running". Nothing self-corrected and the workflow stayed dark for two days, while the author workflow on the SAME host and the SAME scheduler ran normally every day, so a healthy sibling workflow is not evidence that this one is running. Toggling enabled recomputes nextRunAt but does NOT clear latestRun, making it necessary and insufficient. Every run must therefore establish its own continuity from durable state only: a completed_at timestamp, the published artefacts fetched from BOTH live domains, and the coverage counters. Never infer it from a status field, from updated_at, or from any age-like field, because sessions.updated_at and get_session.updated_at both under-report activity by hours or days on runs that demonstrably completed, and heartbeat age measures activity rather than liveness. If a run finds its own previous run recorded as non-terminal with no completed_at, it must report that explicitly as a stalled-automation anomaly naming the stuck run ID and its start time, state how many scheduled ticks were missed, and proceed as a CATCH-UP. It must never mark such a run completed: completed launders a run that never happened into the history the next tick reads, and failed is the only honest terminal state for work that did not finish. READ THAT TRIGGER BROADLY, BECAUSE ITS NARROW FORM WOULD NOT HAVE FIRED ON THE INCIDENT THAT PRODUCED IT. Once the stuck run above was repaired it was recorded failed WITH a completed_at, so a run testing only for "non-terminal with no completed_at" would find the condition absent and reason its way back to NORMAL with this paragraph apparently blessing it. A predecessor recorded failed is a failed predecessor whether or not it carries a completed_at, and whether it was marked so by the scheduler, by a human, or by a repair: the terminal state records how the run ENDED, not whether its work was DONE. Treat non-terminal, failed, skipped, errored, DEFERRED and never-published as one class, and on any of them declare CATCH-UP explicitly. VERIFIED-CURRENT PRODUCTION DOES NOT LICENSE A NORMAL DECLARATION. It proves only that the LAST publish succeeded; it can never prove that NO TICK WAS MISSED, and those are different claims. Throughout the 2026-08-09 to 2026-08-11 outage both live domains served a complete, valid, internally consistent, fully-accounted build the entire time, so a run that accepted healthy artefacts as proof of a healthy schedule would have declared NORMAL on every single day the workflow was dark. The continuity test above is a CONJUNCTION and completed_at comes first: artefacts and coverage counters corroborate it, they never substitute for it. CATCH-UP is a statement about the predecessor RECORDED STATE, not a forecast of how much work will be found, so declare it even when the rebuild then finds nothing to absorb, and say so in that case: name the failed run and its start time, state how many ticks were missed, note that production was verified current on both domains, and confirm the full pipeline ran regardless. INFRASTRUCTURE FAULTS ARE NOT EVIDENCE FAULTS. If a step fails from a transient infrastructure error — session/network creation failure, DNS or socket error, HTTP 5xx, rate limiting, a feed or publisher timeout, a publisher bot-challenge/interstitial, or a Vercel/GitHub API blip — retry that step up to 3 times with exponential backoff (about 30s, 2m, 5m) before treating it as fatal. Never convert a transient infrastructure failure into an evidence change: do NOT drop a mapping, lower a floor, demote or expire a sticky approval, substitute external evidence for Peter evidence, drop or re-review a currency reference, mark a status unavailable, or weaken any gate because a network call failed. If retries are exhausted, STOP, leave the published site exactly as it is, release the interlock, and report the precise failing step and error. Always distinguish in the report: infrastructure failure (retry, then stop having changed nothing) versus interlock DEFERRAL (stop having read nothing, next run catches up) versus genuine evidence/verification failure (fail closed, no publish). Never publish a partially completed pipeline.

  2. EVIDENCE CONTRACT — EVERY PREDICTION ACCOUNTED FOR — HARD DAILY PUBLICATION GATE X-AS-EVIDENCE IS RETIRED; THE SEPARATE X SUPPLEMENT IS AUTHORIZED. The owner's August 13 retirement applies to NEWS (signals.embeds, signals.context, signals.uncited and evidence accounting) and signals.referencePoints: these channels must remain X-free. No X status, permalink, owner, quote or API result may become a NEWS citation, dated NEWS context or reviewed reference source. Retired X evidence floors and ingest files (x-archive.js, verify-peter-evidence.js, review-evidence-candidates.js, verify-id.js, harvest-loop.js, evidence-approvals.json) must not return. evidence-families.js remains the shared concept/family matcher, not an X evidence ledger.

The owner's August 26 authorization permits only the separately labelled signals.xSignals supplement and its UI, with public post links, honest activity dates and explicit non-evidence wording. Only the weekly workflow collects X under XSIGNALS-RUN.md; daily and author workflows preserve this supplement without recollecting, rebuilding or advancing its timestamps. Daily must not invoke x-harvest.js, x-signals.js --write, X API, syndication, oEmbed or Wayback discovery, including as diagnostics. An unavailable weekly harvest does not block independent maintenance when the retained supplement still passes its existing validity guards. Invalid/stale bindings remain a refusal for the weekly owner to resolve, not permission to delete or fabricate activity. Verify channel isolation, not a blanket text ban across signals.json, app.js or index.html. Set-Location C:\Users\peterxing\pap-deploy and run, in exactly this order: node refresh-metr.js node refresh-reference-points.js --refresh node refresh-signals.js

METR MEASURED CAPABILITY LAYER - SEPARATE FROM NEWS AND EDITORIAL FORECASTS

  • The daily source pass first runs node refresh-metr.js under the same interlock. It checks only METR's fixed-version primary YAML with conditional requests, 12-second request/size bounds and at most three attempts. A future Retry-After is persisted and respected; do not bypass it.
  • Collector exit 0 means a valid 200 or conditional 304. Exit 10 means source unavailable or refused schema: this optional measurement layer atomically records the error, retaining every last-good measurement and original source timestamp. Continue the NEWS pipeline normally and publish the explicit METR stale/unavailable state if all gates pass. This is an explicit exception to the general infrastructure-stop rule above: it cannot change news accounting or forecasts. Exit 75 is still interlock DEFERRED (no write); stop the entire run. Other failures stop the run.
  • signals.capabilities.metr holds the two most recent successful 200 snapshots, checksum, ETag/Last-Modified and independent check/fetch dates. A 304 updates check/health only, not measurement, dataset or successful-fetch dates. A first snapshot has no site-change history. The ordinary producer preserves and validates this layer, including during weekly builds.
  • The reviewed v1.1 unit is HUMAN-EXPERT MINUTES at 50% or 80% task success, with 95% intervals; model release date is NOT evaluation or publication date. Those dates remain unknown where METR does not supply them. HTTP Last-Modified is only a file timestamp. Exclude v1.0 rows from v1.1 comparisons; task-revision or scaffold changes invalidate like-for-like comparisons. Display METR's warning that estimates above 16 hours are unreliable for its current task suite.
  • This is a scoped software/ML/cyber capability instrument, not an AGI meter, runtime measure, all-job automation claim or NEWS context/citation. Its context-only relation to 2026-0 is pinned to exact forecast text; changing that text removes the relation. No composite forecast is resolved, no probability is updated, and no new trajectory verdict is inferred.
  • Run the derived suite including verify:metr. Report actual fetch/check times, source revision, source errors and last-good retention separately from news freshness. Collection is daily; METR releases measurements periodically without a guaranteed cadence. Browser five-minute polling reads published artifacts only. No new scheduler or cloud resource is required.

REVIEWED REFERENCE POINTS - A COMPLETE, SEPARATE PREREQUISITE ROSTER

  • Before the ordinary producer, run node refresh-reference-points.js --refresh. The reviewed reference-ledger.json binds each individual dated/horizon ID to its exact full forecast content and text fingerprints, a canonical primary source, a narrowly mapped facet, relation/direction, exact excerpt, bespoke relevance and explicit limitations. This sibling signals.referencePoints channel does NOT change NEWS cited/context/uncited counts, X, measured METR records, source dates or author probabilities.
  • Audit ALL current IDs dynamically, not a fixed 103. A changed, removed or renumbered forecast invalidates its old mapping and queues renewed review. Missing or never-verified references return collector exit 2 and block publication; identify every gap by ID, acquire a defensible source and review it individually. Do not fill gaps with generic AI articles or forced positive evidence. Real prerequisites, constraints, trials, deployments, policies and theoretical proposals are useful when labelled precisely. Registration is not efficacy, a proposal is not enacted policy, a company claim is not independent replication, and a precursor is not the forecast being achieved. Existing whole-forecast assessment requirements are unchanged.
  • Re-fetch each canonical source at most once per daily pass, with conditional ETag/Last-Modified, 15-second total request bounds, a 4 MiB decompressed-body ceiling and exact reviewed redirect URLs. A source explicitly reviewed for browser uses the existing first-party browser transport: 45-second navigation plus a bounded six-second settle, a 4 MiB returned-document cap and pre-navigation URL approval. Browser reads do not invent ETags or conditional responses. The PRIME reference is the specifically reviewed public ClinicalTrials.gov v2 NCT study endpoint, parsed as JSON and validated against its NCT identity, protocol fields and actual first-post date. Sponsor-submitted registered endpoints are not completed outcomes. dateEvidenceUrl, where declared, is the same-publisher parent report supplying a chapter's publication date; fetch and verify that exact page as well, without inventing a chapter date. Only transient HTTPS faults get one short bounded retry; persist/honour Retry-After. No external client-side calls, new scheduler, account or paid source is introduced.
  • Verify the selected excerpt and publication-date evidence against the actual fetched HTML, including text across inline tags. A 304 advances the source check only. Source retrieval, publication, mapping review, excerpt verification and layer update times remain separate. Missing publication dates stay null with original precision, never replaced with fetch time. Foundational literature has NO 14/365-day age cap here; retain its real age and explain why its specific mechanism is more relevant than a newer tangential story.
  • Source outage/changed excerpt preserves the last-good reviewed mapping, source dates and verification hash with a visible unavailable/changed warning. This reference-layer health exception, like METR's, may publish if prior source verification exists and all gates pass; it cannot justify dropping NEWS evidence, changing probabilities or declaring capability decline. A changed/missing excerpt queues actual semantic re-review; never auto-approve new text by overlap score. If an alternative source supersedes it, record a new reviewed source decision, not an invented fresh timestamp on the old source. Unchecked sources become visibly stale after seven days; study age is a different concept.
  • Review canonical deduplication and the explicitly declared reuse family/domain/ID policy. Each source may serve at most six individually justified mappings; repeated rationales are refused. Display actual reused-source counts, not independent corroboration counts. Keep each excerpt short and avoid publishing large cumulative extracts from one source.
  • The full producer deterministically rebuilds this layer from the ledger and preserves its source health on daily AND weekly builds. Run derived verify:references before publication and report mapped/total IDs, canonical source count, relation mix, invalidations/gaps and source warnings independently from the unchanged news partition. --live rechecks all excerpts without writing. A new discovery is a candidate until a reviewer grounds its meaning, scope, dates and limitations in the source; this contract authorizes review, never automatic approval.
  • Every daily forecasting run must also make a bounded newest-vintage review for routine statistics in the roster, especially monthly employment, annual company revenue and annual robot stock/density. Consult the publisher's latest-release page/calendar and compare the SAME definition, geography, denominator and reporting period; do not change annual stock into installations, annual revenue into quarterly sales, or employment into labor-force participation just to obtain a newer number. Record the actual release and measurement period. If no newer compatible release is available, retain the explicitly dated baseline and report that result without calling it newly measured. Foundational theory and controlled experiments need not be replaced merely because they are old.
  • Fixed policy PDFs are not proof of continued policy currency. The RSP reference declares its official Anthropic version index; the collector checks the index even after a PDF 304. A superseding/unreadable version queues renewed review and preserves the dated last-good reference with a visible warning. Treat other fixed-vintage claims as true only as of their recorded review, and inspect their official current-version/release pages during maintenance.
  • When a better direct source, missing metric proof, changed excerpt or forecast invalidation is found, review the affected ID's meaning and limitations before updating its ledger row. New records must pass a fresh full-content receipt; an earlier 304 cannot approve a changed review. Source availability is not renewed scientific approval. If the editorial stage changes any forecast, renew affected mappings and re-run the reference collector before the FINAL signals producer and publication gates. Never edit forecast content merely to make a match.
  • Exit 75 remains full-run DEFERRED. Unexpected errors stop the run. During a preserve-content feature run, do not invoke the editorial forecast rewrite just to rebuild references.

THE CONTRACT IS TOTALITY, NOT COVERAGE. The former gate demanded N/N direct evidence, which is unreachable when evidence must be both genuinely supporting AND published in the last 14 days. Replacing it with "as many as we found" would have been a silent weakening, so it was replaced with a STRICTLY STRONGER property: every prediction must be explicitly ACCOUNTED FOR in exactly one of three channels, and the three channels must partition the prediction set with no gap and no overlap.

  • CITED: the prediction carries a live-verified news citation meeting every bar below.
  • CONTEXT: the prediction carries the MOST RECENT genuinely-supporting article found at ANY age, live-verified by the same fetch-and-quote machinery as CITED, published with its true publishedAt, its real age in days and its age bucket, and rendered visibly as dated background rather than current evidence.
  • UNCITED: the prediction is explicitly recorded in signals.uncited with the reason, the search statement, searchedAt and windowDays — an honest, published, machine-checkable declaration that a real search ran and found nothing qualifying. Required result, computed dynamically from predictions.json:
  • Let N be the count of dated YEAR-INDEX predictions plus horizon-ID items (103 as of 2026-08-13). cited + context + uncited MUST equal N exactly, with ZERO ids in two channels at once and ZERO ids in none. app.js's hasCompleteSignalCoverage() enforces this at render time and blanks BOTH channels if it fails, so a partition defect publishes an empty page rather than a misleading one.
  • ZERO prediction search fallbacks. signals.search must be absent/null/empty and the rendered site must contain zero prediction search chips.
  • EVERY PREDICTION MUST BE MAPPED TO A REAL ARTICLE WHERE ONE EXISTS, AND RECENCY IS SPLIT FROM RELEVANCE. The CITED channel keeps its exact current meaning and its strict 14-day window: never widen it, never relax the relevance gate, never admit a weaker source into it, and never reclassify a prediction to raise the cited number. What changes is that a prediction with no in-window source is no longer left with nothing: search WITHOUT the recency ceiling and attach the most recent genuinely-supporting article found at any age to the CONTEXT channel. THE RELEVANCE GATE IS IDENTICAL IN BOTH CHANNELS -- only the recency ceiling differs, and an article that fails relevance fails it at every age. "Most recent" means the most recent article that PASSES the unchanged relevance gate, sorted by true publishedAt descending, never the first one found or the easiest to source. A CONTEXT article must pass the same live fetch and verbatim-quote verification as a CITED one; there is no second, looser path. If no genuinely-supporting article exists at any age, the prediction STAYS UNCITED -- completeness never outranks truth, and an unfindable source is reported, never invented. The uncited channel therefore narrows and strengthens: it now asserts "no supporting article was found at ANY age", which is a stronger claim than "none in 14 days".

NEWS EVIDENCE BAR (news-evidence.js / npm run verify:news)

  • A URL is far easier to hallucinate than to verify, so the bar is high and every mapping must clear all of it. Live-fetch at review time AND again immediately before deploy/publish, requiring HTTP 200 on the FINAL URL after redirects and recording the resolved URL rather than the input. Carry headline, publisher, byline and publication date EXTRACTED FROM THE FETCHED PAGE (og:/schema.org/rendered), never from memory or inference. Carry an exact verbatim supporting sentence plus a SHA-256 of the extracted main text, re-checked at publish. A missing quote, or a changed headline, publisher or date, FAILS CLOSED.
  • DECLARE WHERE THE DATE CAME FROM. publishedAt names two different facts — the feed's pubDate and the article's own dateline — and they routinely disagree on a genuine article. Every citation MUST carry publishedAtSource naming which one it is ('page' or 'feed'); an undeclared disagreement, a declaration contradicted by its own source, or an unrecognised token all fail closed. Never change a date to resolve a disagreement; declare its provenance.
  • EXTRACTED METADATA IS EVIDENCE AND CAN BE SILENTLY WRONG. MEASURED 2026-08-24: the meta-attribute pattern excluded both quote characters regardless of which one opened the value, so a straight apostrophe inside a double-quoted attribute ended the capture early — "Ukraine's one-time test used fully autonomous drones to kill Russian soldiers" was extracted as "Ukraine", and "Facing US export controls, China's DeepSeek plans to make its own chips" as "Facing US export controls, China". The match SUCCEEDED, so nothing failed: a truncated headline would have been stored, rendered to readers as the article's title, and then confirmed "unchanged" forever by comparing one truncation against another. verify:news now carries an offline regression proof pinned to those exact strings ("an apostrophe in a headline or publisher is not read as a delimiter"). Treat any silently-shortened publisher, headline or byline as an evidence fault, never as a cosmetic one.
  • THE 14-DAY WINDOW IS THE OWNER'S INSTRUCTION ("references based on the latest news from the last 2 weeks"). It is registered as currencyMaxAgeDays in evidence-floors.json and is the only term in the comparison the thing under test cannot rewrite. The implemented rule is Math.round(ageDays) > ceiling, so demotion fires at 14.5 days, not 14.0 — that is the registered semantics, stated explicitly rather than left to be rediscovered. An article outside the window is not a CITED citation. It is not discarded either: it is the CONTEXT channel's raw material, and the most recent out-of-window article that passes the FULL relevance and source-quality bar becomes that prediction's CONTEXT entry, carrying its true age. The window governs which CHANNEL an article may enter; it never governs whether the article was worth finding.
  • REJECT: 404/410, paywalled-unverifiable, aggregators, syndicated republishers, press-release mills, SEO/AI content farms, link shorteners, open publishing platforms and anything without an identifiable real publisher. PREPRINTS ARE INADMISSIBLE — arxiv, biorxiv, medrxiv, ssrn, researchgate and any other unreviewed preprint or open-repository server are a claim, not a finding. THIS LIST IS ILLUSTRATIVE, NOT EXHAUSTIVE, AND READING IT AS EXHAUSTIVE IS HOW THE BAR GETS CROSSED WITHOUT ANYONE DECIDING TO CROSS IT: the test is whether the record carries peer review or editorial responsibility, never whether its host happens to be named here. A preprint is a legitimate DISCOVERY channel and an illegitimate EVIDENCE channel — use a hit to locate the reviewed publication or the reported story and cite THAT, exactly as the feed is used to locate the page. If no reviewed or reported version exists, the claim stays a claim and the prediction stays UNCITED. REQUIRE primary/original reporting, official lab/company/agency/regulator announcements, peer-reviewed journals or named expert analysis. Every source carries a sourceQuality the UI can actually name; a value that would render as a generic "Verified publication" fails, because that silently erases the peer-reviewed / first-party-lab / independent-press distinction.
  • ANTI-ADJACENCY. The article must specifically support THAT prediction. Never attach broad AI/space/economy coverage across unrelated claims, and never loosen a terminology, facet or disambiguation guard to make a match fit. NO AUTO-APPROVAL: mappings are reviewed and bound to the exact predictionText with rationale, evidenceType, reviewedAt and lastVerifiedAt. Changing predictionText invalidates those bindings, so re-run the evidence chain afterwards.
  • Unique sources first. Reuse is allowed only inside an explicitly reviewed compatible concept family or threshold/scenario series, and never above the recorded reuse ceiling. Diversify with additional reviewed sources rather than stretching one article.
  • For far-future/conditional claims a source may be a precise scenario source or concrete leading indicator, but the data and UI must label it as such rather than as proof the prediction will occur.
  • Preserve disambiguation: mathematical/latent/J-space/rulial space is not off-world space; market cap is not a compute cap; building permits are not compute/robot-production permits; political power is not electrical power; continual model learning is not education; generic search agents are not truth advisors; peripheral EMG is not a BCI; endovascular BCIs are minimally invasive, not non-invasive; connectomes are not uploads; orbital storage/edge inference is not a hyperscale data centre; filings are not deployed capacity; solar satellites are not yet a Dyson swarm; Kardashev is a classification, not measured progress; Transcension and the ruliad are theories/frameworks, not demonstrated technologies.

THE UNCITED CHANNEL IS EVIDENCE OF A SEARCH, NOT AN EMPTY SLOT

  • Every uncited entry must carry a reason, a statement of what was searched, searchedAt and windowDays. A blank, a placeholder, a copied reason or a stale searchedAt is a fabrication of diligence and fails closed exactly like a fabricated quote.
  • A CONTEXT ENTRY MUST DECLARE ITS AGE WHERE THE READER CAN SEE IT. Publish publishedAt, the age in days and the age bucket on every CONTEXT card, and label it as dated background -- never in the same "News evidence - , " style as a CITED card. A reader must be able to tell a 200-day-old article from a 3-day-old one without clicking. If a CONTEXT card cannot render its true age, it must not render at all. NEVER render an uncited prediction as though evidence exists, and never fill a gap with a weaker source to shrink the channel. "We looked, in this window, with this statement, and found nothing that genuinely supports this claim" is a true and publishable statement; a stretched citation is not.

CONTEXT SWEEP — RUN EVERY DAY, AFTER THE 14-DAY EVIDENCE PASS AND BEFORE ACCOUNTING

  • Enumerate every prediction id that the 14-day pass left without a CITED citation. Enumerate it as a ROSTER OF IDS, never as a count: a count says some are missing, a roster says which, and only the roster survives contact with a reader or a reviewer.
  • For each such id, search WITHOUT the recency ceiling, apply the IDENTICAL relevance, anti-adjacency, disambiguation and source-quality bars used by the 14-day pass, sort the survivors by true publishedAt descending, and take the most recent one. Nothing about the bar moves; only the ceiling is lifted.
  • Verify the chosen article exactly as a CITED article is verified: live fetch at selection time and again immediately before publish, HTTP 200 on the FINAL url after redirects, publisher and headline read from the fetched document, verbatim quote present in the fetched body, and publishedAtSource declared. A CONTEXT entry that cannot be re-verified immediately before publish is dropped back to UNCITED rather than published on trust.
  • Record ageDays from the true publishedAt at build time and bucket it (<=14d, 15-30d, 31-90d, 91-365d, >1yr). A CONTEXT entry whose age cannot be computed is not publishable.
  • A prediction with NO qualifying article at ANY age stays UNCITED and is named in the run report by id. This is the fail-closed case and it is a legitimate outcome: an unfindable source is reported, never invented, never approximated, and never replaced by an adjacent or weaker one to close the gap.
  • THE SWEEP'S DISCOVERY CHANNEL MUST NEVER BECOME ITS EVIDENCE CHANNEL. Harvesting from a bulk index — a preprint API, an aggregator feed, a search endpoint — is a legitimate way to FIND a lead and never a way to CITE one. Measured on 2026-08-15, the first backfill harvest returned 1036 of 1036 candidates from arxiv.org and would have cited 87 predictions to unreviewed abstracts had they been bound directly; the harvest was correct, treating it as evidence would not have been. Before any candidate is bound, assert its host is not a preprint or open-repository server and that it clears the FULL source-quality bar, and report the count DROPPED by that assertion rather than only the count kept. A CHANNEL THAT LOWERS THE SOURCE TYPE IS NOT THE SAME THING AS A CHANNEL THAT LIFTS THE RECENCY CEILING, and only the second was authorised.
  • A QUALITY LABEL ASSIGNED BY THE HARVESTER IS NOT A QUALITY JUDGEMENT. sourceQuality must be derived from what the fetched page actually is, never copied from the index that supplied the lead, because a label that renders as reviewed on an unreviewed record is a false provenance claim rather than a wrong field.
  • NEVER synthesise a url, headline, publisher, byline, date or quote, and never reuse a CITED article's metadata for a different prediction to manufacture coverage. A fabricated citation is not a bad number on a dashboard; it is a false claim on a published page, and it is the single worst failure available to this automation.
  • Roster refusal runs in BOTH directions before publish: every prediction id must land in exactly one channel, and every embed or context key must resolve to a live prediction id. Leftovers in either direction are named and the run fails nonzero.

BROWSER DISCOVERY — RUN BEFORE DECLARING ANY ABSENCE (browse-evidence.js / npm run verify:browse)

  • THE OWNER'S INSTRUCTION: "if you can't match any news sources or x posts, try using computer use to scrape the information through browsing. include this in the daily automations".
  • WHY IT EXISTS. Discovery reached publishers only through a fixed feed harvest and every candidate was read with a plain HTTPS GET. A publisher with no feed for the relevant section, or one that refuses non-browser clients or renders the article in JavaScript, was never seen — not judged and rejected, simply unreachable. "No authoritative source published in the last 14 days was found" then reads as a statement about the WORLD while being partly a statement about the TRANSPORT. Browsing exists to make that sentence true before it is published.
  • WHEN: after the 14-day evidence pass AND the context sweep, for every id still without a CITED or CONTEXT entry, and BEFORE the uncited statements are written. Browsing is a discovery step, never a publication step.
  • BOUND THE RUN, AND ROTATE. Browsing is minutes per prediction, so browsing every uncited id every day would turn a bounded daily job into an unbounded one and eventually into a run that never finishes. Spend a FIXED budget per run — --limit=12 is the default working figure — and rotate through the uncited roster across days rather than restarting at the top each time, so every id is reached on a predictable cycle instead of the first twelve being browsed repeatedly and the tail never at all. Record in the report which ids this run browsed and where the rotation resumes tomorrow. If a run is already long or the interlock is contended, browsing is the first thing to shorten: it discovers leads for a human to review later, so deferring it costs a day of discovery and never costs correctness.
  • HOW: npm run browse:report for the roster, then npm run browse -- --ids=<roster> --searches=6 (add --publishers= to narrow, --limit= to bound the run). The search surface is the PUBLISHERS' OWN on-site search pages, every host already on the egress allow-list. NEVER a web search engine and never an aggregator: its results page is exactly the aggregator hop the source-quality gate exists to refuse.
  • PROPOSALS ARE NOT EVIDENCE. browse-evidence.js writes browse-evidence-proposals.json and nothing else; the build never reads that file and verify:browse asserts it. Promotion into news-evidence.js is a REVIEWED ACT: judge each proposal on the merits — does this article actually evidence THIS prediction? — then write the ledger row with its rationale, evidenceType, reviewedAt, publishedAtSource, verbatim quote and textSha256, and re-run node refresh-signals.js and npm run verify:news. Never bulk-promote, never promote a proposal you have not read, and never promote one to improve a ratio.
  • THE GATES ARE IMPORTED, NEVER RESTATED. GATE 1 (curated subject), GATE 2 (distinctive shared term at DEFAULT_MIN_SCORE), the source-quality bar, the verbatim quote, the text hash and the 14-day window all come from the existing modules unchanged. The ONLY thing this channel changes is what can be REACHED. If the honest reach is small, the small number is the true one and the residue STAYS UNCITED. A browsing channel that also lowered the bar would close the gap on paper — precisely the substitution the 1036-abstract arXiv harvest attempted, and it must not be repeated in a new costume.
  • 365-DAY DISCOVERY CEILING, AND WHY IT IS NOT THE CURRENCY WINDOW. A publisher's site search reaches its entire archive, while the imported gates were built to rank a pool of RECENT feed items where nothing is old. MEASURED on the first working run: a 2011 Ars Technica primer on corporate valuation — 5,486 days old — cleared both gates for the 2026 trillion-dollar-valuation prediction. The ceiling bounds what may be PROPOSED; it is a TIGHTENING and never a widening, and it is deliberately not the 14-day window, because CONTEXT legitimately carries older background — but its published sentence is "the most recent authoritative source found for this prediction", which an article from the previous decade cannot make true.
  • A QUOTE IS SELECTED, NEVER COMPOSED — AND INTERFACE CHROME IS NOT PROSE. MEASURED: the first genuinely on-topic proposal selected a navigation column ("Text settings Story text Size Small ... Subscribers only ... Minimize to nav ...") as its supporting quote. It was verbatim in the extracted text, it carried the distinctive term, and it was still menu furniture. A supporting quote must read as reporting. Never hand-tidy a chrome quote into a usable one: fix the selector or leave the prediction uncited.
  • TRANSPORT IS DECLARED PER SOURCE AND FAILS CLOSED. A reviewed row may declare transport:"browser" for a publisher that refuses a plain GET; every other row takes the ordinary fetch. The build opens a browser ONLY if such a row exists, and REFUSES to verify one with the plain fetch it is declared to fail rather than reporting the resulting failure as though the article had moved or gone. Provenance then records browser-render+quote-match, so a browser-read citation is never indistinguishable from a fetched one. Always propose the CHEAPEST transport that actually works, so the build acquires no browser dependency it does not need.
  • RUN npm run verify:browse --silent EVERY DAY. It is the executable proof that this channel adds reach without lowering the bar: the proposals file is unreadable by the build, the thresholds are imported rather than restated, aggregators and non-article surfaces are refused before a page is opened, a rendered bot challenge is still not an article, the discovery ceiling is enforced, chrome is refused as a quote, and the transport enumeration is closed and fail-closed.
  • REPORT WHAT BROWSING REACHED AND WHAT IT ADMITTED: predictions browsed, publishers searched, candidates rendered, proposals produced, how many were CURRENT versus ARCHIVAL, how many required the browser transport, and how many candidates were refused at each stage. Browsing that finds nothing is a legitimate and reportable outcome — it is what makes the uncited statement true, not a failure to be hidden.

TRAJECTORY MATCHING AGAINST THE EXISTING HARVEST — RUN THIS BEFORE BROWSING, IT IS FAR CHEAPER

  • THE OWNER'S STANDING INSTRUCTION, restated 2026-08-24: "it's still showing 'No authoritative source published in the last 14 days was found for this prediction' for the majority of predictions - match it to the closest news article you can find online that points towards that trajectory." Read that as: the CONTEXT channel should be worked hard. A real, live-verified article that POINTS AT the trajectory is publishable as dated background with its true age; only a genuinely unfindable source leaves a prediction uncited.
  • node match-trajectory.js --top=4 ranks the existing 53-feed harvest (currency-candidates.json, ~1,900 real articles from ~48 allow-listed publishers) against every prediction that has no mapping, and writes trajectory-matches.json. This costs seconds and needs no browser, so run it FIRST and browse only for what it cannot reach.
  • IT RANKS; IT DOES NOT ADMIT. Read the candidates. A high score is not a verdict — it is a claim that two texts share distinctive vocabulary, which is not the same as being about the same thing.
  • WORD SENSE IS THE DOMINANT FAILURE MODE HERE, AND SCORES DO NOT SEE IT. MEASURED on 2026-08-24, every one of these scored a TITLE match and every one is wrong: macrophage "polarization" for political polarization; lab-grown diamond "auctions" for compute-permit auctions; an implantable myoneural "actuator" for industrial actuators; single-cell embedding "interpretability" for mechanistic interpretability; UN coverage of a South Sudan "election" for AI becoming an election issue. MEASURED AGAIN on 2026-08-27, as top-ranked candidates: protein-data "alignment" for AI alignment-as-a-science; "Managed Compute" for a "Managed branch" prediction; the same myoneural actuator, again, for capital flowing into industrial actuators. Reject them and say so; the reviewer is the only part of this pipeline that can tell two senses of a word apart.
  • THE SAME URL CAN OCCUPY MORE THAN ONE CANDIDATE SLOT. MEASURED 2026-08-27: an Ars Technica clean-energy piece filled two of three slots for 2037-1. Deduplicate by resolved URL when reading, because two slots holding one article looks like corroboration and is not.
  • THE PIPELINE FROM A CANDIDATE TO A LEDGER ROW, AND WHY IT HAS NO TYPING IN IT: node assess-url.js --in=candidates.json --out=assessed.json # live fetch, extract, propose verbatim quotes node promote-from-assessed.js # re-fetch, re-quote-check, emit ledger rows node insert-rows.js # splice the emitted rows into news-evidence.js assess-url.js proposes candidate sentences READ OFF THE LIVE PAGE and promote-from-assessed.js selects one BY INDEX. Never retype a quote into a verdict: a hand-copied sentence puts a transcription step between the page and the published citation, and a dropped clause or straightened apostrophe would be published as verbatim and then fail its own drift check later.
  • REUSE FAMILIES ARE CHECKED AT BUILD TIME AND WILL FAIL THE RUN. Measured: promoting an IEEE humanoid-welding article for a second prediction under a new family name aborted refresh-signals.js with "invalid reviewed reuse". One article serving two predictions is legitimate — it is one source used twice — but both mappings must declare the SAME reuseFamily. Check the existing mapping's family before inventing one.
  • SOME PUBLISHERS FAIL EXTRACTION AND THAT IS A REFUSAL, NOT A DEFECT TO ROUTE AROUND. JS-only pages yield no prose and are refused rather than published with a guessed quote; try the browser transport, or leave the prediction uncited.
  • THE MISSING-PUBLISHER CASE IS NOW FIXED, AND THE FIX HAS A SHAPE WORTH COPYING. First-party lab posts (anthropic.com, research.google) serve a headline, a date and full body text but declare no publisher through ANY tag or JSON-LD field, so extraction failed closed and those labs could not be cited at all — a blind spot aimed at exactly the wrong sources, since primary frontier-lab publications are among the most relevant here. REVIEWED_HOST_PUBLISHERS in news-evidence.js now supplies the publisher NAME for a reviewed list of hosts, consulted LAST so a page that names itself always wins, matched on the exact normalised host so lookalikes and subdomains still miss, and supplying nothing but the name — never a headline, date, quote or claim. ADDING A HOST IS A REVIEWED EDIT, not a workaround for a page that simply failed to load: if the body text is missing too, refuse as before. verify-news-evidence.js proves all three properties (fills, never overrides, never invents) and mutation-testing confirmed the proof bites.
  • EVERY NEW PUBLISHER HOST IS A REVIEWED EDIT IN TWO PLACES: ALLOWED_EGRESS_HOSTS in verify-deploy-surface.js, and the source-quality judgement itself. An undeclared host fails the surface gate closed, which is the gate working. THIS APPLIES TO HOSTNAMES IN VERIFIERS TOO, INCLUDING FAKE ONES: a synthetic domain invented for a test assertion reads as undeclared egress and correctly failed the run on 2026-08-27. Prove a negative with a host that is already declared and genuinely absent from the list under test, rather than inventing a domain.
  • THE CHANNEL IS DECIDED BY RECENCY, NOT BY YOUR JUDGEMENT OF STRENGTH. An article inside the 14-day window is published as a CITATION even when the rationale says it only points at the trajectory; outside it, the same article is dated background. Do not write a rationale asserting which channel an item will land in — on 2026-08-27 a rationale claimed an item was "recorded as background rather than as a citation" and the age-based rule published it as a citation, so the published text contradicted the published placement. State what the source does and does not show, and let the pipeline place it.

PROMOTING A DISCOVERY INTO THE LEDGER — THE ONLY PATH FROM A LEAD TO A CITATION

  • THE STANDING INSTRUCTION IS TO CLOSE THE UNCITED CHANNEL WHERE A REAL ARTICLE EXISTS: "make sure all the predictions have a reference to a news article instead of 'No authoritative source published in the last 14 days was found for this prediction' - try to find the closest and latest article relevant for that prediction". Read that as an instruction to SEARCH HARDER AND REVIEW MORE, never as permission to attach a weaker article. A prediction with no genuinely-supporting source STILL renders UNCITED; that is the honest outcome and it remains always available.
  • THE LOOP, IN ORDER: (1) npm run browse:report for the roster; (2) npm run browse -- --ids=<slice> --searches=6 to discover; (3) READ every proposal AND every nearMiss in the emitted file; (4) record a verdict for the ones that genuinely support their prediction; (5) run the promotion helper, which re-fetches each accepted article live and re-checks the quote verbatim before emitting ledger rows; (6) paste the emitted NEWS_SOURCES/NEWS_GROUPS rows into news-evidence.js; (7) node refresh-signals.js then npm run verify:news --silent.
  • NEAR MISSES ARE A REVIEW QUEUE, NOT A LOWER BAR. browse-evidence.js records candidates that failed GATE 1/GATE 2 or the discovery ceiling but still carry a headline, a date and a quotable sentence. They exist because curated subject lists are a human artefact and are necessarily incomplete — MEASURED: "Claude Code can now take over your computer to complete tasks" was discarded for a computer-use-agent prediction solely because the curated phrase was absent from its headline. A near miss is promoted ONLY on an explicit human verdict that the article supports that specific prediction, and it is then verified exactly like every other row. Nothing about the automated bar moves.
  • REJECT ON THE MERITS AND SAY SO. MEASURED on the 2026-08-24 sweep: 169 near misses across 77 predictions yielded 3 promotions. Rejected examples worth recognising as a class — a 2011 corporate-valuation primer for a trillion-dollar-valuation prediction; "Mac OS X installed base almost 11%" for a 200-million-AI-workers prediction; a 7-year-old robot-tax proposal for a tax-shift prediction; VaultGemma (a privacy-preserving MODEL) for privacy-preserving AUDITS. Keyword overlap is not aboutness. Report how many candidates were reviewed and how many were rejected, not only how many were promoted: a promotion rate is meaningless without its denominator.
  • THE RATIONALE MUST STATE WHAT THE ARTICLE DOES NOT EVIDENCE. Every promoted row carries a rationale naming the specific gap between the article and the prediction — the BCI piece does not state the 3,800-hour figure; the DeepSeek piece evidences the Chinese half and not US concentration; the autonomous-drone piece evidences the PRESSURE for a treaty and not a treaty. A rationale that only says why the article fits is a rationale that cannot be audited.
  • ARCHIVAL PROMOTIONS ARE CONTEXT, NEVER CITED. Most of what browsing finds is outside the 14-day window and enters the CONTEXT channel carrying its true age. Never let a CONTEXT promotion raise the cited count, and never describe the cited number as having improved when what grew was dated background.

REPORT VISUALS — HEADLINE CARDS AND LICENSED PHOTOS, NEVER EVIDENCE

  • Headline cards are drawn from the reviewed record. No publisher page is captured, and no publisher photo or og:image is reproduced.
  • Report photos live in PHOTO_LIBRARY in app.js. Each is a self-hosted, credited Commons or US-government photo under public domain, CC0, CC BY or CC BY-SA, bound to the reports it illustrates. Nothing in the build or the NEWS gates reads them, so a photo can never raise a count or stand in for verification.
  • AFTER ANY WITHDRAWAL OR REVISION, check verify:visuals. A photo bound to a report that left the ledger fails closed. Remove that binding or the photo; never rebind a photo to make the gate pass.
  • ADDING A PHOTO IS A REVIEWED EDIT, never part of a scheduled run. Record the source page, author, licence link, retrieval date and changes, and pin the WebP's size and SHA-256. Use an "Illustrative" caption unless the photo truly shows the event.

THE VISUAL MUST ENCODE THE NUMBER IT DRAWS

  • READER-REPORTED 2026-08-23: "changing the assumptions aren't changing the visual, only changes the % on the text callout below it." MEASURED and confirmed: the probability branch map encoded each outcome ONLY as stroke width (2 + value/16) and opacity (.34 + value/150), so driving a slider to its maximum moved a branch by 0.62px and left the managed-handoff branch bit-identical. The map was technically live and effectively static.
  • EVERY SIMULATOR ASSERTION IN PLACE AT THE TIME PASSED THROUGHOUT, because all of them read TEXT — the outcome cards, the hero figure, the interpretation sentence. A chart that had silently stopped drawing its data would have passed every one of them. Whenever a control drives a visual, assert the DRAWN GEOMETRY, not the label beside it.
  • THE STANDING RULE: probability is drawn as a proportional FILL along each branch (a fill length that IS the percentage), reinforced by width, opacity, endpoint-node radius and a categorical highlight on the leading branch so a lead changing hands is visible as a discrete event. verify:ui now measures drawn length before and after an assumption change and fails if the largest move is under 8 SVG units or if any branch's drawn share stops tracking its own stated percentage. Never satisfy that gate by enlarging the threshold; satisfy it by drawing the data.

EVIDENCE RATCHET — evidence-floors.json is a committed, public-safe monotonic ratchet. The X-era peterTotal, peterAuthored and maxReuse floors were REMOVED by reviewed manual edit when X was retired — removed rather than zeroed, because a floor of 0 reads as a SATISFIED gate while 30/11/9 would fail closed forever. refresh-signals.js, verify-direct-coverage.js and verify-news-evidence.js all REFUSE to run if any retired X floor reappears in that file, so reinstating one is a hard failure and never a way to make a run pass. The mechanism is untouched and still guards the currency registrations: currencyLedgerSources, currencyMaxAgeDays and currencyLedgerIdentities. Environment variables may TIGHTEN a gate and can never loosen one. Lowering any value requires an explicit, reviewed, explained manual edit.

CURRENCY LAYER — RECENT AUTHORITATIVE REFERENCES ALONGSIDE A CITED PREDICTION (currency-build-ledger.js / npm run verify:currency)

  • ADDITIVE, NEVER SUBSTITUTIVE. A currency reference sits ALONGSIDE a prediction's origin citation so a reader sees both the origin and what has been published since. A prediction with no origin citation may NEVER receive a currency card, and attaching one must never change, demote, replace, reorder or hide the card it accompanies. verify-currency.js enforces both halves and fails closed. The UI must keep the ORIGIN versus CURRENT distinction explicit.
  • CURRENCY MUST BE NEWER THAN THE ORIGIN IT REFRESHES. An article published before that prediction's origin citation refreshes nothing. Enforced inside the builder, not merely at review.
  • THE CURRENCY LAYER IS CURRENTLY INERT BY CONSTRUCTION AND THAT IS CORRECT. A currency link must strictly postdate its origin, and every origin citation is itself inside the 14-day window, so there is almost no room between them. verify:currency exits 70 = PASSED BUT INERT, naming the axes it verified NOTHING about. Publication proceeds. An inert pass must NEVER be recorded as a verified currency layer, and its named unverified axes must be reported rather than absorbed into a green.
  • THE FEED IS A DISCOVERY CHANNEL; THE PAGE IS THE RECORD. Never persist RSS/feed metadata. Fetch the candidate URL and extract headline, publisher, byline and date FROM THE FETCHED PAGE. Publishers revise headlines after publication — IEEE Spectrum demonstrably does — so a feed title written into the ledger would later be reported as headline drift on a completely genuine article.
  • QUOTES MUST BE WHOLE SENTENCES AND VERBATIM. Record a complete, capitalised, terminally punctuated sentence present verbatim in the fetched text. Comparison normalises smart quotes, dashes and whitespace ADJACENT TO PUNCTUATION only — a publisher adding a mid-sentence link must not be reported as quote drift — and can never make two different words compare equal.
  • INFRASTRUCTURE FAULTS ARE NOT EVIDENCE FAULTS HERE EITHER. Some publishers — nature.com observed at roughly 25% from some IP ranges — intermittently serve a small bot-challenge page with HTTP 200. NEVER treat HTTP 200 alone as fetched. A challenge is detected explicitly, retried with backoff, and if still unresolved exits 75 = INFRASTRUCTURE/DEFERRED. It must NEVER be reported as "the reviewed supporting quote is no longer present", which is an integrity signal that would justify dropping genuine evidence. For DOI-bearing journal sources an independent Europe PMC corroboration path supplies a second attestation; filter source != 'PPR' so a preprint record of the same work can never be the corroborating hit.
  • A POSITIVELY IDENTIFIED PUBLISHER CHALLENGE ON AN UNCHANGED, DURABLY VERIFIED RECORD IS A DATED LAST-GOOD WARNING, NEVER A PASS (owner-approved 2026-09-24). Only three markers qualify: AWS WAF x-amzn-waf-action: captcha|challenge, an Akamai same-site redirect to /apology_objects/abuse-detection-apology.html, and Cloudflare cf-mitigated: challenge. The record must be byte-identical (full source + every mapping) to both the published mirror HEAD and the commit of the newest real live verify:news PASS recorded in NEWS_LIVE_VERIFICATIONS, and that verification must be at most 14 UTC days old (2026-09-22 → last retained day 2026-10-06). Plain 404/405/410/5xx, timeouts, new/changed/never-verified records, and expiry still FAIL. The retained record shows "Couldn't recheck today", "publisher bot protection" and its last verified date, and verify:news exits 70 naming each LAST-GOOD WARNING. No UA/header spoofing, proxy, captcha solving, cookie replay or archive substitution. The exact rule is in TIMELINE-DAILY-RUN.md and assessNewsLastGood in news-evidence.js; this line does not widen it.
  • ANTI-CHURN. Re-verify every existing reference each run and keep it. Replace one only when a candidate is BOTH materially newer AND genuinely better-supporting for that specific prediction — never for novelty, never to raise the count. Dropping a reference because its source had a transient fault is forbidden. Cited prediction texts are pinned in currency-text-pins.json so a later wording change forces explicit re-review instead of silently invalidating a citation.

Run and require PASS: npm run verify:matcher --silent npm run verify:coverage --silent npm run verify:news --silent npm run verify:currency --silent npm run verify:browse --silent npm run verify:surface --silent

Inspect signals-debug.json for dynamic cited/uncited/total accounting, missing/extra IDs, source freshness, unique source count, maximum and distribution of reuse, reviewed reuse groups, mapping methods, gained/lost citations, guard rejections and unresolved evidence. Manually audit every gained or replaced citation and every changed reuse group. If any prediction is in neither channel or in both, any citation fails live re-verification, sourceFresh=false, or any mapping is weak or misleading, refresh-signals.js and the publication preflights must fail nonzero. STOP before copy/deploy/GitHub and preserve the currently published site. Never fall back to search, never remove a prediction to pass accounting, and never move a prediction into the uncited channel to avoid re-verifying its citation.

  1. REASSESS THE DATED 2026–2040 PREDICTION PORTFOLIO Read REVISE-PREDICTIONS.md in full, then predictions.json's updated timestamp and basis. Most daily runs should leave predictions untouched. Only add, update, move, merge or remove an event when newer verifiable evidence materially changes the forecast or the portfolio-wide coherence gate finds a defect. Do not reword for novelty or bump updated when nothing changed.

Flatten all dated events and remove exact duplicates, near-synonyms, repeated endpoints, weaker later milestones and events whose premise was eliminated earlier. Related later events must raise a measurable threshold, broaden scope, advance proposal→deployment→permanence, or name a distinct conditional branch. Keep cognitive/physical automation, labor/output share, GDP, agents/robots, redistribution, science, capability, BCI, connectomics, orbital compute and off-world industry monotonic. Do not retain conventional career/reskilling predictions after full AI-R&D automation and economy-wide disruption. Keep managed/Plan A, AI 2040 default, Peter-ungoverned and aligned-superintelligence-enabled branches explicit.

Preserve Peter's anchor unless he explicitly changes it: human-level AGI by end-2026; every-industry disruption throughout 2027; first superintelligence in 2028–2030; “hope for the best, but prepare for the worst.” Re-check https://ai-2040.com/ and https://ai-2040.com/supplements/plan-a-assumptions and relevant takeoff/economics/capability supplements when warranted. Plan A is a policy recommendation/conditional managed branch, not literal base history. Preserve the 2029 deal, 2030 transparency regime, 2035 top-expert pause and 2040 handoff labels.

Required technology watchlist on warranted reassessments:

  • BCI: Neuralink official updates and registered trials plus peer-reviewed Synchron, Precision, BrainGate/Blackrock, Paradromics and genuinely non-invasive EEG/MEG/fNIRS/ultrasound/optical work. Distinguish invasive, minimally invasive and non-invasive; track safety, bandwidth, home use, regulatory state and reproducibility.
  • Space data centres/orbital compute: primary Starcloud, NVIDIA, Axiom, Lonestar, Google Project Suncatcher, SpaceX/FCC and comparable technical evidence. Separate launched workloads from lab tests, filings, launch plans and aspirational constellations; track power, compute, links, radiation, radiators, launch cost, debris/licensing and customers.
  • Connectomics/whole-brain-emulation precursors: peer-reviewed connectomes, mammalian reconstruction, functional models, nondestructive scanning, preservation, simulation cost and behavioral validation. Wiring diagrams are not functional emulations; digital replicas are not uploads.
  • Dyson/Kardashev precursors: measurable off-world mining/manufacturing, power collection/transmission, orbital compute and self-replication tests. Do not date a Dyson swarm or Type I/II transition by 2040 without extraordinary evidence.

LATEST-NEWS FORECAST SWEEP — each run, sweep recent authoritative reporting across the watchlist above plus frontier capability, agents, robotics, compute/energy and labour/economic indicators. This is the reassessment side of the news work and is separate from news EVIDENCE: it can move a forecast, it never assigns an evidence card by itself. Where verified reporting materially moves a forecast, update it under the anti-churn rules above — no daily wording churn, only material verifiable change, preserve monotonicity and portfolio coherence, keep Peter's anchor unless he explicitly changes it — and set revisedAt + changeNote citing the specific verified source. Only primary/original reporting, official lab/company/agency/regulator announcements, peer-reviewed journals or named expert analysis qualify; aggregators, syndicators, release mills and content farms are never a basis for a forecast change. Changing predictionText invalidates sticky evidence bindings, so re-run the evidence chain afterwards and re-establish complete ACCOUNTING before publishing — every affected id back in exactly one channel, cited, context or explicitly uncited. Never manufacture a citation to restore a count; a prediction whose text changed and whose citation no longer genuinely supports it belongs in the uncited channel with a reason.

ESTIMATED-MONTH LAYER — WITHIN-YEAR TIMING. Every dated event carries m (1-12), mBand (± months), mPrecision (month|quarter|half|year) and mBasis (the individually reasoned justification for that timing given the observed pace of change). validate-predictions.js enforces their presence and shape and will hard-fail the build on a malformed value, so they must be maintained, not merely present. The UI renders them at display time only and the wording must never assert more precision than mPrecision supports: a named month only at "month" precision, otherwise Qn / Hn / Early-Mid-Late. A BARE YEAR IS A FAILURE — the year-precision bucket is the majority (54 of 96), so rendering it without an early/mid/late qualifier leaves the feature effectively undelivered for most predictions. Always show the band alongside the estimate, and surface mBasis in the UI rather than leaving it dead weight in the JSON. NEVER write a month into the prediction text t: that text is the sticky binding key for every evidence approval and every currency text-pin, and changing it invalidates all of them at once. ANY NEW DATED EVENT THIS RUN ADDS MUST ARRIVE WITH ALL FOUR FIELDS ALREADY REASONED — never copied from a neighbouring event, never defaulted, and never deferred to a later run. validate-predictions.js hard-fails without them, so an event added without them breaks the build for every subsequent run and leaves the month layer with a hole exactly where the newest thinking is. When a forecast's year moves, revisit m/mBand/mPrecision/mBasis with it so the month estimate can never contradict its own year, and re-run the evidence chain. An estimate whose window has already closed must present as elapsed rather than silently pending; whether it actually resolved is an evidence question, not a timing one. The 7 horizon items carry NO month fields by correct design and must keep saying so explicitly — never a blank, never a dash, never a fabricated month.

RENDER DATES IN UTC, NEVER IN THE READER'S ZONE. A cited source's publication date must read identically for every reader and must match the source itself. app.js formats dates with toLocaleDateString/toLocaleString; any such call that omits timeZone:'UTC' renders in the browser's local zone and misdates any timestamp whose UTC time-of-day is late enough to cross midnight. Verified against the published build on 2026-08-11: the Ars Technica currency source stored 2026-07-31T20:39:14Z rendered as "Aug 1, 2026" at UTC+10 — the string "Jul 31, 2026" appeared zero times in the rendered DOM — while the article itself, the stored value and verify-currency.js all say 2026-07-31. L358 already passes timeZone:'UTC' and is correct; the other date-rendering sites (L348, L647, L1296, L1298, L1336, L1339, L1622 at time of writing) do not. Every run must ensure every date-rendering call passes timeZone:'UTC', and must never introduce a new one without it. This is a presentation fix only: ageDays, the freshness histogram and the currency ceiling are computed server-side, are already correct, and must not be adjusted to compensate.

Run node validate-predictions.js even if no forecast edit is warranted. If predictions.json changes, update timestamp+basis precisely, and preserve revisedAt and changeNote on every materially changed event so the site's latest-change view stays accurate and returning readers can see real movement. Then rerun refresh-signals.js because the dynamic ID set changed and reviewed citations are bound to exact predictionText. The run may publish only after every new/current ID is accounted for in exactly one channel — cited, context or explicitly uncited.

  1. MAINTAIN THE UNDATED POST-SUPERINTELLIGENCE HORIZON Keep the dated timeline strictly 2026–2040. Preserve the top-level postSuperintelligence object and dedicated UI. conditionalProb is conditional on aligned superintelligence and every listed prerequisite, not probability by 2040. Preserve explicit coverage of: implantable and genuinely non-invasive neural-symbiosis paths; whole-brain emulation/uploading/digital immortality with unresolved identity continuity; orbital compute/off-world industry toward a proto-Dyson trajectory; measurable Kardashev energy scaling; John Smart's unconfirmed inward Transcension branch; and Stephen Wolfram's ruliad becoming relevant only through discriminating testable predictions. Maintain dependencies, observable indicators, caveats and the evidence ladder: observed precursor → demonstrated subsystem → scalable system → conditional ASI-enabled outcome. Mutually exclusive outward and inward branches may coexist. The horizon is deliberately undated and must keep stating that explicitly. No daily novelty churn.

  2. KEEP CHAPTER 07 AND THE FRONTEND CONSISTENT Chapter 07 is the full article data-idx="8" and teaser idx:'07'. Preserve Peter's first-person thesis and three-clocks narrative. AI 2040's branch is a comparator, not a reason to overwrite Peter's call. Preserve the exact site title “The Hitchhiker's Guide to the Singularity,” the What changes next route, content-specific SVG figures/animations, evidence cards and provenance labels, the origin-versus-current evidence grouping, the estimated-timing blocks, themes, mobile/high-zoom layout, accessibility and reduced motion. Update chapter copies together only when material evidence changes the discussion.

  3. SERVE AND VERIFY Confirm http://127.0.0.1:8787 responds; otherwise run: powershell -File C:\Users\peterxing\pap-deploy\launch.ps1 If dependencies are genuinely missing, restore existing dependencies only; do not add tools merely for this run.

DERIVE THE GATE LIST; DO NOT REMEMBER IT. Run every gate package.json defines — validate, verify, and every verify:* — and require PASS. A HARDCODED LIST GOES STALE SILENTLY, WHICH IS HOW A GUARD STOPS GUARDING WITHOUT ANYONE NOTICING: this contract used to name thirteen gates by hand, and when verify:browse was added on 2026-08-18 neither scheduled workflow ran it — no error, no warning, an assertion that simply stopped being checked before every publish. The opposite failure is also real and is why the old list carried a warning: npm run exits 1 on a script that does not exist, so naming a removed gate (verify:archive, verify:peter, verify:external, review:candidates — all deleted with the X pipeline) turns a healthy run red for a reason that has nothing to do with the site. Deriving from package.json fixes both directions at once. Use the helper that already does exactly this, rather than reimplementing the derivation: powershell -ExecutionPolicy Bypass -File C:\Users\peterxing\pap-deploy\run-gates.ps1 -IsolatedPreview It enumerates from package.json, distinguishes a gate that FAILED from a gate that did not RUN, and reports each exit code as itself. If a gate must be skipped for a stated reason, name it and its reason in the report; never skip one silently, never delete one, and never weaken one to make a run pass. The live browser gates need the local server up first (see above). For reference, the gates defined at the time of writing were: validate, verify, verify:matcher, verify:browse, verify:coverage, verify:news, verify:currency, verify:surface, verify:interlock, verify:predictions, verify:reality, verify:author, verify:ui, verify:performance That list is INFORMATIVE, NOT AUTHORITATIVE — package.json is authoritative, and this line exists only so a reader knows roughly what to expect: npm run validate --silent npm run verify:matcher --silent npm run verify:coverage --silent npm run verify:news --silent npm run verify:currency --silent npm run verify:browse --silent npm run verify:surface --silent npm run verify:interlock --silent npm run verify --silent npm run verify:predictions --silent npm run verify:reality --silent npm run verify:author --silent npm run verify:ui --silent npm run verify:performance --silent

verify:interlock must confirm the concurrency contract is still intact: every guarded entry point claims the tree before reading protected files, a second live actor defers with exit 75 instead of proceeding, stale/dead-pid/corrupt locks are reclaimed loudly, a crashed holder cannot wedge the pipeline, and .pipeline.lock is refused by the local server and the publisher. A failure here is a real fault: fix it, never delete the lock file or bypass the guard to make the run pass. verify:surface must confirm the public deploy surface is still fail-closed: .vercelignore is an allow-list, a hypothetical newly added file is excluded without anyone adding a rule for it, every approved public file still survives the rules, and the effective published set is exactly the approved surface. It enumerates from the real on-disk inventory rather than a hardcoded list, so a script added today is caught automatically instead of being remembered. A failure here means the deploy surface has gone fail-open: fix .vercelignore, never delete or relax the verifier to make the run pass. verify:currency has THREE distinct outcomes and they must never be conflated: exit 1 is a genuine EVIDENCE FAULT (quote drift, headline drift, a fabricated or unreachable-by-construction source, or a demotion that failed to take effect) and blocks publication; exit 75 is INFRASTRUCTURE — a cited publisher unreachable or serving a bot challenge after retries — and must be treated exactly like an interlock DEFERRAL: publish nothing, change nothing, demote nothing, report it distinctly, let the next run retry; and exit 70 is PASSED BUT INERT, a legitimate publishing state in which one or more axes verified NOTHING. Report an inert pass as inert, naming the unverified axes; never record it as a verified currency layer. verify:news exit 70 is likewise PASSED WITH LAST-GOOD WARNINGS (or unexercised proofs): publication may proceed, every named key is reported as "couldn't recheck today" with its last verified date and expiry, and none is ever reported as live-verified. Exit 1 blocks. EMPTY-CURRENT (owner-approved 2026-09-26): verify:currency and verify:news both exit 70, never 0, when the cited channel is empty SOLELY because every reviewed mapping aged past the 14-day window into dated context. That means a complete partition, an explicit coverage.byEvidenceOwner.news: 0 and every mapping accounted for, as classified by classifyNewsCurrency in news-evidence.js. The homepage shows "No news from the last 14 days is linked yet — last linked news: ". A missing or corrupt partition, a missing tally, a dropped or unaccounted mapping, an in-window, forged-age or future-dated context row, and any verification or schema failure still exit 1. The exact rule is in TIMELINE-DAILY-RUN.md; this line does not widen it and does not relax any editorial step. A TEXT-BASED CHECK CANNOT SEE A SYNTAX ERROR. verify:surface and verify:interlock read publish-github.ps1 as TEXT and both return exit 0 on a file that does not parse. After ANY edit to a .ps1 file, parse it explicitly before relying on it: [System.Management.Automation.Language.Parser]::ParseFile($path,[ref]$t,[ref]$e) Exit 0 from a reader is not exit 0 from a runner.

Publish only if all pass AND the signals artefact declares: cited + context + uncited equal to the dynamic N computed from predictions.json (103 as of 2026-08-13) with zero ids double-counted and zero ids missing, every CONTEXT entry carrying a live-verified absolute URL, publisher, headline, verbatim quote, true publishedAt and computed age in days, and every CITED entry still inside the strict 14-day window; zero searches; byEvidenceOwner reporting news only and zero X evidence of any kind; publishedAtSource declared on every citation; every cited article inside the registered 14-day window; and sourceFresh true. The browser/data verifiers must also confirm resolved article URLs, publisher/byline/date/quote integrity, the "News evidence — , " labels, the explicit uncited state rendered honestly rather than as an empty card, the Reality cards, estimated-timing on every dated prediction with no bare years and the explicit undated statement on every horizon item, both themes, filters/search/deep links (including delayed-data deep links), the performance budget, mobile/320/high zoom/reduced motion, zero console errors and zero overflow. Fix real defects; never weaken gates.

  1. PUBLISH TO VERCEL Only after freshness, forecast coherence and every verifier pass, sync the approved public files — including index.html, app.js and styles.css — from pap-deploy to pap-site using ONLY: powershell -ExecutionPolicy Bypass -File C:\Users\peterxing\pap-site\deploy.ps1 Never hand-copy, never use wildcard copies, and never stage anything outside the explicit public allow-list. The hardened helper copies and SHA-256 verifies the six runtime files; a mismatch must fail the run. Use cached Vercel login with VERCEL_TOKEN cleared; never pass a stale token. The deploy helper's direct-coverage/external-evidence/news/currency preflight must pass and exit 0, and it must reject .pipeline.lock; helper exit 75 is the currency INFRASTRUCTURE deferral described above and means stop without publishing, not fail. Confirm both https://post-agi-planning.vercel.app and https://peterxing.com show every prediction accounted for in exactly one channel, zero prediction search chips, news-only evidence with the honest uncited state rendered, current source metadata, working filters/search/deep links, both themes and no errors.

INDEPENDENT LIVE POST-DEPLOY ASSERTION — do not trust local state, the deploy helper's exit code, or a rendered page scan alone. Once the aliases are live, fetch https://peterxing.com/signals.json and https://post-agi-planning.vercel.app/signals.json directly with a cache-busting query string, and assert against the FETCHED PRODUCTION JSON (never the local file) that: the cited embed ids plus the context ids plus the uncited ids equal the dynamic N computed from predictions.json, with zero ids in more than one channel and zero in none, and with every CONTEXT id absent from the cited set; the search object is empty; grouping embeds by evidenceOwner yields news only, with zero X evidence of any kind; every citation declares publishedAtSource and resolves inside the registered 14-day window; the unique source count and maximum per-source reuse satisfy the recorded ceiling; every currency link corresponds to a prediction that still has its origin citation, so the layer is provably still additive; and sourceFresh is true. Assert no X sources or trajectory records in NEWS embeds/context/uncited or referencePoints, and zero X evidence-owner/medium counts. Independently confirm that the authorized xSignals supplement remains separate, labelled non-evidence and unchanged from the retained snapshot; its links and UI are allowed. Both domains must report identical evidence composition. Then re-fetch at least 3 cited article URLs from the LIVE JSON and confirm HTTP 200 on the final URL with the recorded verbatim quote still present. Also confirm both domains refuse /.pipeline.lock. Any failed assertion is a live regression: report it immediately, do not describe the run as successful, and do not let it stand silently until tomorrow. Finally run node verify-deploy-surface.js --live and require PASS: it probes the full repository inventory against both domains and fails if ANY non-public path — a script, corpus, cache, ledger or lock file — is reachable, or if any approved public file stopped being served.

  1. MIRROR TO GITHUB After successful Vercel publication run only: powershell -ExecutionPolicy Bypass -File C:\Users\peterxing\pap-deploy\publish-github.ps1 Do not hand-roll git. Require helper exit 0. The allow-list includes evidence-floors.json, news-evidence.js, currency-evidence.js and currency-text-pins.json, so a run that reviewed a new citation, ratcheted a registration or changed a currency reference must mirror them. evidence-approvals.json was DELETED with the X pipeline and is refused by the publisher's forbidden scan; a run that recreates it fails closed. The publisher copies and adds but never deletes, so a file withdrawn from the tree stays tracked in the mirror until it is declared in $retiredFromMirror by name with a reason. The helper's preflight also runs the interlock and currency verifiers and its forbidden-file scan rejects .pipeline.lock. Never commit pap-secrets, private history, raw activity, the private archive corpus, signals-debug.json, caches, logs, .vercel, node_modules or tokens. The helper uses an explicit allow-list and defense-in-depth scan. Then release the tree: node pipeline-lock.js release --owner=$env:PAP_PIPELINE_OWNER

  2. REPORT Report concisely: whether this was a normal or CATCH-UP run and the state of the previous run; whether the interlock was acquired, inherited, reclaimed from a stale holder, or DEFERRED, and confirmation that it was released; any transient infrastructure retries and whether they succeeded; forecast/Chapter 07 status; event+horizon count/timestamp; the ACCOUNTING — cited + context + uncited against the dynamic N, with zero double-counted and zero missing stated explicitly rather than implied by a single total; zero-search status; every citation named with its publisher, headline date, publishedAtSource and age in days, plus the specific prediction it supports; any citation gained, replaced, retained or lost this run and why; the count of predictions in the CONTEXT channel with each one's publisher, headline date and age in days, and the count in the uncited channel with confirmation that each carries a reason, search statement, searchedAt and windowDays; the ACCOUNTING MOVEMENT since the previous run stated as a delta (referenced = cited + context, and uncited), because the owner judges this work by whether the uncited majority is shrinking, not by the absolute count on any one day; any prediction that remained UNCITED must be listed BY ID, never merely counted, because a count says some are missing while a roster says which; for every id that remained UNCITED, confirmation that the browser discovery channel was actually run against it, with the publishers searched, candidates rendered, proposals produced (CURRENT versus ARCHIVAL) and the stage at which candidates were refused — an uncited record is only honest if the search behind it was real; how many proposals and near misses were REVIEWED this run, how many were PROMOTED into the ledger and how many were REJECTED on the merits with a representative reason (a promotion count without its denominator says nothing), plus which ids the browse rotation covered and where it resumes tomorrow; unique sources and maximum reuse against the recorded ceiling; whether evidence-floors.json ratcheted this run and to what values, and confirmation that no retired X floor reappeared; the currency layer's honest numbers including whether it was INERT and which axes were therefore unverified; any revisedAt/changeNote entries added; any estimated-month fields changed and why; Reality themes and their order; performance numbers against budget; all local/live verifier results with their exit codes distinguished (0 PASS, 70 INERT, 75 DEFERRED/INFRASTRUCTURE, non-zero FAIL); the independent live post-deploy assertion results for BOTH domains; Vercel aliases; and GitHub helper/commit status. Report an INERT or DEFERRED outcome as itself — never absorb it into a green. Never expose private data or credentials.

DAILY ENFORCEMENT IS AN ASSUMPTION PETER CAN OVERRULE. The currency layer, the estimated-month layer and their verifiers are treated as mandatory daily obligations of this workflow because that is the most defensible reading of the standing instruction. If Peter wants currency refreshed weekly rather than daily, or wants month estimates frozen between material forecast changes, say so in the report and follow his direction; do not silently keep enforcing a cadence he has overruled.