Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.3.3 instead.
Reason given by maintainers: security: fixed in 0.3.2; use 0.3.2 or later

sayfirst contract

This distribution publishes generation 1 of the transport-neutral domain contract and its generated HTTP-over-Unix-socket binding. It has no runtime dependencies. The scriptable fake is available only through the stub extra.

Scenarios

Scenario Binds Article Expected
allow both 1 grant=present, outcome=allow, reason=policy_allows
deny both 1 outcome=deny, reason=policy_denies
grant_expired_by_lifetime client 10 grant=present, grant_use=expired, outcome=allow, reason=policy_allows
grant_hit_within_lifetime client 10 grant=present, grant_use=hit, outcome=allow, reason=policy_allows
grant_miss_after_policy_version_change both 10 after_policy_change={'grant': 'absent', 'outcome': 'deny', 'reason': 'policy_denies'}, grant=present, outcome=allow, reason=policy_allows
grant_void_on_arguments_change client 3 grant=present, grant_use=arguments_changed, outcome=allow, reason=policy_allows
grant_void_on_connection_loss client 10 grant=present, grant_use=connection_lost, outcome=allow, reason=policy_allows
missing_policy both 1 outcome=deny, reason=policy_absent
no_grant_on_deny both 10 grant=absent, outcome=deny, reason=policy_denies
no_grant_without_signal_channel both 10 grant=absent, outcome=allow, reason=policy_allows
policy_unavailable_is_could_not_ask both 1 grant=absent, problem=policy_unavailable, result=could_not_ask
review_approve both 12 outcome=suspend, reason=policy_requires_review, state=approved, after_resolution.outcome=allow, after_resolution.reason=approval_granted
review_expire both 12 outcome=suspend, reason=policy_requires_review, state=expired
review_reject both 12 outcome=suspend, reason=policy_requires_review, state=rejected, after_resolution.outcome=deny, after_resolution.reason=approval_rejected
strictest_rule_wins server 1 grant=absent, outcome=deny, reason=policy_denies
unknown_outcome client 13 problem=outcome_unknown, reported_outcome=unknown, result=could_not_ask
unreachable client 1 problem=unreachable, result=could_not_ask

Server conformance replay

Run each server-bound scenario against a daemon instance already arranged for that scenario:

sayfirst-conformance replay \
  --socket allow=/run/conformance/allow.sock \
  --socket deny=/run/conformance/deny.sock \
  --socket missing_policy=/run/conformance/missing_policy.sock \
  --socket review_approve=/run/conformance/review_approve.sock \
  --socket review_expire=/run/conformance/review_expire.sock \
  --socket review_reject=/run/conformance/review_reject.sock

Repeat --socket SCENARIO=PATH for every available server scenario. A scenario whose implementation block has not landed must instead be named with --expected-absent SCENARIO=REASON; an absent socket without that declaration is failed. Client-only scenarios are reported as not applicable because their binds value does not include server. Every result line contains the scenario name, proven, failed, or not-applicable, and a reason. A run proves conformance only if every server-bound scenario is proven. A disagreement makes the run failed; an expected absence makes it unknown, with exit code 3, even when another scenario was proven.

The default expects each per-user daemon to run as the invoking user. System daemon tests name its numeric account with --expected-uid. The client checks that identity before sending each request. review_expire waits 61 seconds by default; a test harness can inject its clock through SocketHarness instead.

The repository acceptance suite uses the same mapping convention under SAYFIRST_CONFORMANCE_SOCKET_DIR: it looks for <scenario>.sock there and uses SAYFIRST_CONFORMANCE_EXPECTED_UID when the daemon does not run as the test user. When the socket directory is not configured, each case is an expected absence whose reason states that observed configuration fact. When it is configured, the same inventory runs live and carries no absence claim.

Distribution boundary

The reusable replayer and its HTTP-over-Unix-socket client remain in this contract distribution. The client verifies the server's peer credential and maps failures to impostor, unreachable, and answer_unreadable. The socket client is published from binding.http_unix_socket.client; the replay harness is in the sibling replay module.

This repository publishes the sayfirst-conformance distribution, the sayfirst_conformance import package and the sayfirst-conformance script; it also publishes the operator surface that inspects the daemon, from packages/cli, as the distribution sayfirstd, the import package sayfirstd and the console script sayfirstd. Each of those names is claimed once, by one distribution, and tests/test_client_distribution_names.py holds that against the [project] tables. The surface re-exports this operation as sayfirstd conformance replay while depending on this contract and on no server distribution.

The distribution sayfirst-cli, the import package sayfirst_cli and the console script sayfirst belong to the product command-line interface and are not published from this repository; the operator settled that on 2026-09-05.

This distribution installs no console script of its own, so nothing here is bound to the name of a surface that forwards to it. The operator surface sayfirstd is the one that reaches this operation today; the product command-line interface may reach it through these same modules, and no release of it does so yet.

Server conformance replay

Run each server-bound scenario against a daemon instance already arranged for that scenario:

sayfirstd conformance replay \
  --socket allow=/run/conformance/allow.sock \
  --socket deny=/run/conformance/deny.sock \
  --socket missing_policy=/run/conformance/missing_policy.sock \
  --socket review_approve=/run/conformance/review_approve.sock \
  --socket review_expire=/run/conformance/review_expire.sock \
  --socket review_reject=/run/conformance/review_reject.sock

Repeat --socket SCENARIO=PATH for every available server scenario. A scenario whose implementation block has not landed must instead be named with --expected-absent SCENARIO=REASON; an absent socket without that declaration is failed. Client-only scenarios are reported as not applicable because their binds value does not include server. Every result line contains the scenario name, proven, failed, or not-applicable, and a reason. A run proves conformance only if it has no failed scenario and at least one proven scenario.

The default expects each per-user daemon to run as the invoking user. System daemon tests name its numeric account with --expected-uid. The client checks that identity before sending each request. review_expire waits 61 seconds by default; a test harness can inject its clock through SocketHarness instead.

The repository acceptance suite uses the same mapping convention, reading the socket directory from the environment — it looks for <scenario>.sock there — and an expected numeric account from the environment when the daemon does not run as the test user. The block that implements the suite fixes the two variable names, so this document names none that nothing here reads. Until the daemon blocks land, each case is an expected absence with its prerequisite stated in the test result.

Metadata

Release files for sayfirst-contract 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for sayfirst-contract 0.2.0
File Interpreter ABI Platform
sayfirst_contract-0.2.0-py3-none-any.whl Python 3 none any Details

Release files / sayfirst_contract-0.2.0-py3-none-any.whl

Download URL sayfirst_contract-0.2.0-py3-none-any.whl
Size 141.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cc9ed88ba2aa1ee247d654c50f0d51d84b39c6b42f37abda3e2abc3b70a48bf7
BLAKE2b-256 checksum
How to use checksums
b013bf9d631f543096a7c548fb9da35396248687d330b338e0d9b554af33ccd1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.5

Release history Release notifications | RSS feed

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

This release

0.2.0 This release

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page