Skip to content

About

Explicit source-read outcomes without confusing unknown with success.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Source Read

CI

Source Read is a small, standard-library-only helper that prevents an unreadable source from being mistaken for a clean result. This source tree prepares version 0.3.0; that version is not yet published. Versioned releases are source-only under the MIT license; no package-registry publication is configured. See RELEASING.md.

The helper preserves a distinction that checks often lose:

  • a source was consulted successfully and returned an empty value; or
  • a source could not be consulted, so a clean verdict would be unsupported.

It records source outcomes supplied by a caller. It does not open files, query services, authenticate callers, validate source integrity, or enforce a policy.

Install the published release

Source Read requires Python 3.11 or newer. CI tests Python 3.11 through 3.14 on Linux, Python 3.11 and 3.14 on Windows, and Python 3.14 on macOS. Newer Python versions are eligible under the package metadata but are not yet validated.

Source Read is not published on PyPI, so do not use a bare pip install source-read command. The latest published version is 0.2.0. Install its immutable source asset directly; Git is not required. The URL's SHA-256 fragment lets pip verify the reviewed source ZIP before building it:

python -m venv ../source-read-runtime
# Windows:
../source-read-runtime/Scripts/python -m pip install "https://github.com/nymrel/source-read/releases/download/v0.2.0/source-read-0.2.0.zip#sha256=6cee0ef1816d992a4b6cd5ee9414d3e280495e263011f5e1aae3af946a49a30c"
../source-read-runtime/Scripts/python -I -c "import source_read; print(source_read.__version__)"
# POSIX:
../source-read-runtime/bin/python -m pip install "https://github.com/nymrel/source-read/releases/download/v0.2.0/source-read-0.2.0.zip#sha256=6cee0ef1816d992a4b6cd5ee9414d3e280495e263011f5e1aae3af946a49a30c"
../source-read-runtime/bin/python -I -c "import source_read; print(source_read.__version__)"
# expected: 0.2.0

The sibling virtual environment is intentional. A checkout-local .venv would be an extra file tree inside the exact source-release verification boundary. The installed package has no third-party runtime dependencies.

Evaluate the 0.3.0 candidate

The published 0.2.0 package does not include to_report(). To evaluate the new API before a 0.3.0 release, install a reviewed checkout of this candidate into the sibling environment:

# Windows, from the candidate checkout:
../source-read-runtime/Scripts/python -m pip install .
../source-read-runtime/Scripts/python -I -c "import source_read; assert source_read.__version__ == '0.3.0'; print(source_read.assess_check([source_read.SourceRead.ok([])], passed=True).to_report())"
# POSIX, from the candidate checkout:
../source-read-runtime/bin/python -m pip install .
../source-read-runtime/bin/python -I -c "import source_read; assert source_read.__version__ == '0.3.0'; print(source_read.assess_check([source_read.SourceRead.ok([])], passed=True).to_report())"

Record the exact candidate commit when pinning an evaluation. Package version 0.3.0 in a checkout does not mean a corresponding immutable release exists.

An ordinary source installation lets pip create an isolated build environment. For the reviewed build path, run python scripts/verify_package_build.py. It downloads only the SHA-256-locked wheels in requirements/build.lock, installs them into two disposable build environments, builds twice with index access disabled, compares the wheel bytes within that interpreter, performs an isolated runtime install, and safely writes the verified local wheel under dist/. Install that wheel into the sibling runtime without index access:

# Windows:
../source-read-runtime/Scripts/python -m pip install --no-index --no-deps --force-reinstall dist/source_read-0.3.0-py3-none-any.whl
# POSIX:
../source-read-runtime/bin/python -m pip install --no-index --no-deps --force-reinstall dist/source_read-0.3.0-py3-none-any.whl

Generated wheels are not release artifacts; ZIP compression can produce different wheel bytes across Python or zlib versions. The initial Python interpreter, its bundled pip bootstrap, the package index, and the hosted runner remain trust inputs; hash locking does not make upstream code safe or provide operating-system network isolation.

Recommended API

Use assess_check() when the caller has a boolean policy result. The required passed argument determines the known machine exit code and supplies default display text. Custom verdict text remains caller-controlled and uninterpreted; source read failures still force UNKNOWN / exit 2:

from source_read import SourceRead, assess_check

read = SourceRead.ok([], label="synthetic inventory")
assessment = assess_check([read], passed=True)

