Document exact native catalogue gap and bounded owner proposal
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
tegwick 2026-10-11 03:07:31 +02:00
parent f0f67a55ce
commit 1eefbfc44a
9 changed files with 296 additions and 0 deletions

View file

@ -0,0 +1,69 @@
{
"application": {
"application_id": "informed-decision",
"display_name": "Informed Decision",
"owner": "informed-decision",
"allowed_profile_scopes": [
"global"
],
"allowed_projection_types": [
"application_runtime"
]
},
"binding": {
"application_id": "informed-decision",
"oidc_client_id": "informed-decision-approver",
"protected_system_id": "informed-decision",
"catalog_namespaces": [],
"event_source": null,
"deployment_ref": null
},
"canonical_store_rows": [
{
"record_type": "applications",
"record_key": "informed-decision",
"payload": {
"application_id": "informed-decision",
"display_name": "Informed Decision",
"owner": "informed-decision",
"allowed_profile_scopes": [
"global"
],
"allowed_projection_types": [
"application_runtime"
]
},
"tenant": null,
"user_id": null,
"application_id": "informed-decision",
"scope_type": null,
"scope_id": null
},
{
"record_type": "application_bindings",
"record_key": "informed-decision",
"payload": {
"application_id": "informed-decision",
"oidc_client_id": "informed-decision-approver",
"protected_system_id": "informed-decision",
"catalog_namespaces": [],
"event_source": null,
"deployment_ref": null
},
"tenant": null,
"user_id": null,
"application_id": "informed-decision",
"scope_type": null,
"scope_id": null
}
],
"application_owner": "informed-decision",
"local_registry_owner": "user-engine",
"protected_system_owner": "access-engine",
"oidc_client_owner": "key-cape",
"entry_url_evidence": "https://decisions.coulomb.social/",
"entry_url_persisted": false,
"entry_url_reason": "Canonical Application/ApplicationBinding model has no entry URL field. URL is separate verified Ingress context, never an invented persisted field.",
"creates_user_permissions": false,
"scope": "One application record and one exact binding; no memberships, roles, grants or user creation."
}

View file

@ -0,0 +1,8 @@
{
"read_only": true,
"secret_objects_read": false,
"real_human_login_performed": false,
"method": "Known client rejects unregistered redirect with native KeyCape redirect_uri error; no login/cookie/state output.",
"http_status": 400,
"registered_client_rejects_wrong_redirect": true
}

View file

@ -0,0 +1,24 @@
{
"ingress_read": true,
"secret_objects_read": false,
"entries": [
{
"name": "informed-decision",
"uid": "98d3885a-a62d-49c2-91ea-6616fa5a04ae",
"hosts": [
"decisions.coulomb.social"
],
"tls_hosts": [
"decisions.coulomb.social"
]
},
{
"name": "informed-decision-http-redirect",
"uid": "550279fb-c9a1-4585-9b21-27b1c8f90b6d",
"hosts": [
"decisions.coulomb.social"
],
"tls_hosts": []
}
]
}

View file

@ -0,0 +1,12 @@
{
"application_absent": true,
"binding_absent": true,
"exact_match": false,
"fixed_application_id": "informed-decision",
"native_mutation": false,
"partial_or_conflicting": false,
"read_only": true,
"pod_uid": "e500bcae-c911-43a2-bd40-6a30b39064ab",
"pod_image_match": true,
"native_exec_returncode": 0
}

View file

