pgc-transformation 2.0.0__py3-none-any.whl
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_transformation-2.0.0.dist-info/METADATA +274 -0
- pgc_transformation-2.0.0.dist-info/RECORD +66 -0
- pgc_transformation-2.0.0.dist-info/WHEEL +5 -0
- pgc_transformation-2.0.0.dist-info/entry_points.txt +2 -0
- pgc_transformation-2.0.0.dist-info/licenses/LICENSE +67 -0
- pgc_transformation-2.0.0.dist-info/licenses/NOTICE +11 -0
- pgc_transformation-2.0.0.dist-info/top_level.txt +1 -0
- transformation/__init__.py +5 -0
- transformation/__main__.py +4 -0
- transformation/baseline.py +134 -0
- transformation/build/__init__.py +0 -0
- transformation/build/completeness.py +176 -0
- transformation/build/generators.py +170 -0
- transformation/build/render.py +1194 -0
- transformation/cli.py +910 -0
- transformation/design/__init__.py +6 -0
- transformation/design/catalog.py +159 -0
- transformation/design/checks.py +2966 -0
- transformation/design/derive.py +207 -0
- transformation/design/emit.py +415 -0
- transformation/design/evaluate.py +172 -0
- transformation/design/families.py +96 -0
- transformation/design/merit.py +155 -0
- transformation/design/meta.py +348 -0
- transformation/design/oracle.py +96 -0
- transformation/design/p0_change_seed/__init__.py +0 -0
- transformation/design/p0_change_seed/rules.py +92 -0
- transformation/design/p1_change_request/__init__.py +0 -0
- transformation/design/p1_change_request/rules.py +153 -0
- transformation/design/p2_domain_model/__init__.py +0 -0
- transformation/design/p2_domain_model/rules.py +130 -0
- transformation/design/p3_analysis_loop/__init__.py +1 -0
- transformation/design/p3_analysis_loop/rules.py +210 -0
- transformation/design/p4_business_model/__init__.py +1 -0
- transformation/design/p4_business_model/rules.py +169 -0
- transformation/design/p5_business_intent/__init__.py +1 -0
- transformation/design/p5_business_intent/rules.py +247 -0
- transformation/design/p6_governance_intent/__init__.py +1 -0
- transformation/design/p6_governance_intent/rules.py +233 -0
- transformation/design/p7_design_intent/__init__.py +1 -0
- transformation/design/p7_design_intent/rules.py +1179 -0
- transformation/design/p8_authoring_mandate/__init__.py +1 -0
- transformation/design/p8_authoring_mandate/rules.py +236 -0
- transformation/design/project.py +178 -0
- transformation/design/read.py +155 -0
- transformation/design/rules.py +190 -0
- transformation/design/sealed.py +55 -0
- transformation/design/template_reader.py +277 -0
- transformation/implementation/__init__.py +0 -0
- transformation/implementation/capability_transforms/__init__.py +0 -0
- transformation/implementation/capability_transforms/atoms/__init__.py +0 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_attribute_provenance_v0.py +73 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_evaluate_rules_v0.py +97 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_measure_completeness_v0.py +72 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_parse_prior_phases_v0.py +64 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_parse_registers_v0.py +53 -0
- transformation/implementation/capability_transforms/atoms/ct_pure_render_artifacts_v0.py +66 -0
- transformation/templates/p0_change_seed_template_v0.md +250 -0
- transformation/templates/p1_change_request_template_v0.md +349 -0
- transformation/templates/p2_domain_model_template_v0.md +272 -0
- transformation/templates/p3_analysis_loop_template_v0.md +196 -0
- transformation/templates/p4_business_model_template_v0.md +238 -0
- transformation/templates/p5_business_intent_template_v0.md +216 -0
- transformation/templates/p6_governance_intent_template_v0.md +205 -0
- transformation/templates/p7_design_intent_template_v0.md +547 -0
- transformation/templates/p8_authoring_mandate_template_v0.md +172 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pgc-transformation
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: PGC transformation compiler — the governed change request to authoring mandate pipeline (P0-P8), and the construction compiler that renders artifacts from an approved design (command: tc)
|
|
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/transformation
|
|
9
|
+
Project-URL: Standard, https://doi.org/10.5281/zenodo.22150616
|
|
10
|
+
Keywords: protocol-governed-computing,pgc,transformation,change-request,evolution
|
|
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 :: Compilers
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
License-File: NOTICE
|
|
23
|
+
Requires-Dist: pgc-inspector>=2.0.0
|
|
24
|
+
Requires-Dist: pgc-runtime>=2.0.0
|
|
25
|
+
Requires-Dist: click
|
|
26
|
+
Requires-Dist: pyyaml
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# transformation
|
|
30
|
+
|
|
31
|
+
**The governed Change Request → Protocol Artifact pipeline**, and it holds **two compilers**.
|
|
32
|
+
|
|
33
|
+
| Compiler | Transforms | Code | Registry |
|
|
34
|
+
|---|---|---|---|
|
|
35
|
+
| **Design** | problem → design | `transformation/design/` | `registry/design/` |
|
|
36
|
+
| **Construction** | design → protocol artifacts | `transformation/build/` | `registry/build/` |
|
|
37
|
+
|
|
38
|
+
They are two because they fail differently. A *design* failure is a mandate that is incomplete or
|
|
39
|
+
contradictory, and a phase's rule set catches it. A *construction* failure is a mandate that was
|
|
40
|
+
valid and did not uniquely determine an artifact — only the thing that renders can expose that, and
|
|
41
|
+
the repair amends the design language rather than one register. Merging them would blur two failure
|
|
42
|
+
classes that different layers repair.
|
|
43
|
+
|
|
44
|
+
The repository is named for the lifecycle, not for either compiler. **`transformation` is not a
|
|
45
|
+
third compiler.** A functional rehost of RI-0's `pgs_change_mgmt`, extended well past where RI-0
|
|
46
|
+
stopped.
|
|
47
|
+
|
|
48
|
+
A change begins as a plain-language problem statement and is driven through gated phases into an
|
|
49
|
+
**Authoring Mandate** — a complete, reviewable dossier — *before* any protocol artifact is written.
|
|
50
|
+
Only after the mandate is approved are artifacts authored, and the protocol compiler then governs
|
|
51
|
+
their admissibility.
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
problem statement → P0 → Gate 0 → seed → dossier P1..P7 → Gate 1 → P8 → Gate 2
|
|
55
|
+
→ construction → authored artifacts
|
|
56
|
+
→ protocol_compiler S1..S9 → snapshot_assembler → conformance → runtime → trace
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
This pipeline is measured in **phases (P0–P8)**; `protocol_compiler` is measured in **stages
|
|
60
|
+
(S1–S9)**. RI-0 numbered both S1–S7/S1–S9, which made every piece of evidence ambiguous about which
|
|
61
|
+
pipeline produced it. A dossier has phases, a compilation has stages, and nothing uses one word for
|
|
62
|
+
the other.
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install pgc-transformation
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Once installed:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
tc --help
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Build-time tool
|
|
77
|
+
|
|
78
|
+
`transformation` is **CLI only** — no TI/TE boundary contract, no Operation Identity, not
|
|
79
|
+
reachable over transport. A boundary contract governs a runtime surface served from a sealed
|
|
80
|
+
snapshot; this tool runs *before* a snapshot exists, its output is authored artifacts a human
|
|
81
|
+
gates, and its only reader is the person driving the change.
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
tc phase list # phases this build governs
|
|
85
|
+
tc phase check --phase p0 <seed.md> # structural oracle — ADMISSIBLE / INADMISSIBLE
|
|
86
|
+
tc phase check --phase p1 <register.md>
|
|
87
|
+
tc phase check --phase p2 <register.md> --snapshot <root> # grounds against the composition
|
|
88
|
+
tc phase template --phase p1 # the required section structure
|
|
89
|
+
tc phase rules --phase p1 # the declared rule set
|
|
90
|
+
tc phase project <prior.md> --phase p1 --out <doc.md> # phases that decide nothing
|
|
91
|
+
|
|
92
|
+
tc phase meta # do the rule sets themselves hold?
|
|
93
|
+
tc phase emit --check # are the sealed workflows current?
|
|
94
|
+
|
|
95
|
+
tc baseline show --snapshot <root> # the composition present, as a pin
|
|
96
|
+
tc baseline verify <pin.json> --snapshot <root>
|
|
97
|
+
tc baseline approve <pin.json> --phase p2 --by <who>
|
|
98
|
+
|
|
99
|
+
tc construction check <dossier> --snapshot <root> # does the design determine its artifacts?
|
|
100
|
+
tc construction emit <dossier> --root <domain> # render them, at 100% or not at all
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Two of these judge the pipeline rather than a dossier. `tc phase meta` asserts that every declared
|
|
104
|
+
rule can run and every implemented mechanism is declared — if that correspondence breaks, a verdict
|
|
105
|
+
over a document is meaningless, because a rule that cannot run reports green over a subject it never
|
|
106
|
+
evaluated. `tc phase emit --check` asserts the sealed copy of a rule set still agrees with the
|
|
107
|
+
generator that produces it; a rule added after a workflow was emitted once left 52 rules sealed
|
|
108
|
+
against 55 declared, and every run reported confidently on the smaller set. Both belong in a build.
|
|
109
|
+
|
|
110
|
+
`tc construction check` measures **determinacy** before anything is written: the fraction of the
|
|
111
|
+
facts the artifacts require that the design determines. Below 100% nothing is emitted, because a
|
|
112
|
+
generator choosing a value it was not given is a generator inventing one.
|
|
113
|
+
|
|
114
|
+
## The two loops
|
|
115
|
+
|
|
116
|
+
`$W` is the workspace root holding the sibling repos.
|
|
117
|
+
|
|
118
|
+
**After editing a dossier's P7 or P8** — skipping a step leaves the snapshot describing a design that
|
|
119
|
+
no longer exists:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
D=$W/business_domains/book_library_mgmt/cr_dossiers/cr_01_catalog
|
|
123
|
+
|
|
124
|
+
tc construction check $D --snapshot $W/snapshot
|
|
125
|
+
tc construction emit $D --root $W/business_domains/book_library_mgmt
|
|
126
|
+
|
|
127
|
+
python $W/transformation/scripts/testbed/construction_acceptance.py
|
|
128
|
+
$W/protocol_compiler/compile_domain.sh $W/business_domains/book_library_mgmt
|
|
129
|
+
PGC_SNAPSHOT_PROFILE=REFERENCE_PLATFORM_PROFILE_V1 $W/snapshot_assembler/assemble.sh
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`--snapshot` on the check is not optional in practice. Completeness never looks at what already
|
|
133
|
+
exists, so an artifact inventoried `EXTEND` is rendered whole and replaces its predecessor — a design
|
|
134
|
+
stating only the delta deletes the rest, at 100% completeness. The flag is what runs the narrowing
|
|
135
|
+
check; without it that check does not run, and says so.
|
|
136
|
+
|
|
137
|
+
Construction writes into `data/`, never into the domain. **Promotion is a separate, deliberate act.**
|
|
138
|
+
A `tc construction build` CLI existed once and was removed, because it duplicated a governed path
|
|
139
|
+
with an ungoverned one.
|
|
140
|
+
|
|
141
|
+
A new capability transform is a protocol artifact *and* a Python implementation. Construction renders
|
|
142
|
+
the first; the second is hand-authored at
|
|
143
|
+
`business_domains/<domain>/implementation/capability_transforms/atoms/<code_lower>.py` with a
|
|
144
|
+
callable `execute(inputs, context)` raising `CTExecutionError`. A CT whose module is missing returns
|
|
145
|
+
nothing and its contract yields `VIOLATION` — while every check above still passes.
|
|
146
|
+
|
|
147
|
+
**After changing a phase's rule set** — the rules are declared in
|
|
148
|
+
`transformation/design/<phase>/rules.py` and *sealed* into that phase's workflow artifact. Editing
|
|
149
|
+
the declaration alone leaves `tc phase check` and the governed workflow evaluating different rule
|
|
150
|
+
sets:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
tc phase emit --check # names the drifted phase
|
|
154
|
+
python $W/transformation/scripts/emit_rule_sets.py # re-seal
|
|
155
|
+
$W/protocol_compiler/compile_domain.sh $W/transformation
|
|
156
|
+
PGC_SNAPSHOT_PROFILE=REFERENCE_PLATFORM_PROFILE_V1 $W/snapshot_assembler/assemble.sh
|
|
157
|
+
python $W/transformation/scripts/testbed/build_fixtures.py
|
|
158
|
+
python $W/transformation/scripts/testbed/build_payloads.py
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Fixtures and payloads are **derived from the live dossier** — never hand-edit one; change the dossier
|
|
162
|
+
or the mutator in `build_fixtures.py`. A derived fixture cannot go stale silently, because the
|
|
163
|
+
derivation raises rather than producing a wrong one.
|
|
164
|
+
|
|
165
|
+
The fast inner loop is `python scripts/testbed/differential.py`, which drives the capability
|
|
166
|
+
transforms directly. It proves the rule sets and the check logic and nothing about workflow wiring;
|
|
167
|
+
`scripts/testbed/e2e_phases_test.py` boots the assembled snapshot and proves the wiring. Neither
|
|
168
|
+
substitutes for the other — a workflow that bound `$.capability_result.header` across nodes passed
|
|
169
|
+
the differential and failed immediately under the runtime.
|
|
170
|
+
|
|
171
|
+
From P2 a phase also needs its **priors**, or the handoff between phases goes unchecked:
|
|
172
|
+
P1←p0 · P2←p1 · P3←p2 · P4←p3 · **P5←p0** · P6←p5 · P7←p5+p6 · P8←p7. P5 reads the seed, not P4: the
|
|
173
|
+
subdomain purpose is authored once at P0, has no register to travel in through P1–P4, and reappears
|
|
174
|
+
at P5.
|
|
175
|
+
|
|
176
|
+
## Why "transformation", not "change management"
|
|
177
|
+
|
|
178
|
+
**PGC evolution is never greenfield.** Every change is a transformation of an existing composition:
|
|
179
|
+
a new domain still compiles against the platform's normative closure and composes into a snapshot
|
|
180
|
+
that already exists. The name states what the tool does; `change_mgmt` named the process around it.
|
|
181
|
+
|
|
182
|
+
That property is also what makes the tool testable. Its distinguishing logic — REUSE / EXTEND
|
|
183
|
+
decisions, placement, ownership, semantic preservation, roundtrip equivalence — is meaningful only
|
|
184
|
+
against a baseline. A greenfield run exercises none of it.
|
|
185
|
+
|
|
186
|
+
## Relationship to the rest of the toolchain
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
protocol_compiler source → compiled projections
|
|
190
|
+
snapshot_assembler projections → assembled snapshot
|
|
191
|
+
protocol_runtime snapshot → execution
|
|
192
|
+
snapshot_inspector snapshot → inspection
|
|
193
|
+
transformation problem → change request → authoring mandate (this repo)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Every snapshot fact this pipeline needs arrives through
|
|
197
|
+
`inspector.api.query(operation, params, snapshot_root)`. It imports nothing from `compiler.*`.
|
|
198
|
+
RI-0's pipeline reached directly into `pgs_compiler.compiler.projections` to build indexes itself;
|
|
199
|
+
removing that coupling is why `snapshot_inspector` was completed first, and building this repo
|
|
200
|
+
without it is that work's acceptance test.
|
|
201
|
+
|
|
202
|
+
## Validation is pinned
|
|
203
|
+
|
|
204
|
+
Runs are validated against a **named, frozen snapshot**, never "the current snapshot" — every
|
|
205
|
+
register a snapshot-reading phase emits encodes facts about one specific composition. A run that
|
|
206
|
+
observes a different `snapshot_id` fails before any phase executes.
|
|
207
|
+
|
|
208
|
+
Rebaselining is deliberate and has two halves. `tc baseline verify` proves the composition is the
|
|
209
|
+
one named; `tc baseline approve` records that someone re-read the registers asserting facts about
|
|
210
|
+
it. Which registers a phase owes is derived from its rule set — a register rests on a snapshot fact
|
|
211
|
+
exactly when a rule governing it consults an observation. The approval lives in the pin, so re-pinning
|
|
212
|
+
drops it: an approval is against one composition and survives no other.
|
|
213
|
+
|
|
214
|
+
## Documents
|
|
215
|
+
|
|
216
|
+
- `doc/THE_SHAPE_OF_A_CHANGE_V0.md` — when a subject is a new change request and when it is the
|
|
217
|
+
same one re-authored, and which artifacts a governance change may amend.
|
|
218
|
+
- `doc/TRANSFORMATION_COMPILER_PLAN_V1_ADDENDUM_A.md` — the `book_library_mgmt` domain, its
|
|
219
|
+
decomposition, and the change request sequence it is worked through.
|
|
220
|
+
- `doc/TRANSFORMATION_COMPILER_PLAN_V1_ADDENDUM_B.md` — self-hosting: why the pipeline's first
|
|
221
|
+
governed change is itself, and what that settles. Plan V1 itself has been removed; the addenda are
|
|
222
|
+
what survives, and a settled ruling is restated where it is needed rather than by restoring the
|
|
223
|
+
plan.
|
|
224
|
+
- `doc/REGISTER_COVERAGE_VERIFICATION.md` — whether a design can state, for an artifact it amends,
|
|
225
|
+
every fact that artifact carries. Four observed instances of one pattern: a fact the authoring
|
|
226
|
+
path never had to state because authoring supplies it, and the amending path must state and
|
|
227
|
+
cannot.
|
|
228
|
+
- `templates/` — the phase templates. **These are the authority**: registers, columns, controlled
|
|
229
|
+
vocabularies and optionality are read from them, and rule sets are derived. A shape declared
|
|
230
|
+
anywhere else is not a template.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## The package family
|
|
235
|
+
|
|
236
|
+
| Package | Repository | Role |
|
|
237
|
+
|---|---|---|
|
|
238
|
+
| `pgc-compiler` | `protocol_compiler` | declarations → compiled projections |
|
|
239
|
+
| `pgc-assembler` | `snapshot_assembler` | projections → sealed snapshot |
|
|
240
|
+
| `pgc-runtime` | `protocol_runtime` | snapshot → governed execution |
|
|
241
|
+
| `pgc-inspector` | `snapshot_inspector` | snapshot → read-only inspection |
|
|
242
|
+
| `pgc-transformation` | `transformation` | change request → protocol artifacts |
|
|
243
|
+
| `pgc-governance` | `software_governance` | the governance surface and its capability implementations |
|
|
244
|
+
| `pgc-workloads` | `conformance_workloads` | the workloads that make conformance observable |
|
|
245
|
+
| `pgc-domains` | `business_domains` | the business domain implementations the composed snapshot binds |
|
|
246
|
+
|
|
247
|
+
`pip install pgc` brings in the whole family.
|
|
248
|
+
|
|
249
|
+
**Installing the toolchain is one of two steps.** The compiler resolves the governance surface from
|
|
250
|
+
`PGC_PLATFORM_ROOT` — fail-hard, cwd-independent, zero inference — so the *declarations* come from a
|
|
251
|
+
repository you point at, never from a wheel. A registry inside a package would be a second governance
|
|
252
|
+
surface competing with the repository's, and a build could then be governed by a stale copy.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
git clone https://github.com/protocol-governed-computing/software_governance
|
|
256
|
+
export PGC_PLATFORM_ROOT=$PWD/software_governance
|
|
257
|
+
pgc # reports what is installed and whether the anchor resolves
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`PGC_BUILD_ROOT` (compiled output, keeping the governance repo read-only) and `PGC_DOMAIN_ROOTS`
|
|
261
|
+
(additional domains contributing their own `registry/structures`) are optional.
|
|
262
|
+
|
|
263
|
+
**Versioning.** Two schemes, and the published version follows the second.
|
|
264
|
+
|
|
265
|
+
- **Internal** — each repository's `VERSION` file, a monotonic composition ordinal. PGC versions the
|
|
266
|
+
composition rather than each repo: they release together and the governance closure forces lockstep,
|
|
267
|
+
so the ordinal names which composition a repo belongs to. Development happens on `dev/<N>` and each
|
|
268
|
+
cycle is tagged `release-<N>`. This is not published.
|
|
269
|
+
- **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v2`**.
|
|
270
|
+
|
|
271
|
+
**The published version is the public one: `v2` is `2.0.0`.** The standard the packages implement is a
|
|
272
|
+
separate artifact on its own track and is not this number.
|
|
273
|
+
|
|
274
|
+
The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
pgc_transformation-2.0.0.dist-info/licenses/LICENSE,sha256=wf4s-Px76q2zHB2b8Gbvuu4ULua8AMds2IY01MkBn0A,2544
|
|
2
|
+
pgc_transformation-2.0.0.dist-info/licenses/NOTICE,sha256=nE4--l6r3rMCz0nVaFyFohZtY4NYADnrhcS9K2pdNr0,407
|
|
3
|
+
transformation/__init__.py,sha256=q8c7McgKNFK9xjFfCt_Mj8RVT8K2tcuNu543bR5i25k,169
|
|
4
|
+
transformation/__main__.py,sha256=V3J6qfRbm9UDicBQ2qtxy88V_OK5RWdocqfA5wMsSJw,75
|
|
5
|
+
transformation/baseline.py,sha256=_On_kaBv1-bdzGu-K42GQtdXIkEI4d_xX3pTeyfxdDw,6055
|
|
6
|
+
transformation/cli.py,sha256=bgBMIwJIQqeX-lSm5kse_ixkJT3ASNP7xZiCj34nEcU,43012
|
|
7
|
+
transformation/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
transformation/build/completeness.py,sha256=rkjW6XKzBSoBoX4L69Ti1DB8hgabxZgF3aoZ2poRVjw,8430
|
|
9
|
+
transformation/build/generators.py,sha256=gjLa3QuWyHJjV1EMHOJHMHG72ifW9_Qs7nHAnz54LSU,7364
|
|
10
|
+
transformation/build/render.py,sha256=E5uHs_-L99CoLe9XXRnLVYC6Q2UDDil0LolrFp9HSac,61850
|
|
11
|
+
transformation/design/__init__.py,sha256=Z4Ot73N2NxnrxuTJRhflZpb0S3mv7CKaFCIZAqrbsNk,263
|
|
12
|
+
transformation/design/catalog.py,sha256=g5fH6hDsfFYcQqN2o9mI2h74LMgHLExhT108aruaMP8,6410
|
|
13
|
+
transformation/design/checks.py,sha256=TQXSRoSUOqXzFtRrkte74ZXf8OUG12-P_cBehCWTchw,142297
|
|
14
|
+
transformation/design/derive.py,sha256=EHTZsMBisSrEY3GoD0cLRRTV-8u5egD9_os7S7yTCGI,8516
|
|
15
|
+
transformation/design/emit.py,sha256=upSsupjgQCN1HzmSj93uXfyPi3v5nyb2DAZ7zvfOrHU,18410
|
|
16
|
+
transformation/design/evaluate.py,sha256=oLybHDfuyJGKO2Xp7W1w-5gGreqDtjJF4ciOOmk-IW0,6699
|
|
17
|
+
transformation/design/families.py,sha256=2Ld01Jln1C5531c9imWHZ_GBBEt7HqdZad5aVF2VV9M,4706
|
|
18
|
+
transformation/design/merit.py,sha256=Hoh28UInXM8lvwPSX0WQLVosE-YEBp0XcA-1EhpUcGo,6284
|
|
19
|
+
transformation/design/meta.py,sha256=q6mXaWTo0jYmJQAy4oA-ls2M2crNet5vfrkEpp6Ex8M,14846
|
|
20
|
+
transformation/design/oracle.py,sha256=sjzNpKcAQZAdvi3lzPatgF2y6TQitOaeA-e9YX1CAUc,3205
|
|
21
|
+
transformation/design/project.py,sha256=f_Y4LkozktHUyDV3X_6xlCKmaO71C4_MVag72g2QLKA,8571
|
|
22
|
+
transformation/design/read.py,sha256=KIFnJNw2PxNjEsmCjoSntLRfbUGdizgITYUhO0brqYw,5962
|
|
23
|
+
transformation/design/rules.py,sha256=m19X2LzwlIkfNEQY-h3r826gkxI6v3A1hg1vxaQQGCs,8325
|
|
24
|
+
transformation/design/sealed.py,sha256=Te9e7d4eU18GyY_m0dDKwmj3u-ZsLz_wfckH76dO_lU,2426
|
|
25
|
+
transformation/design/template_reader.py,sha256=K1n9It1Ul8mJXXn30g9Po4nzhLAUM2h_V2v7sstdqTA,11472
|
|
26
|
+
transformation/design/p0_change_seed/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
transformation/design/p0_change_seed/rules.py,sha256=fe-8CDeW8kCh6RZgPlLl5szsLZlf2AUOEYVRUQZiUBI,3238
|
|
28
|
+
transformation/design/p1_change_request/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
transformation/design/p1_change_request/rules.py,sha256=Nv20v2FxaeqssQ2ifeK71KtvltX52rNSDa30wLRCwww,6675
|
|
30
|
+
transformation/design/p2_domain_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
transformation/design/p2_domain_model/rules.py,sha256=46giEAJDPTMEETJGfZcdGFdm0GpLBfxpNWClC9DUJD4,5097
|
|
32
|
+
transformation/design/p3_analysis_loop/__init__.py,sha256=3CUAaevgUNKto8C0b-pdZt0pMXYmCSxDVRDwj0ea3T4,37
|
|
33
|
+
transformation/design/p3_analysis_loop/rules.py,sha256=X9_aJxCecHGzHJv_BJ7YS9GAL_bqu_PaUT7fPTpMyOs,8219
|
|
34
|
+
transformation/design/p4_business_model/__init__.py,sha256=YEZvDAW8VpfP1hgISWaKb5AOsz2tSW1yaaSSMGKFBqw,38
|
|
35
|
+
transformation/design/p4_business_model/rules.py,sha256=WOcNIpC08a08ckSKnydHGyipTJQnWInX0JvhboMGWJg,6553
|
|
36
|
+
transformation/design/p5_business_intent/__init__.py,sha256=POiYdGnOzH4Z7V8kQ8MiBGMjz2Ye-7P6sd6dmd7rPeo,39
|
|
37
|
+
transformation/design/p5_business_intent/rules.py,sha256=5p4qh1GIbUO5TSaT6d6uiZH7mYu-ec23gr-j9aAxb-Q,9965
|
|
38
|
+
transformation/design/p6_governance_intent/__init__.py,sha256=_BjJlUEWn87iVw4kyHfNghkDrbKojdMtXePLVA_a6CQ,41
|
|
39
|
+
transformation/design/p6_governance_intent/rules.py,sha256=kMusRRbEJ-CX0Xe4-auIBvPm9awTUKlt6H6RwATU_j4,9533
|
|
40
|
+
transformation/design/p7_design_intent/__init__.py,sha256=G6VHVTeSbQ9Ah2DiTno1eOx_ViKZDcXbZ5P6RLDS8kQ,37
|
|
41
|
+
transformation/design/p7_design_intent/rules.py,sha256=JtcO2HYQMHx-HIArgqajB_Ay6q0PiXFsA4n0w0hemCo,51633
|
|
42
|
+
transformation/design/p8_authoring_mandate/__init__.py,sha256=wl3GTBgc0s0K7OJHpDtWYkNxm_6l_CzX2MCjvnjgBZs,41
|
|
43
|
+
transformation/design/p8_authoring_mandate/rules.py,sha256=rgUq_n2QDVZKEK2ECnbicbdt0-4BIlWOafVfI1O_mSA,9878
|
|
44
|
+
transformation/implementation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
+
transformation/implementation/capability_transforms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
transformation/implementation/capability_transforms/atoms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_attribute_provenance_v0.py,sha256=VYKVp52DcBNHX9cBNdUoeGcMfSas1oeWgybPWJFLtPI,3154
|
|
48
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_evaluate_rules_v0.py,sha256=WMz_rgX0IID6JkC0pV_XNMKvgYRof0WY2E8psYAsJXw,3333
|
|
49
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_measure_completeness_v0.py,sha256=TfdoHZSvZQoslashdPem8bV6Olcj24IEhqB1QsP_TuQ,2665
|
|
50
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_parse_prior_phases_v0.py,sha256=wvovHnkCb4UTMyBcqf4gof2fXAxP1FmXsgEHMNXzon8,1994
|
|
51
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_parse_registers_v0.py,sha256=jbGig1hH581UhVxTr9jtTWglunfZszjZd0k6xx9Mk1Y,1648
|
|
52
|
+
transformation/implementation/capability_transforms/atoms/ct_pure_render_artifacts_v0.py,sha256=jFpLEP5Csb9b4fYVFWkJuEH2H8BAWnXkC7Wc2qQxBC0,2682
|
|
53
|
+
transformation/templates/p0_change_seed_template_v0.md,sha256=VtlPW8dA3Rwxh-A_Y62VEPyLdo3DkxAl-U6j9dmnjBE,11434
|
|
54
|
+
transformation/templates/p1_change_request_template_v0.md,sha256=Tgn69x8ZY093VGl_hBzYZgR3rKJ1Wl7X3gDLHKXQoTw,15290
|
|
55
|
+
transformation/templates/p2_domain_model_template_v0.md,sha256=3egSiCoHPzEaXv6uzBWlILqOurWQ7B2yS4G5h1RwoDY,13500
|
|
56
|
+
transformation/templates/p3_analysis_loop_template_v0.md,sha256=IZX7z9EF992hwEwZ4Zn8SiwvZTA04cZMDDKvobsvvWY,9891
|
|
57
|
+
transformation/templates/p4_business_model_template_v0.md,sha256=4T8laAI4Vkr1QA-SgElcz9oVvSQWxFenKfZttilGS2c,10369
|
|
58
|
+
transformation/templates/p5_business_intent_template_v0.md,sha256=H7yCGxcfh5zGJcLAChRGcD74njvD1ah45BeJvv1icqs,10504
|
|
59
|
+
transformation/templates/p6_governance_intent_template_v0.md,sha256=1dvERIKIPoVfc-VIRnjVq8lshWeyAYllT0JwNhzccGE,10200
|
|
60
|
+
transformation/templates/p7_design_intent_template_v0.md,sha256=u6gmjRkmhv1hnbDiNE63BE7ReCeqx20FiToPib181j0,31283
|
|
61
|
+
transformation/templates/p8_authoring_mandate_template_v0.md,sha256=O3QZuZwhzaAqmWxHNKutsyQd49YDYOIcNwWI3agzIPU,7618
|
|
62
|
+
pgc_transformation-2.0.0.dist-info/METADATA,sha256=TsKMFlol8EoPyPasKvwn_oczX5LgZ9PQf_tSdfH2uKg,14612
|
|
63
|
+
pgc_transformation-2.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
64
|
+
pgc_transformation-2.0.0.dist-info/entry_points.txt,sha256=wn_EBvI4GGai_YPTGWYS5KgQ-5vlNbP2naBcZHC9q_s,47
|
|
65
|
+
pgc_transformation-2.0.0.dist-info/top_level.txt,sha256=7lCYYweNL_Fj0SN_bJzAWQqbhEtoIoHaoX0osPwQB1E,15
|
|
66
|
+
pgc_transformation-2.0.0.dist-info/RECORD,,
|
|
@@ -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,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 @@
|
|
|
1
|
+
transformation
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""The pinned baseline.
|
|
2
|
+
|
|
3
|
+
Validation runs against a named, frozen snapshot — never "the current snapshot". Every register a
|
|
4
|
+
snapshot-reading phase emits encodes facts about one specific composition: which artifacts exist,
|
|
5
|
+
what the normative closure contains, what a REUSE decision found. Against a moving snapshot those
|
|
6
|
+
fixtures fail for reasons that have nothing to do with the transformation compiler, and a
|
|
7
|
+
regression becomes indistinguishable from a rebuild.
|
|
8
|
+
|
|
9
|
+
So: a run that observes a different snapshot_id fails before any phase executes. Rebaselining is a
|
|
10
|
+
deliberate, reviewed act — re-pin the id, re-approve the affected registers.
|
|
11
|
+
|
|
12
|
+
**Re-approval is the half the pin could not previously record.** Verifying the id proves the
|
|
13
|
+
composition is the one named; it proves nothing about whether anyone re-read the registers that
|
|
14
|
+
encode facts about it. A register asserting `impacted_count 58` goes false without anyone editing
|
|
15
|
+
it, and after a re-pin there was no way to tell "re-grounded against this snapshot" from "never
|
|
16
|
+
re-checked since the id changed". `approved_registers` records the second half, and because it
|
|
17
|
+
lives in the file the id lives in, re-pinning drops it: an approval is against one composition and
|
|
18
|
+
survives no other.
|
|
19
|
+
|
|
20
|
+
**Which registers need approving is derived, not declared.** A register rests on a snapshot fact
|
|
21
|
+
exactly when a rule governing it consults an observation, which the rule set already says. A
|
|
22
|
+
hand-kept list would be a second declaration that drifts from the rules the moment either changes.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json
|
|
28
|
+
from dataclasses import dataclass, field, replace
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from typing import Iterable
|
|
31
|
+
|
|
32
|
+
from inspector import api
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class BaselineMismatch(RuntimeError):
|
|
36
|
+
"""The snapshot on disk is not the one this CR was validated against."""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class Baseline:
|
|
41
|
+
snapshot_id: str
|
|
42
|
+
artifact_count: int
|
|
43
|
+
domains: tuple[str, ...]
|
|
44
|
+
# phase -> register -> who re-grounded it against this snapshot_id. Absent on a freshly
|
|
45
|
+
# observed pin, because observing a composition approves nothing about it.
|
|
46
|
+
approved_registers: dict[str, dict[str, str]] = field(default_factory=dict)
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def load(path: Path) -> "Baseline":
|
|
50
|
+
if not path.is_file():
|
|
51
|
+
raise FileNotFoundError(f"baseline pin not found: {path}")
|
|
52
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
53
|
+
for key in ("snapshot_id", "artifact_count", "domains"):
|
|
54
|
+
if key not in data:
|
|
55
|
+
raise KeyError(f"baseline pin {path} is missing {key!r}")
|
|
56
|
+
return Baseline(
|
|
57
|
+
snapshot_id=data["snapshot_id"],
|
|
58
|
+
artifact_count=int(data["artifact_count"]),
|
|
59
|
+
domains=tuple(data["domains"]),
|
|
60
|
+
approved_registers={
|
|
61
|
+
phase: dict(registers)
|
|
62
|
+
for phase, registers in (data.get("approved_registers") or {}).items()
|
|
63
|
+
},
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def as_dict(self) -> dict:
|
|
67
|
+
"""The pin as it is written. `approved_registers` is omitted when nothing is approved, so
|
|
68
|
+
a freshly observed pin is byte-identical to what `tc baseline show` has always emitted."""
|
|
69
|
+
out: dict = {
|
|
70
|
+
"snapshot_id": self.snapshot_id,
|
|
71
|
+
"artifact_count": self.artifact_count,
|
|
72
|
+
"domains": list(self.domains),
|
|
73
|
+
}
|
|
74
|
+
if self.approved_registers:
|
|
75
|
+
out["approved_registers"] = {
|
|
76
|
+
phase: dict(sorted(registers.items()))
|
|
77
|
+
for phase, registers in sorted(self.approved_registers.items())
|
|
78
|
+
}
|
|
79
|
+
return out
|
|
80
|
+
|
|
81
|
+
def approve(self, phase: str, registers: Iterable[str], by: str) -> "Baseline":
|
|
82
|
+
"""Record that someone re-grounded these registers against this composition."""
|
|
83
|
+
merged = {p: dict(r) for p, r in self.approved_registers.items()}
|
|
84
|
+
merged.setdefault(phase, {}).update({register: by for register in registers})
|
|
85
|
+
return replace(self, approved_registers=merged)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def grounded_registers(phase: str) -> tuple[str, ...]:
|
|
89
|
+
"""The registers of a phase that rest on a snapshot fact, read from its own rule set.
|
|
90
|
+
|
|
91
|
+
A rule consulting an observation is the definition: it is the only way a register comes to
|
|
92
|
+
assert something the composition could later contradict. Registers governed only by structural
|
|
93
|
+
or cross-phase rules say nothing about the snapshot and need no re-approval.
|
|
94
|
+
"""
|
|
95
|
+
from transformation.design.meta import RULE_MODULES
|
|
96
|
+
|
|
97
|
+
module = RULE_MODULES.get(phase)
|
|
98
|
+
if module is None:
|
|
99
|
+
return ()
|
|
100
|
+
return tuple(sorted({
|
|
101
|
+
rule.register for rule in module.rule_set()
|
|
102
|
+
if rule.register and any(key.endswith("observation") for key in rule.params)
|
|
103
|
+
}))
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def pending(pin: Baseline, phase: str) -> tuple[str, ...]:
|
|
107
|
+
"""Grounded registers of a phase that nobody has approved against this pin."""
|
|
108
|
+
approved = pin.approved_registers.get(phase, {})
|
|
109
|
+
return tuple(r for r in grounded_registers(phase) if r not in approved)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def observe(snapshot_root: Path) -> Baseline:
|
|
113
|
+
"""Read the composition actually present at `snapshot_root`."""
|
|
114
|
+
status, summary = api.query("si.snapshot.summary", {}, str(snapshot_root))
|
|
115
|
+
if status != "SUCCESS":
|
|
116
|
+
raise RuntimeError(f"si.snapshot.summary failed on {snapshot_root}: {status}")
|
|
117
|
+
return Baseline(
|
|
118
|
+
snapshot_id=summary["snapshot_id"],
|
|
119
|
+
artifact_count=int(summary["artifact_count"]),
|
|
120
|
+
domains=tuple(d["domain"] for d in summary.get("domains", [])),
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def verify(pin: Baseline, snapshot_root: Path) -> Baseline:
|
|
125
|
+
"""Assert the snapshot on disk is the pinned one. Fail hard on any drift."""
|
|
126
|
+
actual = observe(snapshot_root)
|
|
127
|
+
if actual.snapshot_id != pin.snapshot_id:
|
|
128
|
+
raise BaselineMismatch(
|
|
129
|
+
"snapshot does not match the pinned baseline — no phase may run.\n"
|
|
130
|
+
f" pinned: {pin.snapshot_id}\n"
|
|
131
|
+
f" observed: {actual.snapshot_id}\n"
|
|
132
|
+
"Rebaselining is deliberate: re-pin the id and re-approve the affected registers."
|
|
133
|
+
)
|
|
134
|
+
return actual
|
|
File without changes
|