pgc-domains 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_domains-2.0.0/LICENSE +67 -0
- pgc_domains-2.0.0/NOTICE +11 -0
- pgc_domains-2.0.0/PKG-INFO +169 -0
- pgc_domains-2.0.0/README.md +144 -0
- pgc_domains-2.0.0/ai_governance/implementation/__init__.py +0 -0
- pgc_domains-2.0.0/ai_governance/implementation/capability_transforms/__init__.py +0 -0
- pgc_domains-2.0.0/ai_governance/implementation/capability_transforms/atoms/__init__.py +0 -0
- pgc_domains-2.0.0/ai_governance/implementation/capability_transforms/atoms/ct_pure_check_quota_available_v0.py +64 -0
- pgc_domains-2.0.0/ai_governance/implementation/capability_transforms/atoms/ct_pure_check_training_status_v0.py +51 -0
- pgc_domains-2.0.0/ai_governance/implementation/capability_transforms/atoms/ct_pure_evaluate_inactivity_v0.py +96 -0
- pgc_domains-2.0.0/blockchain/implementation/__init__.py +0 -0
- pgc_domains-2.0.0/blockchain/implementation/capability_transforms/__init__.py +0 -0
- pgc_domains-2.0.0/blockchain/implementation/capability_transforms/atoms/__init__.py +0 -0
- pgc_domains-2.0.0/blockchain/implementation/capability_transforms/atoms/ct_pure_derive_wallet_address_v0.py +96 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/__init__.py +0 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/__init__.py +0 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/atoms/__init__.py +0 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/atoms/ct_pure_form_book_identity_key_v0.py +96 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/atoms/ct_pure_form_work_identity_key_v0.py +77 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/atoms/ct_pure_group_records_v0.py +72 -0
- pgc_domains-2.0.0/book_library_mgmt/implementation/capability_transforms/atoms/ct_pure_select_records_v0.py +65 -0
- pgc_domains-2.0.0/pgc_domains.egg-info/PKG-INFO +169 -0
- pgc_domains-2.0.0/pgc_domains.egg-info/SOURCES.txt +26 -0
- pgc_domains-2.0.0/pgc_domains.egg-info/dependency_links.txt +1 -0
- pgc_domains-2.0.0/pgc_domains.egg-info/requires.txt +2 -0
- pgc_domains-2.0.0/pgc_domains.egg-info/top_level.txt +3 -0
- pgc_domains-2.0.0/pyproject.toml +61 -0
- pgc_domains-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.
|
pgc_domains-2.0.0/NOTICE
ADDED
|
@@ -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,169 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pgc-domains
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: PGC business domains — the capability implementations the composed reference snapshot binds at execution
|
|
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/business_domains
|
|
9
|
+
Project-URL: Standard, https://doi.org/10.5281/zenodo.22150616
|
|
10
|
+
Keywords: protocol-governed-computing,pgc,business-domain,capability-transforms
|
|
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
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
License-File: NOTICE
|
|
22
|
+
Requires-Dist: pgc-runtime>=2.0.0
|
|
23
|
+
Requires-Dist: pycryptodome
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# business_domains
|
|
27
|
+
|
|
28
|
+
**Real business work, declared as governed protocol.**
|
|
29
|
+
|
|
30
|
+
Registering a participant, cataloguing a book, licensing an AI agent — work that would be worth
|
|
31
|
+
doing whether or not this platform existed. Each domain here is a directory of declarations: a
|
|
32
|
+
workflow graph, the contracts its nodes name, the intents that admit a request, the events it
|
|
33
|
+
announces, the store it writes to. No domain implements admission, routing, persistence, auditing
|
|
34
|
+
or refusal. It declares them, and the platform enforces what it declared.
|
|
35
|
+
|
|
36
|
+
> **New here?** Start with [`ARCHITECTURE.md`](ARCHITECTURE.md) — what this repository is, what it
|
|
37
|
+
> owns, and a hands-on walkthrough. For the whole picture, see the
|
|
38
|
+
> [organization profile](https://github.com/protocol-governed-computing).
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## The domains
|
|
43
|
+
|
|
44
|
+
| Domain | Subdomains | What it does |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| **`blockchain`** | `identity`, `wallet` | Register a participant, then accept or reject them — keeping a durable record of what they registered with. An accepted person is then given exactly one wallet, whose creation is recorded as a moment on its own trail. Reachable over HTTP and the command line, with a web client. |
|
|
47
|
+
| **`book_library_mgmt`** | `catalog` | Register works, editions and physical copies; retire and reinstate them; update bibliographic information; search. Ten workflows — the largest surface here — of which six announce the business moments they complete. |
|
|
48
|
+
| **`ai_governance`** | `agent_governance`, `ai_licensing` | Admit or deny an AI agent's action; provision, deny and reclaim licences. Two subdomains sharing one namespace. |
|
|
49
|
+
|
|
50
|
+
A **domain is a namespace**; a **subdomain is a division within it**. `ai_governance` is the case
|
|
51
|
+
that makes the distinction concrete — two subdomains, one compiled domain, neither a fork of the
|
|
52
|
+
other.
|
|
53
|
+
|
|
54
|
+
Maturity differs, and it is stated rather than implied. `blockchain::identity` is functionally
|
|
55
|
+
complete; two of its validated criteria are not exercised, and both wait on a function that does not
|
|
56
|
+
exist yet — a timed test, and the transaction half of the wallet claim. `blockchain::wallet` is
|
|
57
|
+
delivered and validated, and it is the domain that demonstrates **consulting** another subdomain's
|
|
58
|
+
records without writing them. `book_library_mgmt` now announces: six of its ten acts emit the moments
|
|
59
|
+
they complete, from the ending that completes them. `ai_governance` carries no change dossier —
|
|
60
|
+
deliberately — and is the least exercised.
|
|
61
|
+
|
|
62
|
+
**The wallet is also where a defect and its repair are on the record.** Its validation once read 7/9
|
|
63
|
+
because the suite registered the same people identity's suite registers, so a shared data root left
|
|
64
|
+
the unverified-person criterion testing someone already accepted. The suite now seeds people of its
|
|
65
|
+
own. Both blockchain suites run into one data root, because a domain has one place its records live.
|
|
66
|
+
|
|
67
|
+
## Where this sits
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
software_governance conformance_workloads business_domains
|
|
71
|
+
what is GOVERNED what PROVES the guarantee what is DONE ← here
|
|
72
|
+
└──────────────────────────┼──────────────────────────┘
|
|
73
|
+
│
|
|
74
|
+
compiler → assembler
|
|
75
|
+
│
|
|
76
|
+
┌────────▼────────┐
|
|
77
|
+
│ sealed snapshot │
|
|
78
|
+
└────┬───────┬────┘
|
|
79
|
+
▼ ▼
|
|
80
|
+
runtime inspector
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
A domain is compiled **against** an already-compiled governance surface. Governance is never edited
|
|
84
|
+
to admit a domain — compiling one leaves the platform's identity unchanged. A domain declares its
|
|
85
|
+
own sources in its own build manifest, so adding one is a sibling directory and nothing upstream is
|
|
86
|
+
touched.
|
|
87
|
+
|
|
88
|
+
## Run one
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
./blockchain/client/serve.sh # http://localhost:8000
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Register a name and contact address, then verify that address — accepting or rejecting it. The same
|
|
95
|
+
path without the browser:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
curl -s -X POST http://localhost:8000/blockchain -H 'Content-Type: application/json' \
|
|
99
|
+
-d '{"operation":"blockchain.register_actor",
|
|
100
|
+
"params":{"name":"Ada","contact_address":"ada@example.com"}}'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{ "outcome": "SUCCESS", "result_class": "SUCCESS",
|
|
105
|
+
"result": { "contact_address": "ada@example.com",
|
|
106
|
+
"occurrence": "ACTOR_REGISTERED_UNVERIFIED", "sequence_number": 1 },
|
|
107
|
+
"evidence": [ "trace:traces/blockchain/WF_REGISTER_ACTOR_V0/…" ] }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Accepting an unknown address returns a governed `NOT_FOUND` without writing anything; registering
|
|
111
|
+
twice succeeds twice and advances the sequence, because registration is idempotent **by
|
|
112
|
+
declaration**. Every response points at the trace for that exact run.
|
|
113
|
+
|
|
114
|
+
To run a workflow directly against the sealed snapshot, without any web surface:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
cd ../protocol_runtime
|
|
118
|
+
./run.sh run --wf blockchain::WF_REGISTER_ACTOR_V0 \
|
|
119
|
+
--payload ../business_domains/blockchain/testbed/identity/test_payloads/01_register_actor.json \
|
|
120
|
+
--data-root /tmp/pgc_instance
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Layout
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
blockchain/
|
|
127
|
+
registry/identity/ workflows · intents · contracts · events · actors ·
|
|
128
|
+
storage structure · runtime bindings · transport contracts
|
|
129
|
+
client/ web client, HTTP binding table, composition launcher
|
|
130
|
+
cr_dossiers/ the governed record of each change, with its baseline pin
|
|
131
|
+
testbed/ payloads, including ones that must be refused
|
|
132
|
+
|
|
133
|
+
book_library_mgmt/ same shape; subdomain `catalog`; plus implementation/ transforms
|
|
134
|
+
ai_governance/ same shape; two subdomains in one namespace
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## A change to a domain is itself governed
|
|
138
|
+
|
|
139
|
+
Each domain carries **change dossiers** — the record of a change from the business problem as stated
|
|
140
|
+
(P0) through to the authoring mandate (P8), each phase admissible before the next may be authored.
|
|
141
|
+
Every dossier pins the baseline it was approved against, and that pin stays historical: a completed
|
|
142
|
+
change is never re-pinned forward.
|
|
143
|
+
|
|
144
|
+
A change need not author anything. One dossier here produces a **two-line diff** — a defect
|
|
145
|
+
correction, fully evidenced, every phase admissible. A lifecycle that can only describe creation
|
|
146
|
+
cannot describe maintenance.
|
|
147
|
+
|
|
148
|
+
## What this repository is not
|
|
149
|
+
|
|
150
|
+
- **Not the platform.** The governance surface is `software_governance`; the runtime that executes
|
|
151
|
+
these domains is `protocol_runtime`, and it contains no knowledge of any domain here.
|
|
152
|
+
- **Not a set of examples.** Conformance workloads (`conformance_workloads`) exist to prove a
|
|
153
|
+
guarantee; these exist because the work is worth doing. That both compile by the identical path,
|
|
154
|
+
with no privilege on either side, is the claim.
|
|
155
|
+
- **Not a place for platform mechanisms.** When a domain needs something neutral the substrate
|
|
156
|
+
lacks, the substrate gains it — a domain that compensates with a private rule produces a promise
|
|
157
|
+
stated nowhere and copied everywhere.
|
|
158
|
+
|
|
159
|
+
## Rules
|
|
160
|
+
|
|
161
|
+
- A domain declares; it does not implement admission, routing, persistence or auditing.
|
|
162
|
+
- No import of the compiler, the assembler, the runtime, or another domain. Implementations are
|
|
163
|
+
leaves; cross-domain reference happens through compiled identity.
|
|
164
|
+
- Capability transforms are pure and deterministic. Every effect is a declared capability.
|
|
165
|
+
- All references are by fully-qualified identity, resolved at compile time. No short names.
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
Apache-2.0. See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# business_domains
|
|
2
|
+
|
|
3
|
+
**Real business work, declared as governed protocol.**
|
|
4
|
+
|
|
5
|
+
Registering a participant, cataloguing a book, licensing an AI agent — work that would be worth
|
|
6
|
+
doing whether or not this platform existed. Each domain here is a directory of declarations: a
|
|
7
|
+
workflow graph, the contracts its nodes name, the intents that admit a request, the events it
|
|
8
|
+
announces, the store it writes to. No domain implements admission, routing, persistence, auditing
|
|
9
|
+
or refusal. It declares them, and the platform enforces what it declared.
|
|
10
|
+
|
|
11
|
+
> **New here?** Start with [`ARCHITECTURE.md`](ARCHITECTURE.md) — what this repository is, what it
|
|
12
|
+
> owns, and a hands-on walkthrough. For the whole picture, see the
|
|
13
|
+
> [organization profile](https://github.com/protocol-governed-computing).
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## The domains
|
|
18
|
+
|
|
19
|
+
| Domain | Subdomains | What it does |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| **`blockchain`** | `identity`, `wallet` | Register a participant, then accept or reject them — keeping a durable record of what they registered with. An accepted person is then given exactly one wallet, whose creation is recorded as a moment on its own trail. Reachable over HTTP and the command line, with a web client. |
|
|
22
|
+
| **`book_library_mgmt`** | `catalog` | Register works, editions and physical copies; retire and reinstate them; update bibliographic information; search. Ten workflows — the largest surface here — of which six announce the business moments they complete. |
|
|
23
|
+
| **`ai_governance`** | `agent_governance`, `ai_licensing` | Admit or deny an AI agent's action; provision, deny and reclaim licences. Two subdomains sharing one namespace. |
|
|
24
|
+
|
|
25
|
+
A **domain is a namespace**; a **subdomain is a division within it**. `ai_governance` is the case
|
|
26
|
+
that makes the distinction concrete — two subdomains, one compiled domain, neither a fork of the
|
|
27
|
+
other.
|
|
28
|
+
|
|
29
|
+
Maturity differs, and it is stated rather than implied. `blockchain::identity` is functionally
|
|
30
|
+
complete; two of its validated criteria are not exercised, and both wait on a function that does not
|
|
31
|
+
exist yet — a timed test, and the transaction half of the wallet claim. `blockchain::wallet` is
|
|
32
|
+
delivered and validated, and it is the domain that demonstrates **consulting** another subdomain's
|
|
33
|
+
records without writing them. `book_library_mgmt` now announces: six of its ten acts emit the moments
|
|
34
|
+
they complete, from the ending that completes them. `ai_governance` carries no change dossier —
|
|
35
|
+
deliberately — and is the least exercised.
|
|
36
|
+
|
|
37
|
+
**The wallet is also where a defect and its repair are on the record.** Its validation once read 7/9
|
|
38
|
+
because the suite registered the same people identity's suite registers, so a shared data root left
|
|
39
|
+
the unverified-person criterion testing someone already accepted. The suite now seeds people of its
|
|
40
|
+
own. Both blockchain suites run into one data root, because a domain has one place its records live.
|
|
41
|
+
|
|
42
|
+
## Where this sits
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
software_governance conformance_workloads business_domains
|
|
46
|
+
what is GOVERNED what PROVES the guarantee what is DONE ← here
|
|
47
|
+
└──────────────────────────┼──────────────────────────┘
|
|
48
|
+
│
|
|
49
|
+
compiler → assembler
|
|
50
|
+
│
|
|
51
|
+
┌────────▼────────┐
|
|
52
|
+
│ sealed snapshot │
|
|
53
|
+
└────┬───────┬────┘
|
|
54
|
+
▼ ▼
|
|
55
|
+
runtime inspector
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
A domain is compiled **against** an already-compiled governance surface. Governance is never edited
|
|
59
|
+
to admit a domain — compiling one leaves the platform's identity unchanged. A domain declares its
|
|
60
|
+
own sources in its own build manifest, so adding one is a sibling directory and nothing upstream is
|
|
61
|
+
touched.
|
|
62
|
+
|
|
63
|
+
## Run one
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
./blockchain/client/serve.sh # http://localhost:8000
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Register a name and contact address, then verify that address — accepting or rejecting it. The same
|
|
70
|
+
path without the browser:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
curl -s -X POST http://localhost:8000/blockchain -H 'Content-Type: application/json' \
|
|
74
|
+
-d '{"operation":"blockchain.register_actor",
|
|
75
|
+
"params":{"name":"Ada","contact_address":"ada@example.com"}}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{ "outcome": "SUCCESS", "result_class": "SUCCESS",
|
|
80
|
+
"result": { "contact_address": "ada@example.com",
|
|
81
|
+
"occurrence": "ACTOR_REGISTERED_UNVERIFIED", "sequence_number": 1 },
|
|
82
|
+
"evidence": [ "trace:traces/blockchain/WF_REGISTER_ACTOR_V0/…" ] }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Accepting an unknown address returns a governed `NOT_FOUND` without writing anything; registering
|
|
86
|
+
twice succeeds twice and advances the sequence, because registration is idempotent **by
|
|
87
|
+
declaration**. Every response points at the trace for that exact run.
|
|
88
|
+
|
|
89
|
+
To run a workflow directly against the sealed snapshot, without any web surface:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cd ../protocol_runtime
|
|
93
|
+
./run.sh run --wf blockchain::WF_REGISTER_ACTOR_V0 \
|
|
94
|
+
--payload ../business_domains/blockchain/testbed/identity/test_payloads/01_register_actor.json \
|
|
95
|
+
--data-root /tmp/pgc_instance
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Layout
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
blockchain/
|
|
102
|
+
registry/identity/ workflows · intents · contracts · events · actors ·
|
|
103
|
+
storage structure · runtime bindings · transport contracts
|
|
104
|
+
client/ web client, HTTP binding table, composition launcher
|
|
105
|
+
cr_dossiers/ the governed record of each change, with its baseline pin
|
|
106
|
+
testbed/ payloads, including ones that must be refused
|
|
107
|
+
|
|
108
|
+
book_library_mgmt/ same shape; subdomain `catalog`; plus implementation/ transforms
|
|
109
|
+
ai_governance/ same shape; two subdomains in one namespace
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## A change to a domain is itself governed
|
|
113
|
+
|
|
114
|
+
Each domain carries **change dossiers** — the record of a change from the business problem as stated
|
|
115
|
+
(P0) through to the authoring mandate (P8), each phase admissible before the next may be authored.
|
|
116
|
+
Every dossier pins the baseline it was approved against, and that pin stays historical: a completed
|
|
117
|
+
change is never re-pinned forward.
|
|
118
|
+
|
|
119
|
+
A change need not author anything. One dossier here produces a **two-line diff** — a defect
|
|
120
|
+
correction, fully evidenced, every phase admissible. A lifecycle that can only describe creation
|
|
121
|
+
cannot describe maintenance.
|
|
122
|
+
|
|
123
|
+
## What this repository is not
|
|
124
|
+
|
|
125
|
+
- **Not the platform.** The governance surface is `software_governance`; the runtime that executes
|
|
126
|
+
these domains is `protocol_runtime`, and it contains no knowledge of any domain here.
|
|
127
|
+
- **Not a set of examples.** Conformance workloads (`conformance_workloads`) exist to prove a
|
|
128
|
+
guarantee; these exist because the work is worth doing. That both compile by the identical path,
|
|
129
|
+
with no privilege on either side, is the claim.
|
|
130
|
+
- **Not a place for platform mechanisms.** When a domain needs something neutral the substrate
|
|
131
|
+
lacks, the substrate gains it — a domain that compensates with a private rule produces a promise
|
|
132
|
+
stated nowhere and copied everywhere.
|
|
133
|
+
|
|
134
|
+
## Rules
|
|
135
|
+
|
|
136
|
+
- A domain declares; it does not implement admission, routing, persistence or auditing.
|
|
137
|
+
- No import of the compiler, the assembler, the runtime, or another domain. Implementations are
|
|
138
|
+
leaves; cross-domain reference happens through compiled identity.
|
|
139
|
+
- Capability transforms are pure and deterministic. Every effect is a declared capability.
|
|
140
|
+
- All references are by fully-qualified identity, resolved at compile time. No short names.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
Apache-2.0. See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CT_PURE_CHECK_QUOTA_AVAILABLE_V0
|
|
3
|
+
|
|
4
|
+
Pure Capability Transform (Atom)
|
|
5
|
+
|
|
6
|
+
Purpose:
|
|
7
|
+
Determine whether license quota remains under a declared cap.
|
|
8
|
+
|
|
9
|
+
Implementation:
|
|
10
|
+
- Compares assigned_count against quota
|
|
11
|
+
- Raises CTExecutionError when the cap is reached — the protocol's VIOLATION signal
|
|
12
|
+
for a validating CT; returns the remaining count otherwise
|
|
13
|
+
|
|
14
|
+
Purity Class: ct_pure
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from typing import Any, Dict
|
|
18
|
+
|
|
19
|
+
from runtime.ct_executor import CTExecutionError
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _require_int(inputs: Dict[str, Any], key: str) -> int:
|
|
23
|
+
if key not in inputs:
|
|
24
|
+
raise CTExecutionError(
|
|
25
|
+
f"CT_PURE_CHECK_QUOTA_AVAILABLE_V0: missing required input '{key}'"
|
|
26
|
+
)
|
|
27
|
+
value = inputs[key]
|
|
28
|
+
# bool is a subclass of int — reject it explicitly rather than silently coercing.
|
|
29
|
+
if isinstance(value, bool) or not isinstance(value, int):
|
|
30
|
+
raise CTExecutionError(
|
|
31
|
+
f"CT_PURE_CHECK_QUOTA_AVAILABLE_V0: '{key}' must be an int, "
|
|
32
|
+
f"got {type(value).__name__}"
|
|
33
|
+
)
|
|
34
|
+
if value < 0:
|
|
35
|
+
raise CTExecutionError(
|
|
36
|
+
f"CT_PURE_CHECK_QUOTA_AVAILABLE_V0: '{key}' must be non-negative, got {value}"
|
|
37
|
+
)
|
|
38
|
+
return value
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def execute(inputs: Dict[str, Any], context: Any = None) -> Dict[str, Any]:
|
|
42
|
+
"""
|
|
43
|
+
Execute CT_PURE_CHECK_QUOTA_AVAILABLE_V0.
|
|
44
|
+
|
|
45
|
+
Inputs:
|
|
46
|
+
assigned_count (int): Licenses currently assigned
|
|
47
|
+
quota (int): Declared license cap
|
|
48
|
+
|
|
49
|
+
Outputs:
|
|
50
|
+
quota_available (bool): True when assigned_count is below quota
|
|
51
|
+
remaining (int): Licenses remaining under the cap, floored at zero
|
|
52
|
+
"""
|
|
53
|
+
assigned_count = _require_int(inputs, "assigned_count")
|
|
54
|
+
quota = _require_int(inputs, "quota")
|
|
55
|
+
|
|
56
|
+
remaining = quota - assigned_count
|
|
57
|
+
|
|
58
|
+
if remaining <= 0:
|
|
59
|
+
raise CTExecutionError(
|
|
60
|
+
f"CT_PURE_CHECK_QUOTA_AVAILABLE_V0: license cap reached "
|
|
61
|
+
f"(assigned_count={assigned_count}, quota={quota})"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
return {"result_status": "SUCCESS", "quota_available": True, "remaining": remaining}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CT_PURE_CHECK_TRAINING_STATUS_V0
|
|
3
|
+
|
|
4
|
+
Pure Capability Transform (Atom)
|
|
5
|
+
|
|
6
|
+
Purpose:
|
|
7
|
+
Evaluate whether an employee has completed the training required for AI license
|
|
8
|
+
provisioning.
|
|
9
|
+
|
|
10
|
+
Implementation:
|
|
11
|
+
- Reads the declared training_completed fact
|
|
12
|
+
- Raises CTExecutionError when training is incomplete — the protocol's VIOLATION
|
|
13
|
+
signal for a validating CT; returns the eligibility flag otherwise
|
|
14
|
+
|
|
15
|
+
Purity Class: ct_pure
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from typing import Any, Dict
|
|
19
|
+
|
|
20
|
+
from runtime.ct_executor import CTExecutionError
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def execute(inputs: Dict[str, Any], context: Any = None) -> Dict[str, Any]:
|
|
24
|
+
"""
|
|
25
|
+
Execute CT_PURE_CHECK_TRAINING_STATUS_V0.
|
|
26
|
+
|
|
27
|
+
Inputs:
|
|
28
|
+
training_completed (bool): Whether required training is complete
|
|
29
|
+
|
|
30
|
+
Outputs:
|
|
31
|
+
training_eligible (bool): True when training is complete
|
|
32
|
+
"""
|
|
33
|
+
if "training_completed" not in inputs:
|
|
34
|
+
raise CTExecutionError(
|
|
35
|
+
"CT_PURE_CHECK_TRAINING_STATUS_V0: missing required input 'training_completed'"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
training_completed = inputs["training_completed"]
|
|
39
|
+
|
|
40
|
+
if not isinstance(training_completed, bool):
|
|
41
|
+
raise CTExecutionError(
|
|
42
|
+
"CT_PURE_CHECK_TRAINING_STATUS_V0: 'training_completed' must be a bool, "
|
|
43
|
+
f"got {type(training_completed).__name__}"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if not training_completed:
|
|
47
|
+
raise CTExecutionError(
|
|
48
|
+
"CT_PURE_CHECK_TRAINING_STATUS_V0: required training is not complete"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return {"result_status": "SUCCESS", "training_eligible": True}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CT_PURE_EVALUATE_INACTIVITY_V0
|
|
3
|
+
|
|
4
|
+
Pure Capability Transform (Atom)
|
|
5
|
+
|
|
6
|
+
Purpose:
|
|
7
|
+
Evaluate whether a license has been dormant past its reclamation threshold.
|
|
8
|
+
|
|
9
|
+
Implementation:
|
|
10
|
+
- Parses last_active_date and evaluation_date as ISO-8601
|
|
11
|
+
- Computes whole days elapsed between them
|
|
12
|
+
- Compares against threshold_days
|
|
13
|
+
- Raises CTExecutionError when the license is still active — the protocol's VIOLATION
|
|
14
|
+
signal for a validating CT; returns the dormancy verdict otherwise
|
|
15
|
+
|
|
16
|
+
evaluation_date is a declared input, never a clock read: a pure CT that consulted the
|
|
17
|
+
system clock would be non-deterministic and its trace unreplayable.
|
|
18
|
+
|
|
19
|
+
Purity Class: ct_pure
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from datetime import date, datetime
|
|
23
|
+
from typing import Any, Dict
|
|
24
|
+
|
|
25
|
+
from runtime.ct_executor import CTExecutionError
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _parse_iso_date(inputs: Dict[str, Any], key: str) -> date:
|
|
29
|
+
if key not in inputs:
|
|
30
|
+
raise CTExecutionError(
|
|
31
|
+
f"CT_PURE_EVALUATE_INACTIVITY_V0: missing required input '{key}'"
|
|
32
|
+
)
|
|
33
|
+
raw = inputs[key]
|
|
34
|
+
if not isinstance(raw, str):
|
|
35
|
+
raise CTExecutionError(
|
|
36
|
+
f"CT_PURE_EVALUATE_INACTIVITY_V0: '{key}' must be an ISO-8601 string, "
|
|
37
|
+
f"got {type(raw).__name__}"
|
|
38
|
+
)
|
|
39
|
+
# Accept both date and date-time forms; a trailing Z is ISO-8601 but not accepted by
|
|
40
|
+
# fromisoformat before 3.11, so normalize it.
|
|
41
|
+
normalized = raw[:-1] + "+00:00" if raw.endswith("Z") else raw
|
|
42
|
+
try:
|
|
43
|
+
return datetime.fromisoformat(normalized).date()
|
|
44
|
+
except ValueError:
|
|
45
|
+
raise CTExecutionError(
|
|
46
|
+
f"CT_PURE_EVALUATE_INACTIVITY_V0: '{key}' is not a valid ISO-8601 date: {raw!r}"
|
|
47
|
+
) from None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def execute(inputs: Dict[str, Any], context: Any = None) -> Dict[str, Any]:
|
|
51
|
+
"""
|
|
52
|
+
Execute CT_PURE_EVALUATE_INACTIVITY_V0.
|
|
53
|
+
|
|
54
|
+
Inputs:
|
|
55
|
+
last_active_date (str): ISO-8601 date/date-time of last recorded activity
|
|
56
|
+
evaluation_date (str): ISO-8601 date/date-time the evaluation is made as of
|
|
57
|
+
threshold_days (int): Inactivity threshold in days
|
|
58
|
+
|
|
59
|
+
Outputs:
|
|
60
|
+
is_inactive (bool): True when days_inactive >= threshold_days
|
|
61
|
+
days_inactive (int): Whole days elapsed between the two dates
|
|
62
|
+
"""
|
|
63
|
+
last_active = _parse_iso_date(inputs, "last_active_date")
|
|
64
|
+
evaluated_on = _parse_iso_date(inputs, "evaluation_date")
|
|
65
|
+
|
|
66
|
+
if "threshold_days" not in inputs:
|
|
67
|
+
raise CTExecutionError(
|
|
68
|
+
"CT_PURE_EVALUATE_INACTIVITY_V0: missing required input 'threshold_days'"
|
|
69
|
+
)
|
|
70
|
+
threshold_days = inputs["threshold_days"]
|
|
71
|
+
if isinstance(threshold_days, bool) or not isinstance(threshold_days, int):
|
|
72
|
+
raise CTExecutionError(
|
|
73
|
+
"CT_PURE_EVALUATE_INACTIVITY_V0: 'threshold_days' must be an int, "
|
|
74
|
+
f"got {type(threshold_days).__name__}"
|
|
75
|
+
)
|
|
76
|
+
if threshold_days < 0:
|
|
77
|
+
raise CTExecutionError(
|
|
78
|
+
f"CT_PURE_EVALUATE_INACTIVITY_V0: 'threshold_days' must be non-negative, "
|
|
79
|
+
f"got {threshold_days}"
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
if evaluated_on < last_active:
|
|
83
|
+
raise CTExecutionError(
|
|
84
|
+
"CT_PURE_EVALUATE_INACTIVITY_V0: 'evaluation_date' precedes 'last_active_date' "
|
|
85
|
+
f"({evaluated_on.isoformat()} < {last_active.isoformat()})"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
days_inactive = (evaluated_on - last_active).days
|
|
89
|
+
|
|
90
|
+
if days_inactive < threshold_days:
|
|
91
|
+
raise CTExecutionError(
|
|
92
|
+
f"CT_PURE_EVALUATE_INACTIVITY_V0: license is still active "
|
|
93
|
+
f"(days_inactive={days_inactive} < threshold_days={threshold_days})"
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return {"result_status": "SUCCESS", "is_inactive": True, "days_inactive": days_inactive}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|