@ -0,0 +1,27 @@
# Exact one-application catalogue owner proposal
The live readback adapter is admitted and working. The fixed read-only preflight on its actual published Ready pod proves application informed-decision and its binding are both absent. Exact model/serialized records are attached; no mutation occurred. Existing application metadata registration is owned by User Engine, application facts by informed-decision, OIDC client by KeyCape and protected-system/client contract by Access Engine. Application-owner acknowledgment of the exact facts is required before native registration.
## Exact facts and limits
Application: id informed-decision, display name Informed Decision, owner informed-decision, default global profile scope and application-runtime projection type only. Binding: application informed-decision, OIDC client informed-decision-approver, protected system informed-decision, empty catalog_namespaces, no event_source or deployment_ref. No user, membership, role, entitlement or grant is created. Access's actual registry declares this participant/client/issuer, and actual KeyCape independently rejects its wrong callback. Actual ingress UID98d3885a-a62d-49c2-91ea-6616fa5a04ae binds TLS host decisions.coulomb.social. Canonical Application/ApplicationBinding has no entry URL field, so https://decisions.coulomb.social/ is retained only as context. It is not silently stored in deployment_ref, event_source or a made-up schema field. The local row alone does not prove every fleet workload or scoped mutation/grant contract.
## Existing supported authenticated path
Existing source method is UserEngineService.register_application(verified_operator_actor, application, binding=binding). It checks absence, calls application.register through the normal FlexAuth adapter, atomically stores app/binding, and appends normal AuditRecord plus application.registered OutboxEvent. The genuine actor must come from the existing cryptographically verified User Engine identity boundary. Existing source accepts platform-operator or tenant-admin roles in its package, but this proposal grants neither and may not invent either label. A founder memo approval is not a JWT or authenticated actor. Synthetic actors used for readback policy tests must never authorize this mutation.
Warden route searches found no User Engine management/registration lane. The KeyCape attended OIDC route is not an application.register adapter or grant. Reuse declaration describes library-import/headless consumption and remains draft. Portal/runtime source has no HTTP route for register_application, and no installed operator invocation bridging a real authenticated actor into this headless method was found. The expression above is a supported source API, not an available end-to-end native command. No credentials, login permission, endpoint or helper framework was requested or added.
## Proposed alternative requiring a distinct founder decision
If the owner cannot supply the supported genuine authenticated invocation promptly, the founder may choose a one-time supervised administrative bootstrap exception for exactly the attached two metadata entities. It must be presented truthfully as maintenance outside the ordinary application.register actor/PDP admission, never as a simulated founder JWT/session or a successful PDP-authorized user transaction. This packet does not implement that exception and is not ready for execution until a bounded exact executor, independent owner review and database rollback/dry-run receipt are prepared.
Closed proposed scope: connect through the existing admitted User Engine service database connection without exporting its URL; require the exact current workload/source/schema and target database; serializable transaction and owner lock; compare target app/binding and related records; permit only both absent, or both exact match (no-change). Any partial/different state refuses. Insert exactly the two canonical codec rows using create-only semantics, not the store's unconditional upsert; record actual maintenance actor issuer urn:manual-maintenance and supervised Codex operation identity with the founder approval/proposal reference, no asserted human roles/assurance and no fabricated PDP decision_id. Append a truthful AuditRecord action application.metadata.bootstrap and an ordinary application.registered outbox event with explicit maintenance_exception/proposal/approval attribution in its metadata payload; no normal user creation or privilege claim. These audit/outbox details need owner validation against actual codec/event consumers before approval of execution. Commit only after bounded readback matches exactly; retain row/audit/event IDs and payload hashes as a created-only receipt. The actual operation and its created audit/outbox footprints must all appear in the final founder packet, not just 'two rows'. Direct cost estimate EUR0 on existing resources; engineering time and maintenance-auth exception are the material cost/risk.
Rollback is conditional created-only maintenance, not a generic delete API (none exists for this registration). In an owner-reviewed transaction compare recorded created row IDs/types/payload hashes, prove no later dependent records or subsequent modification, and remove only the two application entities. Retain original audit/event history and record actual rollback attribution. If the registration event was delivered or claimed, stop for owner reconciliation/compensating-event review; do not erase evidence or assert downstream reversal. No blind replay, overwrite or removal of shared/preexisting records. An exact-match no-change outcome has no undo authority. This conditional recovery contract and event handling must be concrete before asking the founder to execute the alternative.
If chosen, record the precise temporary relaxation in Custodian docs/security-close-down-checklist.md: ordinary application.register authenticated actor/PDP admission bypassed only for this one metadata bootstrap; User Engine owns restoration by installing a supported authenticated management path, acceptance evidence and migration before customer production. The current packet is only a proposal; no active relaxation is asserted or checklist entry falsely marked executed. Approval should expire2026-10-12T23:59:59Z, be single-use and exact-source-bound, with no future login privilege or autopilot promotion.
## Acceptance after either approved native path
Repeat admitted User Engine DB/application/binding and runtime catalogue checks without persisted fixtures. Require exactly the real three-way bound informed-decision workload and unchanged native allow/deny/unavailable/expiry behavior. Record whether the account-page catalogue uses that persisted row; browser/MFA proof remains independently human. USER26/28 close only their actual required contract scope, not merely a transport or seeded-row success. Attach work to those existing tasks; do not create another planner or copied task list.

View file

@ -0,0 +1,15 @@
"""Fixed READ ONLY preflight for one proposed catalogue registration; never writes."""
import os,json,datetime,hashlib
from pathlib import Path
from user_engine.domain import Application,ApplicationBinding,ProfileScope,ProjectionType
from user_engine.store_records import store_record_for
from user_engine.adapters.postgres import PostgresUserEngineStore
import psycopg
application=Application('informed-decision','Informed Decision','informed-decision',allowed_profile_scopes=(ProfileScope.GLOBAL,),allowed_projection_types=(ProjectionType.APPLICATION_RUNTIME,))
binding=ApplicationBinding('informed-decision',oidc_client_id='informed-decision-approver',protected_system_id='informed-decision',catalog_namespaces=(),event_source=None,deployment_ref=None)
out={'fixed_application_id':'informed-decision','read_only':True,'native_mutation':False}
try:
with psycopg.connect(os.environ['USER_ENGINE_DATABASE_URL']) as conn:
conn.execute('SET TRANSACTION READ ONLY');store=PostgresUserEngineStore(conn);a=store.application('informed-decision');b=store.binding('informed-decision');out.update(application_absent=a is None,binding_absent=b is None,exact_match=a==application and b==binding,partial_or_conflicting=not ((a is None and b is None) or (a==application and b==binding)));conn.rollback()
except Exception as e:out['exception_class']=type(e).__name__
print(json.dumps(out,sort_keys=True))

