statutor 0.4.0__tar.gz → 0.5.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: statutor
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Typed project-ledger framework for agentic repos: four planes, single-writer files, enforced mutation policies.
5
5
  Author: Hoo
6
6
  License-Expression: MIT
@@ -92,6 +92,15 @@ append-only/cap checks; see adapters/codex/). Residual gaps: MCP tools
92
92
  and Update-File section checks — so the git floor remains
93
93
  mandatory there.
94
94
 
95
+ Worker provenance (v0.5, `statutor machine`/`statutor worker`): automatic
96
+ hooks on every host prove an **attempt** only and record nothing by
97
+ themselves — the hook path stays fail-open. Ingress is executor- or
98
+ custom-run (`begin` → `record --event attempt` → attributed rewrite →
99
+ `complete --session`); `--event mutation` under an automatic harness is
100
+ denied. `worker capabilities` reports proven surfaces and gaps per host
101
+ (verified against Claude Code 2.1.258, Codex CLI 0.152.1, OpenCode 1.18.20
102
+ baselines); `worker compare <ref>` explains sibling handoffs read-only.
103
+
95
104
  ## Install
96
105
 
97
106
  pipx install statutor # or: pip install -e .
@@ -105,7 +114,7 @@ mandatory there.
105
114
  # .pre-commit-config.yaml
106
115
  repos:
107
116
  - repo: https://github.com/hoohugokim/statutor
108
- rev: v0.4.0
117
+ rev: v0.5.0
109
118
  hooks: [{id: statutor}]
110
119
 
111
120
  Per-repo policy lives in `.statutor.yaml`. In-loop checks use the committed
@@ -67,6 +67,15 @@ append-only/cap checks; see adapters/codex/). Residual gaps: MCP tools
67
67
  and Update-File section checks — so the git floor remains
68
68
  mandatory there.
69
69
 
70
+ Worker provenance (v0.5, `statutor machine`/`statutor worker`): automatic
71
+ hooks on every host prove an **attempt** only and record nothing by
72
+ themselves — the hook path stays fail-open. Ingress is executor- or
73
+ custom-run (`begin` → `record --event attempt` → attributed rewrite →
74
+ `complete --session`); `--event mutation` under an automatic harness is
75
+ denied. `worker capabilities` reports proven surfaces and gaps per host
76
+ (verified against Claude Code 2.1.258, Codex CLI 0.152.1, OpenCode 1.18.20
77
+ baselines); `worker compare <ref>` explains sibling handoffs read-only.
78
+
70
79
  ## Install
71
80
 
72
81
  pipx install statutor # or: pip install -e .
@@ -80,7 +89,7 @@ mandatory there.
80
89
  # .pre-commit-config.yaml
81
90
  repos:
82
91
  - repo: https://github.com/hoohugokim/statutor
83
- rev: v0.4.0
92
+ rev: v0.5.0
84
93
  hooks: [{id: statutor}]
85
94
 
86
95
  Per-repo policy lives in `.statutor.yaml`. In-loop checks use the committed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: statutor
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: Typed project-ledger framework for agentic repos: four planes, single-writer files, enforced mutation policies.
5
5
  Author: Hoo
6
6
  License-Expression: MIT
@@ -92,6 +92,15 @@ append-only/cap checks; see adapters/codex/). Residual gaps: MCP tools
92
92
  and Update-File section checks — so the git floor remains
93
93
  mandatory there.
94
94
 
95
+ Worker provenance (v0.5, `statutor machine`/`statutor worker`): automatic
96
+ hooks on every host prove an **attempt** only and record nothing by
97
+ themselves — the hook path stays fail-open. Ingress is executor- or
98
+ custom-run (`begin` → `record --event attempt` → attributed rewrite →
99
+ `complete --session`); `--event mutation` under an automatic harness is
100
+ denied. `worker capabilities` reports proven surfaces and gaps per host
101
+ (verified against Claude Code 2.1.258, Codex CLI 0.152.1, OpenCode 1.18.20
102
+ baselines); `worker compare <ref>` explains sibling handoffs read-only.
103
+
95
104
  ## Install
96
105
 
