pgc-assembler 3.0.0__tar.gz → 4.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.
Files changed (23) hide show
  1. {pgc_assembler-3.0.0/pgc_assembler.egg-info → pgc_assembler-4.0.0}/PKG-INFO +14 -4
  2. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/README.md +13 -3
  3. pgc_assembler-4.0.0/VERSION +1 -0
  4. pgc_assembler-4.0.0/assembler/VERSION +1 -0
  5. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/assembler/__init__.py +1 -1
  6. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/assembler/core.py +12 -7
  7. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/assembler/indexes.py +35 -3
  8. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0/pgc_assembler.egg-info}/PKG-INFO +14 -4
  9. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pyproject.toml +4 -3
  10. pgc_assembler-3.0.0/VERSION +0 -1
  11. pgc_assembler-3.0.0/assembler/VERSION +0 -1
  12. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/LICENSE +0 -0
  13. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/MANIFEST.in +0 -0
  14. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/NOTICE +0 -0
  15. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/_build_hook.py +0 -0
  16. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/assembler/cli.py +0 -0
  17. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/assembler/conformance.py +0 -0
  18. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pgc_assembler.egg-info/SOURCES.txt +0 -0
  19. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pgc_assembler.egg-info/dependency_links.txt +0 -0
  20. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pgc_assembler.egg-info/entry_points.txt +0 -0
  21. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pgc_assembler.egg-info/requires.txt +0 -0
  22. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/pgc_assembler.egg-info/top_level.txt +0 -0
  23. {pgc_assembler-3.0.0 → pgc_assembler-4.0.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgc-assembler
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: PGC snapshot assembler — composes compiled projections into a manifest-pinned executable snapshot (import package: assembler)
5
5
  Author-email: Bhash Ganti <bachipeachy@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -132,8 +132,18 @@ export PGC_PLATFORM_ROOT=$PWD/software_governance
132
132
  pgc # reports what is installed and whether the anchor resolves
133
133
  ```
134
134
 
135
- `PGC_BUILD_ROOT` (compiled output, keeping the governance repo read-only) and `PGC_DOMAIN_ROOTS`
136
- (additional domains contributing their own `registry/structures`) are optional.
135
+ `PGC_DOMAIN_ROOTS` names an additional domain contributing its own `registry/structures` — the
136
+ directory that *directly contains* it, not the repository above it; pointing one level too high is a
137
+ silent no-op. `PGC_SNAPSHOT_ROOT` is where compiled output is written, and each domain build needs
138
+ its own: every layer's output consolidates into one root, and verification rejects any file in that
139
+ root the current build did not declare. `PGC_SNAPSHOT_PROFILES` is the directory holding snapshot
140
+ profiles, required by the assembler and the runtime alike.
141
+
142
+ `PGC_BUILD_ROOT` is accepted and reported and **nothing reads it** — `PGC_SNAPSHOT_ROOT` is the
143
+ anchor that controls output.
144
+
145
+ The full sequence, with the repositories it needs, is in
146
+ [`pgc_install`](https://github.com/protocol-governed-computing/pgc_install).
137
147
 
138
148
  **Versioning.** Two schemes, and the published version follows the second.
139
149
 
@@ -143,7 +153,7 @@ pgc # reports what is installed and whether the anchor resolves
143
153
  cycle is tagged `release-<N>`. This is not published.
144
154
  - **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v3`**.
145
155
 
146
- **The published version is the public one: `v3` is `3.0.0`.** The standard the packages implement is a
156
+ **The published version is the public one: `v4` is `4.0.0`.** The standard the packages implement is a
147
157
  separate artifact on its own track and is not this number.
148
158
 
149
159
  The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
@@ -107,8 +107,18 @@ export PGC_PLATFORM_ROOT=$PWD/software_governance
107
107
  pgc # reports what is installed and whether the anchor resolves
108
108
  ```
109
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.
110
+ `PGC_DOMAIN_ROOTS` names an additional domain contributing its own `registry/structures` — the
111
+ directory that *directly contains* it, not the repository above it; pointing one level too high is a
112
+ silent no-op. `PGC_SNAPSHOT_ROOT` is where compiled output is written, and each domain build needs
113
+ its own: every layer's output consolidates into one root, and verification rejects any file in that
114
+ root the current build did not declare. `PGC_SNAPSHOT_PROFILES` is the directory holding snapshot
115
+ profiles, required by the assembler and the runtime alike.
116
+
117
+ `PGC_BUILD_ROOT` is accepted and reported and **nothing reads it** — `PGC_SNAPSHOT_ROOT` is the
118
+ anchor that controls output.
119
+
120
+ The full sequence, with the repositories it needs, is in
121
+ [`pgc_install`](https://github.com/protocol-governed-computing/pgc_install).
112
122
 
113
123
  **Versioning.** Two schemes, and the published version follows the second.
114
124
 
@@ -118,7 +128,7 @@ pgc # reports what is installed and whether the anchor resolves
118
128
  cycle is tagged `release-<N>`. This is not published.
119
129
  - **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v3`**.
120
130
 
121
- **The published version is the public one: `v3` is `3.0.0`.** The standard the packages implement is a
131
+ **The published version is the public one: `v4` is `4.0.0`.** The standard the packages implement is a
122
132
  separate artifact on its own track and is not this number.
123
133
 
124
134
  The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
@@ -0,0 +1 @@
1
+ 16
@@ -0,0 +1 @@
1
+ 16
@@ -1,6 +1,6 @@
1
1
  """PGC Snapshot Assembler — composes compiled projections into a manifest-pinned snapshot.
2
2
 
3
- Contract: snapshot_assembler/doc/SNAPSHOT_ASSEMBLY_CONTRACT.md
3
+ Contract: snapshot_assembler/CONTRACT.md
4
4
  """
5
5
 
6
6
  from pathlib import Path
@@ -4,7 +4,7 @@ core.py — PGC snapshot assembly.
4
4
  Composes each domain's compiled projections (from the protocol compiler) into one
5
5
  executable snapshot + a content-derived, manifest-pinned identity.
6
6
 
7
- Contract: snapshot_assembler/doc/SNAPSHOT_ASSEMBLY_CONTRACT.md
7
+ Contract: snapshot_assembler/CONTRACT.md
8
8
 
9
9
  Invariants enforced here:
10
10
  * The assembler INVENTS no per-domain identity — every hash is lifted verbatim from
@@ -358,12 +358,6 @@ def verify_profile(out_root: Path, profile: str) -> list[str]:
358
358
  return unmet
359
359
 
360
360
 
361
- def compute_composite_hash(domains: list[dict]) -> str:
362
- """sha256 over canonical-JSON of the identity view. Deterministic; timestamp-free."""
363
- canonical = json.dumps(_identity_view(domains), sort_keys=True, separators=(",", ":"))
364
- return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
365
-
366
-
367
361
  # ---------------------------------------------------------------------------
368
362
  # Cross-domain FQDN uniqueness (per-domain vocabularies are independent address namespaces)
369
363
  # ---------------------------------------------------------------------------
@@ -755,6 +749,17 @@ def verify_snapshot(out_root: Path) -> dict[str, Any]:
755
749
  f"{str(borne)[:16]}… (3b §7 clause 2, SN-2)."
756
750
  )