assert assessment.effective_verdict == "PASS"
assert assessment.is_pass
raise SystemExit(assessment.exit_code)  # exits 0

An unreadable source deliberately exits 2 even when the caller computed a known pass or failure:

from source_read import EXIT_UNKNOWN, SourceRead, assess_check

read = SourceRead.unreadable(
    "synthetic inventory", "synthetic source unavailable", empty=[]
)
assessment = assess_check([read], passed=False)

assert assessment.exit_code == EXIT_UNKNOWN
raise SystemExit(assessment.exit_code)  # deliberately exits 2

The library returns an exit code; it never terminates the process itself.

Lower-level API

assess_sources() preserves arbitrary caller verdict text and a separately supplied exit code. It never guesses that text such as FAIL means exit 1. Its verdict_exit_code defaults to EXIT_PASS (0), so pass an explicit code for every known failure:

from source_read import EXIT_FAIL, SourceRead, assess_sources

read = SourceRead.ok(["synthetic finding"], label="synthetic inventory")
assessment = assess_sources(
    [read],
    "POLICY_FAILED",
    verdict_exit_code=EXIT_FAIL,
)

assert assessment.effective_verdict == "POLICY_FAILED"
assert assessment.is_fail
raise SystemExit(assessment.exit_code)  # exits 1
Source state Requested known outcome Effective outcome
all readable pass / 0 caller verdict / 0
all readable failure / 1 caller verdict / 1
any unreadable either UNKNOWN / 2
zero sources either UNKNOWN / 2 by default

Compact reference

  • SourceRead.ok(value, label=None) records a successful read. An empty value is still readable. Labels accept strings, pure paths, or None.
  • SourceRead.unreadable(label, reason, *, empty=None) records a failed read. empty is only a neutral value for continued computation.
  • SourceRead.describe(include_details=False) returns a generic safe summary. include_details=True explicitly reveals escaped label and reason text.
  • assess_check(reads, *, passed, verdict=None, allow_empty=False) is the recommended boolean-check API. passed must be a real bool, determines exit 0/1, and supplies default text; custom verdict text stays opaque.
  • assess_sources(reads, verdict, *, verdict_exit_code=EXIT_PASS, allow_empty=False) is the lower-level text/code API.
  • SourceAssessment exposes immutable source membership, generic problems, unreadable indexes, requested/effective verdicts and codes, empty-input state, unknown_applied, and is_pass / is_fail / is_unknown.
  • In this unreleased source candidate, SourceAssessment.to_report() exports a content-free machine report as described below.
  • detailed_problems() explicitly reveals escaped labels and reasons.
  • EXIT_PASS, EXIT_FAIL, and EXIT_UNKNOWN are 0, 1, and 2; UNKNOWN is the reserved unknown-verdict text.

assess_sources() and assess_check() materialize their iterable exactly once. Zero supplied sources produce UNKNOWN and exit 2 by default. A caller may deliberately pass allow_empty=True only when zero sources are a valid, reviewed policy state. A successfully read source whose value is empty is not the same thing as zero supplied source records.

problems describes source-read problems, not the policy result. A known failure can have problems == (). Records and assessments also have ordinary Python object truthiness; do not use if assessment, if read, or an empty problems tuple as a success test. Inspect exit_code, the is_* properties, unknown_applied, or readable as appropriate.

Assessment records are frozen, but caller-owned payload values are not deeply copied or frozen. Default representations and generic problem summaries hide values, labels, reasons, and caller verdict text. describe(include_details=True) and detailed_problems() are explicit disclosure operations; sanitize their output before logging or sharing it.

Unreleased integration: machine reports

SourceAssessment.to_report() is an additive API prepared for 0.3.0. It is not included in the published v0.2.0 tag or source archive. The 0.3.0 source candidate needs its own reviewed immutable release. Install a reviewed candidate checkout or locally verified wheel to evaluate this feature.

Use the report between a reader and a CI check, policy engine, or agent tool adapter when those consumers need the machine outcome but not source contents:

import json
from source_read import SourceRead, assess_check

# The adapter, not this library, performed and classified the source operation.
assessment = assess_check([SourceRead.ok([], label="synthetic inventory")], passed=True)
print(json.dumps(assessment.to_report()))
raise SystemExit(assessment.exit_code)

The report is a fresh JSON-ready mapping with this exact initial shape:

