sayfirst-cli 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/CHANGELOG.md +7 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/PKG-INFO +9 -7
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/QUICKSTART.md +13 -12
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/README.md +6 -4
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/docs/PACKS.md +3 -1
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/pyproject.toml +3 -3
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/launch.py +1 -1
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/.github/workflows/ci.yml +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/.github/workflows/release.yml +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/.gitignore +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/LICENSE +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/NOTICE +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/SECURITY.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/TRADEMARKS.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/docs/EVIDENCE-SURFACE.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/docs/PARTITION.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/docs/PROVENANCE.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/docs/publication-checklist.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/scripts/check_dependency_closure.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/scripts/check_developer_certificate_of_origin.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/scripts/gate.sh +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/scripts/release_version.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/__init__.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/approvals.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/ask.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/evidence.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/exit_codes.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/explain.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/__init__.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/_bootstrap/sitecustomize.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/commands.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/designation.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/engine.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/follow.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/harness.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/interpreter.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/manifest.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/verify.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/main.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/__init__.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/database/NOTE.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/database/interpose.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/database/pack.toml +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/http-client/NOTE.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/http-client/interpose.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/http-client/pack.toml +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/subprocess/NOTE.md +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/subprocess/interpose.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs/subprocess/pack.toml +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/packs_cmd.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/pages.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/reads.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/render.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/trace.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/canned_daemon.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/conftest.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/contract_absence.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/documents.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/governed_programs.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/pack_doubles.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/replies.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_approvals.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_ask_connection_loss.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_ask_end_to_end.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_boundary_runtime.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_changelog_names_the_version.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_contract_absence.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_contract_words.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_database_pack.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_decided_name.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_default_socket.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_dependency_closure.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_developer_certificate_of_origin.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_engine.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_engine_is_agnostic.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_evidence_export_and_exports.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_evidence_history_and_audit.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_evidence_reads.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_exit_codes.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_follow_children.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_gate_modes.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_governed_run_leaves_no_trace.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_http_client_pack.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_instrument_run.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_instrument_verify.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_interpreter_target.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_manifest.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_offline_audit_vectors.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_pack_designation.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_pack_doubles.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_packs_cmd.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_packs_shipped.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_partition_boundary.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_pointers_survive_publication.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_public_vocabulary.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_publication_checklist_names_every_act.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_quickstart_names_what_exists.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_read_rendering.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_reads.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_release_workflow_publishes_only_on_a_tag.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_review_bounds.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_running_the_module.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_shipped_wheel_notices.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_source_distribution_notices.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_spdx_identifiers.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_subprocess_pack.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_trace_and_explain.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_verification_claims_what_it_established.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_verify_asks_every_effect.py +0 -0
- {sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_verify_pairs_an_inner_spawn.py +0 -0
|
@@ -6,6 +6,13 @@ declares; a release with no section fails the gate.
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.3.2
|
|
10
|
+
|
|
11
|
+
- The contract and the boundary move to 0.3.2, which carries security fixes.
|
|
12
|
+
Under `sayfirst instrument run`, an act a person approved now runs once;
|
|
13
|
+
asked again, it waits under a new approval.
|
|
14
|
+
- The pages say that an allow produced by an approval carries no grant.
|
|
15
|
+
|
|
9
16
|
## 0.3.1
|
|
10
17
|
|
|
11
18
|
- **`instrument verify` says how a run ended when the program raised, too.** The harness said
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: sayfirst-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: The product command-line interface of the sayfirst control plane
|
|
5
5
|
Project-URL: Repository, https://github.com/fredaime/sayfirst-cli
|
|
6
6
|
Project-URL: Documentation, https://github.com/fredaime/sayfirst-cli/blob/main/README.md
|
|
@@ -15,8 +15,8 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
17
17
|
Requires-Python: <3.15,>=3.12
|
|
18
|
-
Requires-Dist: sayfirst-boundary==0.3.
|
|
19
|
-
Requires-Dist: sayfirst-contract==0.3.
|
|
18
|
+
Requires-Dist: sayfirst-boundary==0.3.2
|
|
19
|
+
Requires-Dist: sayfirst-contract==0.3.2
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
|
|
22
22
|
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
@@ -36,7 +36,9 @@ anything that matters: *may I do this, with these arguments, as this account?*
|
|
|
36
36
|
person can read, over a Unix socket that tells it who is asking from the
|
|
37
37
|
kernel's own credentials. No URL, no token, nothing to leak (article 6).
|
|
38
38
|
- **The program never decides.** It asks, and it does only what was allowed:
|
|
39
|
-
the boundary (`sayfirst-boundary`) holds the grant for
|
|
39
|
+
the boundary (`sayfirst-boundary`) holds the grant a policy allow serves, for the run;
|
|
40
|
+
an allow that a person's approval produced carries no grant — it runs the act
|
|
41
|
+
once, and the same act asked again waits under a new approval.
|
|
40
42
|
- **A person is in the loop by construction, not by dashboard.** A suspension
|
|
41
43
|
is a wait. `sayfirst approvals approve` ends it once, the deadline comes from
|
|
42
44
|
the policy, and a rejection stands until that deadline, or until the daemon
|
|
@@ -114,7 +116,7 @@ command on that page was run, in that order, before it was written down.
|
|
|
114
116
|
|
|
115
117
|
### What the index holds
|
|
116
118
|
|
|
117
|
-
Everything the three commands above need is on the Python index at 0.3.
|
|
119
|
+
Everything the three commands above need is on the Python index at 0.3.2:
|
|
118
120
|
`sayfirst-cli`, the `sayfirst-contract` it speaks and the `sayfirst-boundary` a
|
|
119
121
|
governed program holds its grants in, and the control plane's
|
|
120
122
|
`sayfirst-control-plane` and `sayfirstd`. The first command installs all five
|
|
@@ -247,7 +249,7 @@ contract is built from a checkout of the control plane's repository, at the tag
|
|
|
247
249
|
this client pins:
|
|
248
250
|
|
|
249
251
|
```console
|
|
250
|
-
$ SAYFIRST_CONTRACT_SOURCE=../sayfirst-control-plane SAYFIRST_CONTRACT_REF=v0.3.
|
|
252
|
+
$ SAYFIRST_CONTRACT_SOURCE=../sayfirst-control-plane SAYFIRST_CONTRACT_REF=v0.3.2 ./scripts/gate.sh
|
|
251
253
|
```
|
|
252
254
|
|
|
253
255
|
The workflow does the same and carries no credential of any kind: a fork can
|
|
@@ -274,7 +276,7 @@ GitHub's private reporting, never a public issue — [`LICENSE`](LICENSE),
|
|
|
274
276
|
|
|
275
277
|
## Status
|
|
276
278
|
|
|
277
|
-
**0.2.0 is the first public release**, 2026-09-17. 0.3.
|
|
279
|
+
**0.2.0 is the first public release**, 2026-09-17. 0.3.2 is the current one.
|
|
278
280
|
What is *not* here is named too, because a surface a reader assumes is an
|
|
279
281
|
overclaim: `connect`, `profile`, `whoami`, `integrate` and `version` are in
|
|
280
282
|
[`docs/PARTITION.md`](docs/PARTITION.md) and none of them exists here.
|
|
@@ -12,8 +12,8 @@ $ sayfirst instrument run --pack subprocess --scope local -- python3 my_agent.py
|
|
|
12
12
|
|
|
13
13
|
Everything on this page was run, in this order, before it was written down: the
|
|
14
14
|
commands are pasted from that run, and so are their answers. The run installed
|
|
15
|
-
0.3.
|
|
16
|
-
given `--no-index` (the walk ran before 0.3.
|
|
15
|
+
0.3.2 with the first command from wheels built from the two release trees,
|
|
16
|
+
given `--no-index` (the walk ran before 0.3.2 reached the index; « From
|
|
17
17
|
checkouts instead » below is that install), on a PATH with `python3` and no
|
|
18
18
|
`python`, in a shell with neither repository on any path, under a home
|
|
19
19
|
directory made for it;
|
|
@@ -29,11 +29,12 @@ hashes will differ; the shapes will not.
|
|
|
29
29
|
and macOS name it that; inside an activated virtual environment `python`
|
|
30
30
|
works too), and [`uv`](https://docs.astral.sh/uv/). The walk used
|
|
31
31
|
uv 0.12.
|
|
32
|
-
- A home directory that only you can write. The daemon refuses
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
- A home directory that only you can write. The daemon refuses to start if
|
|
33
|
+
the socket's directory, or any directory on the way to it, can be written
|
|
34
|
+
by a group or by others and is not sticky (`socket_directory_unprotected`),
|
|
35
|
+
and likewise for the policy's directory and those above it
|
|
36
|
+
(`policy_unavailable_at_start … exposed: group_write`); either way it says
|
|
37
|
+
so instead of starting.
|
|
37
38
|
|
|
38
39
|
## 1. Install
|
|
39
40
|
|
|
@@ -42,11 +43,11 @@ $ uv tool install sayfirst-cli --with-executables-from sayfirst-control-plane --
|
|
|
42
43
|
Resolved 5 packages in 3ms
|
|
43
44
|
Prepared 5 packages in 6ms
|
|
44
45
|
Installed 5 packages in 1ms
|
|
45
|
-
+ sayfirst-boundary==0.3.
|
|
46
|
-
+ sayfirst-cli==0.3.
|
|
47
|
-
+ sayfirst-contract==0.3.
|
|
48
|
-
+ sayfirst-control-plane==0.3.
|
|
49
|
-
+ sayfirstd==0.3.
|
|
46
|
+
+ sayfirst-boundary==0.3.2
|
|
47
|
+
+ sayfirst-cli==0.3.2
|
|
48
|
+
+ sayfirst-contract==0.3.2
|
|
49
|
+
+ sayfirst-control-plane==0.3.2
|
|
50
|
+
+ sayfirstd==0.3.2
|
|
50
51
|
Installed 1 executable from `sayfirst-control-plane`: sayfirst-daemon
|
|
51
52
|
Installed 1 executable from `sayfirstd`: sayfirstd
|
|
52
53
|
Installed 1 executable: sayfirst
|
|
@@ -15,7 +15,9 @@ anything that matters: *may I do this, with these arguments, as this account?*
|
|
|
15
15
|
person can read, over a Unix socket that tells it who is asking from the
|
|
16
16
|
kernel's own credentials. No URL, no token, nothing to leak (article 6).
|
|
17
17
|
- **The program never decides.** It asks, and it does only what was allowed:
|
|
18
|
-
the boundary (`sayfirst-boundary`) holds the grant for
|
|
18
|
+
the boundary (`sayfirst-boundary`) holds the grant a policy allow serves, for the run;
|
|
19
|
+
an allow that a person's approval produced carries no grant — it runs the act
|
|
20
|
+
once, and the same act asked again waits under a new approval.
|
|
19
21
|
- **A person is in the loop by construction, not by dashboard.** A suspension
|
|
20
22
|
is a wait. `sayfirst approvals approve` ends it once, the deadline comes from
|
|
21
23
|
the policy, and a rejection stands until that deadline, or until the daemon
|
|
@@ -93,7 +95,7 @@ command on that page was run, in that order, before it was written down.
|
|
|
93
95
|
|
|
94
96
|
### What the index holds
|
|
95
97
|
|
|
96
|
-
Everything the three commands above need is on the Python index at 0.3.
|
|
98
|
+
Everything the three commands above need is on the Python index at 0.3.2:
|
|
97
99
|
`sayfirst-cli`, the `sayfirst-contract` it speaks and the `sayfirst-boundary` a
|
|
98
100
|
governed program holds its grants in, and the control plane's
|
|
99
101
|
`sayfirst-control-plane` and `sayfirstd`. The first command installs all five
|
|
@@ -226,7 +228,7 @@ contract is built from a checkout of the control plane's repository, at the tag
|
|
|
226
228
|
this client pins:
|
|
227
229
|
|
|
228
230
|
```console
|
|
229
|
-
$ SAYFIRST_CONTRACT_SOURCE=../sayfirst-control-plane SAYFIRST_CONTRACT_REF=v0.3.
|
|
231
|
+
$ SAYFIRST_CONTRACT_SOURCE=../sayfirst-control-plane SAYFIRST_CONTRACT_REF=v0.3.2 ./scripts/gate.sh
|
|
230
232
|
```
|
|
231
233
|
|
|
232
234
|
The workflow does the same and carries no credential of any kind: a fork can
|
|
@@ -253,7 +255,7 @@ GitHub's private reporting, never a public issue — [`LICENSE`](LICENSE),
|
|
|
253
255
|
|
|
254
256
|
## Status
|
|
255
257
|
|
|
256
|
-
**0.2.0 is the first public release**, 2026-09-17. 0.3.
|
|
258
|
+
**0.2.0 is the first public release**, 2026-09-17. 0.3.2 is the current one.
|
|
257
259
|
What is *not* here is named too, because a surface a reader assumes is an
|
|
258
260
|
overclaim: `connect`, `profile`, `whoami`, `integrate` and `version` are in
|
|
259
261
|
[`docs/PARTITION.md`](docs/PARTITION.md) and none of them exists here.
|
|
@@ -237,7 +237,9 @@ is stepped over when any of them does not.
|
|
|
237
237
|
are not the same order. **Which is why a verifying run holds no grant.**
|
|
238
238
|
Under `instrument run` the boundary keeps what it was granted (article 10),
|
|
239
239
|
and an identical effect repeated while that grant lives is answered by it
|
|
240
|
-
with nothing asked and nothing recorded.
|
|
240
|
+
with nothing asked and nothing recorded. An allow that a person's approval
|
|
241
|
+
produced carries no grant: it runs the act once, and the same act asked again
|
|
242
|
+
waits under a new approval. Under `verify` the boundary in front
|
|
241
243
|
of the program asks for every effect, so every effect has a record of its
|
|
242
244
|
own: a program that spawns the same command twice is two decisions there,
|
|
243
245
|
and one there would read the second spawn as ungoverned.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
[project]
|
|
3
3
|
name = "sayfirst-cli"
|
|
4
|
-
version = "0.3.
|
|
4
|
+
version = "0.3.2"
|
|
5
5
|
description = "The product command-line interface of the sayfirst control plane"
|
|
6
6
|
readme = "README.md"
|
|
7
7
|
requires-python = ">=3.12,<3.15"
|
|
@@ -20,7 +20,7 @@ classifiers = [
|
|
|
20
20
|
# promise made here — it is measured after an install. `sayfirst-boundary` joins
|
|
21
21
|
# it because a governed program holds a grant in it (article 10); it depends on
|
|
22
22
|
# the contract only, and it is not the server (article 14).
|
|
23
|
-
dependencies = ["sayfirst-contract==0.3.
|
|
23
|
+
dependencies = ["sayfirst-contract==0.3.2", "sayfirst-boundary==0.3.2"]
|
|
24
24
|
|
|
25
25
|
# The public repository this distribution sends a reader to, created fresh in
|
|
26
26
|
# the act that published it (2026-09-17) under the names the operator chose for
|
|
@@ -41,7 +41,7 @@ sayfirst = "sayfirst_cli.main:run"
|
|
|
41
41
|
dev = [
|
|
42
42
|
"pytest==8.4.1",
|
|
43
43
|
"ruff==0.12.12",
|
|
44
|
-
"sayfirst-contract[stub]==0.3.
|
|
44
|
+
"sayfirst-contract[stub]==0.3.2",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
[build-system]
|
|
@@ -152,7 +152,7 @@ def run(
|
|
|
152
152
|
|
|
153
153
|
`hold_grants=False` asks for every effect and holds no grant. The verifier
|
|
154
154
|
runs this way: its proof is one recorded decision for each effect it saw,
|
|
155
|
-
and a grant hit — an identical effect answered by an earlier allow, which is
|
|
155
|
+
and a grant hit — an identical effect answered by an earlier allow the policy gave, which is
|
|
156
156
|
what `run` does (article 10) — records nothing, so a repeated effect would
|
|
157
157
|
read as ungoverned.
|
|
158
158
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/src/sayfirst_cli/instrument/_bootstrap/sitecustomize.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_publication_checklist_names_every_act.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_release_workflow_publishes_only_on_a_tag.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sayfirst_cli-0.3.1 → sayfirst_cli-0.3.2}/tests/test_verification_claims_what_it_established.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|