757
751
 
752
+ # The manifest states its identity twice. Both statements are the claim, so both are evaluated:
753
+ # checking one and not the other let a manifest carry two contradictory identities and be
754
+ # accepted — measured, not hypothesised. A self-description that disagrees with itself is not a
755
+ # self-description.
756
+ borne_composite = manifest.get("composite_hash")
757
+ if borne_composite != derived:
758
+ raise AssemblyError(
759
+ f"identity failure: derived {derived[:16]}… from content, snapshot's composite_hash "
760
+ f"bears {str(borne_composite)[:16]}… (3b §7 clause 2, SN-2)."
761
+ )
762
+
758
763
  # Copies of one identity across domains must agree (GC-12) — a composition obligation rather
759
764
  # than correspondence, and not subsumed by the four conditions above.
760
765
  _verify_copies_agree(out_root)
@@ -35,8 +35,36 @@ SCHEMA_VERSION = "v0"
35
35
  # Shared readers over the consolidated snapshot
36
36
  # ---------------------------------------------------------------------------
37
37
 
38
+ def _authoring_rank(doc: dict) -> int:
39
+ """How authoritative a canonical copy is for its identity. Higher wins.
40
+
41
+ One identity can be published by more than one domain. A domain that CONSUMES a platform
42
+ capability carries it as an execution binding — the compiler lifts the compiled node so the
43
+ capability is executable there, and the authoring stays platform-owned. Both copies are
44
+ canonical and both are legitimate; they are not interchangeable.
45
+
46
+ The binding copy is the authoring copy with the authored parts removed: `content_hash`,
47
+ `frontmatter` and the IR are identical, while `content` and `references` are empty and
48
+ `layer_code` names the consuming layer. So the copy that still carries authored content is the
49
+ authoring copy, and it is the one an identity must resolve to — `si.artifact.show` promises "the
50
+ published canonical artifact for an FQDN, as authored".
51
+
52
+ A binding copy also carries the `content_hash` of content it does not hold, which is the sharper
53
+ tell but not one to select on: a hash mismatch is a defect to report, not a discriminator.
54
+ """
55
+ return 1 if (doc.get("content") or "").strip() else 0
56
+
57
+
38
58
  def _load_canonical(out_root: Path) -> dict[str, dict]:
