5959RELAY_LISTENER = "127.0.0.1:4242"
6060NOTARY_LISTENER = "127.0.0.1:4255"
6161RECORDS_PURPOSE = "public-works-case-management"
62- CANONICAL_WORKBOOK_PROJECT_FILE = "data/public_works_projects.xlsx"
63- CANONICAL_WORKBOOK_RUNTIME_PATH = "/data/public_works_projects.xlsx"
6462MATCH_KEY_ENV = "REGISTRYCTL_LOCAL_RELAY_MATCH_KEY_RAW"
6563NO_MATCH_KEY_ENV = "REGISTRYCTL_LOCAL_RELAY_NO_MATCH_KEY_RAW"
6664MATCH_FIELDS = {"project_id" , "district_code" , "sector" , "status" }
104102 for name , status in {** RELAY_SMOKE_OUTCOMES , ** NOTARY_SMOKE_OUTCOMES }.items ()
105103 ],
106104}
107- NOTARY_MANIFEST_DIGEST_PATHS = {
108- "consultation_relay_config_digest" : (
109- ".registry-stack/build/local/private/relay/config/relay-consultation.yaml"
110- ),
111- "runtime_consultation_relay_config_digest" : (
112- ".registry-stack/runtime/local/private/relay/config/relay-consultation.yaml"
113- ),
114- "compiled_notary_config_digest" : (
115- ".registry-stack/build/local/private/notary/config/notary.yaml"
116- ),
117- "runtime_notary_config_digest" : (
118- ".registry-stack/runtime/local/private/notary/config/notary.yaml"
119- ),
120- "postgres_ca_digest" : (
121- ".registry-stack/runtime/local/private/relay/config/state-plane-ca.pem"
122- ),
123- "database_init_digest" : ".registry-stack/runtime/local/private/db/init.sh" ,
124- "workload_jwks_digest" : (
125- ".registry-stack/runtime/local/private/workload/jwks.json"
126- ),
127- "consultation_relay_env_digest" : (
128- ".registry-stack/runtime/local/secrets/relay-consultation.env"
129- ),
130- "relay_bootstrap_env_digest" : (
131- ".registry-stack/runtime/local/secrets/relay-bootstrap.env"
132- ),
133- "notary_env_digest" : ".registry-stack/runtime/local/secrets/notary.env" ,
134- "postgres_env_digest" : ".registry-stack/runtime/local/secrets/postgres.env" ,
135- "workload_token_digest" : (
136- ".registry-stack/runtime/local/secrets/relay-workload-token"
137- ),
138- "workload_private_jwk_digest" : (
139- ".registry-stack/runtime/local/secrets/workload-private.jwk"
140- ),
141- }
142105SECRET_FILES = {
143106 "local_env" : "local.env" ,
144107 "relay_env" : "relay.env" ,
@@ -622,17 +585,6 @@ def digest_uri(path: Path) -> str:
622585 return f"sha256:{ sha256 (path )} "
623586
624587
625- def require_manifest_digest (
626- manifest : dict [str , Any ],
627- field : str ,
628- path : Path ,
629- ) -> None :
630- if manifest .get (field ) != digest_uri (path ):
631- raise ReleaseFormError (
632- f"canonical runtime manifest does not bind { field } "
633- )
634-
635-
636588def read_runtime_inspection (
637589 project : Path ,
638590 * ,
@@ -659,90 +611,49 @@ def read_runtime_inspection(
659611 expected_topology = (
660612 "combined_notary" if expected_notary_image is not None else "relay_only"
661613 )
662- expected_keys = {
614+ # registryctl start and smoke validate the internal runtime contract. Keep
615+ # this release-form check limited to the identity recorded as evidence.
616+ required_keys = {
663617 "schema_version" ,
664618 "environment" ,
665619 "relay_image" ,
666- "compose_digest" ,
667- "artifact_manifest_digest" ,
668- "relay_config_digest" ,
669- "workbook_digest" ,
670620 "workbook_classification" ,
671- "workbook_project_file" ,
672- "workbook_runtime_path" ,
673- "match_principal" ,
674- "runtime_uid" ,
675- "runtime_gid" ,
676- "runtime_files" ,
677621 "topology" ,
678622 }
679623 if expected_notary_image is not None :
680- expected_keys .add ("notary" )
681- if not isinstance (runtime_manifest , dict ) or set (runtime_manifest ) != expected_keys :
682- raise ReleaseFormError ("canonical runtime manifest fields are not closed" )
624+ required_keys .add ("notary" )
625+ if (
626+ not isinstance (runtime_manifest , dict )
627+ or not required_keys .issubset (runtime_manifest )
628+ ):
629+ raise ReleaseFormError (
630+ "canonical runtime manifest is missing required evidence fields"
631+ )
683632 if (
684633 runtime_manifest .get ("schema_version" ) != "registryctl.local_runtime.v2"
685634 or runtime_manifest .get ("environment" ) != "local"
686635 or runtime_manifest .get ("relay_image" ) != expected_relay_image
687636 or runtime_manifest .get ("workbook_classification" )
688637 != "operator_owned_source_data"
689- or not isinstance (runtime_manifest .get ("match_principal" ), str )
690- or not runtime_manifest ["match_principal" ]
691- or not isinstance (runtime_manifest .get ("runtime_uid" ), str )
692- or not runtime_manifest ["runtime_uid" ].isdigit ()
693- or runtime_manifest .get ("runtime_uid" ) == "0"
694- or not isinstance (runtime_manifest .get ("runtime_gid" ), str )
695- or not runtime_manifest ["runtime_gid" ].isdigit ()
696- or runtime_manifest .get ("runtime_gid" ) == "0"
697- or not isinstance (runtime_manifest .get ("runtime_files" ), dict )
698- or not runtime_manifest ["runtime_files" ]
699638 or runtime_manifest .get ("topology" ) != expected_topology
700639 ):
701640 raise ReleaseFormError (
702- "canonical runtime identity, topology, or workbook classification is invalid"
641+ "canonical runtime release identity, topology, or workbook classification is invalid"
703642 )
704- require_manifest_digest (runtime_manifest , "relay_config_digest" , relay_config )
705- require_manifest_digest (runtime_manifest , "compose_digest" , compose )
706- artifact_manifest = project / ".registry-stack/build/local/artifact-manifest.json"
707- require_manifest_digest (
708- runtime_manifest , "artifact_manifest_digest" , artifact_manifest
709- )
710- workbook_project_file = runtime_manifest .get ("workbook_project_file" )
711- workbook_runtime_path = runtime_manifest .get ("workbook_runtime_path" )
712- if (
713- workbook_project_file != CANONICAL_WORKBOOK_PROJECT_FILE
714- or workbook_runtime_path != CANONICAL_WORKBOOK_RUNTIME_PATH
715- ):
716- raise ReleaseFormError (
717- "canonical runtime does not bind the maintained spreadsheet starter"
718- )
719- require_manifest_digest (
720- runtime_manifest ,
721- "workbook_digest" ,
722- project / workbook_project_file ,
723- )
724643 notary = runtime_manifest .get ("notary" )
725644 if expected_notary_image is None :
726645 if notary is not None or expected_postgresql_image is not None :
727646 raise ReleaseFormError ("Relay-only canonical runtime contains Notary state" )
728647 else :
729- expected_notary_keys = {
730- "notary_image" ,
731- "postgresql_image" ,
732- * NOTARY_MANIFEST_DIGEST_PATHS ,
733- }
734648 if (
735649 expected_postgresql_image is None
736650 or not isinstance (notary , dict )
737- or set (notary ) != expected_notary_keys
738651 or notary .get ("notary_image" ) != expected_notary_image
739652 or notary .get ("postgresql_image" ) != expected_postgresql_image
740653 ):
741654 raise ReleaseFormError (
742655 "combined canonical runtime Notary manifest is incomplete"
743656 )
744- for field , relative in NOTARY_MANIFEST_DIGEST_PATHS .items ():
745- require_manifest_digest (notary , field , project / relative )
746657 return {
747658 "relay_config_sha256" : sha256 (relay_config ),
748659 "runtime_manifest_sha256" : sha256 (manifest ),
0 commit comments