Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
.github/**/*.md
docs/*.md
docs/**/*.md
skills/**/*.md
- uses: actions/setup-python@v7
with:
python-version: "3.13"
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ follow [Semantic Versioning](https://semver.org/) after the initial development

### Added

- Added a compact coding-agent guide and installable ElecTrace skill for routing
existing-output analysis and approval-gated local or Slurm workflows through the
public CLI.
- Added a deterministic `electrace benchmark` command, versioned benchmark JSON
schema, and 15 labeled synthetic cases spanning periodic wrapping, coordinate and
cell perturbations, ordering, direct events, conservation-backed split/merge,
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ same path analysis.

## Learn more

See the [quick start](docs/quickstart.md), [workflow guide](docs/workflows.md), and
[scientific scope](docs/scientific-scope.md) for detailed configuration and supported
data formats.
See the [quick start](docs/quickstart.md), [workflow guide](docs/workflows.md),
[coding-agent guide](docs/agents.md), and [scientific scope](docs/scientific-scope.md)
for detailed configuration and supported data formats.

ElecTrace is available under the [BSD 3-Clause License](LICENSE).
62 changes: 62 additions & 0 deletions docs/agents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Use ElecTrace with coding agents

ElecTrace gives coding agents a reusable command-line workflow for Bader charge trends
across NEB frames, ELF/QTAIM path analysis, and LOBSTER ICOHP/ICOBI changes across an
ordered VASP structure series. It replaces one-off frame discovery, Slurm generation,
output parsing, periodic correspondence, and report code with a tested interface.

## Install the CLI

ElecTrace supports CPython 3.11–3.13. Install the current public source in a virtual
environment:

```bash
python -m pip install "git+https://github.com/Austin243/ElecTrace.git"
electrace --version
electrace doctor --json
```

The built-in demo requires no external scientific program:

```bash
electrace demo --output .electrace-demo
electrace inspect .electrace-demo/electrace-results
```

## Install the Codex skill

The repository ships an
[`electrace` skill](https://github.com/Austin243/ElecTrace/tree/main/skills/electrace)
that teaches Codex when to analyze existing descriptor outputs, when to prepare a
calculation workflow, which commands are non-executing, and which actions require
explicit user authorization.

Ask Codex:

```text
Use $skill-installer to install the ElecTrace skill from
https://github.com/Austin243/ElecTrace/tree/main/skills/electrace
```

The skill becomes available on the next Codex turn. Invoke it explicitly with
`$electrace`, or let its task description trigger when working with Bader, BadELF,
ELF/QTAIM, LOBSTER, DDEC, VASP NEB frames, or ordered periodic structure series.

## Agent workflow

An agent should start with the installed help and a read-only environment check:

```bash
electrace --help
electrace doctor --json
```

If supported descriptor results already exist, it should create and review
`electrace.toml`, run `electrace analyze`, and consume `analysis.json` as the canonical
result. If calculations are missing, it should create and review
`electrace-workflow.yaml`, stage the selected frames, and inspect workflow status.
Local execution and Slurm submission remain explicit actions; the skill does not add
`--yes` unless the user authorizes the reviewed job scope.

See the [workflow guide](workflows.md) for complete manifest options and the
[scientific scope](scientific-scope.md) for interpretation boundaries.
10 changes: 6 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ capabilities from planned or scientifically unvalidated work.
an ordered VASP path.
2. [External calculation workflows](workflows.md) — stage, explicitly execute or
submit, collect, and analyze a VASP→descriptor workflow.
3. [Scientific scope and limitations](scientific-scope.md) — understand what a
3. [Coding agents](agents.md) — install the ElecTrace skill and use the CLI through a
compact, approval-aware agent workflow.
4. [Scientific scope and limitations](scientific-scope.md) — understand what a
ElecTrace event does and does not mean.
4. [Synthetic benchmark](benchmarking.md) — run and interpret the versioned offline
5. [Synthetic benchmark](benchmarking.md) — run and interpret the versioned offline
regression cases without mistaking them for physical validation.
5. [Reproducibility](reproducibility.md) — preserve enough information to audit and
6. [Reproducibility](reproducibility.md) — preserve enough information to audit and
repeat an analysis.
6. [Pre-release namespace migration](migration.md) — update development environments,
7. [Pre-release namespace migration](migration.md) — update development environments,
scripts, configurations, and serialized artifacts for `0.1.0a2`.

## Design and integration
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ nav:
- Overview: index.md
- Quickstart: quickstart.md
- External workflows: workflows.md
- Coding agents: agents.md
- Scientific scope: scientific-scope.md
- Architecture: architecture.md
- Integration:
Expand Down
120 changes: 120 additions & 0 deletions skills/electrace/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
name: electrace
description: Track Bader, BadELF, ELF/QTAIM, LOBSTER ICOHP/ICOBI, or DDEC evidence across ordered VASP NEB images and structure series with ElecTrace. Use for selecting frames, analyzing existing outputs, inspecting ELFCAR/CHGCAR grids, staging local or Slurm calculations, collecting results, and reporting changes across a path. Do not use as a scientific-convergence or formal-oxidation-state oracle.
---

# Use ElecTrace

Use the installed `electrace` CLI as the deterministic execution layer. Do not recreate
its parsers, periodic matching, workflow staging, or report generation in ad hoc code.

## Start safely

1. Work in the user's existing environment or create a project-local virtual environment.
2. Check the installed interface before constructing commands:

```bash
electrace --version
electrace --help
electrace doctor --json
```

3. If the command is missing, offer this public-source installation and install only in
an environment the user has authorized:

```bash
python -m pip install "git+https://github.com/Austin243/ElecTrace.git"
```

4. Determine whether supported descriptor outputs already exist or must be calculated.
5. Inspect first. Use planning and staging before any external execution.

Read [references/workflows.md](references/workflows.md) when selecting capabilities,
constructing a workflow manifest, or checking supported scientific boundaries.

## Analyze existing evidence

Use this route when the ordered frames already contain supported Bader/BaderKit,
critic2, LOBSTER, Chargemol, or normalized ElecTrace descriptor files.

```bash
electrace init electrace.toml --images /absolute/path/to/frames
# Review electrace.toml and configure descriptor_source/descriptor_dir.
electrace doctor --config electrace.toml --json
electrace analyze electrace.toml
electrace inspect electrace-results
```

Treat the generated `analysis.json` as the canonical result. Treat CSV and HTML as
views. Report warnings, missing evidence, ambiguities, frame coverage, and provenance
alongside event summaries. Do not silently switch from strict to permissive analysis.

Top-level analysis uses all frames discovered by its TOML configuration. Use a workflow
manifest when the user asks for an explicit subset or every nth frame.

## Prepare missing calculations

Use this route when VASP or descriptor calculations must be staged across selected
frames.

```bash
electrace workflow init electrace-workflow.yaml --images /absolute/path/to/frames
# Review executables, templates, dependencies, resources, scheduler, and frames.
electrace workflow stage electrace-workflow.yaml
electrace workflow status electrace-workflow.yaml
```

Staging writes an isolated, marker-protected workspace but runs no external program.
Inspect the generated job records and inputs before execution.

For local execution, add `--yes` only when the user explicitly authorizes all staged
commands:

```bash
electrace workflow run electrace-workflow.yaml --yes --max-parallel 2
```

For Slurm, prepare scripts without submitting, review them, then submit only with
explicit authorization:

```bash
electrace workflow submit electrace-workflow.yaml --job-name electrace
# Review scripts and scheduler directives.
electrace workflow submit electrace-workflow.yaml --job-name electrace --yes --force
```

After expected outputs exist:

```bash
electrace workflow status electrace-workflow.yaml
electrace workflow analyze electrace-workflow.yaml
```

Do not assume filesystem completion proves electronic, projection, grid, or scientific
convergence. Inspect external-tool outputs and surface failures.

## Plan and inspect without execution

- Use `electrace plan PLUGIN FRAME --capability CAPABILITY` for one JSON command plan.
- Add `--all-frames` to plan across a discovered path.
- Use `electrace volume ELFCAR --json` to summarize a plain VASP scalar grid.
- Use `electrace volume ELFCAR --sample X,Y,Z` for periodic fractional sampling.
- Use `electrace workflow status MANIFEST` for machine-readable filesystem status.

Planning never executes a tool. `workflow submit` without `--yes` writes Slurm scripts
but does not call `sbatch`.

## Preserve scientific and execution boundaries

- Treat Bader and DDEC values as charge/electron-population evidence, not definitive
formal oxidation states.
- Treat ICOHP/ICOBI and topology events as method-dependent evidence, not unique bond
energies, mechanisms, or identities.
- Never invent or redistribute a `POTCAR`, executable, credential, or private input.
- Never add `--yes`, `--force`, or `--permissive` merely to make a command succeed.
- Never invent a `chargemol` workflow step; ElecTrace can plan Chargemol and ingest
existing DDEC results, but `electrace.workflow.v1` does not stage it.
- Do not combine BaderKit Bader and BadELF atomic records for the same frame unless the
duplicate normalized atom-ID conflict has been resolved deliberately.
- Preserve negative and missing evidence. Stop on schema, provenance, semantic-family,
or ambiguity errors instead of fabricating a correspondence.
4 changes: 4 additions & 0 deletions skills/electrace/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "ElecTrace"
short_description: "Track electronic evidence across VASP paths"
default_prompt: "Use $electrace to track Bader, ELF/QTAIM, or LOBSTER evidence across an ordered VASP path."
94 changes: 94 additions & 0 deletions skills/electrace/references/workflows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# ElecTrace workflow reference

Read this reference only when choosing a descriptor capability, building a workflow,
or interpreting a current support boundary. Confirm exact flags with
`electrace COMMAND --help` because ElecTrace is pre-1.0.

## Frame selection

The workflow manifest accepts `all` or comma-separated indices and Python-style slices:

| Selection | Frames |
| --- | --- |
| `all` | Every discovered frame |
| `0,3,7` | Exact indices 0, 3, and 7 |
| `1:8` | Indices 1 through 7 |
| `0:10:2` | Every second frame from 0 through 8 |
| `::3` | Every third discovered frame |
| `0,2:9:2` | Index 0, then 2, 4, 6, and 8 |

Selections preserve expression order and reject duplicate or empty resolution.

## Capability map

| Goal | Plugin or workflow step | Capability | Required scientific output |
| --- | --- | --- | --- |
| Bader populations | `bader` | `bader_charges` | `ACF.dat` |
| BaderKit populations | `baderkit` | `bader_charges` | `bader.json` |
| BadELF/NNA evidence | `baderkit` | `elf_basins` or `non_nuclear_attractors` | `badelf.json` |
| QTAIM critical points | `critic2` | `qtaim_critical_points` | `critic2.features.json` |
| ELF topology/NNA | `critic2` | `non_nuclear_attractors` | `critic2.features.json` |
| Integrated COHP | `lobster` | `cohp` | `ICOHPLIST.lobster` |
| Integrated COBI | `lobster` | `cobi` | `ICOBILIST.lobster` |
| DDEC charges | `chargemol` planning or existing results only | `ddec_charges` | supported DDEC charge output |

Use `electrace doctor --config CONFIG --json` to check configured executables and
required inputs across discovered frames. Use `electrace plan PLUGIN FRAME
--capability CAPABILITY` to inspect the exact argument vector, standard input,
required inputs, expected outputs, and working directory without execution.

## Existing-output route

```bash
electrace init electrace.toml --images /absolute/path/to/frames
# Set series_kind, descriptor_source, and descriptor_dir as required.
electrace doctor --config electrace.toml --json
electrace analyze electrace.toml
electrace inspect electrace-results
```

Use this route for existing Chargemol/DDEC results. Do not add `chargemol` to a
workflow manifest.

## Calculation route

```bash
electrace workflow init electrace-workflow.yaml --images /absolute/path/to/frames
# Configure frames, executables, templates, steps, dependencies, and scheduler.
electrace workflow stage electrace-workflow.yaml
electrace workflow status electrace-workflow.yaml
```

For local work, run only after authorization:

```bash
electrace workflow run electrace-workflow.yaml --yes --max-parallel 2
```

For Slurm, prepare first and submit second:

```bash
electrace workflow submit electrace-workflow.yaml --job-name electrace
electrace workflow submit electrace-workflow.yaml --job-name electrace --yes --force
```

Then collect and analyze:

```bash
electrace workflow status electrace-workflow.yaml
electrace workflow analyze electrace-workflow.yaml
```

## Current boundaries

- External VASP, Bader/BaderKit, critic2, LOBSTER, and Chargemol installations remain
user-supplied. ElecTrace does not select convergence settings or supply `POTCAR`.
- BaderKit `bader.json` and `badelf.json` both normalize atomic records to
`baderkit:atom:*`; do not attach both for one frame without an explicit resolution.
- critic2 support tracks critical-point topology and NNAs, not integrated ELF basin
populations.
- Native spin-resolved LOBSTER list ingestion is unsupported.
- `workflow status` reports staged files and expected outputs, not scheduler state or
scientific convergence.
- Bader/DDEC populations are not definitive formal oxidation states, and ICOHP is not
a transferable bond energy.
28 changes: 28 additions & 0 deletions tests/test_agent_skill.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from pathlib import Path

import yaml

ROOT = Path(__file__).parents[1]
SKILL = ROOT / "skills" / "electrace"


def test_electrace_skill_is_complete_and_installable() -> None:
skill_text = (SKILL / "SKILL.md").read_text(encoding="utf-8")
_, frontmatter, body = skill_text.split("---", 2)
metadata = yaml.safe_load(frontmatter)

assert metadata.keys() == {"name", "description"}
assert metadata["name"] == "electrace"
assert all(
trigger in metadata["description"].lower()
for trigger in ("bader", "qtaim", "lobster", "vasp neb")
)
assert "[TODO" not in skill_text
assert "references/workflows.md" in body
assert (SKILL / "references" / "workflows.md").is_file()

agent_metadata = yaml.safe_load((SKILL / "agents" / "openai.yaml").read_text(encoding="utf-8"))
interface = agent_metadata["interface"]
assert interface["display_name"] == "ElecTrace"
assert 25 <= len(interface["short_description"]) <= 64
assert "$electrace" in interface["default_prompt"]