39
- """fqdn → canonical artifact doc, across all domains (canonical/<domain>/<type>/*.json)."""
59
+ """fqdn → canonical artifact doc, across all domains (canonical/<domain>/<type>/*.json).
60
+
61
+ Where an identity is published more than once, the authoring copy wins (`_authoring_rank`).
62
+ Selecting by iteration order would resolve an identity by the alphabetical accident of its
63
+ consumer's domain name: `canonical/platform/` sorts before `canonical/workload/` and after
64
+ `canonical/blockchain/`, so last-write-wins returned the authoring copy for consumers named
65
+ early and the binding copy for consumers named late. Renaming a domain would then change what
66
+ an identity resolves to.
67
+ """
40
68
  canon = out_root / "canonical"
41
69
  docs: dict[str, dict] = {}
42
70
  if not canon.is_dir():
@@ -46,8 +74,12 @@ def _load_canonical(out_root: Path) -> dict[str, dict]:
46
74
  continue
47
75
  raw = json.loads(f.read_text(encoding="utf-8"))
48
76
  fqdn = raw.get("fqdn_id")
49
- if fqdn and "::" in fqdn:
50
- raw["_canonical_path"] = f.relative_to(out_root).as_posix()
77
+ if not fqdn or "::" not in fqdn:
78
+ continue
79
+ raw["_canonical_path"] = f.relative_to(out_root).as_posix()
80
+ held = docs.get(fqdn)
81
+ # Ties keep the first seen, so a sorted walk stays the tiebreak and the result is stable.
82
+ if held is None or _authoring_rank(raw) > _authoring_rank(held):
51
83
  docs[fqdn] = raw
52
84
  return docs
53
85
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pgc-assembler
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: PGC snapshot assembler — composes compiled projections into a manifest-pinned executable snapshot (import package: assembler)
5
5
  Author-email: Bhash Ganti <bachipeachy@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -132,8 +132,18 @@ export PGC_PLATFORM_ROOT=$PWD/software_governance
132
132
  pgc # reports what is installed and whether the anchor resolves
133
133
  ```
134
134
 
135
- `PGC_BUILD_ROOT` (compiled output, keeping the governance repo read-only) and `PGC_DOMAIN_ROOTS`
136
- (additional domains contributing their own `registry/structures`) are optional.
135
+ `PGC_DOMAIN_ROOTS` names an additional domain contributing its own `registry/structures` — the
136
+ directory that *directly contains* it, not the repository above it; pointing one level too high is a
137
+ silent no-op. `PGC_SNAPSHOT_ROOT` is where compiled output is written, and each domain build needs
138
+ its own: every layer's output consolidates into one root, and verification rejects any file in that
139
+ root the current build did not declare. `PGC_SNAPSHOT_PROFILES` is the directory holding snapshot
140
+ profiles, required by the assembler and the runtime alike.
141
+
142
+ `PGC_BUILD_ROOT` is accepted and reported and **nothing reads it** — `PGC_SNAPSHOT_ROOT` is the
143
+ anchor that controls output.
144
+
145
+ The full sequence, with the repositories it needs, is in
146
+ [`pgc_install`](https://github.com/protocol-governed-computing/pgc_install).
137
147
 
138
148
  **Versioning.** Two schemes, and the published version follows the second.
139
149
 
@@ -143,7 +153,7 @@ pgc # reports what is installed and whether the anchor resolves
143
153
  cycle is tagged `release-<N>`. This is not published.
144
154
  - **Public** — `PUBLIC_VERSION`, tagged on every component repository. The platform is at **`v3`**.
145
155
 
146
- **The published version is the public one: `v3` is `3.0.0`.** The standard the packages implement is a
156
+ **The published version is the public one: `v4` is `4.0.0`.** The standard the packages implement is a
147
157
  separate artifact on its own track and is not this number.
148
158
 
149
159
  The standard these packages implement is published separately: https://doi.org/10.5281/zenodo.22150616
@@ -5,7 +5,7 @@ backend-path = ["."]
5
5
 
6
6
  [project]
7
7
  name = "pgc-assembler"
8
- version = "3.0.0"
8
+ version = "4.0.0"
9
9
  description = "PGC snapshot assembler — composes compiled projections into a manifest-pinned executable snapshot (import package: assembler)"
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -46,5 +46,6 @@ where = ["."]
46
46
  include = ["assembler*"]
47
47
 
48
48
  [tool.setuptools.package-data]
49
- # VERSION has no extension, so it must be named explicitly.
50
- "*" = ["*.md", "*.yaml", "*.json", "VERSION"]
49
+ # VERSION has no extension, so it must be named explicitly. Scoped to the package
50
+ # rather than "*" — see the note in protocol_compiler.
51
+ "assembler" = ["VERSION"]
@@ -1 +0,0 @@
1
- 15
@@ -1 +0,0 @@
1
- 15
File without changes
File without changes
File without changes
File without changes