pgc-assembler 2.0.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.
- pgc_assembler-2.0.0/LICENSE +67 -0
- pgc_assembler-2.0.0/MANIFEST.in +15 -0
- pgc_assembler-2.0.0/NOTICE +11 -0
- pgc_assembler-2.0.0/PKG-INFO +148 -0
- pgc_assembler-2.0.0/README.md +124 -0
- pgc_assembler-2.0.0/VERSION +1 -0
- pgc_assembler-2.0.0/_build_hook.py +24 -0
- pgc_assembler-2.0.0/assembler/VERSION +1 -0
- pgc_assembler-2.0.0/assembler/__init__.py +27 -0
- pgc_assembler-2.0.0/assembler/cli.py +112 -0
- pgc_assembler-2.0.0/assembler/conformance.py +246 -0
- pgc_assembler-2.0.0/assembler/core.py +762 -0
- pgc_assembler-2.0.0/assembler/indexes.py +421 -0
- pgc_assembler-2.0.0/pgc_assembler.egg-info/PKG-INFO +148 -0
- pgc_assembler-2.0.0/pgc_assembler.egg-info/SOURCES.txt +18 -0
- pgc_assembler-2.0.0/pgc_assembler.egg-info/dependency_links.txt +1 -0
- pgc_assembler-2.0.0/pgc_assembler.egg-info/entry_points.txt +2 -0
- pgc_assembler-2.0.0/pgc_assembler.egg-info/top_level.txt +1 -0
- pgc_assembler-2.0.0/pyproject.toml +47 -0
- pgc_assembler-2.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
Copyright 2026 Bhash Ganti aka Bachi
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
------------------------
|
|
21
|
+
FULL LICENSE TEXT BELOW
|
|
22
|
+
------------------------
|
|
23
|
+
|
|
24
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
25
|
+
|
|
26
|
+
1. Definitions.
|
|
27
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
28
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
29
|
+
"Licensor" shall mean the copyright owner.
|
|
30
|
+
"Legal Entity" shall mean the union of the acting entity and all other
|
|
31
|
+
entities that control, are controlled by, or are under common control.
|
|
32
|
+
"You" shall mean an individual or Legal Entity exercising permissions.
|
|
33
|
+
"Source" form shall mean the preferred form for making modifications.
|
|
34
|
+
"Object" form shall mean any form resulting from mechanical transformation.
|
|
35
|
+
"Work" shall mean the work of authorship.
|
|
36
|
+
"Derivative Works" shall mean any work based on the Work.
|
|
37
|
+
"Contribution" shall mean any work intentionally submitted.
|
|
38
|
+
"Contributor" shall mean Licensor and any individual submitting Contributions.
|
|
39
|
+
|
|
40
|
+
2. Grant of Copyright License.
|
|
41
|
+
Each Contributor grants You a perpetual, worldwide, non-exclusive,
|
|
42
|
+
no-charge, royalty-free copyright license.
|
|
43
|
+
|
|
44
|
+
3. Grant of Patent License.
|
|
45
|
+
Each Contributor grants a patent license to make, use, sell, etc.
|
|
46
|
+
|
|
47
|
+
4. Redistribution.
|
|
48
|
+
You may reproduce and distribute copies provided that:
|
|
49
|
+
- You include a copy of this License
|
|
50
|
+
- You retain notices
|
|
51
|
+
- You state modifications
|
|
52
|
+
- You include NOTICE file if present
|
|
53
|
+
|
|
54
|
+
5. Submission of Contributions.
|
|
55
|
+
Contributions are under this License unless stated otherwise.
|
|
56
|
+
|
|
57
|
+
6. Trademarks.
|
|
58
|
+
This License does not grant trademark rights.
|
|
59
|
+
|
|
60
|
+
7. Disclaimer of Warranty.
|
|
61
|
+
Provided "AS IS", without warranties.
|
|
62
|
+
|
|
63
|
+
8. Limitation of Liability.
|
|
64
|
+
No liability for damages.
|
|
65
|
+
|
|
66
|
+
9. Accepting Warranty or Additional Liability.
|
|
67
|
+
You may offer support/warranty on your own behalf only.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# The in-tree build backend and the file it stages.
|
|
2
|
+
#
|
|
3
|
+
# `pyproject.toml` sets build-backend = "_build_hook" with backend-path = ["."],
|
|
4
|
+
# so the hook must travel in the sdist: `python -m build` builds the wheel FROM
|
|
5
|
+
# the sdist, in an isolated directory where anything not shipped does not exist.
|
|
6
|
+
# Without these two lines the sdist builds and the wheel step then fails with
|
|
7
|
+
# `Backend '_build_hook' is not available`.
|
|
8
|
+
#
|
|
9
|
+
# VERSION is the repo-root composition ordinal the hook copies into the package.
|
|
10
|
+
# Omitting it does not fail the build — `_stage_ordinal` skips a missing file —
|
|
11
|
+
# it produces a wheel whose ordinal is silently absent.
|
|
12
|
+
include _build_hook.py
|
|
13
|
+
include VERSION
|
|
14
|
+
|
|
15
|
+
global-exclude __pycache__ *.pyc .DS_Store
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
PGS — Protocol-Governed Systems
|
|
2
|
+
Copyright 2026 Bhash Ganti aka Bachi
|
|
3
|
+
|
|
4
|
+
This project introduces a protocol-first execution model in which:
|
|
5
|
+
|
|
6
|
+
- Behavior is declared in protocol artifacts
|
|
7
|
+
- Execution is performed by a deterministic runtime
|
|
8
|
+
- Capability implementations are bound at compile time
|
|
9
|
+
- Governance is enforced through invariants and assertions
|
|
10
|
+
|
|
11
|
+
Extensibility is achieved by declaration, not refactor.
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pgc-assembler
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: PGC snapshot assembler — composes compiled projections into a manifest-pinned executable snapshot (import package: assembler)
|
|
5
|
+
Author-email: Bhash Ganti <bachipeachy@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://omnibachi.org/
|
|
8
|
+
Project-URL: Repository, https://github.com/protocol-governed-computing/snapshot_assembler
|
|
9
|
+
Project-URL: Standard, https://doi.org/10.5281/zenodo.22150616
|
|
10
|
+
Keywords: protocol-governed-computing,pgc,snapshot,assembler,manifest
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
License-File: NOTICE
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# snapshot_assembler
|
|
26
|
+
|
|
27
|
+
**Protocol-Governed Computing — snapshot assembler** (import package: `assembler`).
|
|
28
|
+
|
|
29
|
+
Composes each domain's compiled projections (from the protocol compiler) into one **executable
|
|
30
|
+
snapshot** with a content-derived, **manifest-pinned identity**. The runtime consumes only the
|
|
31
|
+
assembled snapshot — never an individual repo's compiled layout.
|
|
32
|
+
|
|
33
|
+
> The assembly contract — what a compiled projection must look like for the assembler to
|
|
34
|
+
> accept it — is governed by the standard, not by this repository.
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
repos → protocol_compiler → each repo's compiled/ projections
|
|
38
|
+
→ snapshot_assembler → protocol-governed-computing/snapshot/ → runtime warm reboot
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The platform is an ordinary member of the composition — no singleton branch. The composition
|
|
42
|
+
currently assembles **seven domains**: `platform`, `workload`, `inspection`, `transformation`,
|
|
43
|
+
and the business domains `ai_governance`, `blockchain` and `book_library_mgmt`.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install pgc-assembler
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Once installed:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
snapshot_assembler --help
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Use
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# assemble sibling platform compiled/ -> sibling snapshot/
|
|
61
|
+
./assemble.sh
|
|
62
|
+
|
|
63
|
+
# explicit / multi-source (future domains)
|
|
64
|
+
./assemble.sh --source /abs/software_governance/snapshot/compiled --out /abs/protocol-governed-computing/snapshot
|
|
65
|
+
|
|
66
|
+
# module form
|
|
67
|
+
PYTHONPATH=. python -m assembler.cli assemble --source <compiled_root> --out <snapshot_dir>
|
|
68
|
+
PYTHONPATH=. python -m assembler.cli verify --out <snapshot_dir>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Product
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
protocol-governed-computing/snapshot/
|
|
75
|
+
manifest.json # COMMITTED — the identity + root of trust
|
|
76
|
+
tokenized/<domain>/ # regenerated build product (gitignored)
|
|
77
|
+
trust/<domain>/ # regenerated build product (gitignored)
|
|
78
|
+
vocabulary/<domain>/ # regenerated build product (gitignored)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- **`manifest.json` is the committed identity record.** The assembled projections are regenerated
|
|
82
|
+
build products whose contents MUST match the manifest during warm reboot.
|
|
83
|
+
- **`composite_hash`** is content-derived over the identity view of `domains[]` (per-domain
|
|
84
|
+
projection/attestation/graph hashes). Provenance and timestamps are excluded → same inputs +
|
|
85
|
+
same compiler + same assembler ⇒ same identity.
|
|
86
|
+
|
|
87
|
+
## Composition conformance
|
|
88
|
+
|
|
89
|
+
Assembly does not end at the manifest. **Composition Conformance** is the lifecycle phase after it:
|
|
90
|
+
rules that can only be asked of the whole — the ones a single domain build contains no evidence for.
|
|
91
|
+
It runs on every assemble and its result is written to `conformance/composition.json`, so a snapshot
|
|
92
|
+
carries the record of having been judged as a composition rather than as a pile of domains.
|
|
93
|
+
|
|
94
|
+
## Scope
|
|
95
|
+
|
|
96
|
+
- **Copy and pin:** each domain's projections are copied, hashes are lifted from compiler output, the
|
|
97
|
+
manifest is written, and round-trip `verify` runs after every `assemble`.
|
|
98
|
+
- **Vocabulary address-space reconciliation** remains the deferred real job. Collision detection is
|
|
99
|
+
enforced today; composing the reconciled forward/reverse maps across domains is not yet done, and
|
|
100
|
+
the composition has grown past the one-domain case that made it postponable.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
Apache-2.0.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## The package family
|
|
109
|
+
|
|
110
|
+
| Package | Repository | Role |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `pgc-compiler` | `protocol_compiler` | declarations → compiled projections |
|
|
113
|
+
| `pgc-assembler` | `snapshot_assembler` | projections → sealed snapshot |
|
|
114
|
+
| `pgc-runtime` | `protocol_runtime` | snapshot → governed execution |
|
|
115
|
+
| `pgc-inspector` | `snapshot_inspector` | snapshot → read-only inspection |
|
|
116
|
+
| `pgc-transformation` | `transformation` | change request → protocol artifacts |
|
|
117
|
+
| `pgc-governance` | `software_governance` | the governance surface and its capability implementations |
|
|
118
|
+
| `pgc-workloads` | `conformance_workloads` | the workloads that make conformance observable |
|
|
119
|
+
| `pgc-domains` | `business_domains` | the business domain implementations the composed snapshot binds |
|
|
120
|
+
|
|
121
|
+
`pip install pgc` brings in the whole family.
|
|
122
|
+
|
|
123
|
+
**Installing the toolchain is one of two steps.** The compiler resolves the governance surface from
|
|
124
|
+
`PGC_PLATFORM_ROOT` — fail-hard, cwd-independent, zero inference — so the *declarations* come from a
|
|
125
|
+
repository you point at, never from a wheel. A registry inside a package would be a second governance
|
|
126
|
+
surface competing with the repository's, and a build could then be governed by a stale copy.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
git clone https://github.com/protocol-governed-computing/software_governance
|
|
130
|
+
export PGC_PLATFORM_ROOT=$PWD/software_governance
|
|
131
|
+
pgc # reports what is installed and whether the anchor resolves
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`PGC_BUILD_ROOT` (compiled output, keeping the governance repo read-only) and `PGC_DOMAIN_ROOTS`
|
|
135
|
+
(additional domains contributing their own `registry/structures`) are optional.
|
|
136
|
+
|
|
137
|
+
**Versioning.** Two schemes, and the published version follows the second.
|
|
138
|
+
|
|
139
|
+
- **Internal** — each repository's `VERSION` file, a monotonic composition ordinal. PGC versions the
|
|
140
|
+
composition rather than each repo: they release together and the governance closure forces lockstep,
|
|
141
|
+
so the ordinal names which composition a repo belongs to. Development happens on `dev/<N>` and each
|
|
142
|
+
cycle is tagged `release-<N>`. This is not published.
|
|
143
|
+
- **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v2`**.
|
|
144
|
+
|
|
145
|
+
**The published version is the public one: `v2` is `2.0.0`.** The standard the packages implement is a
|
|
146
|
+
separate artifact on its own track and is not this number.
|
|
147
|
+
|
|
148
|
+
The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# snapshot_assembler
|
|
2
|
+
|
|
3
|
+
**Protocol-Governed Computing — snapshot assembler** (import package: `assembler`).
|
|
4
|
+
|
|
5
|
+
Composes each domain's compiled projections (from the protocol compiler) into one **executable
|
|
6
|
+
snapshot** with a content-derived, **manifest-pinned identity**. The runtime consumes only the
|
|
7
|
+
assembled snapshot — never an individual repo's compiled layout.
|
|
8
|
+
|
|
9
|
+
> The assembly contract — what a compiled projection must look like for the assembler to
|
|
10
|
+
> accept it — is governed by the standard, not by this repository.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
repos → protocol_compiler → each repo's compiled/ projections
|
|
14
|
+
→ snapshot_assembler → protocol-governed-computing/snapshot/ → runtime warm reboot
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The platform is an ordinary member of the composition — no singleton branch. The composition
|
|
18
|
+
currently assembles **seven domains**: `platform`, `workload`, `inspection`, `transformation`,
|
|
19
|
+
and the business domains `ai_governance`, `blockchain` and `book_library_mgmt`.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install pgc-assembler
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Once installed:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
snapshot_assembler --help
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Use
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# assemble sibling platform compiled/ -> sibling snapshot/
|
|
37
|
+
./assemble.sh
|
|
38
|
+
|
|
39
|
+
# explicit / multi-source (future domains)
|
|
40
|
+
./assemble.sh --source /abs/software_governance/snapshot/compiled --out /abs/protocol-governed-computing/snapshot
|
|
41
|
+
|
|
42
|
+
# module form
|
|
43
|
+
PYTHONPATH=. python -m assembler.cli assemble --source <compiled_root> --out <snapshot_dir>
|
|
44
|
+
PYTHONPATH=. python -m assembler.cli verify --out <snapshot_dir>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Product
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
protocol-governed-computing/snapshot/
|
|
51
|
+
manifest.json # COMMITTED — the identity + root of trust
|
|
52
|
+
tokenized/<domain>/ # regenerated build product (gitignored)
|
|
53
|
+
trust/<domain>/ # regenerated build product (gitignored)
|
|
54
|
+
vocabulary/<domain>/ # regenerated build product (gitignored)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **`manifest.json` is the committed identity record.** The assembled projections are regenerated
|
|
58
|
+
build products whose contents MUST match the manifest during warm reboot.
|
|
59
|
+
- **`composite_hash`** is content-derived over the identity view of `domains[]` (per-domain
|
|
60
|
+
projection/attestation/graph hashes). Provenance and timestamps are excluded → same inputs +
|
|
61
|
+
same compiler + same assembler ⇒ same identity.
|
|
62
|
+
|
|
63
|
+
## Composition conformance
|
|
64
|
+
|
|
65
|
+
Assembly does not end at the manifest. **Composition Conformance** is the lifecycle phase after it:
|
|
66
|
+
rules that can only be asked of the whole — the ones a single domain build contains no evidence for.
|
|
67
|
+
It runs on every assemble and its result is written to `conformance/composition.json`, so a snapshot
|
|
68
|
+
carries the record of having been judged as a composition rather than as a pile of domains.
|
|
69
|
+
|
|
70
|
+
## Scope
|
|
71
|
+
|
|
72
|
+
- **Copy and pin:** each domain's projections are copied, hashes are lifted from compiler output, the
|
|
73
|
+
manifest is written, and round-trip `verify` runs after every `assemble`.
|
|
74
|
+
- **Vocabulary address-space reconciliation** remains the deferred real job. Collision detection is
|
|
75
|
+
enforced today; composing the reconciled forward/reverse maps across domains is not yet done, and
|
|
76
|
+
the composition has grown past the one-domain case that made it postponable.
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
Apache-2.0.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## The package family
|
|
85
|
+
|
|
86
|
+
| Package | Repository | Role |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `pgc-compiler` | `protocol_compiler` | declarations → compiled projections |
|
|
89
|
+
| `pgc-assembler` | `snapshot_assembler` | projections → sealed snapshot |
|
|
90
|
+
| `pgc-runtime` | `protocol_runtime` | snapshot → governed execution |
|
|
91
|
+
| `pgc-inspector` | `snapshot_inspector` | snapshot → read-only inspection |
|
|
92
|
+
| `pgc-transformation` | `transformation` | change request → protocol artifacts |
|
|
93
|
+
| `pgc-governance` | `software_governance` | the governance surface and its capability implementations |
|
|
94
|
+
| `pgc-workloads` | `conformance_workloads` | the workloads that make conformance observable |
|
|
95
|
+
| `pgc-domains` | `business_domains` | the business domain implementations the composed snapshot binds |
|
|
96
|
+
|
|
97
|
+
`pip install pgc` brings in the whole family.
|
|
98
|
+
|
|
99
|
+
**Installing the toolchain is one of two steps.** The compiler resolves the governance surface from
|
|
100
|
+
`PGC_PLATFORM_ROOT` — fail-hard, cwd-independent, zero inference — so the *declarations* come from a
|
|
101
|
+
repository you point at, never from a wheel. A registry inside a package would be a second governance
|
|
102
|
+
surface competing with the repository's, and a build could then be governed by a stale copy.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git clone https://github.com/protocol-governed-computing/software_governance
|
|
106
|
+
export PGC_PLATFORM_ROOT=$PWD/software_governance
|
|
107
|
+
pgc # reports what is installed and whether the anchor resolves
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`PGC_BUILD_ROOT` (compiled output, keeping the governance repo read-only) and `PGC_DOMAIN_ROOTS`
|
|
111
|
+
(additional domains contributing their own `registry/structures`) are optional.
|
|
112
|
+
|
|
113
|
+
**Versioning.** Two schemes, and the published version follows the second.
|
|
114
|
+
|
|
115
|
+
- **Internal** — each repository's `VERSION` file, a monotonic composition ordinal. PGC versions the
|
|
116
|
+
composition rather than each repo: they release together and the governance closure forces lockstep,
|
|
117
|
+
so the ordinal names which composition a repo belongs to. Development happens on `dev/<N>` and each
|
|
118
|
+
cycle is tagged `release-<N>`. This is not published.
|
|
119
|
+
- **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v2`**.
|
|
120
|
+
|
|
121
|
+
**The published version is the public one: `v2` is `2.0.0`.** The standard the packages implement is a
|
|
122
|
+
separate artifact on its own track and is not this number.
|
|
123
|
+
|
|
124
|
+
The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
14
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Build-time hook: stage the composition ordinal inside the package.
|
|
2
|
+
|
|
3
|
+
The repo-root VERSION is the single authored declaration and `release.sh`
|
|
4
|
+
enforces agreement across every repo. A wheel has no repo root, so the value is
|
|
5
|
+
copied into the package during the build. The copy is a build artifact —
|
|
6
|
+
gitignored, regenerated every build, never edited.
|
|
7
|
+
"""
|
|
8
|
+
from setuptools import build_meta as _orig
|
|
9
|
+
from setuptools.build_meta import * # noqa: F401,F403
|
|
10
|
+
import pathlib
|
|
11
|
+
|
|
12
|
+
def _stage_ordinal():
|
|
13
|
+
root = pathlib.Path(__file__).parent
|
|
14
|
+
src = root / "VERSION"
|
|
15
|
+
if src.is_file():
|
|
16
|
+
(root / "assembler" / "VERSION").write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
|
|
17
|
+
|
|
18
|
+
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
|
19
|
+
_stage_ordinal()
|
|
20
|
+
return _orig.build_wheel(wheel_directory, config_settings, metadata_directory)
|
|
21
|
+
|
|
22
|
+
def build_sdist(sdist_directory, config_settings=None):
|
|
23
|
+
_stage_ordinal()
|
|
24
|
+
return _orig.build_sdist(sdist_directory, config_settings)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
14
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""PGC Snapshot Assembler — composes compiled projections into a manifest-pinned snapshot.
|
|
2
|
+
|
|
3
|
+
Contract: snapshot_assembler/doc/SNAPSHOT_ASSEMBLY_CONTRACT.md
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _release() -> str:
|
|
10
|
+
"""The composition's release ordinal, read from the repo's single version declaration.
|
|
11
|
+
|
|
12
|
+
PGC versions the *composition*, not each repo independently: all repos are released together
|
|
13
|
+
and the governance closure forces lockstep, so a monotonic integer names which composition a
|
|
14
|
+
repo belongs to. `VERSION` is the sole declaration — pyproject derives it, and so does this.
|
|
15
|
+
Never restate it as a literal; two statements of one fact is how they drift apart.
|
|
16
|
+
"""
|
|
17
|
+
# Source tree and editable installs: the repo-root VERSION is authoritative.
|
|
18
|
+
declared = Path(__file__).resolve().parent.parent / "VERSION"
|
|
19
|
+
if declared.is_file():
|
|
20
|
+
return declared.read_text(encoding="utf-8").strip()
|
|
21
|
+
# Installed wheel: no repo root. The ordinal is staged into the package at
|
|
22
|
+
# build time by _build_hook.py — a build artifact, not a second declaration.
|
|
23
|
+
return (Path(__file__).resolve().parent / "VERSION").read_text(encoding="utf-8").strip()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
ASSEMBLER_VERSION = _release() # derived from VERSION — never edited here
|
|
27
|
+
MANIFEST_VERSION = "v0"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cli.py — PGC snapshot assembler CLI.
|
|
3
|
+
|
|
4
|
+
assemble — compose compiled projections into the assembled snapshot + manifest,
|
|
5
|
+
then run Composition Conformance over the result
|
|
6
|
+
verify — verify an assembled snapshot against its manifest (root of trust)
|
|
7
|
+
conform — run Composition Conformance alone against an assembled snapshot
|
|
8
|
+
|
|
9
|
+
Assembly and Composition Conformance are distinct lifecycle phases, not one step: the assembler
|
|
10
|
+
composes and proves identity; the conformance phase proves governance properties of the
|
|
11
|
+
composition. `assemble` runs both because an unproven snapshot should never be left on disk
|
|
12
|
+
looking finished — but each is separately invocable, and neither implements the other.
|
|
13
|
+
|
|
14
|
+
Paths are explicit or resolved from documented sibling defaults. No cwd guessing.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import json
|
|
21
|
+
import os
|
|
22
|
+
import sys
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
from assembler import conformance, core
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _build_parser() -> argparse.ArgumentParser:
|
|
29
|
+
p = argparse.ArgumentParser(prog="snapshot_assembler", description="PGC snapshot assembler")
|
|
30
|
+
subs = p.add_subparsers(dest="command", required=True)
|
|
31
|
+
|
|
32
|
+
a = subs.add_parser("assemble", help="Compose compiled projections into the assembled snapshot")
|
|
33
|
+
a.add_argument(
|
|
34
|
+
"--source", action="append", required=True, metavar="COMPILED_ROOT",
|
|
35
|
+
help="A compiler compiled/ root (repeatable). e.g. .../software_governance/snapshot/compiled",
|
|
36
|
+
)
|
|
37
|
+
a.add_argument(
|
|
38
|
+
"--out", required=True, metavar="SNAPSHOT_DIR",
|
|
39
|
+
help="Assembled snapshot output dir (the product). e.g. .../protocol-governed-computing/snapshot",
|
|
40
|
+
)
|
|
41
|
+
a.add_argument(
|
|
42
|
+
"--profile", default=os.environ.get("PGC_SNAPSHOT_PROFILE", ""), metavar="PROFILE_IDENTITY",
|
|
43
|
+
help="The profile identity this snapshot claims (3b SN-5). Required; a snapshot that claims "
|
|
44
|
+
"none cannot have clause 4 of 3b §7 evaluated about it.",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
v = subs.add_parser("verify", help="Verify an assembled snapshot against its manifest")
|
|
48
|
+
v.add_argument("--out", required=True, metavar="SNAPSHOT_DIR", help="Assembled snapshot dir to verify")
|
|
49
|
+
|
|
50
|
+
c = subs.add_parser("conform", help="Run Composition Conformance against an assembled snapshot")
|
|
51
|
+
c.add_argument("--out", required=True, metavar="SNAPSHOT_DIR", help="Assembled snapshot dir to check")
|
|
52
|
+
|
|
53
|
+
return p
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _fatal(msg: str) -> None:
|
|
57
|
+
print(f"[assembler] Error: {msg}", file=sys.stderr)
|
|
58
|
+
sys.exit(1)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main() -> None:
|
|
62
|
+
args = _build_parser().parse_args()
|
|
63
|
+
|
|
64
|
+
if args.command == "assemble":
|
|
65
|
+
source_roots = [Path(s).resolve() for s in args.source]
|
|
66
|
+
out_root = Path(args.out).resolve()
|
|
67
|
+
for s in source_roots:
|
|
68
|
+
if not s.is_dir():
|
|
69
|
+
_fatal(f"source root is not a directory: {s}")
|
|
70
|
+
try:
|
|
71
|
+
manifest = core.assemble(source_roots, out_root, args.profile)
|
|
72
|
+
core.verify_snapshot(out_root) # round-trip self-check
|
|
73
|
+
except core.AssemblyError as exc:
|
|
74
|
+
_fatal(str(exc))
|
|
75
|
+
|
|
76
|
+
doms = [d["domain"] for d in manifest["domains"]]
|
|
77
|
+
print(f"[assembler] Assembled {len(doms)} domain(s): {', '.join(doms)}")
|
|
78
|
+
print(f"[assembler] snapshot_id: {manifest['snapshot_id']}")
|
|
79
|
+
print(f"[assembler] out: {out_root}")
|
|
80
|
+
print(f"[assembler] manifest: {out_root / 'manifest.json'}")
|
|
81
|
+
print("[assembler] round-trip verify: OK")
|
|
82
|
+
|
|
83
|
+
# Composition Conformance — a separate phase over the composed snapshot.
|
|
84
|
+
try:
|
|
85
|
+
ev = conformance.check_composition(out_root)
|
|
86
|
+
except conformance.ConformanceError as exc:
|
|
87
|
+
_fatal(str(exc))
|
|
88
|
+
print(f"[conformance] composition: {ev['status']} "
|
|
89
|
+
f"({ev['rules_evaluated']} rule(s) over {ev['artifacts_examined']} artifacts)")
|
|
90
|
+
|
|
91
|
+
elif args.command == "verify":
|
|
92
|
+
out_root = Path(args.out).resolve()
|
|
93
|
+
try:
|
|
94
|
+
manifest = core.verify_snapshot(out_root)
|
|
95
|
+
except core.AssemblyError as exc:
|
|
96
|
+
_fatal(str(exc))
|
|
97
|
+
print(f"[assembler] VERIFIED snapshot_id={manifest['snapshot_id']}")
|
|
98
|
+
print(f"[assembler] domains: {json.dumps([d['domain'] for d in manifest['domains']])}")
|
|
99
|
+
|
|
100
|
+
elif args.command == "conform":
|
|
101
|
+
out_root = Path(args.out).resolve()
|
|
102
|
+
try:
|
|
103
|
+
ev = conformance.check_composition(out_root)
|
|
104
|
+
except conformance.ConformanceError as exc:
|
|
105
|
+
_fatal(str(exc))
|
|
106
|
+
print(f"[conformance] {ev['status']} snapshot_id={ev['snapshot_id']}")
|
|
107
|
+
for f in ev["findings"]:
|
|
108
|
+
print(f" {f['status']:<7} {f['invariant']:<58} {f['message']}")
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main()
|