Bind the budget memo and point sitting admission at compact-sitting v2
attach_compact_bindings takes --sitting/--batches (defaults unchanged). b01 is bound to the existing named recipient and native approval ba5ce2d8. sitting-admission.json moves to package v2 (sha256:24a52478...) and the currently served image ef6fdd61, so the cutover does not roll back the 2026-09-16 login fixes. Not yet applied. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 272244@bnt-lap001 Assistant-Session: c8962fa7-b290-47df-865f-403ddb6c77e9
This commit is contained in:
parent
e99fb5892a
commit
6d0a81f728
5 changed files with 78 additions and 6 deletions
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:8f55bcecf37a8d65f96e073510b1ffb4636c0a91d75e1ee7d582ad4bce8b953a",
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:ef6fdd61209863654be3adba070661645a2714e86cb4b7f4e847540291b55f07",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v1",
|
||||
"package_digest": "sha256:e0afd52e046616a93142f4064704b1cee6496801d94612fce29a958cf04eb41a",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:24a524785740e60df70e0ced4d884f1a6197bf3fbf7b003471947ce76b763ead",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
|
|
|
|||
15
docs/batches/2026-09-21/bound/index.json
Normal file
15
docs/batches/2026-09-21/bound/index.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"kind": "informed-decision-bound-sitting",
|
||||
"sitting_id": "infd-sitting-2026-09-21",
|
||||
"principal": "uid=platform-root,ou=people,dc=netkingdom,dc=local",
|
||||
"submitted": false,
|
||||
"agent_disposition_forbidden": true,
|
||||
"memos": [
|
||||
{
|
||||
"memo_id": "infd-20260921-b01",
|
||||
"approval_id": "ba5ce2d8-8b6d-40be-af89-2e8c147029a3",
|
||||
"memo": "infd-20260921-b01.memo.json",
|
||||
"packet": "infd-20260921-b01.packet.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"approval_binding_digest":"sha256:e9eaf454e94871ec2060855fcfbd327bcaec873d2c61cae031bec9f95a34bcae","approval_id":"ba5ce2d8-8b6d-40be-af89-2e8c147029a3","binding":{"justification":null,"principal":{"display_name":"uid=platform-root,ou=people,dc=netkingdom,dc=local","id":"uid=platform-root,ou=people,dc=netkingdom,dc=local","identifiers":[],"kind":"person","role":"reviewer"},"target":{"environment":"prod","id":"spend-envelope:hfact-glas-anthropic-2026-09","kind":"spend-envelope","label":"Glas metered runs on the Anthropic key (railiance01)","requires_new_bind":false},"terms":null},"binding_level":"organizational","brief":"Sets the spending authority that rein-aharness MessagesOwner enforces before each metered Glas run on railiance01. Accepting it does not deliver the key, run a model or create an OpenBao policy; those are three separate SECRETS-WP-0009-T03 approvals. The EUR 100 monthly limit is recorded here but not enforced by the software.","highlights":[{"id":"infd-20260921-b01-h1","item_id":"infd-20260921-b01-packet","locator":{"kind":"work_record","task":"SECRETS-WP-0009-T03","workplan":"SECRETS-WP-0009"},"note":"The EUR 100 per month limit is NOT enforced: SpendPolicy has no monthly ceiling. Only EUR 5 per run, EUR 20 per day and EUR 500 total are enforced. Every completed run is charged its full reservation (EUR 4.9938), not its actual cost.","required_ack":true,"severity":"critical"}],"id":"infd-20260921-b01","locale":"en","packet":[{"hash":"sha256:a3d3f4e33d75579795c0e407971c0d472432569ef68a9408e9897587a58f0deb","item_id":"infd-20260921-b01-packet","label":"infd-20260921-b01-packet"}],"question":"Accept the spend envelope for metered Glas runs on the Anthropic key (EUR 5 per run, 20 per day, 500 total, until 2027-01-31)?","requested_act":"approve","sealed":false,"step_kind":"approve","ui_release":"informed-decision@0.2.0","version":1}
|
||||
51
docs/batches/2026-09-21/bound/infd-20260921-b01.packet.md
Normal file
51
docs/batches/2026-09-21/bound/infd-20260921-b01.packet.md
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# SECRETS-WP-0009-T03 — spend envelope for metered Glas runs
|
||||
|
||||
Blocking workplan: SECRETS-WP-0009
|
||||
Blocking task: SECRETS-WP-0009-T03 (hub prefix f8069c8a)
|
||||
Related: HFACT-WP-0001-T01/T04 (SpendPolicy and owner config), GLAS-WP-0012
|
||||
|
||||
## Question
|
||||
Accept the spend envelope for metered Glas runs on the Anthropic key (EUR 5 per run, 20 per day, 500 total, until 2027-01-31)?
|
||||
|
||||
## One act
|
||||
Accept this envelope as the spend authority for rein-aharness MessagesOwner
|
||||
`metered-once` runs on railiance01 using the Anthropic key of catalog lane
|
||||
`glas-claude-agent-dev-anthropic`. The accepted approval id becomes the
|
||||
SpendPolicy `authority_ref` for envelope `hfact-glas-anthropic-2026-09`.
|
||||
|
||||
## Enforced values (rein-aharness SpendPolicy, decimal strings)
|
||||
|
||||
| Field | Value | Note |
|
||||
| --- | --- | --- |
|
||||
| `per_run_eur` | 5 | Operator-stated |
|
||||
| `daily_eur` | 20 | Operator-stated; timezone Europe/Berlin |
|
||||
| `total_eur` | 500 | Operator-stated; over the whole envelope |
|
||||
| `eur_per_usd` | 0.87 | Operator rate 1 EUR = 1.15 USD (1/1.15 = 0.8696), rounded up |
|
||||
| `max_liability_usd` | 5.74 | Per run. Reserves ceil(5.74 x 0.87) = EUR 4.9938, inside EUR 5 |
|
||||
| `max_budget_usd` | 5.00 | Per run. Claude CLI stop threshold, inside liability |
|
||||
| `valid_from` | acceptance time | |
|
||||
| `expires_at` | 2027-01-31T23:59:59+01:00 | Operator-stated |
|
||||
|
||||
Resulting capacity: at most 4 runs per day and 100 runs in total. A completed run
|
||||
is charged its full reservation, not its reported cost. A failed, cancelled or
|
||||
unaccounted run keeps its reservation and blocks further runs until reconciled.
|
||||
Cost above liability permanently marks the envelope breached.
|
||||
|
||||
The operator's overall USD 600 budget and USD 800 liability caps are dominated
|
||||
by `total_eur` 500 (= USD 575) and need no separate field.
|
||||
|
||||
## Recorded, not enforced
|
||||
- EUR 100 per calendar month. SpendPolicy has no monthly ceiling; a rein-aharness
|
||||
follow-up adds `monthly_eur`. Until then the operator reviews monthly use.
|
||||
|
||||
## Scope bound by the SpendPolicy, filled in before the private file is written
|
||||
`worker_id`, `activity_definition_id`, `target_repo`, `project`, `profile_ref`,
|
||||
`profile_sha256`, `descriptor_sha256`, `repository_grant_id`, `max_turns` come from
|
||||
the admitted factory profile (HFACT-WP-0001-T01). They narrow this envelope; they
|
||||
cannot widen the amounts above.
|
||||
|
||||
## Must not
|
||||
- Deliver, read or display the Anthropic key
|
||||
- Authorize the OpenBao apply, verify or exec actions (separate T03 approvals)
|
||||
- Cover llm-connect or its DeepSeek default; that path is not this envelope
|
||||
- Raise any amount or extend the expiry without a new memo
|
||||
|
|
@ -45,13 +45,13 @@ def _approval(row: dict, memo_id: str) -> dict:
|
|||
return approval
|
||||
|
||||
|
||||
def attach(principal: str, receipt: dict, root: Path = ROOT) -> dict:
|
||||
def attach(principal: str, receipt: dict, root: Path = ROOT, batches: tuple[str, ...] = ("credentials", "decisions")) -> dict:
|
||||
actor = _principal(principal)
|
||||
if receipt.get("status") != "created":
|
||||
raise ValueError("created native receipt required")
|
||||
sitting = json.loads((root / "sitting.json").read_text())
|
||||
expected = []
|
||||
for name in ("credentials", "decisions"):
|
||||
for name in batches:
|
||||
index = json.loads((root / name / "index.json").read_text())
|
||||
for row in index["ordinal"]:
|
||||
expected.append((name, row["memo_id"], row["memo"], row["packet"]))
|
||||
|
|
@ -108,9 +108,14 @@ def main() -> None:
|
|||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--principal", required=True, help="exact live KeyCape subject")
|
||||
parser.add_argument("--receipt", type=Path, required=True, help="native created-approval receipt")
|
||||
parser.add_argument("--sitting", help="batch date directory under docs/batches; default 2026-09-14")
|
||||
parser.add_argument("--batches", default="credentials,decisions", help="comma-separated batch directories")
|
||||
args = parser.parse_args()
|
||||
receipt = json.loads(args.receipt.read_text())
|
||||
index = attach(args.principal, receipt)
|
||||
root = ROOT.parent / args.sitting if args.sitting else ROOT
|
||||
if args.sitting and "/" in args.sitting:
|
||||
raise SystemExit("sitting must be a directory name")
|
||||
index = attach(args.principal, receipt, root, tuple(b for b in args.batches.split(",") if b))
|
||||
print(json.dumps({"status": "bound_copies_written", "count": len(index["memos"])}, indent=2))
|
||||
print("No presentations, dispositions, or approval entries created.")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue