Syntagmax - Git-Based Requirements Management System
Fully git-friendly lightweight requirements management system with tracing model verification, change detection, and propagation.
Quick Demo (Development Environment)
Run example analysis with:
uv run syntagmax --render-tree --cwd ./example/obsidian-driver/ analyze
Run example publishing with:
uv run syntagmax --cwd ./example/obsidian-driver publish .syntagmax/outputs/output.md
Run example tracing export with:
uv run syntagmax --cwd ./example/obsidian-driver trace --child REQ --parent SYS
Getting Started
To initialize a new Syntagmax project in the current directory:
syntagmax init
This command creates a .syntagmax directory with:
config.toml: A template configuration file with common options.project.syntagmax: A basic metamodel definition to get you started.
Configuration
Syntagmax uses a TOML configuration file (default .syntagmax/config.toml). Override the path with the global -f / --config-file option:
syntagmax -f path/to/config.toml analyze
Key sections include:
[[input]]— input source definitions (driver, artifact type, filters)output_path— base directory for report-like outputs (relative to config file directory)[publish]— publish pipeline settings (config file path, cross-input duplicate validation)[metrics]— metrics collection settings[impact]— impact analysis settings[metamodel]— metamodel file path[trace]— trace export plugin configuration
For details on how all these paths are resolved relative to the project configuration file, see the Paths Reference.
base = ".."
log_level = "info"
[[input]]
name = "requirements"
dir = "requirements/REQS"
driver = "obsidian"
[metrics]
enabled = true
[metamodel]
filename = "project.syntagmax"
For the full schema, input source options, and marked fragments, see docs/reference/configuration.md. Detailed path resolution rules are described in docs/reference/paths.md.
For detailed Obsidian driver extraction rules, block termination behavior, and fragment marker processing, see docs/reference/obsidian.md.
Git Integration
Syntagmax automatically extracts revision history for each artifact using Git. This provides traceability and helps track changes over time.
Revision Descriptors
Each artifact is attached with a set of revisions. A revision includes:
- Short Hash: The 7-character commit hash.
- Timestamp: Date and time of the commit.
- Author: Email of the commit author.
Extraction Logic
- Text-based artifacts (e.g., source code sections, Obsidian requirements): Syntagmax uses
git blameto identify all commits that affected the specific lines where the artifact is defined. - Sidecar artifacts: Syntagmax identifies the last commit that affected the primary file (e.g., an image) and all commits that affected the sidecar metadata file.
Disabling Git Integration
If you want to skip git history extraction (e.g., if you are not in a git repository or want to speed up analysis), use the --no-git flag:
syntagmax analyze --no-git
Running Analysis
The analyze command is the primary way to process your project. It supports a dynamic execution pipeline where you can request a specific target step.
syntagmax analyze [STEP]
Target Steps
Syntagmax will automatically resolve and execute all dependencies required for the requested step:
| Step | Description |
|---|---|
extract |
Only extract artifacts from source files. |
tree |
Build and validate the artifact tree. |
impact |
Perform impact analysis (requires git history). |
metrics |
(Default) Calculate project metrics and coverage. |
Example:
# Run impact analysis only
syntagmax analyze impact
Report Output
All analysis outputs (errors, metrics, impact, and optionally the artifact tree) are combined into a single Markdown report file.
- Default location:
<output_path>/report.md(default:.syntagmax/outputs/report.md) - Override with:
--output <path>or--output consoleto print to stdout - Tree inclusion: Pass
--render-treeto include the artifact tree in the report - Section order: Errors (grouped by input → category) → Artifact Tree → Metrics (aggregate + per-input) → Impact Analysis → AI Analysis
Example:
# Generate report with tree to default location
syntagmax --render-tree analyze
# Print report to stdout
syntagmax --render-tree analyze --output console
Report Configuration
Optional report formatting settings in config.toml:
[report]
path_as_links = true # Render file paths as clickable links (default: false)
wiki_links = false # Use [[wiki-link]] style for Obsidian (default: false)
path_as_links = false(default): plain text paths in error messagespath_as_links = true, wiki_links = false: standard Markdown links[file.md](path/to/file.md#L10)path_as_links = true, wiki_links = true: Obsidian wiki links[[path/to/file.md]]
File paths are relative to the project root. Standard Markdown links include line anchors (#L<line>) when available; wiki links do not (Obsidian limitation).
Standard Markdown links are percent-encoded for Obsidian compatibility — spaces become %20, Cyrillic and other non-ASCII characters are encoded, and special characters like parentheses are escaped.
Error Grouping
Errors are grouped by input record name, then by error category:
## Errors
Total errors: 151
### system-requirements
#### Attribute Errors (30)
1. Missing mandatory attribute: 'status'
...
#### Reference Errors (15)
...
### software-requirements
#### Schema Errors (20)
...
Errors not attributable to a specific input (e.g., structural issues) appear under a "Global" heading.
Task Generation
Syntagmax can automatically generate task files from impact analysis results. Each outdated artifact (suspicious link) produces a dedicated markdown task file tracking the verification work.
Enable in config.toml:
[impact]
enabled = true
tasks_enabled = true
Alternatively, use the --tasks CLI flag to enable task generation without modifying the config file:
syntagmax analyze --tasks impact
Task files are written to .syntagmax/tasks/ by default (since tasks_dir is resolved relative to the config file directory) and include full references to both parent and child artifacts with their revision information.
For the full configuration reference including custom templates, atype mapping, and de-duplication behavior, see docs/reference/configuration.md.
Metamodel DSL
Syntagmax allows defining a custom metamodel for artifacts and their attributes using a simple DSL. This metamodel is used for static validation of requirements and other artifacts.
Companion VS Code Extension: syntagmax-vscode
artifact REQ:
attribute id is mandatory string
attribute contents is mandatory string
attribute parent is optional reference to parent
attribute status is mandatory enum [draft, active, retired]
attribute verify is optional string
attribute priority is mandatory integer
trace from REQ to SYS is mandatory via commit
For the full syntax reference, types, trace modes, multiple attributes, and impact analysis logic, see docs/reference/metamodel.md.
Editing and Identification
Syntagmax provides a command to assign or update artifact IDs according to a schema. This is useful when you want to ensure a consistent naming convention across your project.
Quick Editing Demo
mkdir tmp
cp -rf ./example/renumber-demo ./tmp/
uv run syntagmax --cwd ./tmp/renumber-demo edit identification --all
Identification Command
To assign IDs to artifacts, use the edit identification command:
syntagmax edit identification --all
Options:
--all: Process all artifacts.--atype <type>: Process only artifacts of a specific type.--force: Renumber all artifacts from 1, ignoring existing valid IDs.--dry-run: Show what changes would be made without actually modifying any files.
ID Preservation
By default, edit identification preserves artifacts that already have valid IDs and only assigns new IDs where needed.
When IDs are preserved: Without --force, artifacts whose current ID matches the resolved schema (defined in the metamodel via id is TYPE as SCHEMA) are never modified. The schema is resolved per artifact type from the metamodel.
When IDs are renumbered: Only artifacts with absent, empty, or template IDs (containing literal {num} or {atype} macros) are renumbered. New IDs start from max(existing valid numbers) + 1 for each artifact type.
--force mode: All artifacts are renumbered sequentially from 1, regardless of current ID validity.
Padding semantics: {num:3} means "at least 3 digits". REQ-1234 is valid under schema REQ-{num:3}. Generated IDs are zero-padded to at least N digits but never truncated.
Per-type isolation: Each artifact type (e.g., REQ, SYS) is numbered independently with its own counter and max tracking.
Example:
Before (metamodel schema: REQ-{num:3}):
file-a.md: REQ-002, <undefined>, REQ-005
file-b.md: REQ-{num:3}, <undefined>
After syntagmax edit identification --all:
file-a.md: REQ-002, REQ-006, REQ-005
file-b.md: REQ-007, REQ-008
REQ-002 and REQ-005 are preserved (valid). New IDs start at 006 (max=5, next=6).
After syntagmax edit identification --all --force:
file-a.md: REQ-001, REQ-002, REQ-003
file-b.md: REQ-004, REQ-005
All artifacts renumbered from 1 in sort order.
Bulk Attribute Manipulation
The edit attrs command adds, removes, or replaces attributes across all artifacts in an input section. Only the Obsidian driver is supported.
syntagmax edit attrs [OPTIONS]
Options:
| Option | Default | Description |
|---|---|---|
-o, --operation |
add |
Operation: add, del, or replace |
-t, --type |
attr |
Target: attr (YAML) or field (inline [FIELD]) |
-n, --name |
— | Attribute name. Omit for add to add all mandatory metamodel attributes. |
-l, --value |
TBD |
Attribute value. Defaults to TBD for add. |
-s, --section |
— | Input record name (required) |
--csv |
— | CSV file for per-artifact value lookup |
--csv-id-column |
id |
CSV column for artifact ID matching |
--csv-value-column |
value |
CSV column for attribute value |
-d, --csv-delimiter |
, |
CSV column delimiter |
--dry-run |
— | Preview changes without modifying files |
Examples (Development Environment):
# Add all missing mandatory attributes (from metamodel) with TBD
uv run syntagmax --cwd ./example/obsidian-driver edit attrs -s software-requirements --dry-run
# Add 'owner' attribute with TBD to all SYS requirements
uv run syntagmax --cwd ./example/obsidian-driver edit attrs -s system-requirements -n owner
Examples as a Tool
# Replace 'status' to 'active' across all REQ artifacts
syntagmax edit attrs -s requirements -o replace -n status -l active
# Remove 'verified' from all artifacts in a section
syntagmax edit attrs -s system-requirements -o del -n verified
# Import values from a CSV file (with --value as fallback for unmatched IDs)
syntagmax edit attrs -s requirements -o replace -n doors_id --csv mapping.csv --csv-id-column ext_id --csv-value-column doors_id -l UNKNOWN
Behavior Notes:
- add: Skips artifacts that already have the attribute. Uses
TBDif no value given. - del: Removes the attribute wherever it exists; no-op otherwise.
- replace: Updates existing values in-place (preserving field position); appends if missing.
- Metamodel-driven add: Omit
--nameto add all mandatory attributes defined in the metamodel. - CSV mapping:
--csvtakes precedence;--valueserves as fallback for unmatched IDs. - Atomic writes: All changes are computed in memory before any file is written.
Marker Renumbering
The edit markers renumber command assigns sequential numeric IDs to non-artifact marked text blocks (e.g., [COM], [NOTE]) that don't already have explicit IDs.
syntagmax edit markers renumber --all
Options:
--all: Renumber across all input records (required unless--sectionis used).--section <name>: Restrict to a specific input record.--marker <name>: Only renumber blocks of a specific marker type.--dry-run: Show what changes would be made without modifying files.
Behaviour:
- Numbering is independent per marker type (COM numbering does not affect NOTE).
- New IDs start from
max_existing + 1(or 1 if no numeric IDs exist for that type). - Original marker casing is preserved:
[com]→[com 3]. - All marker formats are supported: closed (
[COM]...[/COM]), unclosed, and line-prefix.
Examples:
# Renumber all unmarked blocks
syntagmax edit markers renumber --all
# Preview changes
syntagmax edit markers renumber --all --dry-run
# Only renumber COM markers in system-requirements
syntagmax edit markers renumber --section system-requirements --marker COM
Publishing
Syntagmax can combine project inputs into structured markdown documents, with optional DOCX/PDF export via Pandoc. Rendering is controlled by publish.yaml configuration.
# Publish all records to separate files
syntagmax publish --all
# Single consolidated document with DOCX export
syntagmax publish --all --single --docx --output ./reports/full-document.md
For the full command reference, publish.yaml schema, rendering configuration, and DOCX template options, see docs/reference/publishing.md.
Obsidian Attachment Folder Integration
If your Obsidian vault uses a configured attachment folder (set via Vault Settings → Files & Links → Attachment folder path), Syntagmax can read this setting to resolve image references during publishing.
Enable it in your config.toml:
[drivers.obsidian]
integration = true
This reads .obsidian/app.json from your project root to find attachmentFolderPath, and uses it as the primary lookup location for ![[image.png]] references. Both vault-relative (e.g. attachments/pics) and note-relative (e.g. ./assets) paths are supported.
For full details, see the configuration reference.
Strict Line Breaks
Obsidian treats single newlines as visible line breaks by default, which differs from standard Markdown. The strict_line_breaks setting controls whether Syntagmax transforms single newlines into Markdown hard breaks ( \n) during extraction.
[drivers.obsidian]
strict_line_breaks = "off" # Apply Obsidian-style relaxed line breaks
Set to "auto" to read the setting from your vault's .obsidian/app.json (requires integration = true):
[drivers.obsidian]
integration = true
strict_line_breaks = "auto"
For full details, see the configuration reference.
Tracing Export
Syntagmax can export artifact traceability relationships as CSV or TSV matrices. The export uses left outer join semantics — every lead artifact appears even if it has no links to the target type.
syntagmax trace [OPTIONS]
Options
| Option | Required | Default | Description |
|---|---|---|---|
--child <type> |
Yes | — | Artifact type of the child (e.g., REQ) |
--parent <type> |
Yes | — | Artifact type of the parent (e.g., SYS) |
--forward / --reverse |
No | --forward |
Direction: forward (child→parent) or reverse (parent→child) |
--attribute <name> |
No | — | Additional lead artifact attributes to include (repeatable) |
--flat |
No | — | Combine multiple linked IDs into semicolon-separated values |
--delimiter <char> |
No | , |
Column delimiter (auto-detects \t for .tsv output) |
--output <path> |
No | <output_path>/trace/trace-<child>-<parent>-<date>.csv |
Output path (use console for stdout) |
Plugin-Based Export
Trace export can be delegated to plugins via the [trace] config section:
[trace]
plugins = ["tsv-export"]
When trace.plugins is non-empty, all listed plugins run sequentially — each receives the same trace matrix. When the list is empty (or the [trace] section is absent), the built-in CSV/TSV writer is used.
Each plugin listed must be declared in a [[plugin]] block and implement the export_trace hook. See docs/reference/plugins.md for the full plugin API.
Forward vs Reverse
- Forward (default): Lead artifacts are children. Each row shows a child ID and its linked parent ID(s).
- Reverse: Lead artifacts are parents. Each row shows a parent ID and its linked child ID(s).
Left Outer Join
All lead artifacts appear in the output even if they have no links to the target type. Unlinked artifacts have an empty linked ID column, making it easy to spot coverage gaps.
Flat Mode
Without --flat, a child with multiple parents produces one row per link. With --flat, all linked IDs are combined into a single semicolon-separated cell.
Examples
# Forward matrix (REQ → SYS) as CSV
syntagmax trace --child REQ --parent SYS
# Reverse matrix with attributes
syntagmax trace --child REQ --parent SYS --reverse --attribute title
# Flat mode, TSV output
syntagmax trace --child REQ --parent SYS --flat --output .syntagmax/outputs/trace.tsv
# Export to stdout
syntagmax trace --child REQ --parent SYS --output console
Plugins
Syntagmax supports a plugin system that allows custom transformations during the publish pipeline. Plugins are distributed separately from the core project — either as local Python files or as installable packages.
Plugins are declared in config.toml via [[plugin]] blocks and can implement hooks for:
transform_blocks— modify the block tree before renderingtransform_markdown— transform rendered markdown before writingfilter_block— per-block pre-publishing filter (activated via--pre-filter)export_trace— custom tracing export format (activated via[trace] pluginsconfig)
[[plugin]]
name = "add-header"
source = "local"
enabled = true
[plugin.params]
title = "My Document"
For the full plugin API, configuration options, local/package plugin setup, and working examples, see docs/reference/plugins.md.
Change Reports
Syntagmax can generate change reports comparing artifacts between two Git revisions. Reports analyze changes at the artifact level (added, modified, removed requirements) with field-level detail.
Basic Usage
# Compare last commit against current HEAD
syntagmax change report --base HEAD~1 --target HEAD
# Compare two tags
syntagmax change report --base v1.2.0 --target v1.3.0
# Compare branches
syntagmax change report --base release --target develop
Options
| Option | Default | Description |
|---|---|---|
--base |
(required) | Base Git revision (commit, tag, branch, HEAD, HEAD~N) |
--target |
(required) | Target Git revision |
--output |
.syntagmax/outputs/change/ |
Output directory or console for stdout |
--include-non-artifact |
off | Include non-artifact text block changes |
--single |
off | Generate a single consolidated report |
--summary |
off | Generate abbreviated summary report (no content) |
Supported Revisions
- Commit hash (full or short)
- Tag name
- Branch name
HEAD,HEAD~Nworking— compare against uncommitted changes in the working directory
Output
Reports are generated per input record with filenames:
<section>-<base_rev>-to-<target_rev>-<YYYYMMDD>.md
Use --single to generate one consolidated report across all records.
Use --output console to print to stdout.
Use --summary to generate an abbreviated report showing only file paths, changed object IDs, and text fragment locations — no content or attribute diffs are included. Summary reports use the filename suffix -summary (e.g. <section>-...-summary.md).
# Quick overview of changes between tags
syntagmax change report --summary --base v1.2.0 --target v1.3.0
Prerequisites
- Git version >= 2.5 (required for worktree support)
.syntagmax/worktrees/must be listed in.gitignore
Example Report Structure
# Change Report
## Repository Information
## Summary
## Changed Files (table: Filename | Status | Objects changed)
## Detailed Changes
### Artifacts (grouped by file)
### Text fragments (grouped by file)
### Binary Artifacts (grouped by file)
### Extraction Errors
The report includes:
- Summary statistics (files changed, artifacts added/modified/removed)
- Changed files as a table listing affected object IDs and their statuses
- For each modified artifact: text changes rendered as blockquoted markdown and attribute change tables
- For sidecar-managed binary artifacts (images, diagrams): SHA-256 hash comparison, file size, and pixel dimensions (requires optional
Pillowdependency) - Fallback plain-text diffs when artifact extraction fails
Baselining
The change baseline command creates a consistent annotated git tag across all repositories that input records point to. This is useful for marking baseline snapshots in multi-repo requirement projects.
# Create a baseline tag
syntagmax change baseline v1.0.0
# With a custom annotation message
syntagmax change baseline v1.0.0 -m "Release 1.0.0 baseline"
# Preview without creating tags
syntagmax change baseline v1.0.0 --dry-run
# Overwrite existing tags
syntagmax change baseline v1.0.0 --force
Options
| Option | Default | Description |
|---|---|---|
-m, --message |
Baseline created by Syntagmax |
Tag annotation message |
--force |
off | Overwrite existing tags |
--dry-run |
off | Preview actions without creating tags |
Behaviour
- Discovers all distinct git repositories from input records
- Refuses to proceed if any repo has uncommitted or untracked changes
- Creates annotated tags at HEAD in each repo
- Validates tag name against optional
tag_patternregex (see configuration) - Atomic: if tagging fails in any repo, already-created tags are rolled back
- Prints a push reminder after successful tagging
Configuration
Optionally restrict tag names with a regex pattern in config.toml:
[baseline]
tag_pattern = "^v\\d+\\.\\d+\\.\\d+$"
Localization
Syntagmax supports localized report output.
Configuration
Set the output language in your config.toml:
language = "code"
Or use the global CLI flag (overrides the config file):
syntagmax --lang ru analyze
syntagmax --lang ru change report --base HEAD~1 --target HEAD
Resolution Order
- CLI
--langflag (highest priority) - Project
config.tomllanguagefield - Global
~/.config/syntagmax/config.tomllanguagefield - Default:
en
Scope
Localization applies to:
- Analysis reports (metrics, impact, errors)
- Change reports (full and summary)
It does not apply to:
publishcommand output (renders user content as-is)- MCP server responses (remain English for LLM compatibility)
Log Level Control
Syntagmax provides a unified --log CLI option to control console log verbosity.
Available Levels
| Level | Description |
|---|---|
debug |
Verbose output including internal diagnostics |
info |
Standard operational messages (default) |
warning |
Warnings and errors only |
error |
Errors only |
silent |
Suppress all console output |
Usage
# Run with debug logging
syntagmax --log debug analyze
# Suppress warnings
syntagmax --log error analyze
# Treat warnings as fatal errors
syntagmax --warnings-as-errors analyze
Configuration
Log level and warnings behaviour can be set in config.toml:
log_level = "info"
warnings_as_errors = false
Resolution Order
- CLI
--logflag (highest priority) - Project
config.tomllog_levelfield - Global config
log_levelfield - Default:
info
Global Configuration
The global configuration file is located at:
$SYNTAGMAX_HOME/config.toml(ifSYNTAGMAX_HOMEis set)~/.config/syntagmax/config.toml(default)
Set SYNTAGMAX_HOME to override the default global configuration directory.
AI Commands
Syntagmax integrates with local CLI AI coding agents to automate verification tasks. All AI commands are grouped under syntagmax ai.
⚠️ Unrestricted Agent Execution: Syntagmax invokes AI agents with full file system and shell access — the same permissions as the current user. The agent is NOT sandboxed. Always review changes with
git diffbefore committing.
Verify Impact Task
Use an AI agent to verify whether an impact task has been addressed:
syntagmax ai verify .syntagmax/tasks/TASK-IMPACT-REQ-003-SYS-003.md
The agent reads the parent and child artifacts, assesses consistency, and updates the task file with a verification report. The prompt includes explicit repository root paths and file paths relative to those roots, enabling the agent to locate artifacts immediately without searching. The report contains the following sections:
- Parent Changes — summarises what changed in the parent artifact since the link was established.
- Child Changes — summarises what changed in the child artifact.
- Change Mapping — maps each parent change to the corresponding child update (or notes gaps).
- Rationale — the agent's overall assessment of whether the child still satisfies the parent.
For the full report format, see docs/reference/ai.md.
Options
| Option | Default | Description |
|---|---|---|
--agent <name> |
Config default (kiro) |
Override the default agent |
Configuration
[ai]
agent = "kiro"
persona = "You are a systems engineer reviewing requirements traceability."
Supported Agents
Kiro CLI, Claude Code, Codex, Copilot, OpenCode, Antigravity, and Mistral Vibe are supported out of the box. Custom agents can be added via a YAML registry file. Agents that require a .cmd or .ps1 wrapper on Windows are resolved automatically via shutil.which() (see docs/reference/ai.md).
For the full AI commands reference, agent registry format, and prompt customisation, see docs/reference/ai.md.
Required Improvements
- Implement automatic change propagation
MCP Server
Syntagmax includes a Model Context Protocol (MCP) server that allows LLMs to interact with your requirements directly.
Tools
list_artifacts: Returns a list of all artifacts in the system.search_artifacts: Search for requirements by keyword.get_artifact_content: Fetch full details of a specific requirement (including traceability).
Running the Server
To start the server using Server-Sent Events (SSE):
syntagmax mcp run --transport sse --port 8000
Sample Configuration
To use Syntagmax with an MCP client that supports SSE, point it to the server's endpoint:
{
"mcpServers": {
"syntagmax": {
"url": "http://127.0.0.1:8000/sse"
}
}
}
Note: When running via SSE, the server must be started manually or managed by a process manager before the client connects.
Release files for syntagmax 2026.9.16
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| syntagmax-2026.9.16.tar.gz | 3.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| syntagmax-2026.9.16-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:3.2 MB
Release files / syntagmax-2026.9.16.tar.gz
| Download URL | syntagmax-2026.9.16.tar.gz |
|---|---|
| Size | 3.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
885f3658d6ce92583000c20af61c13b001d453005d7f5314a5a0d3e3bf6bb925
|
|
BLAKE2b-256 checksum How to use checksums |
c0d9d8da74351c2a0d1ab7df74d1db8cfbc96ebaa152a2cbceb3ee3152ecfb6d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / syntagmax-2026.9.16-py3-none-any.whl
| Download URL | syntagmax-2026.9.16-py3-none-any.whl |
|---|---|
| Size | 227.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c79667a77e1d42d8cb4ad560eb730754d6bffcfb26ab5d2b46c6f5a66475b942
|
|
BLAKE2b-256 checksum How to use checksums |
d10730d9e8cfb88d42f27fa35884075a4c7cc72549842b53c3ae2b4068299e8a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log