fair-simulation-packager

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

FAIR Simulation Packager

FAIR模拟打包工具

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.
构建材料模拟结果的极简可复现性清单,让其他人或Agent能够了解运行的内容、使用的输入以及如何解读输出。

Requirements

要求

  • Python 3.10+
  • No external dependencies
  • Works on Linux, macOS, and Windows
  • Python 3.10+
  • 无外部依赖
  • 支持Linux、macOS和Windows

Inputs to Gather

需要收集的输入项

InputDescriptionExample
Project nameHuman-readable bundle name
al-cu-diffusion-study
EngineSimulation code
LAMMPS
,
VASP
,
MOOSE
Input filesFiles needed to rerun
in.lammps,data.lmp
Output filesFiles needed to verify results
log.lammps,traj.dump
Structure IDDatabase or local identifier
mp-149
UnitsField/unit mapping
energy=eV,length=angstrom
输入项描述示例
项目名称易读的打包文件名称
al-cu-diffusion-study
引擎模拟代码
LAMMPS
,
VASP
,
MOOSE
输入文件重新运行所需的文件
in.lammps,data.lmp
输出文件验证结果所需的文件
log.lammps,traj.dump
结构ID数据库或本地标识符
mp-149
单位字段/单位映射
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.
  • 始终包含输入文件、输出文件、代码版本和单位。
  • 为每个本地存在的文件添加哈希值。
  • 当使用Materials Project、NOMAD、OPTIMADE、CIF、POSCAR或内部数据库记录时,包含结构标识符。
  • 将缺失的文件记录为警告,而非静默丢弃。

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.<field>
. When
--out PATH
is given, only the bare
manifest
object (not the
inputs
/
results
envelope) is written to
PATH
.
scripts/fair_packager.py --json
会输出一个包含两个顶级键的信封结构:
  • inputs
    :回显解析后的CLI参数(注意:
    inputs.inputs
    是通过
    --inputs
    传入的原始逗号分隔字符串,而非每个文件的记录)。
  • results
    :包含一个键
    manifest
