# Fair Simulation Packager

> >

- **Type:** Skill
- **Install:** `agentstack add skill-heshamfs-materials-simulation-skills-fair-simulation-packager`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [HeshamFS](https://agentstack.voostack.com/s/heshamfs)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [HeshamFS](https://github.com/HeshamFS)
- **Source:** https://github.com/HeshamFS/materials-simulation-skills/tree/main/skills/data-management/fair-simulation-packager

## Install

```sh
agentstack add skill-heshamfs-materials-simulation-skills-fair-simulation-packager
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# FAIR Simulation Packager

## Goal

Build a minimal reproducibility manifest for materials simulation results so another person or agent can understand what was run, with which inputs, and how outputs should be interpreted.

## Requirements

- Python 3.10+
- No external dependencies
- Works on Linux, macOS, and Windows

## Inputs to Gather

| Input | Description | Example |
|-------|-------------|---------|
| Project name | Human-readable bundle name | `al-cu-diffusion-study` |
| Engine | Simulation code | `LAMMPS`, `VASP`, `MOOSE` |
| Input files | Files needed to rerun | `in.lammps,data.lmp` |
| Output files | Files needed to verify results | `log.lammps,traj.dump` |
| Structure ID | Database or local identifier | `mp-149` |
| Units | Field/unit mapping | `energy=eV,length=angstrom` |

## Decision Guidance

- Always include input files, output files, code version, and units.
- Include hashes for every file that exists locally.
- Include structure identifiers when using Materials Project, NOMAD, OPTIMADE, CIF, POSCAR, or internal database records.
- Record missing files as warnings instead of silently dropping them.

## Script Outputs

`scripts/fair_packager.py --json` prints an envelope with two top-level keys:

- `inputs`: the parsed CLI arguments echoed back (note: `inputs.inputs` is the raw
  comma-separated string passed via `--inputs`, not the per-file records).
- `results`: contains a single key `manifest`.

`results.manifest` contains these fields:

- `project_name`, `engine`, `engine_version`, `structure_id`, `units`
- `file_inventory` with `inputs` and `outputs`, each a list of per-file records
  (`path`, `exists`, and when the file exists, `size_bytes` and `sha256`)
- `missing_files`: paths that do not exist on disk
- `provenance` (`working_directory`, `manifest_schema`)
- `fair_checks`: `has_inputs`, `has_outputs`, `has_units`, `has_engine_version`, and
  `has_hashes_for_existing_files` (`true`/`false`, or `null` when no files exist so the
  check is not applicable)
- `recommended_next_steps`

Parse fields at `results.manifest.`. When `--out PATH` is given, only the bare
`manifest` object (not the `inputs`/`results` envelope) is written to `PATH`.

## Workflow

```bash
python3 skills/data-management/fair-simulation-packager/scripts/fair_packager.py \
  --project-name al-cu-diffusion \
  --engine LAMMPS \
  --inputs in.lammps,data.lmp \
  --outputs log.lammps,traj.dump \
  --units energy=eV,length=angstrom,time=ps \
  --structure-id local:alcu-cell-001 \
  --json
```

Use `--out manifest.json` only when the user wants a manifest file written.

## Error Handling

Missing files are reported in `missing_files` (exit code 0). Invalid input stops with
exit code 2: malformed unit entries, fields containing control characters, fields longer
than 4096 characters, more than 1000 input or output entries, or a file larger than
500 MB. Note that ordinary file paths — including absolute paths and paths containing
`..` — are accepted and inventoried; the tool reads file contents only to compute
metadata and SHA-256 hashes.

## Limitations

This skill creates a metadata manifest. It does not upload to NOMAD, Materials Project, or an OPTIMADE provider.

## Verification checklist

- [ ] Confirmed `fair_checks.has_hashes_for_existing_files` is `true` (not `null` or `false`); a `null` means no listed file existed on disk, so re-run from the directory where the files actually live before trusting the manifest.
- [ ] Reviewed `missing_files` and confirmed it is empty, or recorded an explicit reason for each entry — every missing path means an input/output was named but not hashed, so the bundle is not reproducible as-is.
- [ ] Spot-checked at least one `sha256` in `results.manifest.file_inventory` against an independent `sha256sum`/`Get-FileHash` of the same file to confirm the recorded digest matches the bytes on disk.
- [ ] Confirmed `engine_version` is a real version string and not the default `"unknown"`; pass `--engine-version` so the bundle records the exact code build.
- [ ] Verified `units` is non-empty and every reported quantity (energy, length, time, etc.) has an entry, so downstream consumers do not have to guess the unit system.
- [ ] Confirmed `structure_id` is populated when a Materials Project / NOMAD / OPTIMADE / CIF / POSCAR structure was used, so the structure identity is recoverable.
- [ ] When `--out PATH` was used, opened `PATH` and confirmed it holds the bare `manifest` object (not the `inputs`/`results` envelope) and that no unintended path outside the working directory was written.

## Common pitfalls & rationalizations

| Tempting shortcut | Why it's wrong / what to do |
|-------------------|-----------------------------|
| "It exited 0, so the bundle is complete." | Exit 0 only means no validation error; missing files are reported in `missing_files` with exit 0. Inspect `missing_files` and `fair_checks` before trusting completeness. |
| "`has_hashes_for_existing_files` is `null`, close enough to `true`." | `null` means *no listed file existed on disk* — nothing was hashed. Re-run from the correct directory so the files are found and actually digested. |
| "Skip `--engine-version`, the engine name is enough." | The script defaults `engine_version` to `"unknown"`, which silently breaks reproducibility. Always pass the concrete build/version. |
| "Parsing `inputs.inputs` from the JSON gives me the per-file records." | `inputs.inputs` is the raw comma-separated CLI string echoed back, not the records. Read per-file data from `results.manifest.file_inventory.inputs/outputs`. |
| "The manifest captures the structure, so the run is fully reproducible." | This skill only inventories files, hashes, units, and IDs. It does not record code commit, container digest, or parser versions — follow `recommended_next_steps` and add those yourself. |
| "Absolute paths or `..` will be rejected, so the inventory is sandboxed." | Paths are not sandboxed — absolute and `..` paths are inventoried as given, and `--out` can write outside the working directory. Verify the paths you pass are the intended ones. |

## Security

### Input Validation

- `--project-name` and `--engine` are required and must be non-empty after stripping
  whitespace; an empty value stops with exit code 2.
- `--project-name`, `--engine`, `--structure-id` (when given), and every file path are
  checked for control characters (`ord < 32`) and a 4096-character maximum length; either
  condition stops with exit code 2.
- `--inputs` and `--outputs` are split on commas and capped at 1000 entries each; more
  entries stop with exit code 2.
- `--units` entries must be `key=value`; both the key and the value must match the
  allowlist `^[A-Za-z0-9_.:/@+-]+$`. A missing `=` or a non-matching key/value stops with
  exit code 2.
- There are no numeric inputs, so no finite/positive numeric checks are performed.

### File Access

- The script reads each existing input/output file in 1 MB chunks to compute its
  `size_bytes` and SHA-256 hash; files that do not exist are recorded but not read.
- A file larger than 500 MB stops with exit code 2 before it is hashed.
- The script writes no files unless `--out PATH` is given, in which case it writes exactly
  one file (the bare manifest JSON) to that path; otherwise all output goes to stdout.
- Paths are not sandboxed: absolute paths and paths containing `..` are accepted for both
  the inventoried files and `--out`. If `--out` points outside the working directory, the
  file is written there as requested.

### Tool Restrictions

- `Bash` is used to run the bundled `scripts/fair_packager.py`.
- `Read`, `Write`, `Grep`, and `Glob` are declared so the skill can inspect the working
  directory and read or write manifest/metadata files when guiding the user; they are not
  invoked by the script itself, which performs all of its own file I/O directly.

### Safety Measures

- No `eval`, `exec`, `os.system`, or `subprocess` calls; the script does not shell out and
  parses arguments with `argparse`.
- Output is emitted as JSON via `json.dumps` (or a short plain-text summary without
  `--json`).
- DoS caps bound resource use: 500 MB per file, 1000 entries per input/output list, and
  4096 characters per field.

## References

- See `references/fair_manifest.md` for recommended manifest fields.

## Version History

- 1.2.0: Made eval cases discriminating by pinning the script's exact `--json`
  output (per-file `sha256`/`size_bytes`, `units`, `structure_id`, `engine_version`,
  `missing_files`, and the tri-state `has_hashes_for_existing_files`) against
  committed `evals/files/` fixtures.
- 1.1.0: Documented the real `--json` envelope shape; made
  `has_hashes_for_existing_files` tri-state (`null` when no files exist); added entry-count
  (1000) and field-length (4096) caps; corrected the Error Handling and Security wording
  to describe actual path behavior.
- 1.0.0: Initial FAIR simulation packaging skill.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [HeshamFS](https://github.com/HeshamFS)
- **Source:** [HeshamFS/materials-simulation-skills](https://github.com/HeshamFS/materials-simulation-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** yes
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-heshamfs-materials-simulation-skills-fair-simulation-packager
- Seller: https://agentstack.voostack.com/s/heshamfs
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
