Skip to content
Draft
Show file tree
Hide file tree
Changes from 117 commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
343818b
chore: keep I-008 PDep-QM design docs local-only
alongd Jul 26, 2026
3610008
feat(pdep-qm): extract shared is_this_reaction_uncertain() predicate
alongd Jul 26, 2026
2ad564c
fix(uncertainty): read kinetics provenance from the comment text
alongd Jul 26, 2026
d3f251b
feat(pdep): select PDep networks that deserve QM refinement
alongd Jul 27, 2026
e28df06
feat(pdep): expose the network selection decision as a public API
alongd Jul 27, 2026
8d6780b
feat(pdep): add an ME-solver adapter family and a plain-ME success cr…
alongd Jul 27, 2026
d4c6d3b
feat(pdep): write hybrid QM+ILT P-dep network input files
alongd Jul 27, 2026
f571b2a
feat(pdep): derive P-dep product channels so the ME success gate can …
alongd Jul 27, 2026
7ff71b6
feat(pdep): tie network transition states to ARC's by choosing ARC's …
alongd Jul 27, 2026
09f28fd
feat(pdep): queue a qualified network's uncertain transition states t…
alongd Jul 27, 2026
3488400
feat(pdep): decide post-ARC whether a selected transition state is us…
alongd Jul 28, 2026
fcea259
feat(pdep): freeze post-ARC QM artifacts into a durable capture
alongd Jul 28, 2026
f29ccde
feat(pdep): capture a finished ARC run's transition states exactly once
alongd Jul 28, 2026
32c17e6
feat(pdep): freeze the Arkane energy reference into the capture
alongd Jul 29, 2026
3ff391a
feat(pdep): freeze the network source and ME method into the capture
alongd Jul 29, 2026
0721c96
fix(pdep): type-check frozen energy settings at every boundary
alongd Jul 29, 2026
03a2f79
fix(pdep): bind the modelChemistry allowlist to Arkane's real schema
alongd Jul 29, 2026
6e75abe
fix(pdep): make capture supersession atomic and confine verified paths
alongd Jul 29, 2026
ff396a8
fix(pdep): refuse a hybrid write whose corrections cannot be pinned
alongd Jul 29, 2026
25c09a6
fix(pdep): recover a crashed capture swap and serialize capture writers
alongd Jul 29, 2026
fd25d68
fix(pdep): refuse to replay a capture taken against a different network
alongd Jul 29, 2026
24692f7
refactor(pdep): make QMEnergySettings the one frozen-settings schema
alongd Jul 29, 2026
e67f8bb
feat(pdep): freeze the sensitivity evidence that justified each queue…
alongd Jul 29, 2026
e68b9fd
feat(pdep): write hybrid network inputs from the capture alone
alongd Jul 29, 2026
434f396
test: revive test_set_paths and make path-key drift a loud failure
alongd Jul 29, 2026
f451a5d
fix(pdep): prune stale hybrid outputs before rewriting a network
alongd Jul 29, 2026
c4a6165
fix(pdep): confine capture-manifest network_id to the hybrid root
alongd Jul 29, 2026
23bb3fb
fix(pdep): reject network_ids that are not a single safe filename com…
alongd Jul 29, 2026
f3689be
fix(pdep): preflight the entire hybrid root before pruning any stale …
alongd Jul 29, 2026
d7dbad1
fix(pdep): return verified ts_records from verify_capture and enforce…
alongd Jul 29, 2026
1a713b4
fix(pdep): writer consumes verify_capture's ts_records instead of re-…
alongd Jul 29, 2026
690296b
fix(pdep): write the hybrid Arkane input file atomically
alongd Jul 29, 2026
d30b17d
test: replace a prefix-spoofable startswith path assertion with real …
alongd Jul 29, 2026
d663117
docs(pdep): record that library-append idempotency is dedup-by-label …
alongd Jul 29, 2026
822e5f2
chore: gitignore the local-only PDep explorer design doc
alongd Jul 29, 2026
f4d022f
feat(pdep): add the PES-explorer adapter ABC and factory (D5.2)
alongd Jul 29, 2026
5663f01
feat(pdep): write Arkane explorer input files from an existing network
alongd Jul 29, 2026
48e6c17
feat(pdep): drive Arkane PES exploration and judge the result (D5.2)
alongd Jul 29, 2026
efe5fa0
fix(pdep): make the explorer input writer refuse what it cannot safel…
alongd Jul 29, 2026
cd9317d
fix(pdep): close the explorer's fail-open and make rule 0 true before…
alongd Jul 29, 2026
6ad04ca
fix(pdep): stop the explorer writer from splicing executable code int…
alongd Jul 30, 2026
b9b34db
fix(pdep): compare net-reaction channel pairs, not just counts and co…
alongd Jul 30, 2026
2afe8b3
fix(pdep): narrow the spliced-source whitelist to network-source syntax
alongd Jul 30, 2026
5b3b76b
fix(pdep): claim the explorer run directory atomically instead of che…
alongd Jul 30, 2026
3744747
fix(pdep): close a code-injection route through the writer's own argu…
alongd Jul 30, 2026
3927788
fix(pdep): stop the shared parsers treating an attribute call as a DS…
alongd Jul 30, 2026
d200ce1
fix(pdep): make the run-directory claim leaf-only and unbypassable
alongd Jul 30, 2026
413dff2
fix(pdep): never leave the "explore() was never called" sentinel on a…
alongd Jul 30, 2026
49e1b17
fix(pdep): validate each explorer field against its own contract, not…
alongd Jul 30, 2026
f03c660
fix(pdep): refuse a **kwargs unpacking instead of silently dropping it
alongd Jul 30, 2026
103feb8
fix(pdep): make explorer_factory usable, and unbypassable by a forget…
alongd Jul 30, 2026
ad54305
docs(pdep): record why hybrid.py's kwargs comprehensions need no guar…
alongd Jul 30, 2026
14de6b9
fix(pdep): close the third and last escape from explore()'s state con…
alongd Jul 30, 2026
284d855
fix(pdep): refuse a multi-species bath gas whose fractions the run wi…
alongd Jul 30, 2026
5601577
fix(pdep): refuse a bare string as seed_species, which tuple() read a…
alongd Jul 30, 2026
7a11dca
fix(pdep): refuse positional arguments on a DSL call, the **kwargs ho…
alongd Jul 30, 2026
65c6bbb
fix(pdep): accept an integral float as a radical-electron count, coer…
alongd Jul 30, 2026
16c4272
fix(pdep): accept energy_tol=0, the exact cutoff, and correct its rat…
alongd Jul 30, 2026
e5f8fbe
fix(pdep): the factory post-condition checks both seed fields, not ju…
alongd Jul 30, 2026
cd72c8d
fix(pdep): construct the adapter with the normalized seed, not the ra…
alongd Jul 30, 2026
63f8223
fix(pdep): accept explore_tol=0 too, the inconsistency left by the en…
alongd Jul 30, 2026
1e78df2
docs(pdep): state the get_k_tp direction contract, and pin it at the …
alongd Jul 30, 2026
ebe0b4f
feat(pdep): add PDepExplorerConfig, the typed explorer config surface
alongd Jul 30, 2026
a71c74f
feat(pdep): add PDepExplorationResult and a fail-closed JSON/YAML ren…
alongd Jul 30, 2026
21ade20
feat(pdep): wire explore_pdep_network(), the PES exploration entry point
alongd Jul 30, 2026
2872e85
fix(pdep): refuse an unevaluated gate, and stop discarding failure di…
alongd Jul 30, 2026
81d2490
fix(pdep): stop combine() reporting a decision nobody made
alongd Jul 30, 2026
62cdf71
feat(pdep): bind a network decision to the network's CONTENT, not its…
alongd Jul 30, 2026
dd61c5d
fix(pdep): let evaluation_status state coverage, not usability
alongd Jul 30, 2026
231b460
refactor(pdep): one home for the content-hash format, and decode netw…
alongd Jul 30, 2026
a96f1bb
fix(pdep): bind the bytes the explorer writer consumes, not just the …
alongd Jul 30, 2026
b8b6a77
fix(pdep): freeze the hash the selection examined, not a re-read at r…
alongd Jul 30, 2026
033ad82
docs(pdep): correct two claims the code has outgrown
alongd Jul 30, 2026
96a0892
test(pdep): derive PDepExplorationResult.as_dict() coverage from the …
alongd Jul 30, 2026
cfac8c7
refactor(pdep): split SELECTOR_VERSION into three single-job constants
alongd Jul 30, 2026
5fbfa33
test(pdep): pin the REASON in validate_sa_cache tests, not just the v…
alongd Jul 30, 2026
2ec39a5
feat(pdep): persist exploration results, and snapshot the selection t…
alongd Jul 30, 2026
803fd09
feat(pdep): strict loaders for both persisted PDep formats
alongd Jul 30, 2026
8c5944e
test(pdep): pin that select_pdep_network's early-return paths record …
alongd Jul 30, 2026
e98c5cf
fix(pdep): load persisted PDep YAML with safe_load, not a FullLoader
alongd Jul 30, 2026
a8d3707
fix(pdep): validate loader RECORDS, not just the envelope
alongd Jul 30, 2026
5cf58a8
test(pdep): pin the rank_pdep_networks ordering contract
alongd Jul 30, 2026
107b52d
test(pdep): pin the multi-match ambiguity path in resolve_direction_key
alongd Jul 30, 2026
2b9857b
test(pdep): pin the diagnoses of three refusals that survive downstream
alongd Jul 30, 2026
8b28902
fix(pdep): a below-floor verdict is three non-answers and one answer
alongd Jul 30, 2026
63553b5
fix(pdep): an unjoinable sensitive TS makes a negative verdict unsupp…
alongd Jul 30, 2026
285ff64
fix(pdep): refuse non-finite or non-positive selection thresholds
alongd Jul 30, 2026
07c59e5
fix(pdep): as_dict() must not hand out the decision's own containers
alongd Jul 31, 2026
f20dedf
docs(pdep): pin and document the kinetics_params round-trip lossiness
alongd Jul 31, 2026
187b28f
fix(pdep): report every reason a selection cannot gate an exploration
alongd Jul 31, 2026
bd203ec
fix(pdep): fold the method and network-id guards into the accumulated…
alongd Jul 31, 2026
4211442
fix(pdep): a persisted selection cannot forge its way past the budget…
alongd Jul 31, 2026
1dc94e2
fix(pdep): a negative verdict must not rest on discarded rows
alongd Jul 31, 2026
ab7cd36
fix(pdep): guard derived coefficient floor/cutoff overflow, non-strin…
alongd Jul 31, 2026
5d56bd9
fix(pdep): validate cache thresholds before any early return in valid…
alongd Jul 31, 2026
8b91136
fix(pdep): as_dict() must not alias a record's own condition object
alongd Jul 31, 2026
14bec7f
test(pdep): the fake Arkane runner must honour required_artifact
alongd Jul 31, 2026
fb040fb
fix(pdep): cache validity and data usefulness are different questions
alongd Jul 31, 2026
6baf02a
fix(pdep): a below-floor TS response is a dead instrument, not a smal…
alongd Jul 31, 2026
5823c1c
fix(pdep): reason() must not report a verdict on a decision never made
alongd Jul 31, 2026
5555c56
fix(pdep): clamp the Arkane T grid to the network's own thermo ceiling
alongd Jul 31, 2026
be177e1
fix(pdep): drop the stale explicit Tlist, which overrode the clamped …
alongd Jul 31, 2026
17ff64d
fix(pdep): make the thermo ceiling honest and its failure modes disti…
alongd Jul 31, 2026
119958c
feat(pdep): make the clamped T grid reconstructible from the saved re…
alongd Jul 31, 2026
6b9f7b6
fix(pdep): reject forged selections at load, not in the prose
alongd Jul 31, 2026
354476f
refactor(pdep): decide the QM queue with the whole field in view
alongd Aug 1, 2026
e43349d
feat(pdep): bound the QM spend on P-dep networks with a ranked budget
alongd Aug 1, 2026
dcc8d97
feat(pdep): let the caller, not qualification alone, admit an explora…
alongd Aug 1, 2026
3d00fa7
feat(pdep): give the QM budget a record of what it admitted and refused
alongd Aug 1, 2026
38452ad
feat(pdep): write the QM budget's decision to disk each iteration
alongd Aug 1, 2026
883b0cf
fix(pdep): record which RMG-Py actually ran the PDep sensitivity anal…
alongd Aug 1, 2026
2c91568
fix(pdep): read the RMG-Py provenance from Arkane's log, not from thi…
alongd Aug 1, 2026
d251414
test(pdep): pin the qualification gate to two real PDep networks
alongd Aug 1, 2026
c5daacf
feat(pdep): record why a network was never assessed, not just that it…
alongd Aug 1, 2026
f3f707d
feat(pdep): persist the network assessment record atomically, and ref…
alongd Aug 1, 2026
c5143d1
feat(pdep): give the assessment record a path and a stale-clearing rule
alongd Aug 1, 2026
5e29b41
feat(pdep): give every network offer a durable record, and stop letti…
alongd Aug 1, 2026
a11d088
feat(pdep): refuse to write a record file this module could not parse…
alongd Aug 1, 2026
af62c18
feat(pdep): give a selection the field contract its sibling records had
alongd Aug 2, 2026
b74a7bb
feat(pdep): describe the shape of the one dict field that arrives fro…
alongd Aug 2, 2026
a524f1f
fix(schema): canonicalize ME_methods instead of accepting a spelling …
alongd Aug 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,24 @@ htmlcov/*

# Local-only agent working files (never commit)
docs/superpowers/
docs/t3-pdep-qm-scope.md
docs/t3-pdep-qm-impl-plan.md
docs/t3-pdep-qm-next-session-prompt.md
docs/t3-pdep-qm-explorer-design.md

# Vendored test fixtures are real Arkane output and must be tracked, despite the *.log rule
# above which exists to keep run logs out of the repo.
!tests/data/pdep_arkane_log/*.log
# Narrowed to the exact file name, not just the depth: a `*/*.log` negation would also un-ignore
# any other log that happened to land in a network's fixture directory (e.g. a stray debug.log
# from a local run), which is the accidental-commit risk the *.log rule exists to prevent.
!tests/data/pdep_real_networks/*/arkane.log

# Artifacts a test run writes into the tracked fixture trees. Some tests point a real T3 at a
# fixture iteration directory, and T3 writes its per-iteration records where it always does. Named
# exactly, and only under the two fixture directories that are actually written to, so this cannot
# hide a record that was meant to be a fixture.
tests/data/minimal_data/iteration_1/t3_pdep_qm_budget.yml
tests/data/minimal_data/iteration_1/t3_pdep_network_assessments.yml
tests/data/pdep_network/iteration_1/t3_pdep_qm_budget.yml
tests/data/pdep_network/iteration_1/t3_pdep_network_assessments.yml
4 changes: 4 additions & 0 deletions docs/input_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ t3:
pdep_SA_threshold: 0.001 # optional, used to determine wells and reactions to calculate thermo
# and rates for from a PES of a sensitive reaction, default: 0.001
# Pass None to skip PES SA.
pdep_min_delta_ln_k: 0.001 # optional, the smallest ln(k) response to a PES SA perturbation that
# still counts as "sensitive", default: 0.001. Acts as an absolute
# floor alongside the relative pdep_SA_threshold, so that denormal
# near-zero sensitivity coefficients cannot pass on relative grounds.
ME_methods: ['CSE', 'MSC'] # master equation methods for PES SA,
# any combination of 'CSE', 'RS', 'MSC', default: ['CSE', 'MSC']
top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10
Expand Down
28 changes: 28 additions & 0 deletions t3/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,34 @@ def log_species_summary(self,
self.log(f'{key}: {species.qm_label}{smiles} '
f'(status: {clean_t3_status(species)})')

def log_pdep_network_summary(self,
selections: list,
):
"""
Log a summary of the PDep network QM-selection decisions.

Args:
selections (list): The ``PDepNetworkSelection`` decisions to summarize.
"""
self.log('\n\n\nPDep Network Summary:\n'
'---------------------')
qualifying = [selection for selection in selections if selection.qualified]
if not qualifying:
self.log('No PDep networks qualified for QM refinement.')
return
for selection in qualifying:
strongest = max(selection.uncertain_path_reactions,
key=lambda ts: ts.delta_ln_k,
default=None)
evidence = ''
if strongest is not None:
comment = strongest.kinetics_comment.splitlines()[0] if strongest.kinetics_comment else ''
via = f' via {strongest.path_reaction_str}' if strongest.path_reaction_str else ''
kinetics = f', kinetics: {comment}' if comment else ''
evidence = (f' (strongest evidence: TS {strongest.ts_label}{via}, '
f'delta_ln_k={strongest.delta_ln_k:.3g} at {strongest.condition}{kinetics})')
self.log(f'{selection.network_id}: {selection.reason()}{evidence}')

def log_reactions_summary(self,
reactions_dict: dict[int, T3Reaction],
):
Expand Down
1,898 changes: 1,786 additions & 112 deletions t3/main.py

Large diffs are not rendered by default.

97 changes: 97 additions & 0 deletions t3/pdep/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""
t3 pdep module

Deciding which pressure-dependent reaction networks deserve expensive QM refinement, and
parsing the RMG network files that decision is based on.
"""

from t3.pdep.api import (
load_pdep_budget_record,
load_pdep_exploration_results,
load_pdep_network_assessments,
load_pdep_network_selections,
rank_pdep_networks,
save_pdep_budget_record,
save_pdep_exploration_results,
save_pdep_network_assessments,
save_pdep_network_selections,
select_pdep_network,
)
from t3.pdep.budget import (
BUDGET_ALGORITHM_VERSION,
BUDGET_OUTCOME_ADMITTED,
BUDGET_OUTCOME_REFUSED,
BUDGET_RECORD_FILE_NAME,
BUDGET_RECORD_SCHEMA_VERSION,
BUDGET_SKIP_DOES_NOT_FIT_REMAINING,
BUDGET_SKIP_EXCEEDS_BUDGET,
BUDGET_SKIP_MAX_NETWORKS_REACHED,
BUDGET_SKIP_NOT_EVALUATED,
PDepBudgetNetworkOutcome,
PDepBudgetRecord,
VALID_BUDGET_OUTCOMES,
VALID_BUDGET_SKIP_REASON_CODES,
apply_pdep_qm_budget,
budget_record_path,
build_pdep_budget_record,
)
from t3.pdep.cache import (
SA_CACHE_CONTRACT_VERSION,
sa_cache_metadata_path,
validate_sa_cache,
write_sa_cache_metadata,
)
from t3.pdep.hybrid import (
HybridNetworkResult,
QMEnergySettings,
write_hybrid_network_input_file,
)
from t3.pdep.mesolver import (
ArkaneMESolverAdapter,
MESolverAdapter,
mesolver_factory,
register_mesolver_adapter,
)
from t3.pdep.parser import (
PDepNetwork,
PDepPathReaction,
parse_pdep_network_file,
parse_pdep_network_text,
)
from t3.pdep.selector import (
CACHE_STATUS_CACHED_REJECTED,
CACHE_STATUS_CACHED_VALID,
CACHE_STATUS_GENERATED,
CACHE_STATUS_UNVALIDATED,
DEFAULT_MIN_DELTA_LN_K,
E0_PERTURBATION_J_PER_MOL,
EVALUATION_STATUS_EVALUATED,
EVALUATION_STATUS_NOT_EVALUATED,
PDepNetworkSelection,
SELECTION_ALGORITHM_VERSION,
SELECTION_SCHEMA_VERSION,
SensitiveTransitionState,
coefficient_floor,
resolve_direction_key,
select_from_sa_dict,
select_from_sa_dict_with_diagnostics,
select_sensitive_wells,
)
from t3.pdep.assessment import (
ASSESSMENT_RECORD_FILE_NAME,
ASSESSMENT_RECORD_SCHEMA_VERSION,
PDepNetworkAssessment,
assessments_record_path,
)
from t3.pdep.reason_codes import (
INTERNAL_ERROR_REASON_CODES,
PRE_SELECTOR_REASON_CODES,
REASON_CODE_STATUS,
SELECTION_BEARING_REASON_CODES,
STATUS_EVALUATED_NEGATIVE,
STATUS_INTERNAL_ERROR,
STATUS_NOT_EVALUATED,
STATUS_QUALIFIED,
VALID_ASSESSMENT_REASON_CODES,
VALID_ASSESSMENT_STATUSES,
)
Loading
Loading