results.manifest
包含以下字段:
  • project_name
    ,
    engine
    ,
    engine_version
    ,
    structure_id
    ,
    units
  • file_inventory
    ,包含
    inputs
    outputs
    ,各自为每个文件的记录列表(
    path
    exists
    ,当文件存在时还包含
    size_bytes
    sha256
  • missing_files
    :磁盘上不存在的路径
  • provenance
    working_directory
    ,
    manifest_schema
  • fair_checks
    has_inputs
    ,
    has_outputs
    ,
    has_units
    ,
    has_engine_version
    has_hashes_for_existing_files
    (值为
    true
    /
    false
    ,当无文件存在时为
    null
    ,表示该检查不适用)
  • recommended_next_steps
解析字段时使用
results.manifest.<field>
。当指定
--out PATH
时,仅将裸
manifest
对象(而非
inputs
/
results
信封结构)写入
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.
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
仅在用户需要写入清单文件时使用
--out manifest.json

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.
缺失的文件会在
missing_files
中报告(退出码为0)。无效输入会以退出码2终止:格式错误的单位条目、包含控制字符的字段、长度超过4096字符的字段、输入或输出条目超过1000个,或文件大小超过500 MB。请注意,普通文件路径——包括绝对路径和包含
..
的路径——都会被接受并纳入清单;工具仅读取文件内容以计算元数据和SHA-256哈希值。

Limitations

局限性

This skill creates a metadata manifest. It does not upload to NOMAD, Materials Project, or an OPTIMADE provider.
本工具仅创建元数据清单,不会上传至NOMAD、Materials Project或OPTIMADE提供商。

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.
  • 确认
    fair_checks.has_hashes_for_existing_files
    true
    (而非
    null
    false
    );
    null
    表示列出的文件均不存在于磁盘上,因此在信任清单前,请从实际存放文件的目录重新运行工具。
  • 检查
    missing_files
    并确认其为空,或为每个条目记录明确的原因——每个缺失的路径意味着某个输入/输出被命名但未被哈希,因此当前打包文件无法直接复现。
  • 随机抽查
    results.manifest.file_inventory
    中的至少一个
    sha256
    值,与通过独立工具
    sha256sum
    /
    Get-FileHash
    计算的同一文件的摘要进行比对,确认记录的摘要与磁盘上的字节内容匹配。
  • 确认
    engine_version
    是真实的版本字符串,而非默认值
    "unknown"
    ;传入
    --engine-version
    参数,以便打包文件记录确切的代码构建版本。
  • 验证
    units
    非空,且每个报告的量(能量、长度、时间等)都有对应的条目,这样下游使用者无需猜测单位系统。
  • 当使用Materials Project / NOMAD / OPTIMADE / CIF / POSCAR结构时,确认
    structure_id
    已填充,以便结构身份可被恢复。
  • 当使用
    --out PATH
    时,打开
    PATH
    并确认其包含裸
    manifest
    对象(而非
    inputs
    /
    results
    信封结构),且未写入工作目录外的意外路径。

Common pitfalls & rationalizations

常见陷阱与合理化借口

Tempting shortcutWhy 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.
诱人的捷径错误原因/正确做法
"退出码为0,说明打包文件已完整。"退出码0仅表示无验证错误;缺失文件会在
missing_files
中报告且退出码为0。在信任完整性前,请检查
missing_files
fair_checks
"
has_hashes_for_existing_files
null
,和
true
差不多。"
null
表示列出的文件均不存在于磁盘上——没有任何文件被哈希。请从正确的目录重新运行工具,以便找到文件并实际计算哈希。
"跳过
--engine-version
,引擎名称就足够了。"
脚本默认
engine_version
"unknown"
,这会悄无声息地破坏可复现性。请始终传入具体的构建/版本号。
"从JSON中解析
inputs.inputs
就能得到每个文件的记录。"
inputs.inputs
是回显的原始CLI逗号分隔字符串,而非文件记录。请从
results.manifest.file_inventory.inputs/outputs
读取每个文件的数据。
"清单已捕获结构,因此运行完全可复现。"本工具仅记录文件清单、哈希值、单位和ID。它不会记录代码提交、容器摘要或解析器版本——请遵循
recommended_next_steps
自行添加这些信息。
"绝对路径或
..
会被拒绝,因此清单是沙箱化的。"
路径并未沙箱化——绝对路径和包含
..
的路径会按给定的方式被纳入清单,且
--out
可以写入工作目录之外。请验证你传入的路径是预期的路径。

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.
  • --project-name
    --engine
    为必填项,去除空白后必须非空;空值会以退出码2终止。
  • --project-name
    --engine
    --structure-id
    (若提供)以及每个文件路径都会被检查是否包含控制字符(
    ord < 32
    )和是否超过4096字符的最大长度;任一条件满足都会以退出码2终止。
  • --inputs
    --outputs
    会按逗号拆分,且每个列表最多包含1000个条目;超过会以退出码2终止。
  • --units
    条目必须为
    key=value
    格式;键和值必须匹配白名单
    ^[A-Za-z0-9_.:/@+-]+$
    。缺少
    =
    或键/值不匹配会以退出码2终止。
  • 无数值输入,因此无需进行有限/正数值检查。

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.
  • 脚本会以1 MB块的方式读取每个存在的输入/输出文件,以计算其
    size_bytes
    和SHA-256哈希值;不存在的文件会被记录但不会被读取。
  • 大小超过500 MB的文件会在计算哈希前以退出码2终止。
  • 除非指定
    --out PATH
    ,否则脚本不会写入任何文件;指定后会将裸清单JSON写入该路径;否则所有输出都会输出到标准输出。
  • 路径并未沙箱化:绝对路径和包含
    ..
    的路径对于纳入清单的文件和
    --out
    都是可接受的。如果
    --out
    指向工作目录之外,文件会按请求写入该位置。

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.
  • 使用
    Bash
    运行捆绑的
    scripts/fair_packager.py
  • 声明了
    Read
    Write
    Grep
    Glob
    ,以便工具在引导用户时检查工作目录并读取或写入清单/元数据文件;这些操作并非由脚本本身调用,脚本自身的所有文件I/O都是直接执行的。

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.
  • eval
    exec
    os.system
    subprocess
    调用;脚本不会调用shell,而是使用
    argparse
    解析参数。
  • 通过
    json.dumps
    输出JSON(或不带
    --json
    时输出简短的纯文本摘要)。
  • DoS限制约束了资源使用:每个文件最大500 MB,每个输入/输出列表最多1000个条目,每个字段最多4096字符。

References

参考资料

  • See
    references/fair_manifest.md
    for recommended manifest fields.
  • 推荐的清单字段请参阅
    references/fair_manifest.md

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.
  • 1.2.0:通过将脚本的精确
    --json
    输出(每个文件的
    sha256
    /
    size_bytes
    units
    structure_id
    engine_version
    missing_files
    以及三态的
    has_hashes_for_existing_files
    )与已提交的
    evals/files/
    测试用例进行比对,使评估案例更具判别性。
  • 1.1.0:记录了真实的
    --json
    信封结构;将
    has_hashes_for_existing_files
    改为三态(无文件存在时为
    null
    );添加了条目数量(1000)和字段长度(4096)限制;修正了错误处理和安全部分的措辞,以描述实际的路径行为。
  • 1.0.0:初始的FAIR模拟打包工具版本。