diff --git a/.kaizen/agents/custodian-codex/supervision.json b/.kaizen/agents/custodian-codex/supervision.json index 9f5317ba..5be287f3 100644 --- a/.kaizen/agents/custodian-codex/supervision.json +++ b/.kaizen/agents/custodian-codex/supervision.json @@ -1251,7 +1251,7 @@ "outcome": "failed", "target": "railiance01 forgejo/forge; paired repo-manager/railiance-forge/Apps source", "expected_result": "Restore exact existing-policy fragment only at markitect-main; verify171 active hook sets, then reuse sealed JSON correction and same six source changes.", - "verification_ref": "docs/changes/2026-11-01-scanner-json-digest/native-r4/prior-execution-outcome.json", + "verification_ref": "docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json", "rollback_ref": "docs/changes/2026-11-01-scanner-json-digest/native-r4/PLAN.md", "cost_estimate_eur": { "incremental_infrastructure": 0, @@ -1264,10 +1264,10 @@ "risk_estimate_eur": null, "risk_estimate": "Old-policy atomic fragment install then expected1-3 minute JSON-phase Recreate interruption. Retain repaired protection during old-policy rollback. Illustrative recovery EUR100; full security loss and founder time unpriced, supervised judgement required.", "supervisor": "Bernd Worsch", - "approved_revision": 3, - "approved_digest_sha256": "df1cb48259ec5411a3f8cd24d436078daf09d241c39448454526f0a796798c34", - "executed_revision": 3, - "executed_digest_sha256": "df1cb48259ec5411a3f8cd24d436078daf09d241c39448454526f0a796798c34", + "approved_revision": 4, + "approved_digest_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", + "executed_revision": 4, + "executed_digest_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", "refinement_or_rescue": true, "promotion_evidence": false, "revisions": [ @@ -1292,9 +1292,9 @@ "basis": "portable numeric modes; exact known group-write restoration including protected hook metadata; reuse existing immutableCM; fresh native/source receipt gate. Pinned-image/controller/runtime tests passed." } ], - "execution_ref": "docs/changes/2026-11-01-scanner-json-digest/native-r4/failed-r3-recovery-receipt.json", - "verified_outcome": "Approved revision3 repaired missing fragment and verified171 old-policy fragments. Candidate native probe passed, hook migration failed before deployment patch, and old-policy rollback/probes/metadata verified. Published Forgejo image reproduces unsupported chmod --reference. No JSON activation or six-file source application.", - "recovery": "Old-policy rollback verified, repair retained, earlier receipts unchanged; revision4 portable migration/known mode restoration and ConfigMap reuse tested in pinned Forgejo image. No native revision4 execution.", + "execution_ref": "docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/failed-receipt.json", + "verified_outcome": "Exact approved revision4 failed at first get:nodes before any native mutation; access failure category unresolved. Local transport responds anonymously401; public server certificate is not expired. Read-only access diagnostic prepared,3 tests passed. Original packet and authorization unchanged.", + "recovery": "No native mutation, no rollback required. Failed receipt and packet preserved; diagnose access before any unchanged approved retry.", "supervisor_execution_evidence": "User returned bash /tmp/forge-scanner-rollout.sh failure output in active conversation, 2026-11-02", "attempts": [ { @@ -1320,11 +1320,19 @@ "outcome": "failed", "verification_ref": "docs/changes/2026-11-01-scanner-json-digest/native-r4/prior-execution-outcome.json" } + }, + { + "revision": 4, + "attempt": 1, + "packet_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", + "approval_ref": "User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02", + "outcome": "first get:nodes failed before mutation", + "outcome_ref": "docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json" } ], - "current_revision_status": "approved_waiting_founder_execution", - "approved_at": "2026-11-02T01:13:07.073986+00:00", - "approval_ref": "User: Approve exact revision 3; request_user_input_async call_d07a070d30a54a538c872888bd5b0e30 item0, 2026-11-02", + "current_revision_status": "approved_access_recovery_pending", + "approved_at": "2026-11-02T01:59:02.333371+00:00", + "approval_ref": "User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02", "current_revision_approval": { "revision": 4, "packet_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", @@ -1332,12 +1340,14 @@ "disposition": "accepted_revised", "approved_at": "2026-11-02T01:59:02.333371+00:00", "approval_ref": "User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02", - "executed": false + "executed": true, + "outcome": "failed before native mutation", + "verification_ref": "docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json" }, - "score_note": "Summary fields retain the latest completed revision3 failed outcome; current revision4 exact approval is separate pending execution. Original failed attempts stay preserved; no success or missing earlier approval backfilled.", + "score_note": "Latest completed revision4 attempt failed with exact existing approval. Prior revision2 and3 failures stay in the same trial. Approval persists only for unchanged revision4 scope; no success, new authority or missing earlier approval inferred.", "original_digest": "75bc6e4bf1a98444cd844306bf8f3f81aca1e31b1609081905fd42ed1b76ae42", - "approved_digest": "df1cb48259ec5411a3f8cd24d436078daf09d241c39448454526f0a796798c34", - "executed_digest": "df1cb48259ec5411a3f8cd24d436078daf09d241c39448454526f0a796798c34", + "approved_digest": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", + "executed_digest": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", "current_approved_revision": 4, "current_approved_digest_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd" } diff --git a/docs/changes/2026-11-01-scanner-json-digest/README.md b/docs/changes/2026-11-01-scanner-json-digest/README.md index cdb34d07..3f72868c 100644 --- a/docs/changes/2026-11-01-scanner-json-digest/README.md +++ b/docs/changes/2026-11-01-scanner-json-digest/README.md @@ -35,3 +35,5 @@ The founder executed approved revision3: the missing-fragment repair and171-repo [Revision4](native-r4/PLAN.md), packet SHA256 `64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd`, corrects numeric mode handling and exact known group-write restoration, reuses the existing verified immutable ConfigMap, and has a fresh execution/source gate. Eight shell image cases, a four-case171-repository/1539-hook controller run, three controller checks and runtime self-test passed. Candidate scanner/profile and six owner source hashes are unchanged. Await exact revision4 review; no native revision4 action has run. The proposed founder launcher is `/tmp/forge-scanner-rollout-r4.sh`. Founder approval recorded for exact revision4 packet `64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd` via User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02. Attended execution pending at `/tmp/forge-scanner-rollout-r4.sh`; approval receipt `docs/changes/2026-11-01-scanner-json-digest/native-r4-approval.json`. Earlier failures and exact approvals remain preserved; no execution success is inferred from approval. + +Current revision4 execution attempt failed at first get:nodes, before mutation. Packet/approval are unchanged and its failed receipt is preserved in `attempt-r4-access/`. The local bridge/API transport responds, public server certificate is not expired, and a tested read-only access classifier is ready at `bash /tmp/forge-scanner-access-diagnose.sh`. Await selected founder-context status before any unchanged retry; no renewed approval is requested. diff --git a/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/diagnose_access.py b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/diagnose_access.py new file mode 100644 index 00000000..9ed1c9af --- /dev/null +++ b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/diagnose_access.py @@ -0,0 +1,79 @@ +"""Founder-run selected access diagnostics, never config/credentials/raw errors. + +No mutation or receipt reset. Reads selected node and self-identity metadata with +the catalogued attended context. The rollout packet and failed receipt stay intact. +""" +from pathlib import Path +import importlib.util +import json +import os +import subprocess + +HERE=Path(__file__).resolve().parent +R4=HERE.parent/'native-r4' +EXPECTED='64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd' +ADMIN=Path('/home/worsch/.kube/config-railiance01') +OUTPUT=Path('/tmp/forge-scanner-access-diagnostic-receipt.json') + + +def category(returncode,stderr): + if returncode==0:return 'passed' + lower=stderr.lower() + groups=[('authentication-required',[b'the server has asked for the client to provide credentials',b'must be logged in to the server',b'unauthorized',b'invalid bearer token']), + ('authorization-denied',[b'forbidden']), + ('certificate-validity-failure',[b'certificate has expired',b'certificate is not yet valid',b'not yet valid']), + ('certificate-verification-failure',[b'x509:',b'failed to verify certificate',b'certificate signed by unknown authority']), + ('client-certificate-required',[b'tls: certificate required',b'client certificate required']), + ('connection-refused',[b'connection refused']), + ('transport-timeout',[b'i/o timeout',b'context deadline exceeded',b'tls handshake timeout',b'timed out']), + ('name-resolution',[b'no such host']), + ('context-selection-failure',[b'current-context is not set',b'context was not found',b'no context exists',b'does not exist']), + ('configuration-unavailable',[b'error loading config file',b'no configuration has been provided',b'no such file or directory']), + ('configuration-parse-failure',[b'yaml:',b'invalid configuration']), + ('credential-plugin-failure',[b'getting credentials: exec',b'exec plugin',b'no auth provider found']), + ('api-unavailable',[b'serviceunavailable',b'bad gateway',b'currently unable to handle the request',b'connection reset by peer',b'eof']), + ('protocol-mismatch',[b'http response to https client'])] + for name,needles in groups: + if any(n in lower for n in needles):return name + return 'unclassified-command-failure' + + +def selected_nodes(raw,cfg): + data=json.loads(raw);items=data.get('items',[]) + matched=len(items)==1 and items[0].get('metadata',{}).get('uid')==cfg['node_uid'] and any(x.get('address')=='92.205.62.239' for x in items[0].get('status',{}).get('addresses',[])) + return {'node_count':len(items),'target_node_matches':matched} + + +def selected_identity(raw): + data=json.loads(raw);user=data.get('status',{}).get('userInfo',{}) + return {'self_identity_read':True,'identity_is_builder':user.get('username')=='ops-mason-builder', + 'identity_in_system_masters': 'system:masters' in user.get('groups',[])} + + +def main(): + s=importlib.util.spec_from_file_location('reviewed_r4',R4/'rollout.py');m=importlib.util.module_from_spec(s);s.loader.exec_module(m) + if m.verify_packet()!=EXPECTED:raise RuntimeError('reviewed-packet-drift') + cfg=json.loads((R4.parent/'native-r2/inputs.json').read_bytes()) + env=dict(os.environ,KUBECONFIG=str(ADMIN)) + receipt={'read_only':True,'native_mutation':False,'rollout_packet_sha256':EXPECTED, + 'catalog_route':'kubernetes-railiance01-admin','admin_file_present':ADMIN.is_file(), + 'admin_file_readable':os.access(ADMIN,os.R_OK),'checks':[]} + for label,args,select in [('get-nodes',['get','nodes','-o','json'],lambda raw:selected_nodes(raw,cfg)), + ('self-identity',['auth','whoami','-o','json'],selected_identity)]: + try: + q=subprocess.run(['kubectl','--request-timeout=8s',*args],capture_output=True,timeout=15,env=env) + item={'operation':label,'returncode':q.returncode,'category':category(q.returncode,q.stderr)} + if q.returncode==0: + try:item.update(select(q.stdout)) + except (ValueError,TypeError,KeyError,AttributeError):item['category']='unexpected-response; raw withheld' + except subprocess.TimeoutExpired:item={'operation':label,'category':'client-command-timeout'} + receipt['checks'].append(item) + OUTPUT.write_text(json.dumps(receipt,indent=2)+'\n') + print(json.dumps(receipt,indent=2));print('receipt:',str(OUTPUT)) + + +if __name__=='__main__': + try:main() + except Exception as error: + print(json.dumps({'result':'read-only-diagnostic-refused','reason':str(error) if isinstance(error,RuntimeError) else type(error).__name__})) + raise SystemExit(1) diff --git a/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/failed-receipt.json b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/failed-receipt.json new file mode 100644 index 00000000..5d84bdc4 --- /dev/null +++ b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/failed-receipt.json @@ -0,0 +1,15 @@ +{ + "proposal_id": "SYNC-SCANNER-JSON-DIGEST-20261101", + "revision": 4, + "events": [ + { + "event": "command-failed", + "operation": "get:nodes", + "category": "command-failed" + } + ], + "native_mutation": false, + "packet_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", + "reused_r2_packet_sha256": "d22b1f555af96c203b7d68efd25e80815ce18ca4e3bf0dd3ab96b6f699d50237", + "mode": "apply" +} diff --git a/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json new file mode 100644 index 00000000..c80380ab --- /dev/null +++ b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/outcome.json @@ -0,0 +1,22 @@ +{ + "proposal_id": "SYNC-SCANNER-JSON-DIGEST-20261101", + "revision": 4, + "packet_sha256": "64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd", + "outcome": "failed at first Kubernetes read", + "native_mutation": false, + "reported_reason": "kubernetes-command-failed:get:nodes", + "failed_receipt_sha256": "8c876dd2ac8d21a1c4b2a1823802f8a318328d8e16ebb7191160d87525bd50f6", + "authorization": "exact revision4 approval remains valid; no code or scope change", + "transport_observation": { + "bridge": "connected", + "anonymous_api_http_status": 401, + "identity_verified": false, + "server_certificate_expired": false, + "server_certificate_not_after": "2027-03-10T00:47:00Z", + "credentials_used": false + }, + "next_step": "founder-run read-only access diagnostic; determine credentials/configuration/transport error without raw output", + "diagnostic_sha256": "4df7a7a8d88abada354dcd59f6cd452e20d9bfe67aac0813991ea0e2545599c7", + "diagnostic_tests": 3, + "approved_packet_changed": false +} diff --git a/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/test_access_diagnostic.py b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/test_access_diagnostic.py new file mode 100644 index 00000000..538484d1 --- /dev/null +++ b/docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/test_access_diagnostic.py @@ -0,0 +1,26 @@ +import importlib.util +from pathlib import Path +import json +import unittest + +p=Path(__file__).resolve().parent/'diagnose_access.py';s=importlib.util.spec_from_file_location('access_probe',p);d=importlib.util.module_from_spec(s);s.loader.exec_module(d) + + +class Tests(unittest.TestCase): + def test_authentication_challenge_without_unauthorized_word(self): + raw=b'could not get API group list: the server has asked for the client to provide credentials PRIVATE_SENTINEL' + self.assertEqual(d.category(1,raw),'authentication-required') + def test_categories_do_not_echo_raw_errors(self): + for raw,expected in [(b'x509: certificate has expired PRIVATE_SENTINEL','certificate-validity-failure'), + (b'Forbidden PRIVATE_SENTINEL','authorization-denied'), + (b'connect: connection refused PRIVATE_SENTINEL','connection-refused'), + (b'PRIVATE_SENTINEL','unclassified-command-failure')]: + self.assertEqual(d.category(1,raw),expected) + def test_selected_success_fields_do_not_emit_credentials_or_full_objects(self): + raw=json.dumps({'items':[{'metadata':{'uid':'expected','annotations':{'unrelated':'PRIVATE_SENTINEL'}},'status':{'addresses':[{'address':'92.205.62.239'}]}}]}).encode() + self.assertEqual(d.selected_nodes(raw,{'node_uid':'expected'}),{'node_count':1,'target_node_matches':True}) + raw=json.dumps({'status':{'userInfo':{'username':'ops-mason-builder','groups':['PRIVATE_SENTINEL']},'unrelated':'PRIVATE_SENTINEL'}}).encode() + result=d.selected_identity(raw);self.assertTrue(result['identity_is_builder']);self.assertNotIn('PRIVATE_SENTINEL',json.dumps(result)) + + +if __name__=='__main__':unittest.main() diff --git a/docs/repository-sync-2026-11-01.md b/docs/repository-sync-2026-11-01.md index f888326b..65d66903 100644 --- a/docs/repository-sync-2026-11-01.md +++ b/docs/repository-sync-2026-11-01.md @@ -105,3 +105,7 @@ A reproduced userspace defect explains a migration failure: Forgejo11.0.3-rootle Proposed exact revision4 packet SHA256 `64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd`; no native revision4 execution. Existing decision5410707c-ce73-4f80-9c03-805102c31c58 is reopened for this revised action, while exact revision3 approval/outcome stays preserved. The new launcher is `/tmp/forge-scanner-rollout-r4.sh`. Prior failed revisions are one trial, not new successes; exact reviewed revision3's failed outcome is scored as accepted-revised, never unchanged success. Current revision4 remains pending. Founder approval recorded for exact revision4 packet `64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd` via User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02. Attended execution pending at `/tmp/forge-scanner-rollout-r4.sh`; approval receipt `docs/changes/2026-11-01-scanner-json-digest/native-r4-approval.json`. Earlier failures and exact approvals remain preserved; no execution success is inferred from approval. + +### Unchanged revision4: access failure before mutation + +The founder ran the exact approved revision4; first get:nodes failed, with native_mutation false. No runtime self-test, hook change, deployment patch or source application occurred. Original failed receipt and value-free diagnostic/outcome are preserved in attempt-r4-access. Transport-only observations: bridge connected, anonymous HTTPS API responds401, public server certificate valid until2027-03-10; no credentials used or target identity established by these checks. The actual founder-context failure awaits a read-only classifier (three tests passed), `bash /tmp/forge-scanner-access-diagnose.sh`. Keep approval/packet64c73100 unchanged; no new permission request or failed-outcome backfill. diff --git a/workplans/CUST-WP-0083-fleet-sync-and-scanner-remediation.md b/workplans/CUST-WP-0083-fleet-sync-and-scanner-remediation.md index 4d933f97..6258e13b 100644 --- a/workplans/CUST-WP-0083-fleet-sync-and-scanner-remediation.md +++ b/workplans/CUST-WP-0083-fleet-sync-and-scanner-remediation.md @@ -59,7 +59,7 @@ status: progress decision_id: "5410707c-ce73-4f80-9c03-805102c31c58" priority: high needs_human: true -intervention_note: "Founder approved exact revision4 packet 64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd. Run bash /tmp/forge-scanner-rollout-r4.sh in the founder terminal and return its sanitized output/receipt. Approved scope includes portable migration, exact mode restoration, reused ConfigMap and same six source changes." +intervention_note: "Approved unchanged revision4 failed at first get:nodes before mutation. Run bash /tmp/forge-scanner-access-diagnose.sh in the founder terminal and return selected access status. Bridge/API transport responds; actual credentials/configuration failure not yet classified. Existing approval is retained." state_hub_task_id: "589e1a54-9a4e-5f90-bd29-5c61a6cf8081" ``` @@ -67,6 +67,8 @@ Human-lane checkpoint, current 2026-11-02: approved revision3 repaired the missi Revision4 is prepared at `docs/changes/2026-11-01-scanner-json-digest/native-r4/PLAN.md`, packet SHA256 `64c73100f2347470fda1b8b3194dbf6a8009291d9d80223af463b3c5ecab52fd`. It uses portable numeric mode copying, restores only known group-write additions to unchanged/owned hook inodes after pod recreation, verifies/reuses the already-created immutable ConfigMap, and uses a fresh native/source receipt gate. Same scanner/profile, two deployment fields and six source candidates; prior packets/receipts are unchanged. Eight pinned-image shell cases, four full-controller cases across171 repositories/1539 hooks, three controller checks and the runtime self-test passed. The six owner-source preimages remain unchanged. The founder explicitly approved exact revision4 via User: Approve exact revision4; request_user_input_async call_f68b7e7de81a4c089e8864b3d66773a9 item0,2026-11-02. Attended native execution is pending at `bash /tmp/forge-scanner-rollout-r4.sh`; no additional approval is requested within that scope. Source activation awaits verified native outcome. The verified failed revision3 is recorded as failed, with the earlier unscored revision2 preserved in the same trial. +Execution update, 2026-11-02: the founder ran approved revision4, which failed at the first `get:nodes` read. Receipt records no native mutation. Preserve it in `docs/changes/2026-11-01-scanner-json-digest/attempt-r4-access/`; no code/scope revision or renewed approval is requested. The bridge reports connected, the API answers anonymously401, and its public server certificate is valid until2027-03-10. These are transport checks, not authenticated target proof. A separate read-only diagnostic safely distinguishes access errors; three tests passed. Await `bash /tmp/forge-scanner-access-diagnose.sh` from the founder. Retry only after access and zero-mutation receipt are reviewed/preserved; original packet stays unchanged. + Installing the repaired fragment does not retroactively admit existing history or establish why adoption missed this repository. Preserve historical/lifecycle coverage limits and source-owner class-level followup in T03 and the final audit. ## Verify complete remote publication and report exceptions