Skip to content

Commit 56ee548

Browse files
committed
[act.dirac.Ω.D8+] make molecular ML a governed Dirac capability
Motif v3 changes the scientific system of record, so its schemas, PostgreSQL state, execution fencing and resource admission, physical methods, generated adapters, verification, and user/operator documentation must land together. Splitting these layers would leave public Commands or README claims ahead of runtime authority.
1 parent 254007a commit 56ee548

143 files changed

Lines changed: 15295 additions & 4827 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎"ok": true‎

Lines changed: 0 additions & 4 deletions
This file was deleted.

‎.github/workflows/docs.yml‎

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,33 @@
1-
name: Build & Deploy Docs
1+
name: Build vendored Mol* docs
22

33
on:
44
push:
5-
branches: main # was `master`: inherited from upstream Mol*, and this fork's canonical branch is main — so these two workflows had never run here
5+
branches: main
66
paths:
7-
- docs/**
8-
- ".github/workflows/docs.yml"
7+
- docs/docs/**
8+
- docs/mkdocs.yml
9+
- .github/workflows/docs.yml
910
pull_request:
1011
branches: main
1112
paths:
12-
- docs/**
13-
- ".github/workflows/docs.yml"
13+
- docs/docs/**
14+
- docs/mkdocs.yml
15+
- .github/workflows/docs.yml
1416

1517
jobs:
1618
build:
1719
runs-on: ubuntu-latest
1820
steps:
19-
- name: 👨🏼‍💻 checkout
21+
- name: Checkout
2022
uses: actions/checkout@v4
21-
22-
- name: 🐍 python
23+
- name: Python
2324
uses: actions/setup-python@v5
2425
with:
25-
python-version: "3.10"
26-
27-
- name: ⛓️ dependencies
28-
run: |
29-
pip install mkdocs-material
30-
- name: 🔧 build site
31-
run: |
32-
cd docs
33-
mkdocs build
34-
35-
deploy:
36-
runs-on: ubuntu-latest
37-
needs: build
38-
if: github.ref == 'refs/heads/master'
39-
steps:
40-
- name: 👨🏼‍💻 checkout
41-
uses: actions/checkout@v4
42-
43-
- name: 🐍 python
44-
uses: actions/setup-python@v5
45-
with:
46-
python-version: "3.10"
47-
48-
- name: ⛓️ dependencies
49-
run: |
50-
pip install mkdocs-material
51-
- name: 🔧 build site
52-
run: |
53-
cd docs
54-
mkdocs build
55-
56-
- name: 🚢 deploy docs
57-
uses: peaceiris/actions-gh-pages@v4
58-
with:
59-
deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
60-
external_repository: molstar/docs
61-
publish_branch: gh-pages
62-
publish_dir: ./docs/site
26+
python-version: "3.12"
27+
- name: Install MkDocs
28+
run: pip install mkdocs-material
29+
- name: Build inherited Mol* manual
30+
run: cd docs && mkdocs build
31+
32+
# This workflow deliberately does not deploy to molstar/docs. Dirac is a fork and must
33+
# not publish into the upstream project's documentation repository.

‎.gitignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ dev-key.pem
3434
data/sym/syminfo.lib
3535
backend/env/
3636
/.runtime/
37+
/openfe-runtime-v2
38+
/backups/
3739

3840
# a tracked .pyc dirties the worktree on every import (it happened)
3941
__pycache__/

‎AGENTS.md‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,9 @@ Examples:
126126
## Build and run
127127

128128
```bash
129-
# Baseline (existing shipped facet)
130-
node ./scripts/build.mjs -a dirac --prd
131-
node_modules/.bin/http-server build/examples/mn-compiler-lab -p 1338 -g
132-
# open http://localhost:1338/
133-
134-
# Each new facet uses the same pattern with its own -a dirac
129+
npm run build:dirac
130+
# Reload the one supervised application at http://localhost:1360/.
131+
# Do not start a second server for a facet or screenshot.
135132
```
136133

137134
## RDKit-JS notes (critical)

‎ARCHITECTURE.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Invocation kernel
2020
│ │ │
2121
│ │ └─ Inline / Thread / Process / Remote
2222
│ └─ field cache + generic method-version result cache
23-
└─ 12 executable scientific Methods
23+
└─ 28 executable scientific Methods
2424
│
2525
┌──────────┼──────────┐
2626
▼ ▼ ▼
@@ -42,7 +42,7 @@ errors and provenance belong below those adapters.
4242

4343
## Canonical contracts
4444

45-
- `contracts/domain/object-kinds.json` owns 30 stable `ObjectKind` values and the
45+
- `contracts/domain/object-kinds.json` owns 83 stable `ObjectKind` values and the
4646
`{kind,id}` `ObjectRef` shape.
4747
- `contracts/domain/relations.json` owns the controlled relation vocabulary.
4848
- `contracts/commands/registry.json` owns semantic commands, schemas, mutation and Job
@@ -59,7 +59,7 @@ errors and provenance belong below those adapters.
5959
validates command input and output, records `human | agent | service` actor identity,
6060
and enforces that long commands declared `job_policy=required` actually return a Job.
6161

62-
`backend/invocation.py` is the single scientific invocation path. It validates method
62+
`backend/invocation.py` is the single scientific invocation path for 28 registered Methods. It validates method
6363
input/output, consults method-current caches, creates or joins Jobs, runs an injected
6464
Executor, stores content-addressed artifacts, and returns one v2 envelope with exact
6565
method version and provenance. Long scientific commands always submit through the
@@ -90,7 +90,7 @@ PostgreSQL is the durable authority:
9090
- `app.command_trace` and `app.v_command_observation` retain semantic-command outcomes,
9191
latency, cache, actor and linked-Job evidence for the architecture twin.
9292

93-
Migrations are forward-only and content-hash checked. Applied migrations 000–018 are the
93+
Migrations are forward-only and content-hash checked. Migrations 000–038 are the
9494
current schema history.
9595

9696
## Client application
@@ -101,7 +101,8 @@ the separate truth for connected scientific capability. `AppShell` owns routing
101101
`ScientificContextStore` owns Program, focus, selection and the application's only
102102
staleness generation; `SceneService` owns one mol* instance that survives navigation.
103103

104-
The current vertical slice exposes Design, Structures and Runs. Existing chemistry
104+
Twelve of thirty Views currently expose connected modules across Programs, Design,
105+
Structures, Campaigns, Synthesis, Experiments, Knowledge and Runs. Existing chemistry
105106
facets are modules over the shared scene and context. Molecule embedding, fields,
106107
surface MEP and torsion strain enter through semantic commands; long results return by
107108
Job and content-addressed artifacts.
@@ -147,7 +148,7 @@ rebuilds. The model can therefore calibrate observed command latency and outcome
147148
addition to detecting drift, ranking static hotspots and estimating dependency radius.
148149
It still cannot predict unseen inputs or autonomously change the architecture; that is
149150
the L4 boundary. The platform substrate is complete against its approved DoD; the
150-
product capability is explicitly partial (currently 3/8 Workspaces and 7/30 Views connected)
151+
product capability is explicitly partial (currently 8/8 Workspaces represented and 12/30 Views connected)
151152
even though the navigable product shell is complete at 8/8 and 30/30.
152153

153154
`scripts/digital_twin_scope.json` is the ownership boundary. The watcher recursively

‎CHANGELOG.md‎

Lines changed: 56 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,58 @@
11
# Changelog
22

3-
All notable changes to **Dirac** are documented here. This project forks from [mol\*](https://github.com/molstar/molstar) at upstream SHA `e594cc6` (mol\* master, August 2026); mol\*'s pre-fork history is not included. When mol\* features are pulled forward they appear here with a `upstream:` tag.
4-
5-
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/2.1.0/).
6-
7-
## [Unreleased]
8-
9-
### Added
10-
11-
- **Field Wells facet** (`facets/field-wells/`, new `Fields` master-tab) + **fields backend** (`backend/field_server.py`). 3D energy/potential wells for the focused ligand, rendered as signed x-ray-shaded isosurfaces inside the protein scene: classical electrostatic well (RDKit Gasteiger + Coulomb grid, ~0.1 s), and quantum HOMO / LUMO / electron density / QM electrostatic potential via pyscf HF + cubegen (real SCF; an unconverged SCF returns an error, never a field). The ligand molfile already carries scene coordinates, so every cube lands registered with zero alignment code. Isovalue slider updates the two `VolumeRepresentation3D` nodes in place; SCF results cached per (geometry, basis). Backend is a self-contained stdlib HTTP daemon on `127.0.0.1:8901` with its own conda env (RDKit 2026.03.5 + pyscf 2.14.0, gitignored); the panel reports online/offline honestly. Verified on 1CBS REA: MEP well in the β-barrel pocket 0.12 s; RHF/STO-3G E=−911.9424 Ha, HOMO −5.15 eV, LUMO +4.69 eV, 138 basis functions, 5.27 s first SCF, cached thereafter.
12-
- **V2000 counts-line fix in both hand-rolled molfile builders** (`semantic-chemistry-rdkit.ts`, `pharmacophore-features.ts`): nine zero fields between the bond count and `999` where the spec says eight. RDKit-JS tolerates the malformed line, desktop RDKit rejects it (`CTAB version string invalid`) — invisible until the first spec-strict consumer (the fields backend) refused every molfile.
13-
14-
- **Pharmacophore Designer facet** (`facets/pharmacophore-designer/`, new `Designer` master-tab). Drag-editable pharmacophore model seeded from the focused ligand's RDKit perception (same `computePharmacophoreFeatures` as the read-only 3D layer): per-feature enable/disable, tolerance radius (0.5–3 Å), delete, add free-standing features, camera-plane 3D drag with the trackball suppressed while a feature is armed (hover → grab cursor). Live inter-feature distance matrix. Topological SMARTS screening of a shipped 68-molecule library (probes, fragments, drugs, natural products, steroids) against the model's feature-count requirements plus an optional custom SMARTS constraint; hit rows show per-kind have/required chips and click through to a 2D depiction with per-channel atom highlights. Model export/import as versioned JSON. Screening counts reuse the substrate's `computeLigandChemistry` (identical SMARTS both sides); the only facet-local pattern is the hydrophobic-carbon SMARTS, held in parity with the 3D layer's neighbor rule. Validation gate: `node scripts/check-pharmacophore-library.mjs` (node-side RDKit 2025.03.4 — parse validity, canonical-SMILES dedup, SMARTS parity vs the substrate source, exact probe counts for benzene / cyclohexane / pyridine / caffeine). Screening is topological only — the library ships no conformers and the UI says so. Verified end-to-end via CDP: 1CBS/REA seeds 2 HBA · 1 HBD · 19 HYD and the only library match is retinoic acid itself; drag moves a feature 5.4 Å with zero camera motion; 4HHB/HEM seeds 2 aromatic-ring features from SSSR.
15-
16-
- **Production database** (`backend/db/`, PostgreSQL 18, database `dirac`). The persistence and registration layer: 37 tables in six schemas — `meta` (toolkits, sources, unit legality, migrations), `chem` (compound / form / batch registry, descriptors, fingerprints, conformer sets), `bio` (targets, PDB structures, assays, dose-response curves, partitioned results), `design` (projects, series, ideas, pharmacophore models, screening runs), `app` (content-addressed blobs, field-cube cache, workspaces), `audit` (row history). 23 enums, 88 CHECK constraints, 72 foreign keys: identity is the InChIKey of the RDKit-standardized parent (never SMILES); results attach to batches and carry a qualifier, with `(result_type, unit)` a foreign key into a dimensional-legality table so "IC50 in percent" is unwritable; every computed number references the `meta.toolkit` row that produced it; `dirac_app` has no DELETE and retraction is a column. Similarity search runs in-database over Morgan-2 `bit(2048)` with pgvector HNSW `bit_jaccard_ops` (Tanimoto = 1 − Jaccard; the RDKit cartridge is not installed and the README documents the drop-in path if it ever is). Gates: `backend/db/check_constraints.sql` — 19 attacks each asserting its expected SQLSTATE, plus 10 positive controls so a schema that rejected everything could not score. Loaded and verified: 68 library compounds registered with real InChIKeys, 1156 descriptors, 68 fingerprints; aspirin's Tanimoto neighbours come back benzoic acid → ketoprofen → phenol; a Designer model exported from the browser (22 features, 1CBS/REA) round-trips into `design.pharmacophore_model` and its single screening hit resolves to `DRC-0000059`, which is the deposited ligand REA itself. Dirac still runs with no backend at all; the database adds registration, persistence and provenance.
17-
- **Audit-trail partition fix** (`003_audit_partition_root.sql`). A row trigger on a partitioned table reports the PARTITION in `TG_TABLE_NAME`, so every `bio.result` audit row was filed under `bio.result_2026` and the obvious query returned nothing — an audit trail that fragments every January is indistinguishable from no audit trail. Now records the partition root as the logical table and keeps the physical partition beside it. Found by gate P9, not by reading.
18-
19-
### Pending product workstreams
20-
21-
- **Conformer Explorer** — RDKit ETKDG conformer generation, mol\* morph animation, overlay view, energy landscape. ⚠ The vendored RDKit-JS 2025.03.4 wasm exposes no 3D embedding (`ETKDG` / `EmbedMolecule` absent from the binary) — this workstream needs a custom RDKit-JS build with 3D coords enabled, precomputed conformer data, or the Python backend escalation path.
22-
23-
## [0.1.0] — 2026-08-10
24-
25-
Initial Dirac snapshot consolidating the mn-compiler-lab workbench and its RDKit-JS chemistry substrate.
26-
27-
### Added
28-
29-
- **mn-compiler-lab UI redesign.** Replaced the single-pane scrolling sidebar with a master-detail layout: 64-px top bar (molecule / representation / picking / status / clear), 380-px sidebar with five master-tabs (Focus / Semantics / Ligand / VFX / Ledger), sticky diagnostics strip with 4 always-visible metrics. Cuts vertical overflow from 260 px to 0 on a 900-px viewport.
30-
- **RDKit-JS chemistry integration.** Vendored `@rdkit/rdkit` 2025.3.4-1.0.0 WASM at `src/app.frontend.facets.molstar-rdkit.editable/assets/rdkit/` (7 MB). Singleton loader at `src/chemistry.backend.perception.rdkit-wasm.editable/semantic-chemistry-rdkit.ts` exposes SMARTS-based perception for aromaticity, Lipinski H-bond donor, and Lipinski H-bond acceptor over the focused ligand. Acceptor SMARTS excludes positively charged atoms (no quaternary-ammonium false positives). Donor SMARTS includes protonated species (NH3+ is a real donor).
31-
- **2D ligand depiction panel.** New master-tab `Ligand` renders `mol.get_svg_with_highlights()` with synchronized atom highlights matching the enabled RDKit chemistry layers. Uses `mol.get_new_coords()` + re-parse to regenerate 2D coordinates from the 3D molfile (the documented `forceCoords: true` flag does not work in the 2025.03.4 build). Atom-click → mol\* selection + camera focus is wired via the same atom-index contract as the molfile builder.
32-
- **3D pharmacophore feature rendering.** New module `src/chemistry.backend.perception.rdkit-wasm.editable/pharmacophore-features.ts` draws H-bond acceptor cones (red, ~1 Å, oriented by neighbor centroid), H-bond donor sticks (blue), aromatic ring disks (amber, perpendicular to ring plane via `Mat4.targetTo` + `Circle` primitive), and hydrophobic halos (grey translucent spheres) as mol\* `Shape` primitives. Each feature is its own mesh group, so the picker returns the originating feature. Aromatic rings are detected via RDKit SSSR (`a1aaaaa1` + `a1aaaa1` with dedup), correctly handling fused systems (caffeine, naphthalene, indole, adenine).
33-
- **AGENTS.md.** Defines branch model (`main` integration, `feature/<product>` per workstream, `master` upstream-molstar-sync only), file ownership rules per workstream, PR verification gate, commit-message convention, and the RDKit-JS 2025.03.4 known-limitations list.
34-
35-
### Fixed
36-
37-
- **Pharmacophore availability badge leak.** Switching to a ligand-free structure (e.g., 1CRN) now clears the pharmacophore availability text instead of leaving stale counts from the previous molecule.
38-
- **Fused-ring detection.** Replaced the BFS connected-component approach (which over-grouped fused systems into 9-10-atom blobs that failed the 5-7 size filter) with RDKit SSSR queries.
39-
- **Charged-species SMARTS.** Acceptor pattern now excludes positively charged atoms (was matching quaternary ammonium as a false-positive acceptor). Donor pattern keeps positive charges (NH3+ is a real donor).
40-
41-
### Known limitations
42-
43-
- `compute_gasteiger_charges` is not exposed in RDKit-JS 2025.03.4. The partial-charge layer is a graceful-stub — displays "Gasteiger computation unavailable in this RDKit-JS build" instead of silent failure.
44-
- `<metadata>` block is not emitted by `get_svg_with_highlights` regardless of the `includeMetadata` flag. Atom click mapping falls back to a bond-path centroid computation over the rendered SVG.
45-
- The lab's `getLigandFocusTargets` exposes a malformed label on `1GRM` (option text starts with the CIF file header). Pre-existing in the mol\* lab code, not introduced here.
46-
47-
### Verification
48-
49-
Tested against 9 lab fixture structures (zero runtime errors across all), 22 external reference molecules for SMARTS correctness (22 / 22 expected counts after the SMARTS fixes), 15-cycle reload test (heap stable at 58-63 MB, zero state-cell leak), 8-cycle rapid molecule switching (zero stuck states), and end-to-end 2D-click → 3D-selection on 1CBS-REA and 4HHB-HEM.
3+
This file records product-level changes after Dirac became a distinct application. The
4+
repository inherited mol\* history and currently has no reliable release-tag series;
5+
`package.json` is the package version authority and Git is the detailed change ledger.
6+
7+
## Unreleased
8+
9+
### Application platform
10+
11+
- Established one canonical domain vocabulary, semantic Command registry and generated
12+
Python/TypeScript contracts.
13+
- Added a transport-neutral dispatcher and one Method invocation path shared by HTTP,
14+
Python SDK, CLI, MCP and the browser.
15+
- Added durable Jobs, content-addressed Artifacts, provenance, command observations,
16+
attention and method-current caches in PostgreSQL.
17+
- Added local, process, GPU and Kubernetes/Kueue execution adapters with fenced attempt,
18+
lease, retry and completion semantics.
19+
20+
### Product operating model
21+
22+
- Made Program the durable root for objectives, hypotheses, compounds, portfolios,
23+
decisions, work packages/items, evidence and lineage.
24+
- Added an 8-Workspace / 30-View AppShell with one ScientificContextStore and one
25+
persistent mol\* SceneService.
26+
- Connected Program, molecular design, structure, campaign, synthesis, experiment,
27+
knowledge and compute projections without presenting the remaining shells as shipped
28+
scientific capability.
29+
- Added typed HCI contracts for context, actions, work graphs, handoffs and projection
30+
truthfulness.
31+
32+
### Scientific workflows
33+
34+
- Integrated RDKit-JS chemistry, 2D/3D ligand synchronization, properties,
35+
pharmacophores, field wells, surface MEP, torsion and explicit evidence boundaries.
36+
- Added Motif contracts and implementations for dataset snapshots, model training and
37+
calibration, proposal generation, ranking, structure work, MD, RBFE, OpenFE and
38+
governed closed-loop execution.
39+
- Preserved scientific runtime identity, units, refusal conditions and artifacts through
40+
the same Job/provenance path.
41+
42+
### Operations and verification
43+
44+
- Standardized the current local topology on web `:1360`, unified application service
45+
`:8901`, and read-only operations `:1355`; the standalone `:8902` service is retired.
46+
- Added source-derived architecture-twin generation and drift checks.
47+
- Added gates for types, production builds, design invariants, documentation facts,
48+
contracts, migrations, portability, layering, physics protections, security and
49+
architecture coherence.
50+
- Added a remote fail-closed security profile while retaining the explicitly
51+
unauthenticated local/LAN development profile.
52+
53+
## Initial Dirac application — 2026-08-10
54+
55+
- Forked the application surface from mol\* while preserving upstream engine history.
56+
- Added the first integrated molecular workbench with RDKit-JS chemistry perception,
57+
ligand depiction, pharmacophore overlays and the initial Fields backend.
58+
- Adopted the single-tree `main` development model and Dirac visual identity.

‎CLAUDE.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ failure never announces itself — it hands you a plausible screenshot.
6464
## ⚠ THE BACKEND DAEMON DOES NOT RELOAD ITSELF
6565

6666
**After touching anything in `backend/`: `systemctl --user restart dirac-fields`.**
67-
(`dirac-physics` likewise for `backend/physics/`.)
67+
The standalone `dirac-physics` service is retired; physics routes now run through the
68+
unified service on 8901.
6869

6970
The daemon on `:8901` holds your code in memory. Edit a handler, take a
7071
screenshot, and you have photographed a build that no longer exists on disk —

0 commit comments

Comments
 (0)