97
106
  pipx install statutor # or: pip install -e .
@@ -105,7 +114,7 @@ mandatory there.
105
114
  # .pre-commit-config.yaml
106
115
  repos:
107
116
  - repo: https://github.com/hoohugokim/statutor
108
- rev: v0.4.0
117
+ rev: v0.5.0
109
118
  hooks: [{id: statutor}]
110
119
 
111
120
  Per-repo policy lives in `.statutor.yaml`. In-loop checks use the committed
@@ -8,6 +8,7 @@ core/statutor_global.py
8
8
  core/statutor_global_cli.py
9
9
  core/statutor_global_status.py
10
10
  core/statutor_skills.py
11
+ core/statutor_worker.py
11
12
  core/statutor.egg-info/PKG-INFO
12
13
  core/statutor.egg-info/SOURCES.txt
13
14
  core/statutor.egg-info/dependency_links.txt
@@ -4,3 +4,4 @@ statutor_global
4
4
  statutor_global_cli
5
5
  statutor_global_status
6
6
  statutor_skills
7
+ statutor_worker
@@ -27,6 +27,8 @@ Entry modes (all share the same validate() core):
27
27
  exit 1 on violations.
28
28
  statutor init [DIR] Scaffold governed files from embedded templates.
29
29
  statutor global ... Opt-in global instruction and skill projection manager.
30
+ statutor machine ... Random machine identity (mode 0600, rotation).
31
+ statutor worker ... Machine-local worker provenance (begin/record/show/active/complete/compare).
30
32
 
31
33
  No third-party dependencies. The policy format is a deterministic YAML subset;
32
34
  PyYAML is optional for ancillary tooling, never required by the trust floor.
@@ -1314,6 +1316,10 @@ TEMPLATES: dict[str, str] = {
1314
1316
  # HANDOFF
1315
1317
 
1316
1318
  last_verified: 1970-01-01 by `<command that proved the state below>`
1319
+ last_worker: unknown
1320
+ last_machine: unknown
1321
+ handoff_id: none
1322
+ supersedes: none
1317
1323
 
1318
1324
  ## Goal
1319
1325
  <the single objective of the current work stream>
@@ -1420,6 +1426,12 @@ def main() -> None:
1420
1426
  if mode == "global":
1421
1427
  import statutor_global_cli
1422
1428
  sys.exit(statutor_global_cli.main(argv[1:]))
1429
+ if mode == "machine":
1430
+ import statutor_worker
1431
+ sys.exit(statutor_worker.machine_cli(argv[1:]))
1432
+ if mode == "worker":
1433
+ import statutor_worker
1434
+ sys.exit(statutor_worker.worker_cli(argv[1:]))
1423
1435
  print(__doc__)
1424
1436
  sys.exit(64)
1425
1437
 
@@ -42,6 +42,7 @@ import sys
42
42
  from datetime import date, datetime
43
43
 
44
44
  import statutor_core
45
+ import statutor_worker
45
46
 
46
47
  SOFT_AGENTS_LINES = 120
47
48
  HANDOFF_STALE_DAYS = 3
@@ -141,6 +142,19 @@ def check(root: str) -> None:
141
142
  "bypassed the hook/floor (that's drift)."
142
143
  )
143
144
 
145
+ fields = statutor_worker.parse_handoff_fields(text)
146
+ if all(fields[name] is None
147
+ for name in statutor_worker.ATTRIBUTION_FIELDS):
148
+ warnings.append(
149
+ f"{handoff_filename} has no v0.5 worker attribution block "
150
+ "(last_worker/last_machine/handoff_id/supersedes) — pre-v0.5 "
151
+ "ledger, still valid; add it on the next rewrite and record "
152
+ "completion with `statutor worker complete --session <id>`."
153
+ )
154
+ else:
155
+ for problem in statutor_worker.validate_handoff_metadata(text):
156
+ errors.append(f"{handoff_filename}: {problem}")
157
+
144
158
  done_ids: set[str] = set()
145
159
  if os.path.isfile(p(tasks_filename)):
146
160
  state_body = open(p(tasks_filename), encoding="utf-8").read()