{
  "schema": "source-read.assessment.v1",
  "outcome": "PASS",
  "exit_code": 0,
  "source_count": 1,
  "unreadable_indexes": [],
  "empty_input": false,
  "allow_empty": false,
  "unknown_applied": false
}

outcome is derived only from the effective machine exit code: 0 means PASS, 1 means FAIL, and 2 means UNKNOWN. Arbitrary caller verdict text is not interpreted or copied. Source indexes are zero-based positions in the materialized input, not source identities. empty_input records zero sources; allow_empty makes an explicit empty-source policy exception visible.

The report omits payloads, labels, reasons, generic/detailed problem text, and requested/effective caller verdict text. It never calls payload serialization or string conversion. A caller can mutate the returned mapping or index list without changing the assessment; a later report is independent of that mutation. The schema identifies this projection's initial contract, not a universal agent protocol. This API exports reports; it does not parse or validate received JSON.

Content-free does not mean universally safe to share. Counts and outcomes can still reveal sensitive facts. Review recipients and logs, and do not treat a report as authenticated, tamper-evident, independently observed, fresh, complete, or proof of a source read. Those properties require their own integration.

A reader and a CI consumer

The HTTP reference adapter is a standard-library-only example for a caller-controlled HTTP(S) JSON inventory. The policy is deliberately simple: a full HTTP 200 response containing an empty list passes, an obtained nonempty list fails, and HTTP/read/UTF-8/JSON/shape failure becomes unknown. Partial HTTP 206 responses are not complete inventories. The adapter uses a bounded read and timeout. It is not a crawler, network sandbox, pagination implementation, or production SSRF boundary. The caller remains responsible for whether a response represents the complete source required by its policy.

Run the example with the Python environment that has the candidate installed:

python examples/http_check.py --url http://127.0.0.1:8080/inventory
python examples/http_check.py --no-sources

Each supported run writes only the content-free JSON report to stdout and exits with that report's exit_code. The second command deliberately returns 2. An empty HTTP body, malformed JSON, or a server outage is not an empty inventory. An integration must explicitly classify source acquisition and policy results; for example, an MCP tool's domain rejection is not automatically a transport failure. No MCP-specific classifier or dependency is added here.

python scripts/verify_package_build.py copies the example into a new temporary consumer outside the checkout, installs the actual verified wheel in a separate external runtime, and invokes it using Python -I. A synthetic loopback server supplies empty, findings, unavailable, malformed, wrong-shape, and partial response cases; a seventh case supplies zero sources. The check verifies installed module origin, JSON and exit codes, privacy sentinels, wheel identity, and zero runtime dependencies. It retains dist/installed-consumer-acceptance.json, including the exact wheel/core/copied-consumer hashes. This demonstrates installed integration with a reader and CI-style machine output, not external-user adoption or a live provider test.

Local validation

The runtime and unit-test suite use only the Python standard library. The locked package-build validation downloads only reviewed, hashed build wheels.

python -m unittest discover -s tests -v
python scripts/verify_release.py
python scripts/build_source_archive.py --check-reproducible
python scripts/verify_release.py --archive dist/source-read-0.3.0.zip
python scripts/verify_package_build.py

These commands validate source and packaging artifacts. They do not publish to a registry or create a hosted release.

Releases

GitHub's release list is the authoritative record of published versions. The v0.2.0 release page records the exact tag target, source-archive digest, independent review, hosted checks, and GitHub asset attestation. Tagged documentation is immutable release-time evidence; the current main documentation may contain later guidance.

The 0.3.0 candidate adds the content-free report and controlled HTTP/CI reference consumer. It keeps the core API compatible, I/O-free, and free of third-party runtime dependencies. The new version is release preparation; merging its source does not create a tag, release asset, or registry package.

The historical initial release remains available as immutable evidence: v0.1.0, tag target 51ba075b2a956785e45f236db383526979e31922, and release review PR #1. Never move an existing release tag to pick up documentation changes.

Scope

The package is intentionally small and generic. It does not include internal incidents, private paths, customer data, operational tooling, or infrastructure configuration. Its behavior is covered with synthetic examples only.

License and support

Source Read is licensed under the MIT License. Maintainer and security contacts are documented in MAINTAINERS.md and SECURITY.md. Contributions are covered by CONTRIBUTING.md, ordinary defects can be filed in the issue tracker, and sensitive reports belong in a private vulnerability report.

About

Explicit source-read outcomes without confusing unknown with success.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages