Skip to content

v0.2.0

Choose a tag to compare

@Kohulan Kohulan released this 24 Sep 12:02
55b5b1d

0.2.0 (2026-09-24)

⚠ BREAKING CHANGES

  • refresh vendored Orthonym and adopt its new tier vocabulary

Features

  • /api/iupac-to-smiles returns canonical SMILES, InChI, InChIKey and a molblock (2d7f384)
  • /explain becomes one page, one voice, on a recomposed ground (cf67d97)
  • /from-name puts the structure beside its identifiers, not above them (30e6715)
  • /from-name renders two or more names as a table with CSV and SDF (828bc76)
  • /from-name shows the full identifier set and stops wasting the page (412ed36)
  • a flat pint mark, and a favicon drawn from it (b239a27)
  • a floating label on /from-name, a genuinely bigger box, less duplicate copy (e7811b0)
  • About becomes a needlework pattern chart, worked live (b9a3b97)
  • add /api/explain-name endpoint, retire opsin_substituents (6e05ac1)
  • add deterministic glossary for name parts (8275ae6)
  • allow a deployment to gate the site behind Basic Auth (88a7db8)
  • an info notch on /from-name explaining how OPSIN reads a name (a84e4be)
  • an OPSIN-verify switch, default on, beside best-effort (22c8e68)
  • an unverified name says which switch produced it (6f0c987)
  • batch jobs with chunked tasks, progress and CSV download (7da5a1a)
  • batch upload on Home, so the job layer has a user (9ae980d)
  • bounded pooled conversion for many IUPAC names (e70c7db)
  • build CSV and SDF downloads in the browser from rows in hand (01fd652)
  • CDK draws every structure, with CIP stereo labels (c51f31e)
  • Celery app with a pinned prefork pool and the JVM guards (8f45a47)
  • Celery app with two queues and the JVM fork guards (9b475af)
  • character spans into the IUPAC name for each part (4418313)
  • chemical names and formulas are typeset the way IUPAC prints them (50d2b06)
  • collect OPSIN name parts after buildFragment with locants (da3bae8)
  • derive name spans by assigning raw tokens to decomposition parts (2dfc713)
  • emit modifier segments and cover split_root degrade paths (d428185)
  • emit per-atom pixel coordinates for highlighting (fc1f453)
  • env-configurable settings with deployment profiles (4a0f29f)
  • every button crimson, glossy, and carrying a real icon (a0e0c1a)
  • explain each name token as its own hoverable part (9e2bd9e)
  • fold a bis/tris-cloned block of parts back to one written slot (3f9e224)
  • four pages open on bare ground, like Home (3fc4c4e)
  • group explain segments by written occurrence, not by shared text (9cf0af6)
  • Health Check becomes a status board on About, not a route of its own (12b065c)
  • Home gains a Draw tab (c06c24e)
  • Home overhaul — clay notch tabs, normal-scroll shell, richer results (3830235)
  • hover the IUPAC name to explore the structure (31ae631)
  • hover the name on the teaching page to see which atoms it describes (4f30d69)
  • job cancellation, and an owner token for cancel and delete (1b07ddf)
  • let a caller refuse OPSIN-unverified names (aa50a56)
  • link the learning page from the navigation (5ef1ded)
  • log why a name fell back, and pin atom-point distinctness (7cf5858)
  • make a batch's misses visible, and give every tier a lamp (d55061e)
  • make ExplainSegment recursive with ownership flag (d44fb03)
  • map OPSIN atom ids to RDKit heavy-atom indices (3eb2b93)
  • mark referential name parts as notation on /explain (c2da04d)
  • mark referential name parts as notation on /explain (3e6502e)
  • merge /structure and /teach into /explain, and strip the footer (7486bcb)
  • move every OPSIN call onto workers, add per-IP caps (a1dae9a)
  • name cache keyed on the Orthonym version (e910816)
  • parse SDF, molfile, CSV and SMILES-list input (46d234e)
  • populate name_range from proven character spans (37538f0)
  • rebuild explain around OPSIN part tree, drop SMARTS rules (b29d98a)
  • redesign /about as the round trip, drawn (15beb73)
  • Redis and worker services, and a build that proves OPSIN works (1a03abc)
  • Redis store owning every key and TTL (84143b4)
  • refresh vendored Orthonym and adopt its new tier vocabulary (e08d721)
  • sleeker /from-name — denser rows, smaller buttons, pastel downloads (4df9800)
  • split OPSIN root part into parent and suffix by locant (9265401)
  • teaching route with a drawing area that names what you draw (87d1a60)
  • TechX card-bento redesign wearing ChemAudit chrome (ae10123)
  • the /from-name table carries InChI and canonical SMILES too (55ce771)
  • the /from-name table fills its card instead of centring in it (11c228c)
  • the confidence key becomes an INFO notch on the input card (8f0a5b9)
  • the INFO tab flips and re-attaches to the panel it opened (6ee1112)
  • the Orthonym mark stands in for a letter of the hero wordmark (04e4823)
  • the table's second line is InChI alone, aligned under SMILES (ddc67dc)
  • the toggle is a moulded rocker, at half the size (243086c)
  • the toggle wears the buttons' glass (283cb80)
  • the upload target shows what it actually read (05e98aa)
  • the wordmark gets a real flare, raking light along its outlines (b7ba61a)
  • tighter /from-name table — one frame, one-line keys, smaller thumbnails (fbc5edd)
  • two-input explain page with hoverable segment tree (3df16d6)
  • yellow glow highlight drawn from atom coordinates (1e80db4)

