Commit graph

90 commits

Author SHA1 Message Date
b428ffecb1 Bound approval transport and refuse redirects and proxies
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 16:45:18 +02:00
2eb045bfbf Record completed approval transport repair preparation
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 16:29:53 +02:00
custodian-sync
6923259aa7 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-11:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 15:46:12 +02:00
e864305d4d Publish reviewed strict execution consumption confirmation client
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 15:03:24 +02:00
097a2f2834 Record bounded execution consumption contract source preparation
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 14:38:14 +02:00
custodian-sync
c8ae88057d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-10:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-10 20:29:28 +02:00
17f2225caa Added workstats 2026-10-04 18:24:43 +02:00
custodian-sync
5733205de8 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-04:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
2026-10-04 11:37:28 +02:00
24a5ecd56b Add bounded source reconciliation counts and clarify receiver dependencies
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
2026-10-04 11:34:42 +02:00
custodian-sync
1044a5f36d chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-04:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
2026-10-04 11:28:36 +02:00
custodian-sync
bff815ad55 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-04:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
2026-10-04 11:27:12 +02:00
c9ad5c2dd7 Retain verified tenant provenance and reconcile production blockers
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1046e-fdbf-7b93-a267-5f72b9b24526
2026-10-04 11:26:32 +02:00
931e0b3249 Migrate owned cadence declaration to published contract
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1029d-2c93-7500-a0e0-e3e089668b29
2026-10-03 22:59:46 +02:00
custodian-sync
3abb576821 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-10-03:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1029d-2c93-7500-a0e0-e3e089668b29
2026-10-03 22:51:29 +02:00
901d569757 Close flex-auth -> access-engine rename intake with evidence (FLEX-WP-0020)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 101414@bnt-lap001
Assistant-Session: 60b5a221-d435-42b9-b778-983c90c7eed6
2026-09-30 18:56:31 +02:00
custodian-sync
2b6e4f2c11 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-09-30:
  - update .custodian-brief.md for approval-engine

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 101414@bnt-lap001
Assistant-Session: 60b5a221-d435-42b9-b778-983c90c7eed6
2026-09-30 15:06:50 +02:00
d485c77740 intake: flex-auth to access-engine rename consumer confirmation (FLEX-WP-0020)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 101414@bnt-lap001
Assistant-Session: 60b5a221-d435-42b9-b778-983c90c7eed6
2026-09-30 15:06:21 +02:00
74feb4e414 chore(consistency): regenerate WORK-RECORDS.md
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 270084@bnt-lap001
Assistant-Session: 350b785a-4dfd-4984-a852-dc6cc29bbc4f
2026-09-28 22:43:27 +02:00
custodian-sync
ee0173bec6 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-09-28:
  - update .custodian-brief.md for approval-engine

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 270084@bnt-lap001
Assistant-Session: 350b785a-4dfd-4984-a852-dc6cc29bbc4f
2026-09-28 22:37:42 +02:00
bd83befabe Move progress tasks with external gates to wait
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 270084@bnt-lap001
Assistant-Session: 350b785a-4dfd-4984-a852-dc6cc29bbc4f
2026-09-28 22:36:46 +02:00
b81b651ff4 chore(consistency): regenerate WORK-RECORDS.md [auto]
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 230497@bnt-lap001
Assistant-Session: 418cd0ab-dc61-43d8-8828-9ed571ac5c70
2026-09-27 21:08:07 +02:00
4a755ed3af Mark APPROVAL-WP-0002 blocked after loose-ends sweep finds no reachable local work
WP-0001 and WP-0003 are already finished with no open tasks. WP-0002's
remaining tasks (T01, T04, T05) are all gated on external owners
(KeyCape, audit-core, secrets-engine, platform credential custody);
nothing in this repo's own surface moves them forward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 230497@bnt-lap001
Assistant-Session: 418cd0ab-dc61-43d8-8828-9ed571ac5c70
2026-09-27 21:07:00 +02:00
093c51a245 chore(consistency): sync hub ids and work records [auto]
Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 20:24:46 +02:00
custodian-sync
23022dcf8a chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-09-27:
  - update .custodian-brief.md for approval-engine

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 20:24:38 +02:00
c93628a017 Let supersede() reissue an expired approval given a fresh window
expired stays a terminal exit from valid (state machine unchanged),
but supersede() now also accepts it as a source status when the
caller supplies a validity window, linking a new successor approval
to the expired original instead of requiring a caller to mint an
unlinked replacement from scratch. Without a fresh window, an expired
source still conflicts exactly as before.

The original's status becomes superseded (not left as a bare dead-end
expired) and superseded_by points at the successor, so the link is
documented rather than hidden -- informed-decision's overview already
renders this automatically, no changes needed there.

