Skip to main content

Auditable text-only preparation and restoration for controlled file transfers

Project description

Controlled Text Transfer 0.1.0

Controlled Text Transfer (ctt) prepares an allowlisted set of text files for a controlled transfer that accepts only .txt names. It appends .txt, preserves content and paths in a signed-ready JSON manifest, adds an optional UTF-8 BOM only to transfer copies, and restores byte-identical originals. Python 3.12 or newer is required.

For the shortest path to running the application, see README-quickstart.md.

Documentation

Repository Map

GitHub automation

GitHub-specific automation enforces the same build, test, security, and release requirements documented for local development. It uses least-privilege permissions, immutable action references, and locked Python dependencies.

Quick start

python -m pip install .
ctt prepare ./source ./transfer --policy ctt.yaml
ctt preflight ./source --policy ctt.yaml --json
ctt verify ./transfer
ctt restore ./transfer ./restored
ctt diff ./transfer ./source --json

Commands

Command Purpose
uv run ctt preflight SOURCE --json Produce a read-only compatibility report
uv run ctt prepare SOURCE TRANSFER --strict Build only when every candidate passes
uv run ctt verify TRANSFER Verify a directory or supported archive
uv run ctt restore TRANSFER DESTINATION Restore verified original files
uv run --extra dev pytest Install missing development tools and run all tests
bash scripts/run.sh check Run the complete local quality gate
bash scripts/run.sh report Generate browsable API, coverage, quality, and security reports

Use --dry-run with prepare or restore to inspect the operation without writing. Use --log-json for machine-readable audit events. Directory format publishes the requested directory; zip, tar, and tar.gz publish only the corresponding archive.

Use prepare --strict --json-report preflight.json to publish nothing when a candidate is rejected while retaining a deterministic compatibility report. Verification and restoration accept canonical directories and generated archives directly. Directory verification rejects linked package or payload paths, and restoration publishes only after its staged output validates.

diff is read-only and reports added, removed, modified, and unchanged allowlisted files when compared with the source directory.

Architecture

The package keeps transformation, integrity verification, packaging, signing hooks, and CLI concerns small and separable. The core uses a policy-driven allowlist and a versioned manifest; archive creation is optional; signing is delegated to externally managed key infrastructure. See ADR-001 through ADR-012 for the rationale and rejected alternatives.

Policy and detection

The default policy uses an explicit extension/name allowlist, UTF-8 decoding, a 10 MiB per-file limit, and SHA-256. Files that are binary, undecodable, ignored by .cttignore, oversized, or not allowlisted are reported in the manifest and never copied. .cttignore patterns use simple gitignore-like glob matching.

The concrete generic-text-v1 compatibility profile also checks aggregate size, file count, path depth and length, filename characters, line endings, control characters, Unicode policy, line length, prohibited textual patterns, and the .txt transfer extension. See the policy reference for every field, default, and example.

SHA-512 is available through hash_algorithm: sha512. BLAKE3 is optional (uv sync --extra blake3) and fails closed with a clear message when unavailable.

Security notes

The source directory is never modified. Destination directories must not already exist. Oversized sources are rejected before content reads. Every manifest path is checked against a link-free package root to prevent traversal and external reads. Verification hashes transfer bytes before restoration; restoration validates a staged destination after removing the transport BOM and publishes it atomically. Do not treat a checksum as authenticity: use a separately managed digital signature and verify it in the approved environment.

Signing is exposed through a detached-signature hook in controlled_text_transfer.signing; integrate approved GPG or X.509 tooling outside this package. Never pass private keys or passphrases through CLI arguments, environment variables, or manifest content. See SECURITY.md for the operating guidance. Archives should be scanned by the CDS and malware controls; renaming or encoding is not a bypass.

Packages that declare a signature require a trusted verifier by default. --allow-unverified-signature performs explicitly unauthenticated, integrity-only verification.

Development

The Bash dispatcher provides memorable shortcuts:

bash scripts/run.sh setup
bash scripts/run.sh test
bash scripts/run.sh check
bash scripts/run.sh build
bash scripts/run.sh clean --dry-run

Run bash scripts/run.sh help for the command summary. The underlying commands remain available directly:

uv sync --extra dev
uv run pytest
uv run ruff check .
uv run black --check .
uv run mypy src
uv run bandit -r src scripts

After deleting .venv, either run uv sync --extra dev before the quality commands or use uv run --extra dev pytest to install the development extra and run the complete test suite in one step. Plain uv run pytest cannot find pytest in a newly created runtime-only environment. Use uv run --extra dev pytest -q as the equivalent concise-output alternative.

The package is pipx-friendly because it exposes the ctt console script. Build a standalone executable with pyinstaller ctt.spec; keep generated binaries out of source control.

Clean generated artifacts

Preview the repository-scoped cleanup, then remove reproducible build and test artifacts:

bash scripts/run.sh clean --dry-run
bash scripts/run.sh clean

The default removes build/, dist/, tool caches, .coverage, __pycache__/, and *.egg-info/; it preserves source, configuration, uv.lock, and .venv. To remove .venv too, run bash scripts/run.sh clean --environment; the dispatcher selects the first python on PATH outside the project environment. The action refuses to delete its active interpreter. It never cleans uv's shared global cache because that can affect other projects.

Publishing

Releases use PyPI Trusted Publishing through .github/workflows/release.yml. Configure a pending GitHub publisher for project controlled-text-transfer, owner dgomez407, repository ctt, workflow release.yml, and environment pypi. After the quality gates pass, push a version tag such as v0.1.0 from a commit contained in main. The workflow verifies that the tagged commit belongs to origin/main, the tag, package version, README, and changelog agree; reruns the locked quality gates; validates the wheel and source distribution; and publishes them without a stored API token.

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

controlled_text_transfer-0.1.0.tar.gz (79.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

controlled_text_transfer-0.1.0-py3-none-any.whl (22.4 kB view details)

Uploaded Python 3

File details

Details for the file controlled_text_transfer-0.1.0.tar.gz.

File metadata

  • Download URL: controlled_text_transfer-0.1.0.tar.gz
  • Upload date:
  • Size: 79.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for controlled_text_transfer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 51e43e066a1249c47f07ed943c8e4b29743915f67e0008a578a88d2ce9e15202
MD5 093b53c71fe4b0c318b87285ffc1d7ba
BLAKE2b-256 03d35b28e508b5adad26053b69160c37e1340ed4da00c368da393b6f8a03b698

See more details on using hashes here.

Provenance

The following attestation bundles were made for controlled_text_transfer-0.1.0.tar.gz:

Publisher: release.yml on dgomez407/ctt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file controlled_text_transfer-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for controlled_text_transfer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b8f85562659ddd4048cc8c98e407f46e5894acdc2954f20a3d9fec22fe90c325
MD5 4e38318e7edfb1a43be761cd7f1d2086
BLAKE2b-256 50be7fde0178f49bddc794f3868b50576034f6fcb8e998756cbe66fcad891d7d

See more details on using hashes here.

Provenance

The following attestation bundles were made for controlled_text_transfer-0.1.0-py3-none-any.whl:

Publisher: release.yml on dgomez407/ctt

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page