Bug Fixes

  • /explain works for 313 of 544 names, up from 170 (132932b)
  • a broken /explain shim took the whole site offline (92f30ee)
  • a job whose meta was evicted mid-flight reported as never having existed (7adef8e)
  • a rate-limit counter could lose its TTL and lock an IP out permanently (f5051ad)
  • a Redis blip at worker boot made a child invisible for its whole life (0aadeec)
  • a verified tier could ship without the round-trip that earns it (18a9645)
  • accept OPSIN's case-folded D/L tokens instead of rejecting them (a1502d3)
  • add a daemon heartbeat so worker OPSIN status never ages out (C1) (b4c05a0)
  • an uploaded file could not ask for verified-only names (8adbd2d)
  • assemble_rows must report a missing chunk, not swallow it (514f9a9)
  • atomic per-IP job admission, correct client IP, self-healing release (094957d)
  • check the JVM before charging job quota, and stop masking renames (b10d717)
  • clear the pinned name part on each new naming; add aria-live to the name; correct nav count (124feca)
  • closing a job pushed its expiry past the expires_at already reported (a3b5a85)
  • config hygiene, a measured depict budget, and a cross-path cache test (eeace0d)
  • correct Explain's confirmation rule and stale user-facing copy (1a427a2)
  • count a part's decorating locants from the previous part's end (2fc5425)
  • count SDF terminators by line, not substring, in the molecule counter (235165b)
  • derive top-level name spans from token runs, not text search (ae74031)
  • draw the best-effort rule as real dots (0f3100d)
  • drop the raw tier badge from tiles and disclose a missing round-trip proof (ab20f31)
  • fence an unlocanted hydro run's multiplier prefix out of claims (ca278c5)
  • give every locant child its own span, including caffeine's 1H (df85b5c)
  • guard onProgress separately so convertNames never rejects (f63b2ad)
  • guard partial substructure matches, cover the symmetry path (2f87085)
  • guard the OPSIN heartbeat's interval floor and thread start (C1 residuals) (67943ab)
  • guard translate_job_inline's redelivery with begin_chunk too (I1) (9c175d2)
  • handle apply_async timeouts, canonicalize job input, restore old contracts (5b20608)
  • Home invited 50 molecules the app could not answer (82c0bfd)
  • kill the web-process JVM, prove the 503 fail-closed rule (be92bd4)
  • make the name cache invalidate itself on a vendor refresh (ae9363c)
  • make the parent JVM guard's confirmation actually observable (45b94c2)
  • name the as-typed SMILES; refresh vendored Orthonym to 404b69e (67dcb0b)
  • never ship a partially spanned name, and test the contract (7fd73d3)
  • nothing may escape a cell, and a reload clears the page (65dcec8)
  • one paint source for the tabs and their bleed, and a real lift (ac202a8)
  • one raising molecule lost an entire fast-path request (6d1f938)
  • probe the JVM-fork property in a fresh subprocess, not the pytest process (b1a323e)
  • raise nginx upload cap to cover the largest deployment profile (c3de228)
  • rate-limit job polling, unify depict's error shape, fix flaky atomicity test (fa3cd62)
  • rate-limit POST /api/jobs per-minute before the JVM liveness check (c56cb31)
  • re-tag meta key TTL on every progress write, NX-guarded (6d4268b)
  • recognise OPSIN's two-token tetra-and-higher multipliers (812db97)
  • refuse to cache a verified tier with no round-trip proof (C3) (e7dd663)
  • require contiguous token runs and bound growth by the neighbouring run (809d797)
  • results.csv shared the naming budget while costing 10,000x more (8066c7d)
  • run-tests.sh exited 0 on a failing suite under -q (dd67a0f)
  • run-tests.sh finds .venv when .venv-mac is not there (9690cd4)
  • run-tests.sh reported a false hang under -q (9820c3c)
  • scope modifier locants and stop fabricating atom labels (0b42a28)
  • SDF molecule_count undercounts an unterminated final record (abb4a3c)
  • set glow fill as a style property, not a presentation attribute (141ee6f)
  • show a partial result's reason, and let the keyboard pin a name piece (b509351)
  • split the hourly job cap out atomically, fix client-IP bucketing bugs (e111dff)
  • stop a coarse locant token from shadowing its own precise children (5eb9da8)
  • stop Home's tier colouring reaching another route, and de-duplicate a rule (48ef571)
  • stop job_status/results.csv claiming done over evicted rows (C4) (690f606)
  • stop parse-preview's full RDKit parse, move job-cap checks earlier (43d168a)
  • surface a queued batch job instead of an empty result grid (5102f40)
  • surface ATOM_GAP in the census table and stop double-walking segments (f907e31)
  • task 6 fix round 1 -- drop unused run_chunk bind/self, add 3 tests (31ca2c5)
  • task 6 fix round 2 -- one honest close, real timeout handling (0861ef0)
  • task 6 fix round 3 -- terminal state on task failure, CSV safety, depict bounds (39379a8)
  • the bloom is an ellipse over the tabs, not a band across the card (9636641)
  • the curves are back, and the strip fades as one piece (b39fa59)
  • the default job path had no errback, stranding failed jobs for 24 hours (6be1594)
  • the final review's findings, plus an emptied card foot and a smaller box (61aa77f)
  • the health page reads the payload, not just the reply (4fdefae)
  • the heartbeat replayed a boot verdict, so a dead JVM still read healthy (9fffd37)
  • the INFO notch uses the header's fillets, not a flipped copy (0790d13)
  • the info panel welds to the tab instead of floating below it (acc3513)
  • the round-trip proof was crying wolf on zwitterions (4e7b164)
  • the tab strip is one ramp, sliced, so no junction shows (d65f45c)
  • the tabs meet the card with no line, no rim and no crop (80a8493)
  • three defects this session's own changes introduced (d9d5572)
  • try every OPSIN candidate parse instead of only the first (b79bfbd)
  • two labels implied OPSIN verification does not always run (0f13768)
  • two redelivery guards stop a chunk un-completing a finished job (I1) (e158c36)
  • vendor-orthonym.sh works from a plain Orthonym clone (2610df6)
  • widen the C1 heartbeat test's sleep margin past the TTL truncation error (89db8e0)
  • wire admission/JVM-guard fixes into endpoints, bound depict cost (f928ff5)
  • withhold spans when a grouped substituent's span cannot name its atoms (6b2dd14)