Prompted by the operator missing infd-20260927-b01's approval window
during today's key-cape login outage (APPROVAL-WP-0003).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 169987@bnt-lap001
Assistant-Session: 322ef1ef-9048-4021-8570-b6d6f6347999
2026-09-27 20:23:56 +02:00
71ae259877 Apply GH-DEC-2026-020: remove companion_version from layer.yaml
A12 r2 reaches every key and value of the declaration, including the
companion's version. The standard: path in INTENT.md was already
unversioned and is unchanged. tests/test_layer_declaration.py fails if a
version key, a versioned standard path, or companion_version returns to
the INTENT.md frontmatter or layer.yaml; schema_version and comments are
not reached. One prose citation ("the v0.5 scope rule") in a rationale
value is allowlisted by exact text and reported to gate-house as open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-21 09:37:12 +02:00
39e3380447 Apply GH-DEC-2026-017: INTENT.md governs, layer.yaml is derived, no version
Verified against gate-house's committed files before editing: GH-DEC-2026-017
in decisions/decisions.md and amendments A9-A13 in
docs/amendments/v0.8-section-11-declaration-amendments.md, then ops-warden's
reference change set (wiki/playbooks/netkingdom-layer-declaration.md and its
applied instance, ops-warden a70f559). Ruling and playbook agree.

layer.yaml: standard_version removed; marked derived: true / derived_from:
INTENT.md; header rewritten to say it does not govern and that a post-fold
disagreement between the forms is a finding. The Framework comment is
de-versioned for the same reason.

INTENT.md: the frontmatter layer: key is the declaration. It carried no
standard_version key, but its standard: path pinned _v0.7.md; de-versioned as
the reference instance did, since a pinned path reads as a validity condition.
Prose citing v0.7 as the accepted statute is left as is.

NO LAYER VALUE IS CHANGED. INTENT.md says Engine, layer.yaml says engine; the
section 3 vocabulary is closed and compared after an ASCII fold, so they agree.

No conformance checker exists in this repository, and no test reads
standard_version, so nothing else had to change with the field. Test suite:
156 passed. companion_version and schema_version are left untouched; the
ruling does not cover them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 63291@bnt-lap001
Assistant-Session: 8bd77868-ca68-4f49-bb1e-d539ecc0d703
2026-09-21 07:35:00 +02:00
675d3df2e0 Classify open workplans with flavor (CUST-WP-0072).
Set flavor on open workplans from origin/prose/status. Copy existing
depends_on aliases only. Do not promote residuals.

Assistant: grok
Assistant-Session: 01a09dc1-b21e-77e1-919e-fcad2f82b267
2026-09-14 15:50:41 +02:00
c55574cf7f Record T03 review admission and measured CPU request
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
2026-09-14 02:47:31 +02:00
abb273d2a7 Sync approval deployment completion index
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
2026-09-14 01:11:44 +02:00
custodian-sync
68a25109e9 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-09-14:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
2026-09-14 01:10:28 +02:00
d710bf0088 Deploy approval service and verify native persistence and audit
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
2026-09-14 01:08:50 +02:00
a0a602976e Principal is the requesting party, not the approver
informed-decision asked whether its binding.principal and ours name the same
field, since both GH rulings said its slice canonicalizes "two of the five".
They do not: ours is the party on whose behalf the act is performed, taken from
the decision request's subject, while theirs is the approver — which appears
here only as an entry and never in binding. Only target overlaps.

Records the four-role distinction normatively in docs/approval-claim.md and
guards it with a test asserting the act digest is insensitive to the approver
while the approver stays recorded on the entry. Folding approver identity into
the digest would now break view_hash's assumption here rather than silently in
that repository.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QDzGbdDFnVJBxDgdp7RvpH

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2191554@bnt-lap001
Assistant-Session: d69bb7c3-b7b2-41c4-8287-6baef48c0993
2026-09-10 22:43:33 +02:00
2fdb01d42a Disable the live operator client, keep its custody
key-cape reports the withdrawal came too late: approval-engine-operator
was provisioned in the 2026-09-09 custody window and is wired into a pod.
A live credential that can create and approve approvals, presented by
nobody, is a worse resting state than either extreme.

As requesting owner: disable, do not delete. CCR-2026-0018 stands so it
is restorable under the narrowing constraint once a presenter exists. A
recorded expiry was rejected — it promises to act later on a capability
that is dangerous now, guarding exactly the case where nobody is
watching.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-10 20:49:36 +02:00
bfb1e66646 Heartbeat per event class, not per source
audit-core's completeness contract landed, and our single per-source beat
is the shape it rules inadequate: it is discharged by whichever class is
busy, so a revocation stream that has gone silent looks identical to a
quiet one — and revocation is the only silence here that matters.

Emit one nothing-to-report assertion per declared class, all four in one
transaction so a partial emission cannot report some classes healthy and
others stalled. Carry type audit-core.heartbeat with class and assertion
on data. Pin that the first beat goes out at startup rather than an
interval later, since a declared-but-never-sent class is their
no_heartbeat_since_registration finding and not a skip.

