English: README.en.md
中文 · English · Deutsch · Español · Français · 日本語 · 한국어 · Русский · 繁體中文
From a real run, not a mock-up: the code, parameters and environment fingerprint behind this chart are archived step by step under docs/demo-verification/.
PureScience is the research workbench that keeps every step of your science inspectable. It runs locally-first on your own computer — macOS, Windows, and Linux installers ship with every release — works with any model provider you already have, and turns one plain-language task into an agent session that reads files, runs Python and R, searches the web, and calls scientific data connectors. What comes back is reproducible: reports, tables, and figures linked to the exact activity history that produced them.
Where PureScience differs: agents are built with self-awareness and skill-building — they can say what they actually did in a project, evaluate and author their own reusable skills, and check figures against publication-grade rules before you ever see them. Every notebook run is audited; every memory carries its source; nothing leaves your machine unless you allow it. Today that power is sharpest in bioinformatics, computational biology, genomics, structural biology, and computational drug discovery — 18 featured research skills and 35 built-in scientific connectors — with an extensible architecture ready for more disciplines.
We label every capability the way we build it: ✅ shipped and verified on a real machine; 🚧 partly done, with the gap written next to it; 🗺️ planned. Each claim is traceable — a commit, a real-run log, or a record under docs/evidence/.
-
✅ Shipped and machine-verified: This version added four connectors and two numbers the panel had never stated. Two of those connectors were measured on this machine against the live services (LIPID MAPS:
pubchem_cid=5997→LMST01010001,C27H46O,386.354866, with a name lookup refused by name because that API has none; OmniPath: directed interactions plus annotations plus enzyme→substrate edges, where/annotationsturned out to rejectorganismsand the result now says so instead of pretending). Two were not: every TCIA address answers000from here andsearch.foldseek.comis intermittent, so those readings are taken by a live probe on the CI runner and printed into its job log — the connectors ship with that gap named rather than with a claim this machine cannot support. Structure similarity also required a real capability: RCSB's public search has no working structure service (service:"structure"→ 400 for everyentry_idshape, 500 forvalue, whilechemical→ 204), so the tool uploads coordinates to FoldSeek through a newpostFormtransport. The connector panel now names each row's scientific area, groups the directory by area in place, and states 35 connectors · 290 tools from the registry. Notebook kernels can only write where they were told: a seatbelt profile denies writes first, allows the session and figures directories and the temp trees back, then denies the managed runtime last (last match wins) — measured asWROTEinside,PermissionErroroutside,PermissionErrorinside the runtime even under an allowed temp tree. Open and named: shell and background jobs are not confined, Linux and Windows have no write guard and claim none, and the packaged-lane screening certifications run again (p0109 passed / 12 skippedin 31.5 min) after the first-window budget went 30 s → 180 s. This version made the gallery's own claims harder to fake, and fixed the instrument that looks at the packaged lane. Three cards joined the home page (an import verdict you can recompute, four turns on one screen, a remote import refused), each holding readings and quotes that must appear verbatim in its named evidence file, with nine-language copy and rerun paths that have to exist. The packaged-lane checks that four certifications sit behind were only ever measured as1 skipped;PURESCIENCE_E2E_PACKAGED_SKIP_BYPASS=1now runs them and reproduces the failure here (1 failed), and the fixture writes its transcript intotest-results/because the app hands its agent a sanitised environment — the previous env-only path never reached the child. Three days of incidents are recorded entry by entry, and what is still broken stays on the label: the packaged screening lane still stalls at 0/N behind four named skips, the connector panel still groups by curation rather than discipline (35 connectors, 290 tools), and a measured 51.8 s cold start is unoptimised. This version made what leaves the app come back with its own receipts, and made a long session readable. The same session exported from the window, the web surface and the CLI produced a byte-identical payload —d36518b53a7dat 24 / 49 / 326 ms — with the whole-package digests differing only inexportedAt, because forging one timestamp to make three numbers agree would forge where the file came from; zip entries now carry a fixed 1980 epoch so the same content and stamp pack to the same bytes. An imported package recomputes its own claims: usage is derived fromconversation.jsonand compared field by field (state: match,turns: 1, with turns that recorded nothing counted apart), tool readings judge the manifest's declaration against the bytes it shipped (absent:no-tool-callsstays a named absence, never "0 tool calls checked"), the verdict is written into the import record and compared there, and a remote import is refused outright (401,local-only-authority) rather than quietly allowed. A settled turn keeps its own 24 px summary row with its own token total, and the three inputs stay apart — a number, "usage not recorded", or no line at all, never a 0 — while the row still folds: on a real window two turns producedgroups=2withexpanded: falsethentrue, and four turns producedsummaryRows:[24,24,24,24]in an 806 px viewport. That pair of readings took four attempts, and the reason is worth keeping: only one summary row ever appeared, and the cause was the deterministic test agent reusing the same tool-call ids every turn — the app correctly treated them as updates of the first turn's rows — so the product-side fix that shipped is the transcript merging the document's activity list with the live run's instead of letting the live run replace history. The CLI now serves an external MCP client: four read tools watched one audit line per call, then a write (archive_session) that resolves its target read-only, hangs the app's own approval card, and only then acts, refusing by name (not-approved,approval-unavailable,permission-gate-not-wired,already-archived) with the two ledgers paired by the sametoolCallId— cancelling leaves the row untouched, approving writesarchivedand the client reads it back (2 passed, 18.3 s). The home page gained five use-case cards whose every number and quote must appear verbatim in its own evidence file — a reading drifting by a tenth of a second turns that guard red — with a copy control answered by the main process's clipboard bridge rather than the window's denied one. DOCX tables are now drawn from what the document declares instead of what the renderer assumed: the table's six edges read fromtblBorders(falling back one level totblStyle), applied by rendered geometry, a cell's own rules winning, and a table that declares nothing left untouched — a 3 pt green double frame over a 0.5 pt grey grid measured 3.21 px and 0.80 px on a real window. Along the way a real defect came out of a red lane rather than from reading code: the egress proxy'sstop()waited forever when a client held its CONNECT tunnel open, whichcloseAllConnectionsdoes not cover. The previous version gave the wait a name and a price, and made the literature library check a retraction, follow citations both ways, and remember how far you read. Seven of the app's slowest requests were attributed from a week of its own log — 141 of 214 error/warn lines were slow IPC — before anything was changed.notebook:statere-parsed whole run documents on every read: on the real 60.1 MB file with 80 runs the hot median went 358.2 ms → 1.6 ms (cold 222.7 → 165.1) after an mtime+size cache that deliberately does not deep-copy, guarded by two tests that make the cache unable to lie.reviewer:get-for-sessionscanned two tables carrying only primary-key indexes behind an N+1 read and now has both indexes plus one query;notifications:get-snapshotqueued its reads behind writes and no longer does;artifacts:read-previewwas left alone on purpose, because an event-loop canary sampled at the same moment (261 ms against its 430 ms) accounts for most of it — rotation is reported rather than "fixed".sessions:save-sessionturned out to be two different slownesses: the 400 ms that dominated the samples was a database query in the post-write capture step (writeMs 3 ms,cpuShare 0), so it is skipped when no artifact version was finalised; the other half is a 60 MB document's write and rename (writeDiskMs 211,writeReplaceMs 176 ms) and is left at the I/O floor.settings:list-skillsis the honest non-result: the log says 662 ms median while a full in-process call takes 50.8 ms cold and 11.0 ms hot over 67 real skills, so parallel reads and an mtime+size cache landed (11.0 → 8.1 ms, plus askill list attributionline past 150 ms) and no target is claimed — without a baseline of the same size, "we improved it" would stand in for "it is fast enough". An event-loop stall used to end atno-cpu-in-process, which is a measurement and not a cause: every record now carriesgarbage-collection,fs-queue-saturated,cpu-in-process,unexplainedorunmeasured, withunexplainednaming the milliseconds it ruled out andunmeasuredsaying an instrument was missing — merging those two is how "nobody was watching" starts reading as "the machine was fine"; the GC observer and the thread-pool canary are started with the app rather than when a stall is noticed, and the 20 ms saturation threshold comes from 57 real canary samples (min 1 / median 24 / p90 180 / max 686 ms). The literature library grew three connected pieces: a retraction check reading four independent Crossref signals instead of onlyrelation['is-retracted-by'](which hit 0 of 12 sampled withdrawn works, which is why the old checker found nothing), with the winning signal and the check time stored on the reference and the export gate reading only what was already stored; citation discovery in both directions on live data, where one English record reports 83,700 citing works and reads 50 of them while the result says so (incomplete), four Chinese-source records return 47–50 citations each, andlanguage: zhcatches only 2 of 200 rows so it is not the criterion; and a three-state reading status (unread / reading / read) that survives a restart, filters the list, and counts what the text cites but you have not finished — where "reading" counts as unfinished, since onlyreadis finished. Previously it made a framework selection stop being silently ignored: two hand-maintained whitelists listed three of four framework ids, socodebuddysurvived the settings parser and vanished on the next read, and session persistence dropped it too. and before that a windowless run used to stall where nobody could look, and the review that was supposed to audit it never started.start --no-openhas no window to click a permission card in: a real task sat after its first gated tool call with no further event for six minutes.GET /api/v1/permissionsandPOST /api/v1/permissions/:id/approve(purescience permissions/purescience approve) now read and answer those cards through the same narrow Task view (acp:get-state/acp:respond-permission, 11 → 13 commands — without them the route exists and answers 500), and approving is a named authority,satisfy-approval, which a generic task context cannot exercise: "who approved this" is never abstracted into "automation". Auto-review moved from the renderer to main, because a window was its only trigger — two identical CLI runs, the one with a window open reviewed, the other recorded nothing. Both paths converge through the existing already-reviewed check, so a turn is reviewed once. That first version of the trigger read the session once and so never fired at all — theend_turnevent lands before the session is written (~1.8 s later, measured), which left a finished CLI turn unaudited with a clean-looking log; it now waits out the write on a bounded schedule and reportsunreadablerather than dropping a turn silently (v2.15.3, measured before/after on the same CLI channel: 0 review rows → 1, verdictpass). Also in this version: a review persists outside any default five-second transaction budget, names its failures in seven families (the raw text kept as evidence), and stops at 300 tool calls per session; a client reset on a tunnel is no longer anuncaughtException; artifact finalisation waits out a durability race with a bounded retry instead of failing the turn; a Session leftrunningby a dead process is closed as interrupted at startup, and a Session that died between "plan approved" and "no longer waiting" comes back idle instead of showing an approval that already happened; a notebook kernel now leads its own process group on POSIX, so teardown is onekill(-pgid)instead of a pid walk that misses whatever forked mid-teardown and cannot see a child launchd adopted (the old path reportedreaped: trueon that), with the group claim checked against the kernel's real pgid and a named log when it does not match; external-source verification no longer fails every call (an emptyresponse.urlfell through??intoInvalid URL:, and a redirect's three outcomes now have three answers); and the review locator no longer demands a hash the model had to guess —contentHashis optional, pinned to the frozen block, withexpected/receivednamed on a mismatch. Measured during the audit that produced this batch, on the 2.15.1 candidate build: a windowless review returningflaggedacross five checks, 26 real approvals in the same run (PubMed / DOI / Wayback), three livefetch_sourcefetches (6,988 / 7,018 / 5,403 characters), and that runcompletedwith its artifact written. Re-checked on the build of this commit: the app boots headless in 3 s andGET /api/v1/permissionsanswers200 {"data":[]}with no window open — the failure that replaced was a 500 from that same route. The performance conclusion was wrong and the correction is the reading: the 118.9 s save peak and the 203 s projection panel were one process-level freeze, caught by an event-loop stall watchdog that samples from a second thread while the loop is stuck — withdrawn, not optimised around. Not done here: the read-only expression for built-in specialists. -
✅ Shipped and machine-verified: Batch removal is one write now: all of the ticked rows go, or none do. The previous version looped the single removal and said what that cost — a crash halfway could leave half the rows gone, and copy pruning decided row by row would depend on list order. This writes the register once and judges pruning against the sources that remain, so two sources sharing bytes clean up once and a surviving source never loses its copy. The change also changes what a refusal means, and the copy had to follow: an atomic batch that fails was not partly applied, so the sentence says the batch was not applied and nothing was removed — and the old "removed 3, 1 refused" string is deleted from all nine dictionaries, because a key describing a failure that can no longer happen is worse than no key. The armed-then-confirm step and page-scoped select-all stay: they guard against a human misclick, which has nothing to do with whether the batch is a loop. Measured: three registered, two ticked, armed, confirmed —
1 passed (7.4s), the unticked row still there. Sources can be removed in batches, without a new channel. One batch is N runs of the single removal, so copy pruning by reference and the verbatim refusal of a rejected row keep working exactly as they always did — a batch cannot become a shortcut around them. Three restraints: the first click only arms the action and a second confirms it, because this is the one control whose effect cannot be undone from the screen; select-all covers only the current page, since ticking rows nobody has looked at would decide on their behalf; and a row the store refuses stays where it is, with the reason shown verbatim. Measured: three registered, two ticked, armed and confirmed —1 passed (5.4s), and the unticked source is still there. The trade this version made and names: a batch is not atomic, because it is N writes, so a crash halfway could leave some rows gone and some not. An atomic alternative (one write, pruning judged against what remains) was built and not adopted; the choice is recorded in the evidence file. Not done: no undo, paging is still client-side. Molecular dynamics on CPU, and an honest answer about reproducibility. GROMACS 2025.4 from conda-forge minimises crambin and runs 10 ps in seconds: 11 frames, 642 atoms, 303 K measured against a 300 K target, mean potential −2859.6 kJ/mol. The important finding is a negative one — the output is not byte-reproducible, measured at 4 threads, at-nt 1and fully serial. So the contract differs from inverse folding: the input fingerprint (structure sha256, steps, temperature, seed, force field, engine version) is recomputable anywhere, frames and statistics are what two runs should agree on, and the trajectory digest is the identity of this artifact rather than a promise it can be regenerated. The panel says that next to the digests and the engine payload carriesbyteIdenticalOutput: false. Not done: vacuum rather than solvent, no trajectory viewer, no RMSD analysis, and binder design is still blocked on a CUDA host. A sweep now leaves a reading behind. Every completed sweep records when it ran and what it found — scanned, kept, removed, still-failed, bytes freed — and that record rides along with the source list the panel already fetches, so no new channel appears. After the fact you can still answer "when did this last run and what did it do"; a cleanup nobody can audit is indistinguishable from one that never happened. Three states stay apart: never swept (no record), swept and found nothing (zeros), and a record that will not parse (treated as no record, because reading a corrupt note as zero would report "nothing was cleaned" while the truth is that we do not know). The source list pages at twenty rows, with the page index clamped so a refresh that shortens the list cannot point past its end. Not done, and said here: bulk removal, a server-side page for very large stores, and sweep history beyond the most recent run. The previous version did inverse folding for real: give it a backbone and it designs sequences, with the fingerprint that lets anyone recompute them. Measured on this machine (CPU, 8 GB): crambin's 46 residues in 0.29 s, two designs scoring 0.8519 and 0.7794 at 0.50 and 0.57 recovery against the input, and the native chain the engine parsed matches the PDB. Two independent runs with the same seed produced byte-identical FASTA — that is what makes a design citable rather than merely plausible, and the result carries the seed, model, temperature and the sha256 of both the structure and the checkpoint so someone without this app can reproduce it. The engine is not bundled (6.7 MB of MIT weights, but ~740 MB of torch): the app declares it, decides availability from whether this machine has it, and lists each missing path instead of saying "not installed". Not done, and named here: no weight download, no environment provisioning, binder design and MD are still open, and designs do not flow back into the structure workbench. The previous version swept the copies nobody references — once per start, and never on a register it could not read. The previous version deleted a stored copy only when its source was removed, which left a gap: a hand-edited register, a restore from backup or a crash between save and delete could orphan a copy that nothing would ever collect. The sweep closes it, with the one guard that matters: the register is read first and an unreadable register aborts the sweep with nothing deleted — an unreadable register looks exactly like "nothing is referenced", and acting on that reading would delete the whole store. Two smaller conservatisms: only digest-shaped names are removed (a file someone dropped in that directory is not this store's copy), and a copy that will not delete is reported by its absence from the pruned list rather than claimed as cleaned. It runs asynchronously at start so a slow disk cannot hold the window, and logs one line when it does something. Still open, and named here: there is no manual trigger, the sweep matches on the digest in the filename rather than re-hashing contents, and there is still no bulk removal or pagination. The previous version added the action the store was missing: removal. A registered source could not leave before, and a URL's stored copy only ever grew. The two facts are handled apart — the row always leaves the register, while the copy is deleted only when no remaining source still names that digest, because two sources can hold the same bytes and deleting the file for one would break the other's search. The response reports which digests were pruned, so a caller never has to guess whether the disk changed. Both the model (a fifth tool, with an unknown id refused by name) and the window (a remove control on each row) go through the same store call and the same refusals. Measured on a real window: register → search → remove,1 passed (7.6s), the row gone from the list and the panel saying how many copies were pruned. Not done, and said in the same place: no bulk removal, and copy cleanup happens by reference on removal rather than as a periodic sweep — an orphaned copy still sits in the contents directory until that sweep exists. The previous version gave the knowledge store a window of its own. Settings gains a Knowledge panel: the sources this workspace registered with their kind, location and the first bytes of each sha256; a way to register a file, a folder or a URL; and a search that returns each hit's location down to the line, its digest, and how it was matched. The window and the model's tools go through one module and one set of refusals, so what a reader sees cannot drift from what an agent gets — a refused path still says why (source-outside-roots), and three kinds of absence stay apart: a record that cannot be read is never shown as "no sources",staleis marked separately from "could not re-read", andindexed/pendingsit beside the status so "nothing matched" and "some sources were not read" are different sentences. Measured on a real window: open the panel, register a real file, search TP53 —1 passed (6.1s), with both digests on screen (the whole 85 B file and the cited line) equal to what the test process computed from disk, and the citation's:2-2line range visible. The 26 text keys are written in all nine languages rather than filled with English. The previous version made searching a URL stop meaning re-crawling it. A URL's body is stored at registration under its own sha256, and a search answers from that copy — no network, no waiting, and a slow origin can no longer fail a query. The two paths are deliberately kept apart: the search reads the copy while the citation verifier still re-fetches, so changed content is stillstaleand an unreachable origin is still the third stateunreadablerather thanfresh. Measured against a real HTTP server that is really closed after registration:status: okfrom the copy, thesha256equal to an independent hash of the body, the verificationunreadable— and while the origin was still alive, not one fetch happened during the query. A registration that predates the copy heals once on the next query, so upgrading does not silently turn existing URL sources into "unreadable"; a source with neither a copy nor a reader remainsnot-indexed, never "no matches". The previous version gave the knowledge store a surface the model can actually reach. Four tools —knowledge_search,knowledge_register_source,knowledge_list_sources,knowledge_render_wiki— sit on a capability that is granted per session, behind an RPC whitelist with exactly those four methods, revoked when the session ends. Every result carries the sha256 of the exact bytes it was taken from, recomputed on the read side, and a location precise to the line; an empty answer never collapses three different findings into one —ok,no-matches, andnot-indexedstay apart, so a source that could not be read is never reported as nothing being there. Retrieval is lexical, and every response says so (mode: lexical,semantic-source-unconfigured), withmatchedBynaming per row whether lexical, semantic or both lists produced it — a row both found readsboth, never one coincidence dressed as agreement. The four tools hold separate identities in the permission catalog, so a grant can hand out search without handing out registration. Measured on a real window, not by a script asserting itself: the prompt named no tool, only a folder and a question, and the model chose register → search → render by itself; the digest it came back with for the cited line (5c47f7fa…564b) and the one the rendered document carries for the whole file (c60a2637…538d, 85 bytes) each matched an independent recomputation, and two runs of the same document are byte-identical. Also in this version: citations export as BibTeX and RIS and are persisted on the record with their time and session; a session's conversation is stored once, with the three projections rebuilt from the graph on read; chemical structures are recognised only where two mutually independent engines agree; a library id read off a figure is bound to the record actually fetched from the library, never to what a model asserted; and a vector-drawn figure becomes a candidate without a single criterion being relaxed. What this version does not do is said in the same place: a URL source is re-read at every query, so it cannot be searched offline yet — the next piece is a copy taken at registration for search while verification still goes to the network, because a cache that answers the verifier can only ever vouch for itself; and the knowledge store still has no window of its own, so registering and searching currently go through the model's tools only. The previous version made progress a matter of evidence: a session's goal moves only on a reading the app itself resolves and fingerprints — a false fingerprint is refused by name with the record untouched — and the window shows each criterion either carrying that reading or sayingunmet. Beside it, a knowledge store fingerprints every source it registers (file, folder or URL; the digest is of the response body, so the same content through a redirect stays one source), marks a resultstalewhen its bytes moved, keeps "could not read" as its own third state, and renders a folder as a byte-deterministic document whose every line cites the file and its current digest. Retrieval is lexical only, and says so on every response. multi-agent orchestration and delegated subagents · Python and R runtimes with audited notebook runs · artifact versions and lineage · reproducibility verification (isolated re-run + byte-exact per-file comparison + environment fingerprint) · the review-to-evidence loop · a nine-language interface · a signed specialist marketplace (24 Chinese-medical packages, 18 skill packs) · 35 connectors (290 tools: gnomAD, Ensembl, UCSC, STRING, PubMed, OpenAlex, IEDB, …) plus ENA run metadata that reports the bytes and MD5 each archive declares instead of downloading it · PDF text, tables, figures and captions with page-level geometry (pdf_tables,pdf_figures) · gene-set enrichment recomputed locally from the integers a service reports, from two services (g:Profiler and Enrichr) · a provider save gate whose runtime availability is kept in sync, with an actionable next step when a provider is unreachable · global search filter sets saved by name and named on the evidence line · NCBI reference sequences with SHA-256, byte count and base count · global search ·.sciencesession packages that carry the literature PDFs behind their citations · a citation-style layer (nine built-in styles plus CSL import) · private session bookmarks pinned to an exact artifact version · session forking that carries a count first and a provenance link back · a session information card · and a command line whosedoctorreports measured facts while the readiness verdict stays where it belongs. This version fixes what the installed build's own record showed, and adds the first layer of illustration understanding. A read-only audit of the app users are actually running — its own last seven days: 28 sessions, 3,883 completed activities, 126 problem activities — ranked the friction by signature, and the fixes follow that order. An agent that did the work and reported a plan stepcompletedwas refused for never having bookkept a start, and a refusal about dependencies never named the one to do first; a completion reported without a start is now legal and still passes the same dependency gate, and the refusal says which step to start with. A whole tool family was silently unattached whenever a server name's hyphen met a framework that folds it to an underscore — the model held the correct name and gotNo such tool available— and both sides are normalized now. The app could be configured with a proxy and still fail its own 299 MB weight download with a barefetch failed, because main-process fetches ignored both the app's proxy setting and the operating system's: the download now runs on Chromium's stack, and its failures name the cause and the next step. And a guard that refused a path outside the project described the data root as "the project folder itself", which sent the agent to the wrong place; it now lists the roots it actually enforces. Then illustration understanding, first layer: a figure is classified as chemical structure, protein structure, chart or generic schematic with every vote naming its own evidence, and evidence that is not enough refuses by name instead of letting a generic description impersonate the three classes it must not cover; what a class may derive is stated per class — a chart yields the numbers printed inside its box, each with the geometry of the line it came from, and the rest refuse by name. Deriving lands on the existing provenance surface as a third observation kind carrying an input fingerprint whose recipe is published for recomputation. One real reading contradicted the design and is recorded as such: on this machine's real PDFs every figure candidate was unclassifiable, so the next version widens the evidence instead of loosening the rules. The previous version shipped the assets the parsers will need, and made them arrive verifiable rather than trusted. The manifest that names each local parsing model ships inside the app and is read offline by the app's own validator — field by field, each refusal named (a weight url that is not https is one), because a manifest that reaches users cannot be fixed by a later commit and therefore has to be right before it ships. A model is fetched only when a reader asks for it: streamed to disk, hashed as it arrives, and kept only if those bytes match the published SHA256 — a mismatch or a failure removes the temporary file, because a half-written weight that a later run reads as "cached" is the one thing this path exists to prevent. Three digests do three jobs and are labelled as such: the publisher's md5 from the source record (a cross-check), the sha256 over the bytes we distribute (what the download verifies), and the hosting release's own server-side digest (a third party's, so nobody has to trust our transcription) — all three agree on 298,662,033 bytes, and an independent recomputation on this machine reproduces them. The window lists what the manifest carries — revision, publisher, licence, size, digest — and keeps its download button disabled until the reader ticks that they understand it pulls 299 MB over the internet; the reply is the app's own sentence (downloaded and verified,already cached, or a named refusal), and the list is then re-read, so what is on screen is a fresh reading rather than a guess. A manifest that will not validate names every problem beside its entry and shows no button at all. What this version does not do is said in the same place: fetching a model here does not make anything parse with it yet, because wiring these assets into document and figure parsing is the next piece of work. The previous version turned a method into a product: a recorded notebook run compiles into a callable skill, and a third-party public repository can be read, checked and deployed as a plugin — with the deployment atomic, the execution gated by the protection policy, and nothing written or started before the reader confirms. The previous version widened the read side, and made every new number carry what it is relative to. Pairwise LD arrives with its panel and sample size, an assay's list with the source's own total, a per-submission record with who said it, a miRNA-target table with its header verbatim and its unrecognised columns named, a file listing with declared bytes and no download, a PDB entry's residues in both numbering schemes at once, and one more provenance step that names which later run changed a value and how — under a hash you can recompute. The previous version made a notebook run reviewable before it happens, and named what a run did to your files. A cell is checked against four named rules —fs-delete,fs-overwrite,shell-execandlarge-allocation, each carrying its own rule version — and a flagged cell asks on the very card the app already uses, so one decision costs one card: the card lists the rule, its version and the line of code that matched, instead of a sentence saying that something looks risky. Declining is concrete — no kernel is provisioned, no code runs and no run record is written — and what the panel then shows uses that same rule vocabulary in all nine languages (Notebook run declined: deletes files (fs-delete) — no code was executed.), where it used to show an engine class name wrapped in a transport envelope. Every run carries a risk receipt — verdict, rule-set version, code hash and the hits — persisted with the run and discarded wholesale when it fails to parse on read, because half a receipt is worse than none; and a record with no receipt reads as not assessed, never as no risk. Beside it, dependency lineage now works at the alias and in-place-mutation level across runs: each stale-input reason names its kind (name-rewriteordirect-mutation) with the mutation's line and the alias chain it came through, and the content hash a lineage row needs is computed on read, where anyone can recompute it — 1,412 of 1,412 rows on this machine's real data, against 0 before. The in-session file-change review records a real sha256 on both sides of every change: the before side is observed when the run starts, under a bounded sweep (64 MiB of entries and bytes;too-large,not-recordedandunreadablenamed one by one, never chained from an earlier run's after), so the panel can print abefore → afterpair you can recompute yourself. Real-machine readings this version: the approval card on a real window (1 passed (11.9s), withNotebookRunDeclinedError: … fs-deletein the app's own log and zerormtreerecords after declining), the sentence the panel's own terminal prints (1 passed (8.8s), matching the strip character for character and carrying neither the engine error nor the IPC envelope), and a real 182 MB session workspace whose before and after hashes equal an independent recomputation — with a 6 MB weight file namedtoo-largeon both sides, not one byte of it read. Both notebook specs then ran on the certification lane's own machine as well (103 specs: 90 passed, 1 flaky on an unrelated PDF spec that passed on retry, 12 skipped), so the card and that sentence are checked twice, on two machines. The previous version added two working lines. Structures: open a PDB/mmCIF or a predicted model in a 3D view, select a residue range, and what enters the conversation is that selection's own identity plus a fingerprint you can recompute — structure id, chain, residue range, representation and derived sets, never a timestamp and never the name — so "this region" means the same thing tomorrow; a Chinese sentence ("把 145 号半胱氨酸 5 埃以内的残基标出来") becomes a real selection with the parameters it sent shown on screen, and a measurement is either taken on atoms that exist exactly once in that structure or refused by name (a residue-level distance is refused outright, because which atom pair to measure is ambiguous); a selection can be named and coloured, and the name travels in the context block but not in the fingerprint (the same region may be a binding pocket today and an active site tomorrow); exporting the view goes through the approval card — refusing writes nothing at all — and the exported image carries that region's fingerprint and name inside it, while those same text chunks are stripped from anything handed to a model; fetching a structure by PDB or UniProt id is decided by the deny-list / allow-list / protection gates, and the renderer can never name a host or a URL; and prediction-engine outputs land underpredictions/<engine>/, where the view labels them with engine, output kind and licence — saying "not an experimental structure" in words. Literature: translate a PDF paragraph by paragraph with resumable checkpoints, so reopening the app never re-translates a finished paragraph — the evidence is that not a single request goes out; read it in source / translation / side-by-side, where both columns share one set of rows so there is nothing to keep in sync; per-page state tells "this page has no text layer" apart from "not translated yet", with four numbers beside it for checking; per-paragraph terminology deviations are named against the app's own MeSH-sourced table and judged only where a translation exists; clicking a translation jumps back to its own line in the source; references are kept verbatim and shown as kept rather than as missing; and the exported side-by-side file carries a recipe, the source hash and both counts in its header, so you can count its pages and paragraphs yourself. Real readings this version: a real 7-page / 39-paragraph PDF (its seventh page has no text layer, and the panel says so), one real translation (deepseek-v4-flash, 20.0 s) that stored its record and surfaced a genuine terminology deviation — the prose came back as 阿司匹林 / 随机对照试验 / 荟萃分析 while the journal nameLancetstayed in Latin — and a prediction-structure load that was refused with no network and no file because nobody could answer the approval card. The previous version asked what examination was done — 20 terms for imaging, endoscopy, pathology and lab procedures (磁共振成像, 内镜检查, 活组织检查, 心电图, 高通量测序 …), each with its English side read from MeSH and the descriptor recorded on the row.磁共振成像 脑卒中now goes out asmagnetic resonance imaging stroke(PubMed 49,165),all:磁共振成像asall:magnetic resonance imaging(arXiv 498,230) and超声心动图 心力衰竭asechocardiography heart failure(OpenAlex 284,090); before, the examination half of such a question was refused by name with nothing sent. Six rows that had landed undermethodmoved to a newprocedurekind — measurement, not study design, and the kind travels to the agent, so the label has to mean what it says — with their English sides and descriptors untouched. All 100 sourced rows still verify against NLM. The previous version asked a mechanism question in Chinese — the term table now carries 33 subject-matter terms (apoptosis, autophagy, ferroptosis, epithelial-mesenchymal transition, exosomes, ubiquitination …), each with its English side read from MeSH and the descriptor recorded on the row.细胞凋亡 肺癌now goes out asapoptosis lung cancer(PubMed 31,551) andall:铁死亡asall:ferroptosis(arXiv 6); before, the mechanism half of such a question was refused by name with nothing sent. The batch's design, rows and readings are the autonomous executor's, replayed here from the recipe its own evidence note lays out after a stand-down — the two read-source cases now share one helper so a new sourced kind cannot land with weaker checks than the ones beside it, and the whole table still verifies 86 of 86 rows against NLM. The previous version made the table's provenance checkable by hand — every sourced row claims its English side was read from a MeSH descriptor, and until now that claim could only be trusted or checked manually.node scripts/verify-mesh-sources.mjsnow resolves each descriptor at NLM and compares its preferred label with the term the row actually sends; it reports a row that cannot be fetched differently from a row that disagrees, names entries that are not in the table at all, and exits non-zero on any mismatch. Run over the whole table on the day it landed: 53 of 53 rows matched. It is deliberately not wired into CI — a lane that goes red because a third party is slow teaches people to ignore it. The previous version asked the design half of a Chinese clinical question — the term table now carries 30 study-design, statistics and omics terms (队列研究, 随机对照试验, 荟萃分析, 机器学习 …), each with its English side READ from MeSH rather than translated here: the MeSH descriptor is recorded on the row (mesh:D016449), so anyone can resolve it and check the term. A Chinese question is usually a design word plus a subject, and without these the design half was refused by name —随机对照试验 阿司匹林now goes out asrandomized controlled trial aspirin(PubMed 9,072) andall:随机对照试验asall:randomized controlled trial(arXiv 401,679), where before both were refused with nothing sent. The Chinese half is the term as Chinese medical literature writes it, and the evidence note says so per row: only the English side is an authority's. The previous version answered Chinese questions on arXiv — and it earned the rewrite policy the hard way. A single probe came back as HTTP 500 with a valid-looking Atom feed whosetotalResultssaid 1: that1was an error entry counting itself, and reading it naively would have reported "one Chinese match" for a query that never ran. The app already detects that feed and raises by name, and this version verified it with a real reading rather than by reading the code. The decisive comparison then settled the policy:all:阿司匹林returns 0 whileall:aspirinreturns 42, so arXiv indexes Latin text and refuses unmappable Chinese by name with nothing sent. The rewrite is done IN PLACE — arXiv's query language carries meaning in punctuation, so composing it from space-joined pieces would turnti:阿司匹林intoti: aspirinand move the prefix off the term it applies to. The previous version answered Chinese questions on OpenAlex — the app's Chinese term table now rewrites queries for the all-disciplines literature source, and the policy differs from PubMed's because the two sources behave differently, measured rather than assumed: PubMed indexes Latin text (term=阿司匹林returns zero whether or not the evidence exists) while OpenAlex indexes and answers Chinese (search=阿司匹林returns 11,867). So OpenAlex gets the rewrite where the table knows a term — the English term of record is far better covered (aspirin443,778 against 11,867) — and searches what it does not know as typed, naming those terms in the result instead of refusing the query. Only a query made of nothing but function words is refused, by name, without sending anything. The previous version let you check a reading from the window — every reading in an artifact Version's provenance now has a button that re-issues the request it came from and reports what came back: the same bytes, different bytes (both digests are shown), or a refusal that names its reason. Re-issuing is the only thing that can turn a recorded digest into a checked one, because the digest is computed over the response bytes and the bytes are deliberately not stored. The request never carries a URL: the window sends a session and a digest, and the main process looks the reading up among the ones it recorded, so the capability is exactly "re-verify a reading this app took" and cannot be used to fetch an arbitrary URL. A request that was not a read, a URL whose credentials were stripped, and a record that predates the fields a faithful re-issue needs are all refused by name rather than re-issued approximately. The previous version said which run a reading came from — every reading in an artifact Version's provenance can now name the run that recorded it, and the one taken by the run that produced that Version is marked on screen. The id comes from the main process's own session state, never from a caller-supplied argument: run identity is not something a call gets to assert about itself. When no run was executing, the reading carries no id at all rather than a guessed one. And the window promise from the previous version is now kept only where it can be: if the Version's evidence carries no readable creation time, the panel says the readings are the whole session's instead of printing "before this version was written" over a set it never filtered. The previous version made the readings window real — the panel said "what this session read … before this version was written", and the projection listed every reading of the session regardless: a version written at 10:00 showed readings taken at 15:00 under a label that claimed a window. The window is now enforced against the version's own created_at, and readings that fall after it are counted and named on the panel instead of being silently absent — a stamp that will not parse is counted too, never quietly promoted into the list. The certification spec gains a seed on each side of the window and asserts that exactly one reading is listed, so the promise is checked on a real window as well. One correction rides along: the previous body said the panel's real-machine reading had not been taken, and it had — from the certification lane, with its own printed reading. The previous version paid for the readings chain only where it is returned — the journal is one file read per session, and three paths were paying it for answers with nowhere to put it (a reproduction verdict, a code reconstruction, the bulk card listing), so each now says it does not want it; and a session's parallel calls no longer overwrite one another — eight overlapping writes used to leave exactly one reading behind while the dropped count still read zero, a loss that looked like completeness, so writes are serialised per session. A verifier nobody called was removed with the rest of the unconsumed exports, and the shape guard it relied on now runs where the journal is read: a digest nobody could recompute is reported as unreadable rather than shown as a reading. The previous version put that chain on the screen — the artifact-Version provenance panel gains a Readings section: every reading the session recorded, with the service and tool, the request method and URL, the status, the byte count and its sha256; the published recipe it is computed under, read straight from the constant instead of retyped; and how many older readings the cap dropped. The three missing states stay apart — no journal, unreadable, and empty — so an empty list is never drawn where "nothing was read" belongs. The panel asks for the readings on that one read, and the bulk card path still pays no file read per card. **The previous version walked from an artifact Version back to the readings — provenance now lists what was read in that session: the service and tool, the request, the response byte count and its sha256, under a published recipe an independent implementation reproduced byte-for-byte here. The attribution is carried on the value — session plus time window, never per-run causality, because the connector layer knows the session and nothing finer — and a missing journal saysnot-recorded, an unloaded one saysnot-loaded, a corrupt one saysunreadable, so an empty list is never read as "nothing was read". The GB/T 7714 block for electronic resources also gains the issuing body, which is the shape a Chinese evidence item actually takes ("中华医学会, 2021"); the slot opens only when the record carries a publisher, so a record without one keeps its exact bytes. The previous version named what a call leaves behind — the connector approval card now says when a call creates state on the service rather than only sending a query: the tool that registers your gene list on Enrichr's own servers is marked as such and the card prints that the entry outlives the call and cannot be removed from here. The card used to describe only how long the APPROVAL lasts ("applies to this call only"), which reads as how long the call's effect lasts. The declaring set is pinned by a test in both directions: the twenty-odd POST-only connectors here merely carry queries and are asserted to stay unmarked, so the line keeps its meaning. The previous version answered Chinese questions with evidence — a Chinese term is mapped to the language the sources index before anything is sent, and the rewrite is reported in full: what was recognised, which words were dropped, and the exact query that went out (阿司匹林 returns 80,708 matches and 阿司匹林治疗高血压 4,910, against a count of 0 for the raw Chinese, which the live service answers with an empty result whether or not the evidence exists); Chinese the table cannot map is refused BY NAME with nothing sent, so a zero-match answer can never again be read as 'no evidence'; the connector panel gains zh_medical_terms, which resolves a Chinese term the app has never seen to a citable entity and says which label or alias it matched on without collapsing ranked candidates into one answer; and every connector reading now carries a fingerprint — service, request, response bytes and sha256, under a published recipe, reproduced byte-for-byte here by an independent implementation. The previous version made a stop say only what it did — a remote host that cannot be reached gets a refusal that carries ssh's own sentence and exit status, and its job row staysrunninginstead of being written ascancelled; a stop that does arrive takes the job's whole process group, not just the launcher, and the row readscancelledon the way back out. A host with neithertimeoutnorgtimeout— stock macOS — no longer fails the job outright: the workload runs, and the host's stderr carries one named line about the wall-clock limit the app's own budget stands in for. It also adds IEDB immune epitopes, whose every record carries its assay method, MHC restriction, quantitative result and citation, whose empty results name the family that was empty and say this is not an absence of response, and whose truncation flag comes from asking for one row more, because the service reports no total. The previous version made a named environment's packages reachable from the window, and stopped a refusal from claiming an approval that never happened — the Settings Packages dialog adds to and removes from a named environment for real (a distribution installed through it is importable by that environment's own interpreter; one removed through it is gone from the inventory the dialog re-reads), with the app-managed default's inventory compared row by row before and after so a silent retarget cannot pass, and the default itself still additive-only; and a remote run refused by the execution-protection policy now reportsprotection_refused— saying that nothing was submitted and nobody was asked, and where to change the policy — instead of the oldApproval denied, which sent readers after a grant that could not have helped. The previous version inspected what arrives from elsewhere, and let you take back what was merged, delivered or imported — an RO-Crate someone hands you is read in place and checked requirement by requirement, writing nothing and touching no byte of your project, with its payload bytes recomputed too so the checked rule set is the same one the export side applies; an imported skill can be duplicated into a skill of your own that you can edit, while the copy you imported stays as it was imported; the alias a journal merge left behind can be released, with the metrics and references that merge moved left where they are, as the window says before you act; the message centre deletes one notice or clears the whole inbox, stating that your conversations are not deleted and that it cannot be undone; the engine panel reads itself out — seven engines, each with its availability and a named reason, and no download button is offered where no published checksum exists to accept it; and a session replay step can be asked about, the answer assembled locally with the field behind every sentence cited, and the record's silence reported rather than filled in. It also re-read two gaps that had been carried as product defects: the journal-import panel in Settings does render its row-by-row outcome (the earlier reading came from a locator that matched a toolbar button by substring), and the progress detail fields do reach the renderer — both sides of the broadcast read the same message object. The previous version carried the evidence with the package, and gave an interrupted run its own name — a.sciencesession package that lands in a fresh project now writes its citations, review findings, review conclusions and human-pinned evidence into the receiver's own tables, and the certification run compares all four dimensions row by row against the sender's source instead of asserting a hand-written 1 (the receiver is an empty project, so every landed row can only have come from the package); a notebook cell in flight when the app went away is recorded asinterruptedwithapp-terminated— the domain rule has said from the start that this is not a failure, "the code may have been fine", and the write path now agrees, including when the process tree is killed from outside while the app is still shutting down (the crash path consults a shutdown latch, and the shutdown refuses in-flight runs immediately while still letting a queued persistence write finish); a scanned PDF says how many of its pages carry no extractable text rather than only naming the document; a screening batch names the kind of failure it hit so a reader can tell whether to re-run; a failed handoff prints which step to resume from; a script the app truncated is labelled as truncated instead of being shown, and exported to.ipynb, as if it were whole; andpdb_search_by_sequencesearches the PDB from a bare sequence, without a UniProt accession. Previously it added a way in to what was already built — a managed artifact preview can open the file in its default application or reveal it in the file manager, with the opener resolving the path through the repository in the main process (anything outside artifact storage is refused by name rather than quietly opened, and a refusal is shown in the handler’s own words); a finished remote job shows what it produced, listing the featured outputs and every file left on the remote host with its own size and reason, saying how many more the payload did not list instead of showing a subset, and printing a failed harvest beside the workdir that is kept so the files can still be fetched by hand; the message-centre badge lights up on its own when a task finishes, without the bell being opened first; and three settings channels that had no handler on the Electron bus — which left the function-model panel saying it could not read its own settings, with every button inert — now answer. Previously it added index coverage you can read — global search reports how much of the corpus the incremental index holds (indexed), how much changed since (pending) and when it was last measured, with an "Index now" step that runs one bounded tick and answers with the reading it produced; on the real window a restart does not moveindexedbackwards, and deleting the index directory does not turn the corpus into "nothing found" — the next query rebuilds it on disk and the files are still returned (3 hits), while the coverage block keeps reporting the last measured tick instead of a reading taken mid-rebuild. Together with two values for one year printed side by side with their own sources, a batch of interface copy localised in all nine languages, and a measured contrast ratio for text on the brand colour (4.144:1 — below the 4.5 body-text floor, and pure white only reaches 4.330:1, so the gap is recorded rather than papered over). Before that it added importing an environment from an external lock file — every package verified against the md5 the lock publishes, and a single unverifiable entry builds nothing — together with named environments that can be listed, used as a notebook runtime, or removed, with a running kernel's hold on one refused by name rather than reworded. Earlier it added journal entities — an ISSN, or an exact normalised name, resolves a journal; every impact factor and CAS partition carries the year and the source it came from, withUnknownwhere none was imported (never a 0); two spellings of one journal merge only when you say so, and the old spelling keeps resolving; and metrics import from CSV/TSV with one named result per row. The previous version added a reason for a page that yields no table — the extractor's own measurement, with the counts and floors behind the decision, and a named throw when a shape passes every gate — together with rotation-normalised table reading (text drawn at an angle is measured in its own frame, and the page whose coordinates were rewritten says so) and a named reason on the turn path for a turn that never reached the skill selector, so the trail answers that question instead of staying silent. The version before that added per-run file evidence in three states — read, written, and not captured with a named reason, so a list with no explanation cannot be expressed — together with content-addressed storage that keeps identical bytes once and measures the space it saved off the filesystem (an in-place tidy-up decides by hash, not file size) · explicit states for the official skills catalog, a recomputable quality score on every skill row and an import check that says whether a skill's content still matches what was imported · and a real function-model probe round-trip reporting measured elapsed time and the skill it selected. Earlier it added an execution-protection matrix (four execution surfaces × the filesystem-write and network-allowlist axes, each row naming its gap and the fix path) with unprotected remote runs denied by default · global search scopes split into uploads and generated files, each scope chip carrying what that scan actually covered and showing a dash — never a 0 — for a scope that was not searched · advanced search filters (time window, ordering) that print the request's own condition string on the results, with a re-run check that reports the evidence as unchanged, changed or not found · per-purpose function models whose row names the model in force, the service it comes from and the built-in path used when it is unavailable, plus a real detection round-trip reporting measured elapsed time and token usage and a retrievable trail for every fallback · and a locally recomputable skill trigger-quality score with the missing pieces named, beside a per-reader skill availability matrix whose always-on and globally-disabled entries are shown as locks with their reason · literature and journal records that keep their own history — a replaced PDF stays in view, a reference's notes are writable and survive a restart, and a journal metric corrected by hand keeps the old value beside the new one, each with its own source and year. -
✅ Shipped and machine-verified: A sweep now leaves a reading behind. Every completed sweep records when it ran and what it found — scanned, kept, removed, still-failed, bytes freed — and that record rides along with the source list the panel already fetches, so no new channel appears. After the fact you can still answer "when did this last run and what did it do". Three states stay apart: never swept, swept and found nothing, and a record that will not parse. The source list pages at twenty rows with a clamped page index. The previous version did inverse folding for real.
-
🚧 Partly done: Retrieval is lexical only in this version — no semantic source is wired, so every response carries
mode: lexicaland names the degradation and every row sayslexicalOnly; the semantic step is left for the version that actually has an embedding source rather than pre-wired as dead code. The goals panel is read-only by design (creation and progress belong to the session's own tools, which can name a reading the app resolves). Citations are not yet persisted: what this version ships is the re-checker and the per-row marks. Windows builds are not code-signed — the installer works, but Windows warns about an unknown publisher at install time; we say so here rather than let it surprise you, and signed Windows builds wait for a certificate and a signing identity. CSL import runs a fidelity probe against each document — of eight real published styles, five pass and three are labelled drafts with the missing piece named (their author macros branch on record types we do not model yet). ENA is metadata and reachability only: no FASTQ is downloaded. The shared diff viewer covers artifact comparison and tool-edit diffs; skill updates and session-package record verification are not wired to it yet. Distribution has just started — both READMEs lead with a result the product produced and nine languages now exist — but the download site is not deployed yet and the repository is still young. Two things remain unshipped: the skill-marketplace slice (K1a) is archived, not shipped — the official skill catalog could not be reached from the build machine (the CDN metadata path returned 404, the raw host timed out) and the marketplace protocol root carries specialists only, so no consumer-less code was written and the slice waits for the version that publishes the catalog — and two of the five real-machine criteria for per-purpose models are still uncertified, and the previous version isolated exactly why: the narrow model call is only reached on a bridged (Codex) turn path. A real codex session was established for this version — through the app's own managed install inside a throwaway root (303 MB, nothing on this machine changed) — and a live turn now records for itself that it had no skill-selection bridge (bridge-unavailable, readable in the trail), which is the first of those criteria certified on the turn path. The remaining one — 'the answer on a live turn really comes from the configured vendor model' — is still uncertified, and the previous version isolated why the earlier attempt could not even reach that question: the function-model host handed to the runtime was being dropped at the composition layer, so the configured model was never consulted on a turn and no trail was written. With that fixed, a live turn on the same isolated instance records a real round trip andused-model, and the fallback path that used to claim the model had answered now recordscall-failedby name — but the party answering in that live reading was a stub endpoint, so 'answered by the vendor model' stays uncertified. Also open and named: the app's own detection accepts only its managed adapter, so a user-installedcodex-acponPATHis not usable in-app yet — a detected-but-unusable adapter reportsCodex native executable not found. The two units this narrative previously named as not started are shipped in this version and verified on a real machine: an imported session states where it came from (imported from X / exported at Y / not verified on this machine) and stays read-only, and a data-root move that never finished is re-discovered from its marker on disk after a restart, so it can be completed or discarded without the window that started it. This version also gives a user-added MCP server its whole action surface — its detail page lists the tools the server itself advertises with per-tool permissions, the skip-approvals switch holds, a connection test separates "the server did not answer" from "the server advertises nothing", a signed-in server can be signed out, an unusable one says why on its own row, and the bulk buttons cover these servers too — beside the runtime surface: installing packages into a managed environment, binding and switching a notebook's runtime, a prep overlay whose Cancel works, and a card that says where the app-managed runtime comes from before anything is downloaded. -
🗺️ Planned: explicit guidance when a plan is resumed · a wider serverless GPU surface.
Rules we do not relax: no model weight is downloaded without a published SHA256; an imported style or skill without a licence is not installed; a field the record does not carry stays empty and is named — never filled in on its own; code a model reconstructed is never certified as a reproduction; timing conclusions are only drawn from the same corpus, the same driver, measured before and after (a millisecond assertion that wobbles under load is reported as unstable rather than tuned until it passes).
💡 PureScience v2.21.2 released — Four new connectors, and two numbers the panel had never stated. LIPID MAPS answers exact compound lookups (
pubchem_cid=5997→LMST01010001 / Cholesterol / C27H46O / 386.354866on this machine) and refuses a name by name, because that API has no name search — the service itself lists the eleven identifier kinds it accepts. OmniPath answers directed interactions, per-protein annotations and enzyme→substrate modifications, withis_stimulationandis_inhibitionkept apart fromconsensus_*; the probe found that/annotationsrejectsorganisms, so that parameter is no longer sent and the result saysorganismFilterApplied: falseinstead of pretending. TCIA and structure similarity ship too, but their readings come from a live probe on CI, not from this machine: every TCIA address answers000here andsearch.foldseek.comis intermittent, so those two are measured where the network reaches them and printed into the job log — writing them up as verified from a laptop that cannot reach them would be the exact thing this project keeps refusing to do. Structure similarity also needed infrastructure: RCSB's public search has no working structure service (service:"structure"answers 400 for everyentry_idshape, 500 forvalue, whilechemicalanswers 204), soToolContextgainedpostFormand FoldSeek takes the coordinates themselves. The connector panel now labels every row with its scientific area, groups the directory by area in place (no second layer of collapse to click through), and states 35 connectors · 290 tools — both numbers from the registry, so a search cannot change the total. And notebook kernels can only write inside the folders they were given: a real seatbelt profile deniesfile-write*first, allows the session directory, the figures directory and the two temp trees back, then denies the managed runtime last, because last match wins — measured on this machine asWROTEinside,PermissionErroroutside, andPermissionErrorinside the runtime even though it sits under an allowed temp tree. What is still open is said in the same breath: shell and background jobs are not covered by that confinement, Linux and Windows get no write guard at all (and claim none), and the packaged screening lane's four certifications now run again (p0109 passed / 12 skipped, 31.5 min) after the first-window budget went from 30 s to 180 s.
Previous: v2.19.0 — A framework you select could be silently ignored: two hand-maintained whitelists listed three of the four framework ids, so
codebuddywas dropped by the settings parser and again by session persistence; both now read one source with a compile-time completeness check, and the four-runtime machine check reached 3/4 with codex's first reproducible reading.
- Quick Start
- Product Tour
- Showcase
- Real Runs Behind the Claims
- Extreme Adversarial Stress Tests
- How PureScience Compares
- Maturity and Known Limitations
- Why PureScience
- Design Principles
- Core Capabilities
- Model Providers
- Data, Permissions, and Trust
- Project Status
- Development & Packaging
- Roadmap
- Brand & Ecosystem
- What This Is Not
- Frequently Asked Questions
- Get Involved
- License
Open the latest release, expand Assets, and choose the installer for your computer:
| Your computer | Choose |
|---|---|
| macOS / Windows / Linux | Installers for every platform are published on each release — pick yours from the Assets list. macOS packages are signed and notarized by Apple when release signing credentials are configured, and each release page states the signing state that build actually shipped |
Windows: the installer is not code-signed, so Windows will warn about an unknown publisher — compare the package against SHA256SUMS.txt on the release page before running it; signed Windows builds wait for a certificate and a signing identity. macOS packages are signed and notarized by Apple when release signing credentials are configured. Linux packages are not signed.
Review the assets and verification information published on the release page. See Verifying your download before installation if you need to validate a package.
If macOS shows an unidentified-developer warning, verify that the package came from the official Releases page before continuing.
The first launch has five guided steps:
- Environment checks compatibility, app storage, secure credential storage, and network access.
- Agent runtime selects and prepares Claude Code, OpenCode, Codex, or CodeBuddy. App-managed runtimes can be installed without requiring Node.js, npm, or an administrator password.
- Model provider connects and tests the model you want to use. Choose a built-in provider, a custom gateway, or an existing Claude or Codex subscription login.
- Notebook runtime optionally prepares app-managed Python and R environments or enables detected and manually registered interpreters for either language.
- Data location chooses where large artifacts, notebooks, uploads, and environments are stored.
Notebook execution is optional. Every required environment and agent-runtime check must pass before Continue becomes available, and the model connection must pass before setup finishes. Notebook and data-location settings can keep their defaults and be changed later in Settings.
- Click New project and give the project a stable research name and optional description.
- Open a session and describe the goal, input data, constraints, desired outputs, and how the result should be checked.
- Attach source files, select a verified model, and choose an approval mode.
- Send the task. Inspect the agent's tool activity, approve sensitive actions, and open generated artifacts in the preview panel.
- To explore a different direction, edit an earlier user message and resend it on a new branch; use the message revision controls to return to either path.
- Open an artifact's Provenance view to inspect its versions and the available evidence behind the selected result.
- Continue the work in later sessions. Use
@to reference an existing project file and/to explicitly select an enabled skill.
Screenshots in this README illustrate the workflow. Labels, catalogs, and other interface details may differ from the version you install.
PureScience organizes research into projects and sessions so that every result can stay connected to the evidence that produced it. The sections below walk through the workspace, artifact provenance, previews, scientific skills, and data connectors.
Projects keep related sessions, uploads, generated files, and preview state together. The conversation records the agent's answer and the commands, file reads, edits, searches, and connector calls that produced it. Each generated artifact is stored as an immutable, checksummed version. Its Provenance view exposes the evidence PureScience could verify at creation time: producer code and execution history, referenced inputs, an observed environment inventory, the producing conversation branch, and any version-scoped reviewer findings. Missing evidence is shown as unavailable instead of being guessed.
Generated reports, figures, and tables remain attached to the session and are also collected in the project file library. Preview tabs keep the active result visible as the panel changes size, and long names preserve their identifying suffix and extension. PureScience previews common scientific data, PDFs, Office documents (DOCX, XLSX, PPTX), images (with zoom and pan), source code with syntax highlighting, molecular structures and reactions, and Notebook history. Preview limits do not truncate the underlying file—the full artifact stays available to the agent and external tools. Use Cmd/Ctrl+F to search transcripts, Notebook output, and rendered pages across the workspace, or Cmd/Ctrl+K to open the project-scoped command palette. A dark mode rounds out the workspace: toggle the theme in Settings → General and the whole shell, transcript, and renderer palette switch without a flash.
From the release build: this session's figure was produced by the agent, checked by the built-in reviewer, and stored together with the script and provenance record that produced it.
Edit a completed user message to resend a revised prompt from that point. PureScience creates a new message branch instead of deleting the turns that followed, and revision controls let you move between the original and alternative paths. Branch selection, tool activity, attachments, and generated artifacts persist across project switches and restarts. Provenance remains tied to the exact branch that produced each artifact version, so exploring a different hypothesis does not blur the record of the earlier result.
PureScience includes a growing catalog of 18 featured, file-based research skills: AlphaFold2, Boltz, Borzoi, Chai-1, DiffDock, Environment & Packages, ESM-2, ESMFold2, Evo 2, Indication Dossier, LigandMPNN, Literature Review, OpenFold3, ProteinMPNN, scGPT, scvi-tools, SolubleMPNN, and Remote Compute (SSH) for submitting and harvesting long-running jobs on remote HPC clusters. You can create personal skills, upload SKILL.md/ZIP/.skill packages, preview and import compatible skills from GitHub, or import skills already installed in your global agent directories. The agent can also request a package import from a session attachment or a public GitHub URL, with an app-owned preview and confirmation step before anything is written. Enabled skills can be selected directly in the composer with /.
It also includes 35 built-in research connectors: Literature Graph, PubMed, bioRxiv, Genes & Ontologies, Genomes, BioMart, Variants, Sequence Analysis, Human Genetics, Clinical Genomics, Structures & Interactions, PDBe, Protein Annotation, Immune Epitopes, Expression, Omics Archives, CellGuide, Regulation, Chinese Term Resolution, RNA, ENCORI, Chemistry, ChEMBL, ZINC, Molecule Viewer, Multi-Agent Orchestration, Clinical Trials, Drug Regulatory, Cancer Models, PDC, LIPID MAPS, OmniPath, TCIA, Structure similarity, and Research Resources. Built-in and custom connectors remain behind the permission system, with per-tool Always allow, Ask each time, and Block controls. The installed app shows the current skill, connector, and tool catalogs.
PureScience brings research tasks, execution, files, and evidence into one local, inspectable desktop workspace.
Research work is usually split across chat windows, notebooks, local scripts, scientific databases, file browsers, and reporting tools. Context is lost at every handoff, and the answer is often separated from the code and files that produced it.
PureScience brings those pieces into one inspectable desktop workspace:
- Work that persists. Projects, sessions, drafts, files, previews, and run history survive application restarts.
- Execution, not just suggestions. The agent can run commands, Python, and R, edit files, search, call connectors, and generate artifacts with the user's approval.
- Alternative paths without lost work. Revise an earlier prompt on a new message branch and switch between the resulting research directions.
- Traceable results. Immutable artifact versions retain the production evidence PureScience can verify, and explicitly mark evidence it cannot.
- Multiple model choices. Use a built-in cloud provider, a compatible custom gateway, or a Claude or Codex subscription; choose the model and its reasoning effort together in the composer.
- Local-first ownership. The application and project state run on your computer; external calls happen through services you explicitly configure or approve.
- Inspectability. The source code, skills, connector definitions, tool activity, generated files, and artifact provenance are available for review.
- Extensibility. Add skills and MCP connectors instead of waiting for a closed plugin roadmap.
- No seat license. PureScience is Apache-2.0 software. You pay only for the model or infrastructure you choose to use.
PureScience is an independent product built from scratch. It is not a proxy, unofficial client, or reskin of another AI research application.
One natural-language prompt → multi-step agentic research → traceable, reproducible science. The demo below ran end-to-end in ~11 minutes: the agent queried three scientific databases (ChEMBL, ClinicalTrials.gov, PubMed — 19 connector calls), executed 34 notebook cells (Python + pandas + matplotlib), caught and fixed two of its own bugs, and delivered three artifacts with provenance.
The task (verbatim):
Build a drug-discovery intelligence dossier for EGFR T790M (non-small cell lung cancer).
1. Use the ChEMBL connector to retrieve published small-molecule inhibitors of
EGFR T790M (Homo sapiens, IC50 < 100 nM). Rank by potency, take the top 5.
2. Cross-reference those 5 compounds against ClinicalTrials.gov: which are in
active clinical trials for NSCLC? Record trial phase, status, and sponsor.
3. Use PubMed to find up to 3 key papers per compound (mechanism / clinical evidence).
4. Write a Python script to merge everything into one table (compound, target,
IC50, trial phase, status, sponsor) and generate a bar chart of IC50 values.
5. Deliver three artifacts: (a) the merged table as CSV, (b) the potency figure,
(c) a one-page markdown dossier with citations. Explicitly state which data
was verified via connectors and which could not be found.
What it produced — every file real, every number independently verified:
| Deliverable | File |
|---|---|
| One-page dossier with citations and a verified-vs-not-found statement | egfr_t790m_dossier.md |
| Merged table (compound · target · IC50 · trial phase · status · sponsor) | egfr_t790m_merged.csv |
| Potency figure (log scale; green = active trials, grey = none) | egfr_t790m_ic50.png |
| In-app preview of the generated chart | shot4-figure-preview.png |
All key data points were re-checked against the public APIs after the run: 5/5 ChEMBL IC50 values, the representative FLAURA2 trial (NCT04035486) on ClinicalTrials.gov, and the cited PMIDs on PubMed all match. The agent also disclosed its own limits in the dossier — records it could not resolve, connector pagination constraints, and compounds with no active trials — instead of guessing. Full details: demo verification report.
PureScience is built around one position: AI for science only pays off when the loop between computation and experiment actually closes. We frame that loop as hypothesis (dry) → AI prediction (dry) → computational verification (before the wet bench) → wet-lab handoff → data feedback → knowledge reuse, and every step must land as a real, versioned, re-runnable artifact — not a chat summary.
That is why PureScience is implemented as the open, local-first, model-agnostic agent-and-workflow layer of the AI4S stack — with an evidence, reproducibility and compliance layer running across the whole loop — rather than a hosted research chat that ships your data somewhere else. Screenshots below come from real local sessions on v1.37: no demo data, every file on disk. The 13-project acceptance suite spans seven capability levels (L1 literature synthesis → L7 evidence chain & reproducibility); most chat-style tools stop at L1–L2.
Protein design, cross-database consistency, paper reproduction with counter-evidence, compound-target selectivity audits, anti-hallucination stress tests, single-cell analysis, environment reconstruction, drug-evidence cross-checks — each project holds real sessions and real artifacts.
Three tasks in one project — a GFP/enzyme panel for E. coli expression, de-novo SARS-CoV-2 RBD binders (PDB 6M0J), and 1,000-sequence Ubiquitin inverse folding (PDB 1UBQ). The 9-row GFP panel (V0–V8: designed spectra, monomerization, pH axis, dark control) is delivered as a handoff document for the wet lab, with ORF FASTA and metadata TSV beside it.
诚实性即产物:失败与局限照实入库(Honesty is logged, not hidden)
Mid-run the agent caught its own bug and fixed it on record — “chromophore detection was wrong: water molecules were treated as protein-like HETATM.” Without a GPU it stated ESMFold was unavailable and switched to structure-anchored design instead of pretending. Failures and limits are recorded as negative samples — the data layer AI4S needs most — and every report separates “verified via connectors” from “could not be verified”.
SARS-CoV-2 Mpro (PDB 7VH8) + nirmatrelvir: 280 docking poses scored by interaction energy (best E_int −52.9 kcal/mol; 16/21 pocket contacts match the crystal), then explicit-solvent molecular dynamics with 82,563 atoms — protein Cα RMSD 0.93 Å, ligand RMSD 0.79 Å, key Glu166 hydrogen bond held in 62% of frames. The whole OpenMM pipeline ran on a laptop, and the report states its own limitations (charge model, non-covalent approximation, 1 ns scale, monomer).
中文速览:PureScience 把 AI4S 干湿闭环跑成真实产物——以上截图均为 v1.37 本机实跑(13 项能力验收 + 蛋白设计 / 分子动力学 / 多库情报真实会话),每个截图对应的产物文件均可按会话路径复核;报告自带「已验证 / 无法核实」分离与局限声明。更多可复核的独立验证见 demo verification report。
Between 2026-09-04 and 2026-09-07, PureScience was handed 30 adversarial research challenges by external reviewers — no demo data, no curated inputs. The reviewer spread them across five daily sessions, and the runs themselves finished in ~6 hours of total runtime on a single Apple M2 laptop with 8 GB of RAM. Each challenge described a state-of-the-art but deeply flawed research claim (a kinase "selectivity" chemistry cannot support, an antibody whose affinity defeats its own brain delivery, a condensate drug that "dissolves" a transcription factory by gelling it, a CAR whose affinity can never compensate sparse antigen…) and demanded a mechanism-level verdict. Every run ended with a versioned deliverable set: a Chinese adjudication report (with its own Data-Gap list), the solver code, and publication-grade figures — visible in the project's Files panel and replayable from the conversation. Every wave also carries an external reviewer scorecard — see the scoring archive.
The complete evidence is archived case-by-case: all 30 reports, solvers, and figures live under docs/extreme-tests-2026-09/cases/, with an in-app session screenshot per flagship case in the full evidence gallery. Below is a condensed tour.
The projects page after the marathon — every row lists the actual file types its session produced (MD · PY · PNG · CSV · HTML).
More sessions, same pattern — each with its own solver outputs in the Files panel:
Sampled verdicts — each row is a direct summary of a real session's report:
| Challenge area | The trap in the claim | What the run concluded |
|---|---|---|
| Kinase selectivity (TNIK vs its paralogs) | Hinge backbone H-bonds + a high docking score ⇒ "1,000× selective" | Contact residues are 100% conserved between paralogs; the thermodynamic upper bound (≤1.5 kcal/mol) cannot encode a 1,000× difference |
| BBB transcytosis (TfR bispecific) | Higher affinity ⇒ more antibody reaches the brain | Off-rate half-life 9.6 h vs a ~3.3 min endosomal sorting window ⇒ ~92 % routed to lysosomal degradation; the working regime is 50–300 nM affinity with a pH-sensitive release |
| Condensate-targeted drug (LLPS) | Partition ratio > 300 into the condensate ⇒ dissolution of the oncogenic network | High partitioning deepens the thermodynamic well first: percolation/gelation (θc ≈ 0.28) happens long before any dissolution threshold — a physical sequestration trap for p53 |
| Single-cell trajectory (CD8 exhaustion) | Trajectory endpoint = true terminal state | Dissociation-stress cells are injected into the "terminal" branch (~48 % of it); gene-set filtering / regression restores terminal classification F1 from 0.52 to 0.96 |
| CAR-T killing at low antigen density | Near-infinite affinity compensates sparse antigen | Below ~500 copies per cell the membrane cannot be pinned to exclude CD45 — signaling output stays ≈0 regardless of affinity |
| Synthetic ecology (engineered bacteria) | A synchronized lysis circuit releases drug forever | Every lysis pulse amplifies non-lysis "cheater" mutants 20–50×; the clock stops within a few pulses (spatial structure delays, never prevents it) |
Every one of the 30 runs has its own archived case folder with the full report, solver and figures — see the case index and per-case one-line verdicts (EN + 中文) in the gallery.
Every figure below is a real artifact produced by that session's own numerical solver (ODE / PDE / lattice Monte-Carlo) — not a stock graphic:
*LLPS condensate drug: Flory-Huggins phase diagram, curing heatmaps — Cahn–Hilliard phase-field solver.* *BBB/TfR transcytosis: affinity × dose × brain-exposure phase diagram — the high-affinity plateau where delivery collapses.* *ADC multiscale barrier: radial concentration contours around a vessel at 168 h — high-affinity arm pinned within 1–2 cell diameters.* *TNIK vs paralog selectivity audit: P-loop conformational snapshots across crystal forms — the "1,000× selectivity" has no physical basis.* *TPD futile-cycle model: degradation efficiency over ternary-complex lifetime × DUB activity — too-tight binding burns ATP and degrades nothing.* *bNAb directed evolution: pairwise epistasis deviations — greedy mutation stacking loses ~10× affinity to negative epistasis.*…and 24 more challenge figures (RNA polyelectrolyte entropy, lyophilization water-percolation, CAR-T synapse phase diagrams, engineered-bacteria cheater sweeps, antibody ΔCₚ cold reversal, …) are archived with their reports and solver code in the full evidence gallery.
中文速览(2026-09 极限压测):30 道研发委员会级对抗性压测(激酶同源选择性 → 血脑屏障转胞吞 → 相分离凝胶化 → 免疫突触 → 演化博弈…)于 09-04 → 09-07 在一台 Apple M2 8GB 笔记本上完成 —— 合计计算 ≈6 小时,评审分 5 天逐批发出;每题交付「中文裁决研报 + 数值求解器 + 出版级图件」,全部保留在会话 Files 面板、可版本回放;报告延续「Data Gap 清单」与「已验证 / 无法核实」分离口径。压测中系统还多次驳回出题方的诱导性前提(如「强表达必致混沌」被数值结论直接否定)。全量证据已入库:30 个案例文件夹(研报/代码/图件)见
docs/extreme-tests-2026-09/cases/,带会话截图与逐题一句话裁决的完整图库见docs/extreme-tests-2026-09/README.md,历轮评审打分(外部评审 1–10 分/等级制原表)见SCORECARD.md;实证介绍 PPT(含会话截图与产物图)随 Release 资产与演示素材提供。
PureScience competes on architecture, not on feature-count prose. The table contrasts PureScience with the common profile of hosted, closed-source, single-model AI research workstations (profile assembled from public documentation and sandbox audits, 2026-08 — treat their own docs as authoritative). No product is named here: the differences are structural and apply to the category.
| Dimension | Hosted · closed · single-model workstation | PureScience | 一句话 |
|---|---|---|---|
| Deployment | Cloud-hosted; research data flows through the vendor | Local-first desktop + optional loopback web UI; self-hostable | 数据不出实验室 |
| Model choice | Bound to one vendor model | Model-agnostic: many built-in cloud providers, custom gateways, subscription reuse — across four selectable agent backends | 不锁模型 |
| Openness | Closed source | Apache-2.0 — inspectable and forkable | 合规可审计 |
| Data governance | Data + artifacts transit vendor cloud | Local storage, OS-keychain credentials, optional network egress allowlist, license-gated connectors (non-commercial sources fail closed) | 数据主权是准入门槛 |
| Evidence | Text-level citations | Checksummed artifact versions with producer code / execution history / environment / branch + reviewer findings; “verified” and “could not be verified” kept separate | 做得对且能重做 |
| Scientific data | Broad coverage, but license-limited sources are often disabled | 35 built-in connectors across genomics, variants, human genetics, chemistry, clinical trials, literature, structures, expression, cancer models and more; same biomedical domains covered per the 2026-08 audit | 覆盖持平 + 合规反超 |
| Honesty | Chat-level disclaimers | Anti-hallucination stress suite; mid-run self-correction stays on record; failures and limits logged as negative samples | 诚实性即产物 |
| Orchestration | Adding scheduled jobs, hosted model endpoints, PDF layering (2026-08 wave) | Same mechanisms landed locally: routine tasks, local model endpoints, layered PDF reading, figure checks, skill authoring, agent self-introspection, file annotations | 对齐并本地化 |
| Language | English-first | Nine interface languages (English fallback); Chinese-native scientific reports | 本地化就绪 |
诚实边界(我们不宣称什么):交互式分子查看、云同步类便利功能等少数前端体验暂未提供——我们刻意先做执行—证据—主权三条主轴;“同域覆盖”基于 2026-08 的审计结论,双方版本演进后需复核;本表为 v1.37 已发布形态,安装版应用内的目录与界面为准。
PureScience is shaped by a small set of principles that govern how code, data, models, and human oversight fit together.
- Open by default. Source code, formats, connectors, and skills should remain inspectable and forkable.
- Multi-provider with explicit compatibility. The app validates provider configuration and makes endpoint requirements visible instead of treating every API protocol as interchangeable.
- Local-first and data-aware. Keep project state local, surface external data flows, and make autonomy opt-in.
- Human-in-the-loop. File edits, commands, network access, and connector calls are governed by explicit approval profiles.
- Durable research records. Sessions, tool activity, Notebook history, and immutable artifact versions should remain reviewable after the run ends, with unavailable evidence stated plainly.
- Composable capabilities. Skills, connectors, models, previews, and future compute backends should be replaceable parts rather than one black box.
- Honest scientific boundaries. Generated output does not replace expert judgment, statistical review, or validation against primary evidence.
PureScience combines project management, multi-model agent execution, Python and R notebooks, scientific data connectors, immutable artifact versions with provenance, and permissioned human-in-the-loop control in one local workspace. The installed app and latest release notes are the source of truth for changing catalogs, packaging details, and newly added options.
| Area | Core capability |
|---|---|
| Projects and sessions | Create, rename, and delete projects; maintain multiple sessions with pinning; edit completed prompts into persistent, selectable message branches without deleting the original downstream path; restore recent work, drafts, conversation history, and preview state. |
| Agent workflow | Natural-language tasks, streamed responses, typed tool-activity cards grouped under declared purpose titles, a live context-usage indicator with category-level estimates, on-demand context compaction, and persistence across restarts, stop controls, approval pauses, a confirmation step (with a remembered preference) before closing or quitting during a running task, desktop notifications plus durable unread conversation badges and native attention on blocking approvals, message timing metadata with elapsed-time and usage popovers, completed-turn agent framework and model identification, a project-scoped command palette, and recovery of sessions interrupted by an application restart. The transcript also marks configuration changes mid-session with a visible divider, and notebook editors offer live kernel variable suggestions. A cross-resource Tags manager organizes projects, sessions, and files from one master-detail panel. |
| Models | Built-in cloud providers, custom compatible gateways, Claude and Codex subscription logins, connection validation, per-model multimodal image input, and a combined composer picker for model and model-supported reasoning effort. Available providers and API formats are validated against the selected agent backend. |
| Agent backend | A selectable agent-framework backend — Claude Code, OpenCode, Codex, and CodeBuddy — so the same workspace can run on more than one underlying agent implementation, with provider and model choices validated against the selected backend, and app-managed backends installable, switchable, and removable from Settings. |
| Execution | Persistent Python, R, and REPL control-plane kernels with durable code/output history, plus stateless shell commands recorded in the same run history; app-managed environments with offline provisioning; bring-your-own Python and R interpreters; remote SSH compute hosts as additional execution targets; a user terminal shared with the agent; and a read-only installed-package inventory per runtime environment. Package management for external R runtimes remains manual. |
| Inputs and files | File attachments (up to 10 GB per file with streaming upload), a project-level library with indexed pagination, session grouping, source-scoped filename search, grid and list views, a large expand modal for large projects, split-view file preview beside the session, generated artifact cards, @ references to existing uploads/outputs, file download/export, and session export as .ipynb (per-tab or download-all). |
| Artifacts and provenance | Immutable, session-scoped artifact versions with checksummed content and available producer code, execution history, exact input references, environment inventory, producing message-branch context, and version-scoped reviewer evidence, with version navigation and direct links between related evidence. |
| Preview formats | Responsive multi-tab previews for common scientific data, PDFs, Office documents (DOCX, XLSX, PPTX), images (with zoom and pan), source code with syntax highlighting, molecular structures and reactions, and Notebook history, viewable inline or full-screen. |
| Local data management | Local project and application data, configurable storage location, and guided migration. |
| Skills | 18 featured built-in skills; personal skills, package upload, GitHub preview/import, import of installed global skills with candidate preview, agent-requested package imports from session attachments or GitHub URLs, enable/disable controls, and explicit / selection in a session. |
| Connectors | 35 built-in research connectors, custom local/remote MCP connectors, contact metadata, and connector/tool-level permissions. |
| Safety controls | Ask for approval, Auto-approve edits, and Full access conversation profiles; approval dialogs with code previews and call/conversation decisions; durable global, project, and session-scoped allow grants with filtering, per-row and family revoke, and Undo; plus per-connector and per-tool policies. |
| Memory | A structured, cross-session memory with categories and notes: an always-visible composer to capture facts, per-category save guidance and auto-recall controls, recall injection into every agent session (bounded blocks), and an agent-facing save tool so the model can persist durable preferences mid-conversation — the panel, the recall path, and the write path form one closed loop. |
| Credentials | A unified, encrypted credential store for 8 scientific services (AWS, GitHub, Google Cloud, Azure, Modal, NVIDIA, OpenAlex, literature access) plus custom entries: secrets are OS-keychain encrypted at rest, the renderer only ever sees masked hints, editing keeps the existing secret unless retyped, deletion is confirmation-gated, and GitHub credentials get a real connectivity test. |
| Network egress allowlist | An optional network-restriction mode for notebook, REPL and shell child processes: when enabled, they are routed through a local filtering proxy that only reaches the enabled scientific domain groups (literature, genomics, structures & chemistry, clinical, bioinformatics, code & package repositories) plus your custom domains — everything else is refused, keeping data kernels sandboxed. |
| External compute endpoints | Run jobs beyond your own machines: configure Modal serverless-GPU endpoints (jobs execute in a GPU container via the modal CLI) and NVIDIA NIM inference endpoints (OpenAI-compatible model calls) — each bound to a credential from the Credentials panel so secrets never live in the compute config. The dispatcher routes by provider id, so a job submitted to a Modal or NIM target runs end-to-end like any SSH job. |
| Review and verification | An opt-in reviewer that audits a completed turn against its own transcript, execution log, and artifacts, reports pass/warn/fail findings, and can run a bounded fix loop to correct them. |
| Distribution and support | Installers for macOS (Apple Silicon and Intel), Windows, and Linux are published with every release, plus update guidance, local diagnostics, and community links. macOS builds are Developer ID signed and notarized by Apple when release signing credentials are configured; the signing state a given release actually shipped is stated on that release's page and in its release certification record (macSignature). |
| Localization | Nine interface languages with English fallback (English, German, Spanish, French, Japanese, Korean, Russian, Simplified Chinese, Traditional Chinese), a full terminology audit across the UI, and Chinese-native formatting for scientific reports and documentation. |
PureScience is model-agnostic at the product level: connect it to major cloud LLM providers, a custom gateway, or reuse an existing Claude or Codex subscription. Provider availability currently depends on the selected agent backend and the API protocols it supports. There are four ways to connect a model:
| Provider mode | How it works |
|---|---|
| Built-in cloud providers | Choose from the provider list shown by the installed app and authenticate with the requested key. |
| Custom Gateway | Supply a compatible Base URL, API Key, and exact model ID. The default API format (Messages, Chat Completions, or Responses) is derived from the active agent framework, so a new custom gateway is compatible out of the box. |
| Codex Subscription | Select the Codex agent framework first, then you can select Codex subscription in provider type |
| Claude Subscription | Sign in with a Claude subscription in two modes: shared (a browser login that stores credentials in your default ~/.claude profile) or isolated (an app-managed claude setup-token run under an app-owned CLAUDE_CONFIG_DIR, fully isolated from ~/.claude/, with a browser flow plus a paste-a-token fallback). |
The legacy Local Claude provider has been removed. Previously stored Local Claude entries are
dropped during upgrade; add Claude Subscription and authenticate with shared browser login or
the isolated claude setup-token flow instead.
Built-in cloud vendors currently include OpenAI, Anthropic, Grok (xAI), DeepSeek, Zhipu AI (GLM) with a dedicated GLM Coding Plan endpoint, Kimi (Moonshot), MiniMax, StepFun with a dedicated Step Plan subscription endpoint, Xiaomi MIMO, SenseNova, Volcengine Ark, Bailian (Alibaba Cloud) with a dedicated Bailian for Plan subscription endpoint, and the OpenRouter aggregation gateway, among others; some are region-specific.
Provider vendors, available models, and regional endpoints can evolve independently of this README. Treat the provider picker and connection test in the installed app as the source of truth.
PureScience stores project data, settings, artifact versions, and provenance evidence on the local computer. API Keys are kept locally and use the operating system's secure credential storage when it is available. Logs are local and are not uploaded automatically.
External data flow is still possible and should be reviewed:
- Model requests send the prompt and necessary context to the selected model provider.
- Web searches and remote connectors send their displayed parameters to external services.
- Local connectors may execute trusted commands on the computer.
- Attachments,
@references, logs, and generated reports may contain sensitive research data.
Choose the narrowest permission profile that fits the task:
| Mode | Behavior | Recommended use |
|---|---|---|
Ask for approval |
Asks before edits, commands, network, and connector calls | New workflows, sensitive data, unfamiliar scripts |
Auto-approve edits |
Automatically allows workspace edits; asks for commands, network, and connectors | Trusted file-editing work with controlled external access |
Full access |
Automatically allows edits, commands, network, and connectors | Clearly scoped, fully trusted, unattended work |
Review connector parameters and tool activity before approving them. Never include API Keys, access tokens, patient identifiers, unpublished data, or sensitive local paths in screenshots or public issue logs.
PureScience is available as a released desktop application and is actively developed. Recent releases have focused on reproducible artifacts, workspace extensibility, and session reliability.
- v0.8.0 established immutable artifact versioning and inspectable provenance as shipped foundations.
- v0.9.0 added personal specialist agents with scoped capabilities, scoped permission management, conversation and artifact export, TIFF previews, collapsible side panels, and per-turn token usage.
- v0.9.1 added mobile remote access through Remote.It, conversational specialist customization, and message timing metadata.
- v0.9.2 added immediate specialist handoff, completed-turn agent and model identification, context-usage persistence across restarts, and Windows renderer crash recovery.
- v0.10.0 adds a project-scoped command palette, code syntax highlighting in previews and notebook cells, read-only package inventories per runtime environment, conversational skill imports from GitHub URLs, direct file preview beside the session, and Bailian as a built-in model provider.
- v0.10.1 adds branching a conversation into a new session, GitHub skill search by keyword, specialist package import/export with contribution channels, and session-age metadata in the artifact list, while keeping oversized data files out of model context and hardening branch replay, reviewer correction provenance, and Codex prompt-runtime ownership.
- v0.11.0 adds review-gated session plans with durable execution contracts, hot-switching ACP models and providers without reconnecting the agent process, agent-aware context replay that respects each framework's context path, prompt history navigation in the composer, session link favicons, and a settings keyboard shortcut, while hardening Windows auto-update and local RPC, logger data redaction, artifact provenance binding, and notebook process-group cleanup.
- v0.11.1 adds on-demand artifact code reconstruction, live permission profile changes during a running turn, project and session archiving with undo, MCP connector OAuth and portable configuration import/export, tool-activity elapsed time in the transcript, persistent plan call records, and branded loading indicators, while hardening Windows runtime recovery, session-plan turn completion, and cross-platform release certification.
- v1.31 – v1.37 completes the orchestration-and-evidence wave: routine scheduled tasks (5–1440 min, auto-pause on repeated failure), locally hosted model endpoints (sha256-whitelisted lifecycle scripts, readiness probing), layered PDF reading (outline → keyword scan → on-demand pages, zero context cost for a 50-page paper), publication-grade figure checks, agent skill authoring and self-introspection (read-only, project-scoped queries), file annotations, license-gated access to non-commercial data sources, folded-context search with immutable chunks, memory provenance with superseded markers, and a review checklist aggregated across turns.
- v1.37.0 adds a fourth agent backend (CodeBuddy) alongside Claude Code, OpenCode, and Codex; nine interface languages with English fallback; a cross-resource Tags manager; live kernel variable suggestions in notebook editors; and a config-change divider in the transcript. See the release note at the top of this file and the latest release notes.
Deterministic reconstruction, portable environment restoration, and full-fidelity session replay remain on the roadmap.
Independent acceptance runs and re-verification notes are summarized in the benchmark notes.
For version-specific features, provider and catalog changes, platform packaging, and recent fixes, use the latest release notes and the installed app. For a maintained shipped/partial/planned breakdown, see the Capability Map.
PureScience assists execution and record-keeping; researchers remain responsible for methods, interpretation, privacy, and scientific validity.
PureScience is an Electron application built with React, TypeScript, Prisma/SQLite, and an ACP-based agent runtime.
Prerequisites for source development:
- Node.js LTS or newer with npm
- Git
- Python 3 only if you want Notebook execution
git clone https://github.com/naiyixi/PureScience.git
cd purescience
npm install
npm run devnpm install automatically generates the Prisma client and installs Electron native dependencies. npm run dev builds the Electron main/preload bundles, starts the renderer, and opens the desktop app. Development data is isolated under ~/.purescience-project.
Useful commands:
| Command | Purpose |
|---|---|
npm run dev |
Start the development application |
npm run dev:web |
Dev app + localhost web UI (127.0.0.1) |
npm run dev:headless |
Dev backend + web UI, no Electron window |
npm run lint |
Run ESLint |
npm run typecheck |
Type-check main and renderer code |
npm test |
Run the Vitest suite |
npm run build |
Type-check and build the application |
npm run build:web |
Build the optional localhost web UI |
npm run build:mac |
Package macOS builds |
npm run build:win |
Package Windows builds |
npm run build:linux |
Package Linux builds |
Packaged output is written under dist/.
The desktop backend can optionally serve the same renderer to a browser on the local computer. This
feature is off by default and binds only to 127.0.0.1.
npm run build:web
npm run dev:webOpen the authenticated URL printed by the application. Use npm run dev:headless to start the
backend, tray, agent runtime, and localhost web service without opening an Electron window.
Set PURESCIENCE_WEB_PORT to choose a port (default 44100). Explicitly quitting the
application still shuts down agent and Notebook processes normally.
The same localhost web UI can be reached from a phone or tablet through Remote.It pairing. Pair a browser with a six-digit PureScience code, approve it once on the desktop, and the workspace stays reachable without exposing the loopback server directly. Browser trust is revocable, and mode changes or service shutdown immediately invalidate active remote sessions.
The headless CLI and zero-dependency Node.js SDK use the same local daemon, projects, sessions, credentials, and permissions as the desktop and web interfaces. Detailed usage lives with the publishable package so there is one command reference to maintain:
- CLI guide - installation, service lifecycle, task automation, artifacts, output formats, and exit codes
- SDK package overview - Node.js quick start and package entry point
PureScience is an independent, original open-source project — its own codebase, data model, interface, and roadmap, developed openly for the benefit of all researchers. It is not a fork or a downstream derivative of any other product.
- 官网 / Website: purescience.work
- 更新日记(含版本代号)/ Changelog: CHANGELOG.md
- GitHub: naiyixi/PureScience
- Cite / archive with a DOI: Zenodo archiving runbook
- Cite PureScience v1.43.0: DOI 10.5281/zenodo.22441075
The product roadmap and capability status are maintained in ROADMAP.md. This README intentionally does not duplicate the moving list of priorities or release targets.
PureScience is a research execution and record-keeping tool, not a generic chat wrapper, unofficial client, or substitute for scientific review.
- Not just a chat UI. The product is organized around persistent projects, execution, files, artifacts, and reviewable tool activity.
- Not an unofficial client for another product. It is an independent implementation with its own codebase, data model, interface, and roadmap.
- Not a replacement for scientific judgment. Outputs still require domain review, statistical validation, and verification against primary sources.
A: Complete the five setup steps: Environment, Agent runtime, Model provider, Notebook runtime, and Data location. Fix required rows marked Action needed, install or repair the selected agent if offered, and test the model connection. Notebook setup and a custom data location are optional.
A: An API Key is a secret credential issued by a model provider. Create or copy one from that provider's developer/API console. The provider may bill requests made with the key. Treat it like a password: never share it or commit it to a repository.
A: Not if you reuse an existing subscription login — a Claude subscription through shared browser login or an isolated app-managed claude setup-token flow, or a ChatGPT/Codex subscription login on the Codex backend. Built-in cloud providers and custom gateways require their own keys.
A: Open the provider picker during setup or under Settings → Model for the choices supported by your installed app and selected agent backend. You can use a built-in cloud provider, a compatible Custom Gateway, a Claude subscription through shared or isolated login, or a Codex subscription on the Codex backend.
A: Check the API Key for missing characters or spaces, verify the Base URL and region, use the provider's exact model ID, and confirm network access and account balance. For a Claude subscription, retry the shared browser login or refresh the isolated claude setup-token credential, depending on the selected mode.
A: The current step has not met its required condition. Fix any environment row marked Action needed, install or repair the selected agent runtime, or validate the model provider, depending on the active step. Notebook setup is optional and only affects Notebook execution.
A: Create or open a project, start a session, attach any source files, and describe the goal, constraints, expected output, and validation criteria. Use @ to reference a project file and / to select an enabled skill.
A: Enable the Remote Compute (SSH) skill under Settings → Skills, register your cluster under Settings → Compute, then start a session and select the skill with /remote-compute-ssh. The skill handles host registration, short commands via SSH, and fully async job submission — the app automatically starts an analysis turn when the job finishes, so you never write a polling loop.
A: Yes. Install it in one click from Settings → General → Command line tool → Install command (adds purescience to your PATH; no separate Node.js needed). The CLI controls the local service and submits research tasks without opening a browser:
# Start the service in the background
purescience start --no-open
# Create a project and run a task, wait for completion
purescience project create "Systematic review"
purescience run --project "Systematic review" \
--prompt-file ./task.md \
--approval-profile auto \
--skill literature-review \
--wait --json
# Download a generated artifact
purescience artifacts list <session-id> --json
purescience artifacts download <artifact-id> --output ./report.mdSee the CLI guide for the full command reference, JSON/JSONL output formats, exit codes, and headless service options.
A: Open the generated artifact and choose Provenance. Select a version to inspect the content identity and the available producer code, execution history, inputs, environment inventory, producing conversation context, and reviewer evidence. Evidence PureScience could not verify is marked unavailable.
A: Yes. Edit a completed user message and resend it to create a new branch from that point. The original later turns remain available, and the revision arrows beside the message switch between the alternative paths.
A: Projects, sessions, files, settings, and configured credentials are stored locally by default. Content needed for model requests, web searches, or connector calls may still be sent to the external service you selected, so review sensitive inputs and provider policies before running a task.
| Channel | Use it for |
|---|---|
| GitHub Issues | Bugs, reproducible failures, and concrete feature proposals |
| GitHub Discussions | Design questions, roadmap proposals, and longer technical conversations |
| X / @zerolink_ai | Release announcements and build-in-public updates |
Before opening a public issue, remove API Keys, tokens, private file paths, unpublished data, patient identifiers, and other sensitive material from logs and screenshots. See CONTRIBUTING.md for the development workflow.
⭐ Star the repo: If this project has been helpful, we'd greatly appreciate a star on GitHub. Starring the repository encourages continued development. It only takes a second, but it has a meaningful impact on the project.
Apache License 2.0 — see LICENSE.