View file

@ -0,0 +1,26 @@
{
"proposal_id": "USER-CATALOGUE-INFDEC-20261011-R1",
"status": "owner-proposal-no-native-write",
"beneficiary_tasks": [
"USER-WP-0026-T03",
"USER-WP-0028-T02"
],
"target": "User Engine catalogue in user-engine-pg on railiance01",
"preferred_existing_contract": "UserEngineService.register_application(real_verified_operator_actor, Application, binding=ApplicationBinding)",
"native_authenticated_management_entrypoint_found": false,
"ordinary_pdp_action": "application.register",
"ordinary_mutation_transaction": "app/binding + actual audit/application.registered outbox",
"proposed_alternative": "One-time supervised administrative bootstrap exception, only if founder explicitly chooses after exact owner-reviewed executor/dry-run is prepared. No bypass is implemented by this packet.",
"expiration_if_selected": "2026-10-12T23:59:59Z",
"approval_required": true,
"approval_grants_iam_claims": false,
"new_endpoint": false,
"new_login_permission": false,
"new_generic_helper_framework": false,
"rollback_prerequisites": [
"exact created app and binding payloads still match",
"no later dependent records or changed payloads",
"outbox delivery/consumer side effects reconciled; refuse blind event deletion"
],
"risk": "Administrative alternative skips the ordinary application.register actor/PDP admission for exactly this metadata registration, requiring explicit maintenance attribution and recorded relaxation. It is not an authenticated user-engine transaction or simulated human session."
}

View file

@ -0,0 +1,94 @@
[
{
"query": "user-engine application registration administrative management",
"command_success": true,
"matches": [
{
"id": "openbao-structure-survey",
"owner_repo": "ops-mason",
"warden_executes": false,
"exec_capable": false,
"resolvable": false,
"status": "active"
},
{
"id": "agent-harness-forgejo-deploy",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": true,
"resolvable": true,
"status": "active"
},
{
"id": "coulomb-social-runtime-env",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": false,
"resolvable": false,
"status": "active"
},
{
"id": "keycape-client-secret-generate",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": false,
"resolvable": false,
"status": "active"
},
{
"id": "net-kingdom-privacyidea-admin-token",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": false,
"resolvable": false,
"status": "active"
}
]
},
{
"query": "key-cape human operator OIDC login",
"command_success": true,
"matches": [
{
"id": "key-cape-oidc-login",
"owner_repo": "key-cape",
"warden_executes": false,
"exec_capable": true,
"resolvable": false,
"status": "active"
},
{
"id": "keycape-client-secret-generate",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": false,
"resolvable": false,
"status": "active"
},
{
"id": "rapp-qonto-keycape-client",
"owner_repo": "key-cape",
"warden_executes": false,
"exec_capable": true,
"resolvable": true,
"status": "active"
},
{
"id": "agent-harness-forgejo-deploy",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": true,
"resolvable": true,
"status": "active"
},
{
"id": "openbao-api-key",
"owner_repo": "railiance-platform",
"warden_executes": false,
"exec_capable": true,
"resolvable": false,
"status": "active"
}
]
}
]

View file

@ -0,0 +1,21 @@
import json,subprocess,base64
from pathlib import Path
probe=Path('/tmp/user-catalogue-preflight.py').read_bytes()
remote=r'''
import json,subprocess,base64,sys
r=subprocess.run(['kubectl','get','pods','-n','user-engine','-l','app.kubernetes.io/name=user-engine','-o','json'],capture_output=True,text=True)
if r.returncode:print(json.dumps({'pod_selection_success':False}));sys.exit(1)
pods=[p for p in json.loads(r.stdout)['items'] if p.get('status',{}).get('phase')=='Running' and any(c['type']=='Ready' and c['status']=='True' for c in p.get('status',{}).get('conditions',[]))]
if len(pods)!=1:print(json.dumps({'pod_selection_success':False,'ready_pod_count':len(pods)}));sys.exit(1)
p=pods[0]
if p['spec']['containers'][0]['image']!='forgejo.coulomb.social/coulomb/user-engine@sha256:f239bbf332b8eb87320c86390fddca1dcb4f7c628a7af75e79dee8058d446a7b':print(json.dumps({'image_match':False}));sys.exit(1)
r=subprocess.run(['kubectl','exec','-i','-n','user-engine',p['metadata']['name'],'-c','portal','--','python3','-'],input=base64.b64decode('__PROBE__'),capture_output=True)
try:out=json.loads(r.stdout)
except Exception:out={'native_probe_output_valid':False,'raw_output_suppressed':True}
out['pod_uid']=p['metadata']['uid'];out['pod_image_match']=True;out['native_exec_returncode']=r.returncode
print(json.dumps(out))
'''.replace('__PROBE__',base64.b64encode(probe).decode())
r=subprocess.run(['ssh','railiance01','python3 -'],input=remote,text=True,capture_output=True)
try:out=json.loads(r.stdout)
except Exception:out={'native_probe_output_valid':False,'raw_output_suppressed':True}
Path('/tmp/user-catalogue-preflight.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps(out))