Performance

  • parse uploads in a worker instead of the web process (dcbb0eb)
  • stop caching a structure picture nobody reads back (01dc1ed)

Refactoring

  • collapse six duplications the session's diff introduced (b89be36)
  • delete dead code (32b9064)
  • delete the dead compute_spans anchor scan and its module (7ee45d2)
  • extract duplicated SVG-highlight and Ketcher-handshake code (5083eab)
  • extract splitLines so names and SMILES share one splitter (8e76082)
  • extract the atom-highlight effects Explain and Teach both carried (b93a594)
  • one row shape in convertNames instead of two spellings of it (58ae8d1)
  • one statement of each fact, and the store keeps its own rule (33b7954)
  • promote the shared input and result CSS out of Home.css (eefe35a)
  • quality pass from a four-angle review — reuse, simplicity, waste, altitude (f77a340)
  • sweep old job keys by rule, not by list (f00d726)
  • tell the app and its engine apart, and retire the needlework (ee645f7)

Documentation

  • add CLAUDE.md, screenshot tooling, and ignore generated output (8959b1e)
  • CLAUDE.md's shared-component claim is true now (a125c6f)
  • close the backend plan, and correct four claims that had gone false (d6bea09)
  • correct 14 verified stale claims in CLAUDE.md, DESIGN.md and PRODUCT.md (56d2e47)
  • correct a count the previous commit made stale (373809e)
  • correct four comments that misdescribe the code they sit on (706c311)
  • correct six places where the design spec describes something else (e5ee8c8)
  • correct stale comments that describe code we no longer have (a3de68d)
  • fix CLAUDE.md's stale claim about the SVG-highlight duplication (cc2fead)
  • fix step 1 of the runbook -- /opt is root-owned (bb3533c)
  • make the README a front page, move the manual to INSTALL.md (3916c89)
  • move the framed-input rationale to sit with the rule it describes (70746db)
  • note the MODIFIER_KEY overlap-proof backstop at the claims fence (583bada)
  • point .env.example at nginx as the binding upload limit (ff7a62f)
  • record the flare's five load-bearing choices (626bb95)
  • refresh README/CLAUDE/PRODUCT for the Celery/Redis architecture (c779beb)
  • six route-count claims the Health Check move made false (072d43b)
  • split the firewall step by front-door route (91aa949)
  • the button system, and the contrast rule that governs it (8bf6594)
  • the Orthonym snapshot is already current, and the local clone is a trap (0721b2d)
  • the README shows the flat pint wordmark and the current pages (cd56c0e)
  • the runbook assumed a VM with a public address (e99a310)
  • update an older install in place (2501f74)
  • use the real Orthonym logo in the README header (9105db8)