Declare heartbeat_classes and the reconciliation surface in the source
registration, including the residual neither control covers: a
compromised emitter suppresses the event and its own heartbeat together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-10 20:36:21 +02:00
c8f85c6d76 Publish and pin the verified schema-v5 approval candidate
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 19:35:05 +02:00
be1a388a84 Enforce declared human controls at approval binding
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 19:26:12 +02:00
a3c94fb241 docs: refresh work record index after digest contract proof
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 18:48:01 +02:00
custodian-sync
efff75f790 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-09-10:
  - update .custodian-brief.md for approval-engine

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 18:46:34 +02:00
repo-manager
694d215652 repo.work.assign_missing_identifiers
source: repo-manager
reason: deterministic projection registration

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 18:39:31 +02:00
adb5cb0a9a test: enforce the presentation exclusion contract for approval digests
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-10 18:39:30 +02:00
62233c7c52 Say what the tenant check is, and what view_hash is not
gate-house (GH-DEC-2026-013) was right that our wording implied a fact
about the person. The tenant comparison is store isolation — does this
caller belong to the store this engine serves — and a registration-
supplied claim satisfies that while satisfying no doctrine about the
approver's own membership. Exact equality cannot see the difference, so
state it, and note that provenance gets recorded on the entry the way v4
records principal_type once the claim carries it.

Answer informed-decision's R3 in the claim contract: view_hash and
binding.digest answer different questions and must not be merged. Three
hashes, three questions. Recommend their binding document carry our
digest rather than re-canonicalize the same five fields, so the act has
one canonicalization and a mismatch is detectable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-10 07:56:28 +02:00
849c75bb09 Answer who presents approval-engine-operator: nobody
railiance-platform asked and declined to guess, which was right — this
registration carries the widest scope set of the pair. Nothing in this
repo obtains an OAuth token; it only verifies them. Scope by scope the
bundle describes no single actor: approve now belongs to
informed-decision's human client, emit is redundant against the server's
own heartbeat, and no requester identity was ever settled for create.

Cancel CCR-2026-0020 as an owner decision rather than leave it in_flight,
keep verifier custody CCR-2026-0018, and record that a future presenter
gets a narrowed registration — approve must not travel with the
operational scopes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 23:17:43 +02:00
fec4eaeb1b Hold the pinned image against the repository's schema
Schema v4 gave the deployment a silent drift surface: the pinned pair is
self-consistent, migrating to 3 and serving 3, while this repository has
moved to 4. That reads as healthy, which makes it worse than an error —
the failure is the assumption that the deployment records approver
principal type.

Document v4 in storage-operations, state in the deploy runbook that the
pin predates it, and add a test that requires the statement whenever the
release record's schema version differs from this repository's. Verified
to fail when the acknowledgement is removed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 14:38:21 +02:00
92043cfe51 Log the T01 approver-evidence work
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 14:10:31 +02:00
31da1af5e4 Record the verified principal type on approver entries (schema v4)
An entry stored subject_id, assurance and evidence_ref but nothing about
what kind of principal bound the approval, and subject_id is a naming
convention rather than a verified claim. /entries is not restricted by
principal type — only /consume is — and the approval-engine-operator
client holds approval:approve, so a service can supply approver evidence
today. Whether it may is gate-house doctrine; that it is legible is ours.

Add entries.principal_type, populate it from the verified token, surface
it on the object and the audit evidence path (not the claim, which stays
least-disclosure), and migrate v3 stores leaving legacy rows null rather
than back-filling a claim nobody made.

Also corrects two statements in the requirements issued to
informed-decision: agent tokens are not barred from approval:approve, and
an empty assurance object is accepted rather than refused.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 14:09:54 +02:00
8b8ada6c4a Log the approver-surface handoff against T01
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 12:48:45 +02:00
5203f46e47 State approval-engine's requirements on the informed-decision approver surface
informed-decision (INFD-WP-0001) has claimed the browser-facing approver
UI this repo disowned. Write down what this engine requires of it, and
name the three places the current contract does not fit: the human client
lacks approval:read for the object it must render, the assurance claim is
the only place MFA survives into the record and must be given a shape,
and view_hash has nowhere to ride into an entry whose body is discarded
by design. Also record that there is no inbox endpoint and never will be.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-09 12:48:34 +02:00
b46b0f2666 docs(admission): resolve approval audit tenant and redaction inputs
Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-08 17:01:42 +02:00
24ec18fe3f Refuse to invent the human approver client_id and callback URI
key-cape (KEY-WP-0013-T02) asked for two exact strings for the human
approver registration. This engine is a bearer-token resource server: no
redirect endpoint, no authorization-code/PKCE path, and no Ingress or
external origin, so neither string exists here. Record why, name the
missing owner (a browser-facing approver UI outside this repo), and
confirm that the access token — never the ID token — is what this
resource validates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HyybaE7DUXrWYrhbnESCTe

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1275879@bnt-lap001
Assistant-Session: eb464208-f821-41b2-bc5a-a6c33d92a8ad
2026-09-08 14:47:40 +02:00