Reference Python implementation and tooling baseline for ICSD.
Project description
ICSD Python Tooling
Reference Python implementation for Invariant-Closed System Design (ICSD). This repository provides:
- Core primitives for invariant validation, transitions, and deterministic evidence.
- A CI-friendly CLI with stable non-zero exit semantics.
- A workstream-based collaboration model for concurrent contributors.
Status
As of 2026-03-04, v1.0.0 includes implemented core modules and CLI commands:
icsd-dpa verify <evidence.json>icsd-dpa lint <path>icsd-dpa lintprofile selection and JSON output for CI/audit pipelines.- Versioned invariant policy profiles selectable by profile name.
- Authority-source metadata and transition-time authority validation hooks.
- Transparency-log adapter hooks for append/verify workflows.
The package-level public API remains intentionally narrow at the v1.0.0 boundary.
See Stability Policy before depending on import paths.
Install
Published package identity:
- Distribution name:
dpa-icsd - Import module:
icsd - CLI entry point:
icsd-dpa
Install from PyPI:
python -m pip install dpa-icsd
Install from local source (development):
python -m pip install -e ".[dev]"
v1.0.0 Migration Guide (from v0.x prerelease)
- Upgrade or pin to the stable release:
python -m pip install --upgrade dpa-icsd==1.0.0
- Use
icsd-dpaas the CLI entry point in scripts/CI (verify,lint, and exit codes0/1/2are stable acrossv1.x). - Keep package-root usage minimal (
icsd.__version__); import runtime primitives fromicsd.coreand CLI internals fromicsd.cli. - Compatibility retained in
v1.0.0: evidence schema0.1and lint profile namepolicy-v0.1. - Breaking-change policy: documented public-contract breaks require a major
release (
2.0.0).
Domain-Neutral Examples
Runnable non-finance examples live in examples/:
- legal case lifecycle with statutory policy cutover and authority-backed audit trail
- construction tolerance gating with inspection authority checks and evidence-level inspector/measurement provenance
- schema contract evolution with migration and temporal policy cutover
- supply-chain provenance with cold-chain custody continuity, per-hop provenance receipts, and out-of-range rejection
- IAM access governance with least privilege, approval evidence enforcement, and trustless authority-proposal refusal
- healthcare/lab sample custody with calibration-window policy cutover and release-authority gating
- safety-critical robotics leash flow with agent-constrained execution and emergency-stop override
- agent guardrails workflow with deterministic refusal reporting for unsafe autonomous actions
- event-pipeline schema governance with v1->v2 cutover, migration/quarantine, and stream-event emission
- D&D rules cutover demo with temporal profile provenance (
Standardtier) - trustless D&D dice-plugin proposal refusal demo (
Standardtier) - lite examples pack for minimal adoption (
invariants + transition + one rejection) - fun D&D lite examples for combat and character-sheet invariant learning
Run from repository root:
python examples/legal_case_lifecycle.py
python examples/construction_tolerance_gate.py
python examples/schema_evolution_contracts.py
python examples/supply_chain_provenance.py
python examples/iam_access_governance.py
python examples/lab_sample_workflow.py
python examples/robotics_safety_leash.py
python examples/agent_guardrails.py
python examples/event_pipeline_schema_governance.py
python examples/dnd_rules_cutover_standard.py
python examples/dnd_trustless_dice_proposal.py
python examples/lite_supply_chain_temperature_gate.py
python examples/lite_legal_case_required_fields.py
python examples/lite_construction_tolerance.py
python examples/lite_schema_contracts.py
python examples/dnd_combat_lite.py
python examples/dnd_character_sheet_lite.py
Each script emits JSON artifacts under examples/out/ (gitignored).
Learning ICSD via Toy Domains
ICSD is not limited to compliance-heavy systems. To learn the invariant and refusal model quickly, start with toy game-state examples first:
python examples/dnd_combat_lite.pypython examples/dnd_character_sheet_lite.py
Then move to regulated-system examples and their conformance suites in docs/domains.md (legal, construction, schema governance, supply chain, IAM, healthcare, robotics, and event pipelines).
Regulated Systems Guides
High-signal docs for domain mapping and rollout:
- docs/domains.md: domain index mapping invariants, evidence/provenance sources, and policy-cutover patterns to runnable examples.
- docs/adoption_ladder.md: progressive adoption tiers
(
Lite -> Standard -> Full) with feature-to-tier mapping and concrete exit criteria. - docs/ai_agents.md: AI-agent guardrail integration workflow
(
proposal -> context -> transition -> evidence/refusal) with refusal handling and anti-pattern guidance. - docs/fastapi_integration.md: docs-only wrapper pattern for request schema validation, authority proposal ingestion, and deterministic evidence/refusal API responses.
- docs/adoption_metrics.md: manual-first PyPI download
snapshot workflow via pypistats (
dpa-icsd, daily/weekly/monthly counts).
Conformance Scenario Tests
Narrative non-finance conformance suites live in tests/:
tests/test_conformance_runner.pytests/test_conformance_legal.pytests/test_conformance_construction.pytests/test_conformance_schema.pytests/test_conformance_supply_chain.pytests/test_conformance_iam.pytests/test_conformance_lab.pytests/test_conformance_robotics.pytests/test_conformance_agent_guardrails.pytests/test_conformance_event_pipeline.pytests/test_conformance_dnd.py
These scenarios intentionally validate ICSD behaviour claims without asserting formal standards compliance:
- valid-by-construction state setup via
InvariantSet.construct_state(...) - transition application via
Transition.apply_with_context(...)orAgentExecutionContext - deterministic evidence integrity + provenance verification
- explicit rejection of invalid/unrepresentable transitions
Run only the conformance suites:
pytest -q tests/test_conformance_legal.py tests/test_conformance_construction.py tests/test_conformance_schema.py tests/test_conformance_supply_chain.py tests/test_conformance_iam.py tests/test_conformance_lab.py tests/test_conformance_robotics.py tests/test_conformance_agent_guardrails.py tests/test_conformance_event_pipeline.py tests/test_conformance_dnd.py
Single-entry umbrella conformance run:
pytest -q tests/test_conformance_runner.py
Import Policy (v1.x)
- Package root import contract remains intentionally narrow in v1.x:
icsd.__version__. - Prefer deep imports for runtime primitives in v1.x, for example:
from icsd.core import EvidenceBundle. - Do not assume
from icsd import EvidenceBundleis part of the stable root-import contract.
PyPI Name Decision and Claim Checklist
Name decision (WS-0022, checked on 2026-03-03):
- Keep distribution name as
dpa-icsdfor first publish. - Keep import module as
icsdand CLI command asicsd-dpa. - Treat the distribution name as sticky after first successful PyPI upload.
Availability check references:
https://pypi.org/pypi/icsd/jsonreturns200(name already occupied).https://pypi.org/pypi/dpa-icsd/jsonreturns404(name available at check time).
Pre-release namespace checklist:
- Re-run the JSON endpoint check immediately before creating a release tag.
- If
dpa-icsdreturns200before first publish, stop the release and open a new workstream to select and apply a new distribution name. - After first successful publish, do not rename the distribution.
Baseline validation:
python -c "import icsd; print(icsd.__version__)"
icsd-dpa --version
ruff format --check .
ruff check .
pytest -q
Deterministic CI/local parity validation:
python -m pip install -e ".[dev]"
python -m pip check
python -m ruff format --check .
python -m ruff check .
python -c "from pathlib import Path; Path('.ci_tmp').mkdir(exist_ok=True)"
python -m pytest --basetemp .ci_tmp/pytest
Release Rehearsal (TestPyPI Readiness)
This project keeps release verification manual-first for the v1.0.0 release flow.
For a local one-command rehearsal (without upload), run scripts/release_check.sh.
- Install release tooling.
python -m pip install --upgrade build twine
- Build source and wheel distributions.
python -m build
- Validate built metadata before upload.
python -m twine check dist/*
- Smoke-test install from the built wheel in an isolated virtual environment.
python -m venv .rehearsal-venv
.rehearsal-venv/bin/python -m pip install --upgrade pip
.rehearsal-venv/bin/python -m pip install --force-reinstall dist/dpa_icsd-*.whl
.rehearsal-venv/bin/icsd-dpa --version
.rehearsal-venv/bin/python -c "import icsd; print(icsd.__version__)"
PowerShell equivalent:
$PY = ".\.rehearsal-venv\Scripts\python.exe"
& $PY -m pip install --upgrade pip
& $PY -m pip install --force-reinstall dist\dpa_icsd-*.whl
& ".\.rehearsal-venv\Scripts\icsd-dpa.exe" --version
& $PY -c "import icsd; print(icsd.__version__)"
- Upload rehearsal artifacts to TestPyPI.
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="<testpypi-token>"
python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
PowerShell equivalent:
$env:TWINE_USERNAME = "__token__"
$env:TWINE_PASSWORD = "<testpypi-token>"
python -m twine upload --repository-url https://test.pypi.org/legacy/ dist/*
- Verify installation from TestPyPI.
python -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple dpa-icsd==1.0.0
icsd-dpa --version
Release Automation (Gitea Tags)
Release publishing is separated from normal CI:
- CI workflow:
.gitea/workflows/ci.yml(branches/PRs only). - Release workflow:
.gitea/workflows/release.yml(tag pushv*and manualworkflow_dispatch).
Release workflow stages:
- Build distributions and run
twine check. - Publish artifacts to TestPyPI.
- Install from TestPyPI and smoke-test
icsd-dpa. - Publish the same validated artifacts to PyPI (
publishmode only).
Dry-run gate (no PyPI publish):
- Trigger
Release Publishmanually (workflow_dispatch) withrelease_mode=dry-run(default). - Optional input
tag_namecan be set to a target release tag (vX.Y.Z). - If
tag_nameis omitted in dry-run mode, the workflow derivesv<package_version>fromsrc/icsd/_version.py. - Dry-run mode still executes build, TestPyPI publish, and TestPyPI install verification.
- Dry-run mode skips the
publish-pypijob, so no live PyPI upload occurs.
Tagging rule:
- Create tags matching package version with a
vprefix, for examplev1.0.0. - The release workflow validates that
tag[1:] == icsd._version.__version__before any publish flow. - Release workflow tag resolution prefers
GITEA_REF_NAME, falls back toGITHUB_REF_NAME, then falls back to parsingGITEA_REF/GITHUB_REF, thenworkflow_dispatchinputtag_name. - In manual
publishmode, a release tag (ortag_name) is required; indry-runmode, missing tag input is auto-derived from package version.
Required Gitea secrets:
TESTPYPI_API_TOKEN: API token for TestPyPI (__token__user).PYPI_API_TOKEN: API token for PyPI (__token__user, required only forpublishmode).
CLI Quick Reference
icsd-dpa --version
icsd-dpa verify <evidence.json>
icsd-dpa lint <path>
icsd-dpa lint <path> --profile policy-v0.1 --format json
Exit codes:
0: success / no findings1: lint findings2: tool error (invalid args, unreadable file, invalid JSON, schema/integrity failure)
Lint Profiles and Output
baseline(default): Python/JSON syntax checks only.policy-v0.1: Adds stricter structural checks:- Blocks dynamic execution calls (
eval,exec) in Python sources. - Requires JSON root objects and validates evidence-shaped JSON payloads.
- Profile name retains the
v0.1suffix for backward compatibility in v1.x.
- Blocks dynamic execution calls (
--format text(default): human-readable stderr findings.--format json: machine-readable report on stdout with profile, status, exit code, and findings.
Python Example: Invariants
from icsd.core.errors import InvariantFailure
from icsd.core.invariants import Invariant, InvariantSet
def owner_required(state: dict[str, str]) -> bool | InvariantFailure:
owner = state.get("owner", "").strip()
if owner:
return True
return InvariantFailure(
invariant="owner_required",
code="missing_owner",
message="Owner must be set before transition execution.",
)
invariants = InvariantSet(
[
Invariant(name="status_known", check=lambda s: s.get("status") in {"draft", "approved"}),
Invariant(name="owner_required", check=owner_required),
]
)
failures = invariants.validate({"status": "draft", "owner": ""})
assert len(failures) == 1
Python Example: Invariant-Safe Construction Helpers
from icsd.core.evidence import AuthoritySource
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
invariants = InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
)
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 20}),
invariants=invariants,
authority_validator=Transition.require_authority_sources(minimum=1),
)
# State objects are copied and validated before use.
safe_state = invariants.construct_state({"balance": 100})
# Authority/profile checks can be validated before apply-time.
context = transition.build_context(
authority="policy/account-debit",
authority_sources=[
AuthoritySource(
source_type="registry",
source_id="uk-companies-house",
reference="company/00000006",
)
],
)
result = transition.apply_with_context(
state=safe_state,
entity_type="account",
entity_id="acct-001",
actor="user:ops",
context=context,
)
Python Example: Legacy Migration and Quarantine
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.migration import migrate_legacy_states
invariants = InvariantSet(
[
Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0),
Invariant(name="owner_required", check=lambda state: bool(state["owner"].strip())),
]
)
def repair_legacy(state: dict[str, object]) -> None:
if isinstance(state.get("balance"), int) and state["balance"] < 0:
state["balance"] = 0
if isinstance(state.get("owner"), str) and not state["owner"].strip():
state["owner"] = "migrated-owner"
report = migrate_legacy_states(
[{"balance": -10, "owner": ""}, {"balance": 50, "owner": "ops"}],
invariants=invariants,
transform=repair_legacy,
)
assert report.migrated_count == 2
assert report.quarantined_count == 0
Python Example: Versioned Invariant Profiles
from icsd.core.invariants import (
Invariant,
InvariantProfile,
InvariantProfileRegistry,
InvariantSet,
)
from icsd.core.transition import Transition
registry = InvariantProfileRegistry(
[
InvariantProfile(
name="uk-payroll",
policy="policy/payroll-tax",
policy_version="2026.03",
invariants=InvariantSet(
[Invariant(name="non_negative_pay", check=lambda state: state["pay"] >= 0)]
),
)
]
)
transition = Transition(
name="apply_payroll_adjustment",
mutate=lambda state: state.update({"pay": state["pay"] - 20}),
profile_registry=registry,
default_profile="uk-payroll",
)
result = transition.apply(
state={"pay": 100},
entity_type="payroll_record",
entity_id="pay-001",
actor="user:ops",
policy_version="2026.03",
)
assert result.after_state == {"pay": 80}
assert result.evidence.authority == "policy/payroll-tax@2026.03"
Python Example: Temporal Policy Activation and Cutover
from icsd.core.invariants import Invariant, InvariantProfile, InvariantProfileRegistry, InvariantSet
from icsd.core.transition import Transition
registry = InvariantProfileRegistry(
[
InvariantProfile(
name="uk-payroll",
policy="policy/payroll-tax",
policy_version="2026.03",
active_from="2026-01-01T00:00:00Z",
active_until="2026-06-01T00:00:00Z",
invariants=InvariantSet(
[Invariant(name="non_negative_pay", check=lambda state: state["pay"] >= 0)]
),
),
InvariantProfile(
name="uk-payroll",
policy="policy/payroll-tax",
policy_version="2026.06",
active_from="2026-06-01T00:00:00Z",
invariants=InvariantSet(
[Invariant(name="non_negative_pay", check=lambda state: state["pay"] >= 0)]
),
),
]
)
transition = Transition(
name="apply_payroll_adjustment",
mutate=lambda state: state.update({"pay": state["pay"] - 20}),
profile_registry=registry,
default_profile="uk-payroll",
)
before_cutover = transition.apply(
state={"pay": 100},
entity_type="payroll_record",
entity_id="pay-001",
actor="user:ops",
timestamp="2026-05-31T23:59:59Z",
)
after_cutover = transition.apply(
state={"pay": 100},
entity_type="payroll_record",
entity_id="pay-001",
actor="user:ops",
timestamp="2026-06-01T00:00:00Z",
)
assert before_cutover.evidence.authority == "policy/payroll-tax@2026.03"
assert after_cutover.evidence.authority == "policy/payroll-tax@2026.06"
Python Example: Transition and Evidence
from datetime import datetime, timezone
from icsd.core.evidence import AuthoritySource
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
invariants = InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
)
def debit(state: dict[str, int]) -> None:
state["balance"] -= 20
transition = Transition(name="debit_account", mutate=debit, invariants=invariants)
result = transition.apply(
state={"balance": 100},
entity_type="account",
entity_id="acct-001",
actor="user:ops",
authority="policy/account-debit",
authority_sources=[
AuthoritySource(
source_type="registry",
source_id="uk-companies-house",
reference="company/00000006",
)
],
transition_id="11111111-1111-4111-8111-111111111111",
timestamp=datetime(2026, 3, 3, 10, 0, tzinfo=timezone.utc),
)
assert result.before_state == {"balance": 100}
assert result.after_state == {"balance": 80}
assert result.evidence.verify_integrity(
before_state=result.before_state,
after_state=result.after_state,
)
Python Example: Minimal Transition Helper
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
transition = Transition.simple(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 20}),
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
)
Transition.simple(...) is constructor sugar for direct-invariant transitions.
It does not bypass invariant checks or authority validation hooks.
Python Example: Authority Validation Hook
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 20}),
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
authority_validator=Transition.require_authority_sources(minimum=1),
)
Python Example: Authority Adapter (Trustless Proposal Verification)
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
class ExternalAuthorityAdapter:
def propose(self, *, current_state, authority_response):
# External responses are proposal inputs, not direct truth.
return {
"changes": {
"balance": authority_response["approved_balance"],
},
"source": "authority-api",
"reference": authority_response["response_id"],
}
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 5}),
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
authority_adapter=ExternalAuthorityAdapter(),
)
result = transition.apply(
state={"balance": 100},
entity_type="account",
entity_id="acct-001",
actor="user:ops",
authority="policy/account-debit",
authority_response={"approved_balance": 60, "response_id": "resp-001"},
)
assert result.after_state == {"balance": 95}
For a deterministic refusal-report pattern when an adapter proposes impossible
state, see tests/test_trustless_authority_refusal.py.
Python Example: Schema Contract Adapters (JSON Schema + Pydantic)
from pydantic import BaseModel, Field
from icsd.adapters import JsonSchemaInvariant, PydanticModelInvariant
from icsd.core.invariants import Invariant, InvariantSet
json_contract = JsonSchemaInvariant(
schema={
"type": "object",
"required": ["status", "count"],
"properties": {
"status": {"type": "string", "enum": ["draft", "review", "approved"]},
"count": {"type": "integer", "minimum": 0},
},
"additionalProperties": False,
}
)
class ContractModel(BaseModel):
status: str = Field(min_length=1)
count: int = Field(ge=0)
pydantic_contract = PydanticModelInvariant(model=ContractModel)
invariants = InvariantSet(
[
Invariant(name="json_contract", check=json_contract),
Invariant(name="pydantic_contract", check=pydantic_contract),
]
)
invariants.assert_valid({"status": "review", "count": 2})
JsonSchemaInvariant uses jsonschema when installed and falls back to a deterministic
subset validator (type, required, properties, additionalProperties, enum,
const, length/number bounds, and array item checks) when it is not.
PydanticModelInvariant requires optional pydantic to be installed.
Python Example: Agent-Constrained Execution Context
from icsd.core.context import AgentExecutionContext, AgentPolicyEnforcement
from icsd.core.invariants import Invariant, InvariantProfile, InvariantProfileRegistry, InvariantSet
from icsd.core.transition import Transition
registry = InvariantProfileRegistry(
[
InvariantProfile(
name="retail-banking",
policy="policy/account-debit",
policy_version="2026.03",
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
)
]
)
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 5}),
profile_registry=registry,
)
agent_context = AgentExecutionContext(
transition,
enforcement=AgentPolicyEnforcement(
require_profile=True,
require_policy_version=True,
minimum_authority_sources=1,
),
)
result = agent_context.apply(
state={"balance": 100},
entity_type="account",
entity_id="acct-001",
actor="user:ops",
profile="retail-banking",
policy_version="2026.03",
authority_sources=[
{
"source_type": "registry",
"source_id": "uk-companies-house",
"reference": "company/00000006",
}
],
)
assert result.after_state == {"balance": 95}
Python Example: Transparency Log Adapter
from icsd.adapters import TransparencyLogReceipt, TransparencyVerification
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
class MemoryLogAdapter:
def append(self, *, evidence_payload):
return TransparencyLogReceipt(adapter="memory-log", reference="entry/1")
def verify(self, *, evidence_payload, receipt=None):
return TransparencyVerification(verified=True, checkpoint="checkpoint-1")
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 20}),
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
transparency_log=MemoryLogAdapter(),
verify_transparency_after_append=True,
)
Python Example: Real-time Evidence Stream Adapter
from icsd.adapters.transparency_stream import TransparencyStreamReceipt
from icsd.core.invariants import Invariant, InvariantSet
from icsd.core.transition import Transition
class AuditorFeedAdapter:
def emit(self, *, event_payload):
# event_payload includes evidence, signable_hash, and transition metadata.
return TransparencyStreamReceipt(
adapter="auditor-feed",
event_id=f"evt/{event_payload['transition_id']}",
)
transition = Transition(
name="debit_account",
mutate=lambda state: state.update({"balance": state["balance"] - 20}),
invariants=InvariantSet(
[Invariant(name="non_negative_balance", check=lambda state: state["balance"] >= 0)]
),
transparency_stream=AuditorFeedAdapter(),
)
Invisible Compliance Layer Guides
Deployment-oriented guidance for evidence-stream and auditor workflows:
- docs/transparency_feed.md
- docs/auditor_subscribe.md
- docs/domains.md
- docs/adoption_ladder.md
- docs/fastapi_integration.md
- docs/whitepaper_integration.md
Operational pattern:
- A transition emits deterministic evidence and a stream event payload.
- A stream adapter publishes the event payload to subscriber infrastructure.
- A transparency-log adapter stores/returns inclusion receipts for later checks.
- Auditors subscribe to the feed and verify evidence locally.
Concrete CLI walkthrough:
python examples/legal_case_lifecycle.py
icsd-dpa verify examples/out/legal_case_04_appealed.evidence.json
Whitepaper Integration (Non-Normative)
For whitepaper usage, see docs/whitepaper_integration.md for a ready-to-use "Reference Implementation and Conformance Testing" section and claim-to-test/example mapping.
The package is a reference implementation only; it does not define the ICSD normative specification.
Evidence Payload Shape (Schema v0.1, Supported in v1.x)
icsd-dpa verify validates the required evidence fields and hash format.
{
"schema_version": "0.1",
"transition_id": "11111111-1111-4111-8111-111111111111",
"entity_type": "account",
"entity_id": "acct-001",
"actor": "user:ops",
"authority": "policy/account-debit",
"authority_sources": [
{
"source_type": "registry",
"source_id": "uk-companies-house",
"reference": "company/00000006"
}
],
"timestamp": "2026-03-03T10:00:00Z",
"before_hash": "d2ec8f050e788f96279be8f1a1d7e56ce3f180ebea047a1bf6f019f06f5f0a18",
"after_hash": "55459e863d1c8fcdaff7ac18549f96db4495ea3a74c4d659e410cd554d65ff43"
}
Philosophy Linkouts
- ORIGINAL_DIRECTION.md: v0.1 blueprint and design intent.
- AGENTS.md: contributor rules and commit requirements.
- WORKSTREAMS.md: reservation ledger and execution tracking.
- CHANGELOG.md: release notes and update discipline.
Stability Policy (v1.x)
1.xreleases follow semantic versioning: breaking changes to documented public contracts require a2.0.0release.- Package root API guarantee in v1.x remains intentionally narrow:
icsd.__version__. icsd.core.*andicsd.cli.*are supported import paths in v1.x; incompatible changes require a major-version bump.- CLI command surface (
icsd-dpa --version,verify,lint) and exit-code semantics (0,1,2) are stable for v1.x automation. - Evidence schema
0.1and lint profilepolicy-v0.1remain supported in v1.x for compatibility. - Breaking behavior changes should be labelled
Kind/Breakingin issue/commit metadata.
Changelog Discipline
- Add all user-visible changes to the
[Unreleased]section inCHANGELOG.md. - Use categories (
Added,Changed,Fixed,Removed,Security) consistently. - Keep entries concrete, short, and scoped to behavior, API, or operational impact.
Repository Layout
icsd-python/
AGENTS.md
WORKSTREAMS.md
README.md
CHANGELOG.md
pyproject.toml
ruff.toml
src/icsd/
tests/
Credits
- Framework: https://datatracker.ietf.org/doc/draft-dpa-icsd/
- Author: Benjamin Anthony Fisher
License
Apache-2.0. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dpa_icsd-1.0.7.tar.gz.
File metadata
- Download URL: dpa_icsd-1.0.7.tar.gz
- Upload date:
- Size: 76.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb763d86bdf9ff94d3672bd768894bd73ad2223b973740d5e530a8122b3ae471
|
|
| MD5 |
5ca94e6ff2170d6933ae371afa0fe77a
|
|
| BLAKE2b-256 |
72a32af7015e5754b7bae065c899833eb14542e17614a96984dcd8a4abc2a5de
|
File details
Details for the file dpa_icsd-1.0.7-py3-none-any.whl.
File metadata
- Download URL: dpa_icsd-1.0.7-py3-none-any.whl
- Upload date:
- Size: 44.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b003632753ba505b0d6b1298a9b24c173cb5dd61e06d79a64cc8702c6d5a8d5a
|
|
| MD5 |
059ec8f9922e44aebd00fa7cc7db47d8
|
|
| BLAKE2b-256 |
42d4bf5dbee1ce0ad068767977268b084beed96b8808ab97468fdee4c54d866b
|