594 lines
24 KiB
Python
594 lines
24 KiB
Python
|
|
"""Draft the unsigned 2026-10-05 dependency-root sitting.
|
||
|
|
|
||
|
|
One question per memo. Lanes whose packet is not a single ready human act are
|
||
|
|
recorded as excluded. Does not submit, present, create approvals, or bind.
|
||
|
|
"""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import json
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||
|
|
|
||
|
|
from prepare_compact_batches import REVIEW_GROUP, _memo, _sha # noqa: E402
|
||
|
|
|
||
|
|
from informed_decision.intake import check_one_question, scan_secret_markers # noqa: E402
|
||
|
|
from informed_decision.memo import Scope # noqa: E402
|
||
|
|
from informed_decision.records import dumps, memo_from # noqa: E402
|
||
|
|
|
||
|
|
SITTING = "2026-10-05-dependency-roots"
|
||
|
|
ROOT = Path(__file__).resolve().parents[1] / "docs" / "batches" / SITTING
|
||
|
|
SITTING_ID = "infd-sitting-2026-10-05-dependency-roots"
|
||
|
|
BATCH = "dependency-roots"
|
||
|
|
|
||
|
|
MEMOS = [
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-s1-red-controls",
|
||
|
|
"workplan": "RAIL-HO-WP-0011",
|
||
|
|
"task": "RAIL-HO-WP-0011-T05",
|
||
|
|
"hub_task_prefix": "ba526585",
|
||
|
|
"hub_decision": "83263d8d-d6ee-4395-ac84-86b71e967648",
|
||
|
|
"resolves": "on-answer",
|
||
|
|
"question": "Approve remediation of exactly the two red S1 controls found by the 2026-10-05 Goss refresh?",
|
||
|
|
"brief": (
|
||
|
|
"The attended refresh already installed the source-rendered Goss surface on "
|
||
|
|
"Railiance01 and CoulombCore. Validation then failed on two controls. "
|
||
|
|
"Accepting this memo approves a later reviewed remediation of only those "
|
||
|
|
"controls. This draft does not edit a host."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"Railiance01 failed 1 of 48 checks: /etc/ssh/sshd_config.d/10-hardening.conf "
|
||
|
|
"lacks the line ChallengeResponseAuthentication no. CoulombCore failed 2 of 28 "
|
||
|
|
"checks: /usr/local/bin/age is not executable, and the same SSH line is absent. "
|
||
|
|
"Firewall checks passed, including CoulombCore iptables INPUT DROP. Accepting "
|
||
|
|
"does not enable UFW, rerun the refresh, or change any other SSH line."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"host-baseline",
|
||
|
|
"rail-ho-wp-0011-t05",
|
||
|
|
"Two red S1 controls from the 2026-10-05 Goss refresh",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "railiance-infra",
|
||
|
|
"purpose": "Approve remediation of the two red S1 controls from the 2026-10-05 Goss refresh",
|
||
|
|
"target": {
|
||
|
|
"id": "rail-ho-wp-0011-t05",
|
||
|
|
"type": "host-baseline",
|
||
|
|
"system": "railiance-infra",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# RAIL-HO-WP-0011-T05 — two red S1 controls
|
||
|
|
|
||
|
|
Blocking workplan: RAIL-HO-WP-0011 (railiance-infra)
|
||
|
|
Blocking task: RAIL-HO-WP-0011-T05 (hub prefix ba526585)
|
||
|
|
Hub decision: 83263d8d-d6ee-4395-ac84-86b71e967648
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Approve remediation of exactly the two red S1 controls found by the 2026-10-05 Goss refresh?
|
||
|
|
|
||
|
|
## What already ran
|
||
|
|
`make verify-refresh-host` with the per-host approval tokens ran for Railiance01
|
||
|
|
and CoulombCore after the rendered baseline was reviewed. Both hosts now have
|
||
|
|
the goss binary, `/etc/goss/baseline.yaml`, the wrapper, the service, and the
|
||
|
|
hourly timer. Validation exited non-zero after that install.
|
||
|
|
|
||
|
|
## The two controls
|
||
|
|
- Railiance01, 1 of 48: `/etc/ssh/sshd_config.d/10-hardening.conf` lacks
|
||
|
|
`ChallengeResponseAuthentication no`.
|
||
|
|
- CoulombCore, 2 of 28: `/usr/local/bin/age` is not executable, and the same
|
||
|
|
SSH line is absent.
|
||
|
|
- Firewall checks passed, including CoulombCore `iptables -S INPUT` policy DROP
|
||
|
|
and Railiance01 tunnel-only 6443.
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Authorize a later reviewed change that adds only that SSH line on both hosts
|
||
|
|
and makes `/usr/local/bin/age` executable on CoulombCore.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Enable or rewrite UFW on CoulombCore
|
||
|
|
- Rerun the Goss refresh as a substitute for the two controls
|
||
|
|
- Treat this draft as the host change itself
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-activity-empty-projections",
|
||
|
|
"workplan": "STATE-WP-0095",
|
||
|
|
"task": "STATE-WP-0095-T04",
|
||
|
|
"hub_task_prefix": "3bbb311f",
|
||
|
|
"hub_decision": "91b7c633-a66f-5d43-9f4b-6565aefb9356",
|
||
|
|
"resolves": "never",
|
||
|
|
"question": "Approve retirement of only the three named empty Activity projections while preserving their parent projection?",
|
||
|
|
"brief": (
|
||
|
|
"Normal Activity replay refused three empty historical projections. "
|
||
|
|
"The prepared set names those three UUIDs and preserves the parent. "
|
||
|
|
"State Hub source commit 968a811 can require that exact set. Accepting "
|
||
|
|
"records the disposition. It does not retire a row."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"Targets are 683724d9-4249-5e0e-88e0-7baff4330d58 (custodian-wp-0003), "
|
||
|
|
"644017c7-c5f2-5a64-81c3-d8ee806f8251 (custodian-wp-0003a) and "
|
||
|
|
"a5806df9-5b9a-50da-81c1-7e606076bed9 (custodian-wp-0003b). Preserve parent "
|
||
|
|
"b4eb45a9-69e3-4ab0-b00c-67a53c3117c5. Activity Core still owes its own "
|
||
|
|
"return. Accepting is not a live retirement, a deletion, or a rollout of 968a811."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"projection-disposition",
|
||
|
|
"activity-history-duplicate-disposition-20261004",
|
||
|
|
"Three empty Activity historical projections",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "state-hub",
|
||
|
|
"purpose": "Approve the prepared disposition of three empty Activity projections",
|
||
|
|
"target": {
|
||
|
|
"id": "activity-history-duplicate-disposition-20261004",
|
||
|
|
"type": "projection-disposition",
|
||
|
|
"system": "state-hub",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# STATE-WP-0095-T04 — three empty Activity projections
|
||
|
|
|
||
|
|
Blocking workplan: STATE-WP-0095 (state-hub)
|
||
|
|
Blocking task: STATE-WP-0095-T04 (hub prefix 3bbb311f)
|
||
|
|
Hub decision: 91b7c633-a66f-5d43-9f4b-6565aefb9356
|
||
|
|
Proposal: the-custodian `docs/evidence/2026-10-04-dependency-root-wave/activity-stale-disposition-proposal.json`
|
||
|
|
Source exact-set: state-hub commit `968a811` (on origin/main). Not a live rollout.
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Approve retirement of only the three named empty Activity projections while preserving their parent projection?
|
||
|
|
|
||
|
|
## Exact set
|
||
|
|
- `683724d9-4249-5e0e-88e0-7baff4330d58` slug custodian-wp-0003
|
||
|
|
- `644017c7-c5f2-5a64-81c3-d8ee806f8251` slug custodian-wp-0003a
|
||
|
|
- `a5806df9-5b9a-50da-81c1-7e606076bed9` slug custodian-wp-0003b
|
||
|
|
- Preserve parent `b4eb45a9-69e3-4ab0-b00c-67a53c3117c5`
|
||
|
|
|
||
|
|
Each target was recorded with zero tasks and zero global dependency edges.
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Record the founder's disposition of that set. An answer here does not resolve
|
||
|
|
the hub decision by itself, because Activity Core's separate return and a
|
||
|
|
reviewed live writer are still required before any retirement runs.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Blanket-acknowledge every stale projection
|
||
|
|
- Delete rows, replace UUIDs, move tasks, or rewrite source history
|
||
|
|
- Treat source commit 968a811 as already deployed
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-hall-signing-key",
|
||
|
|
"workplan": "FT-WP-0001",
|
||
|
|
"task": "FT-WP-0001-T04",
|
||
|
|
"hub_task_prefix": "13a92a96",
|
||
|
|
"hub_decision": "d5d8a24d-d77e-4c63-ab52-b878d687e8b9",
|
||
|
|
"resolves": "on-answer",
|
||
|
|
"question": "Authorize a durable Hall of Helix R-1 signing key held outside git, without creating that key in this draft?",
|
||
|
|
"brief": (
|
||
|
|
"FT-WP-0001-T04 cannot publish R-1 with an ephemeral key. The key has "
|
||
|
|
"to survive restart and stay outside git. Accepting authorizes that "
|
||
|
|
"key. This draft does not create it and does not publish R-1."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"No key material is in this packet. Accepting does not create the key, "
|
||
|
|
"does not choose a generated value, and does not publish revision R-1. "
|
||
|
|
"A later attended lane has to create the key outside every worktree."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"signing-key",
|
||
|
|
"ft-wp-0001-t04",
|
||
|
|
"Durable Hall of Helix R-1 signing key outside git",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "fluid-telegram",
|
||
|
|
"purpose": "Authorize a durable Hall of Helix R-1 signing key held outside git",
|
||
|
|
"target": {
|
||
|
|
"id": "ft-wp-0001-t04",
|
||
|
|
"type": "signing-key",
|
||
|
|
"system": "fluid-telegram",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# FT-WP-0001-T04 — durable signing key
|
||
|
|
|
||
|
|
Blocking workplan: FT-WP-0001 (fluid-telegram)
|
||
|
|
Blocking task: FT-WP-0001-T04 (hub prefix 13a92a96)
|
||
|
|
Hub decision: d5d8a24d-d77e-4c63-ab52-b878d687e8b9
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Authorize a durable Hall of Helix R-1 signing key held outside git, without creating that key in this draft?
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Authorize a later attended creation of one durable signing key for Hall of Helix
|
||
|
|
revision R-1. The key stays outside git and outside the hall worktree.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Put key material in this packet, in git, or in a workplan
|
||
|
|
- Publish R-1 as part of this answer
|
||
|
|
- Treat an ephemeral process key as satisfying the task
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-telegram-bot",
|
||
|
|
"workplan": "FLUID-WP-0008",
|
||
|
|
"task": "FLUID-WP-0008-T02",
|
||
|
|
"hub_task_prefix": "9896fee4",
|
||
|
|
"hub_decision": "7f455718-66c9-4049-9aaf-1143aea39d34",
|
||
|
|
"resolves": "never",
|
||
|
|
"question": "Authorize one attended BotFather registration of the HelixForge bot, with the credential stored only through the attended OpenBao path?",
|
||
|
|
"brief": (
|
||
|
|
"FLUID-WP-0008-T02 and FT-WP-0001-T01 are the same human step. "
|
||
|
|
"Accepting authorizes that registration. This draft does not call "
|
||
|
|
"BotFather and does not store a credential. The shared hub decision "
|
||
|
|
"also covers channels and the user session, so this answer must not "
|
||
|
|
"be treated as resolving those other acts."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"The BotFather result stays on the attended OpenBao path and never "
|
||
|
|
"enters git. Accepting does not register the bot. It does not create "
|
||
|
|
"channels and it does not bootstrap the FT-WP-0002 account session."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"operator-session",
|
||
|
|
"fluid-wp-0008-t02",
|
||
|
|
"HelixForge bot registration",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "fluid-core",
|
||
|
|
"purpose": "Authorize one attended HelixForge bot registration",
|
||
|
|
"target": {
|
||
|
|
"id": "fluid-wp-0008-t02",
|
||
|
|
"type": "operator-session",
|
||
|
|
"system": "fluid-core",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# FLUID-WP-0008-T02 — HelixForge bot registration
|
||
|
|
|
||
|
|
Blocking workplan: FLUID-WP-0008 (fluid-core)
|
||
|
|
Blocking task: FLUID-WP-0008-T02 (hub prefix 9896fee4)
|
||
|
|
Same act: FT-WP-0001-T01 (fluid-telegram)
|
||
|
|
Hub decision: 7f455718-66c9-4049-9aaf-1143aea39d34
|
||
|
|
This memo does not resolve that decision. Channels and the user session are separate memos.
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Authorize one attended BotFather registration of the HelixForge bot, with the credential stored only through the attended OpenBao path?
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Authorize the operator to register the HelixForge bot and store the result only
|
||
|
|
through the attended OpenBao path.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Place the credential in git, chat, or this packet
|
||
|
|
- Create the channels in this same act
|
||
|
|
- Bootstrap the dedicated account session in this same act
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-telegram-channels",
|
||
|
|
"workplan": "FLUID-WP-0008",
|
||
|
|
"task": "FLUID-WP-0008-T03",
|
||
|
|
"hub_task_prefix": "bb02bf5b",
|
||
|
|
"hub_decision": "7f455718-66c9-4049-9aaf-1143aea39d34",
|
||
|
|
"resolves": "never",
|
||
|
|
"question": "Authorize one attended creation of the private HelixForge test channel and then the public channel?",
|
||
|
|
"brief": (
|
||
|
|
"FLUID-WP-0008-T03 is one operator step: private test channel, then "
|
||
|
|
"the public channel. FT-WP-0001-T02 names the same step. Accepting "
|
||
|
|
"authorizes that step. This draft does not create a channel."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"Accepting does not create either channel and does not register the "
|
||
|
|
"bot. The shared hub decision stays open because the bot registration "
|
||
|
|
"and the account session are separate acts."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"operator-session",
|
||
|
|
"fluid-wp-0008-t03",
|
||
|
|
"HelixForge private and public channels",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "fluid-core",
|
||
|
|
"purpose": "Authorize attended creation of the HelixForge channels",
|
||
|
|
"target": {
|
||
|
|
"id": "fluid-wp-0008-t03",
|
||
|
|
"type": "operator-session",
|
||
|
|
"system": "fluid-core",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# FLUID-WP-0008-T03 — HelixForge channels
|
||
|
|
|
||
|
|
Blocking workplan: FLUID-WP-0008 (fluid-core)
|
||
|
|
Blocking task: FLUID-WP-0008-T03 (hub prefix bb02bf5b)
|
||
|
|
Same act: FT-WP-0001-T02 (fluid-telegram)
|
||
|
|
Hub decision: 7f455718-66c9-4049-9aaf-1143aea39d34
|
||
|
|
This memo does not resolve that decision.
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Authorize one attended creation of the private HelixForge test channel and then the public channel?
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Authorize the operator to create the private test channel and then the public
|
||
|
|
channel. Order is part of the act.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Register the bot in this same act
|
||
|
|
- Bootstrap the dedicated account session in this same act
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"id": "infd-20261005-telegram-user-session",
|
||
|
|
"workplan": "FT-WP-0002",
|
||
|
|
"task": "FT-WP-0002-T01",
|
||
|
|
"hub_task_prefix": "039e5358",
|
||
|
|
"hub_decision": "7f455718-66c9-4049-9aaf-1143aea39d34",
|
||
|
|
"resolves": "never",
|
||
|
|
"question": "Authorize one attended bootstrap of a dedicated Telegram account session for FT-WP-0002, with the account material kept outside git?",
|
||
|
|
"brief": (
|
||
|
|
"FT-WP-0002-T01 is an operator runbook: a dedicated account, api_id "
|
||
|
|
"and api_hash, then the guided session bootstrap into OpenBao. The "
|
||
|
|
"runbook is fluid-telegram docs/seeding-runbook.md. Accepting "
|
||
|
|
"authorizes that session. This draft does not run it."
|
||
|
|
),
|
||
|
|
"highlight": (
|
||
|
|
"No account material is in this packet. Accepting does not register "
|
||
|
|
"an account, obtain api_id or api_hash, or create a session. The bot "
|
||
|
|
"and channel memos stay separate."
|
||
|
|
),
|
||
|
|
"target": Scope(
|
||
|
|
"operator-session",
|
||
|
|
"ft-wp-0002-t01",
|
||
|
|
"Dedicated Telegram account session bootstrap",
|
||
|
|
"prod",
|
||
|
|
),
|
||
|
|
"binding": {
|
||
|
|
"action": "accept",
|
||
|
|
"actor": "informed-decision",
|
||
|
|
"principal": "fluid-telegram",
|
||
|
|
"purpose": "Authorize the attended FT-WP-0002 account-session bootstrap",
|
||
|
|
"target": {
|
||
|
|
"id": "ft-wp-0002-t01",
|
||
|
|
"type": "operator-session",
|
||
|
|
"system": "fluid-telegram",
|
||
|
|
},
|
||
|
|
},
|
||
|
|
"packet": """# FT-WP-0002-T01 — dedicated account session
|
||
|
|
|
||
|
|
Blocking workplan: FT-WP-0002 (fluid-telegram)
|
||
|
|
Blocking task: FT-WP-0002-T01 (hub prefix 039e5358)
|
||
|
|
Hub decision: 7f455718-66c9-4049-9aaf-1143aea39d34
|
||
|
|
Runbook: fluid-telegram `docs/seeding-runbook.md`
|
||
|
|
This memo does not resolve that decision.
|
||
|
|
|
||
|
|
## Question
|
||
|
|
Authorize one attended bootstrap of a dedicated Telegram account session for FT-WP-0002, with the account material kept outside git?
|
||
|
|
|
||
|
|
## One act
|
||
|
|
Authorize the operator to follow the existing seeding runbook for one dedicated
|
||
|
|
account. Account material stays outside git.
|
||
|
|
|
||
|
|
## Must not
|
||
|
|
- Use a person's own account
|
||
|
|
- Put api_id, api_hash, or a session string in this packet or in git
|
||
|
|
- Register the bot or create the channels in this same act
|
||
|
|
""",
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
EXCLUDED = [
|
||
|
|
{
|
||
|
|
"workplan": "KEY-WP-0037",
|
||
|
|
"task": "KEY-WP-0037-T03",
|
||
|
|
"owner_repo": "key-cape",
|
||
|
|
"hub_decision": "caafe4be-4f68-47b4-9567-316d47b94992",
|
||
|
|
"reason": (
|
||
|
|
"Custody boundary 632a8893 is approved. The live registration still has "
|
||
|
|
"no exact reviewed revision, image digest, config preservation test, or "
|
||
|
|
"synthetic issuance and denial record. Resolving caafe4be would be that live go."
|
||
|
|
),
|
||
|
|
"ready_when": "An owner records the exact revision, digest, preservation test, and synthetic issuance and denial, then one memo asks only for the live go.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"workplan": "FT-WP-0001",
|
||
|
|
"task": "FT-WP-0001-T07",
|
||
|
|
"owner_repo": "fluid-telegram",
|
||
|
|
"hub_decision": "8a095daa-35f9-4561-ae50-256558600be7",
|
||
|
|
"reason": (
|
||
|
|
"Ninety-four hall entries have no Telegram-channel agreement. The decision "
|
||
|
|
"asks which basis to record, including whether a revocable standing agreement "
|
||
|
|
"belongs in hall-of-helix/ENTRY.md and how earlier contributors are asked. "
|
||
|
|
"That choice is not yet a single prepared act."
|
||
|
|
),
|
||
|
|
"ready_when": "The hall owner writes the candidate basis as one question with the exact text the founder would be accepting.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"workplan": "RAPPS-WP-0014",
|
||
|
|
"task": "RAPPS-WP-0014-T03",
|
||
|
|
"owner_repo": "railiance-apps",
|
||
|
|
"hub_decision": "d06307e5-2737-461a-a2f4-a12c3b492a9a",
|
||
|
|
"reason": (
|
||
|
|
"The invited two-user workflow is not ready to run. Create login for the "
|
||
|
|
"invited tenant-admin was refused because that email already belongs to "
|
||
|
|
"directory login platform-root. No second login was created."
|
||
|
|
),
|
||
|
|
"ready_when": "The account owner records a usable second person, then one memo asks the founder to run the acceptance with that person.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"workplan": "STATE-WP-0079",
|
||
|
|
"task": "STATE-WP-0079-T06",
|
||
|
|
"owner_repo": "state-hub",
|
||
|
|
"hub_decision": "2fd5849c-240e-4d0a-bf07-5ebf8dfce3fd",
|
||
|
|
"reason": (
|
||
|
|
"The same hub decision also covers the single-node risk, the core-hub cutover, "
|
||
|
|
"clock verification, and live-host authorization. Stopping the primary still "
|
||
|
|
"waits on STATE-WP-0079-T04 route receipts and the legacy-meter week."
|
||
|
|
),
|
||
|
|
"ready_when": "Each remaining act has its own reviewed packet. Do not pose the bundle as one memo.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"workplan": "RPF-WP-0044",
|
||
|
|
"task": "RPF-WP-0044-T03",
|
||
|
|
"owner_repo": "railiance-platform",
|
||
|
|
"hub_decision": "89f1058f-33bc-47a8-8a49-0b44d426c67e",
|
||
|
|
"reason": (
|
||
|
|
"The ArgoCD go-ahead covers issue-core, policy-nexus, activity-core automation, "
|
||
|
|
"and prune restoration. The policy-nexus Application draft still has unfilled "
|
||
|
|
"revision and values placeholders. One memo cannot carry those acts."
|
||
|
|
),
|
||
|
|
"ready_when": "Each adoption has one reviewed command and its own memo.",
|
||
|
|
},
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
def main() -> None:
|
||
|
|
directory = ROOT / BATCH
|
||
|
|
directory.mkdir(parents=True, exist_ok=True)
|
||
|
|
ordinal = []
|
||
|
|
intents = []
|
||
|
|
for n, spec in enumerate(MEMOS, start=1):
|
||
|
|
check_one_question(spec["question"])
|
||
|
|
packet_path = directory / f"{spec['id']}.packet.md"
|
||
|
|
packet_path.write_text(spec["packet"], encoding="utf-8")
|
||
|
|
digest = _sha(spec["packet"])
|
||
|
|
memo = _memo(
|
||
|
|
memo_id=spec["id"],
|
||
|
|
question=spec["question"],
|
||
|
|
brief=spec["brief"],
|
||
|
|
target=spec["target"],
|
||
|
|
packet_id=spec["id"] + "-packet",
|
||
|
|
packet_hash=digest,
|
||
|
|
highlight=spec["highlight"],
|
||
|
|
workplan=spec["workplan"],
|
||
|
|
task=spec["task"],
|
||
|
|
)
|
||
|
|
payload = json.loads(dumps(memo))
|
||
|
|
if memo_from(payload).question != spec["question"]:
|
||
|
|
raise RuntimeError(f"round-trip failed for {spec['id']}")
|
||
|
|
scan_secret_markers(payload)
|
||
|
|
scan_secret_markers(spec["packet"])
|
||
|
|
memo_path = directory / f"{spec['id']}.memo.json"
|
||
|
|
memo_path.write_text(dumps(memo) + "\n", encoding="utf-8")
|
||
|
|
ordinal.append(
|
||
|
|
{
|
||
|
|
"n": n,
|
||
|
|
"memo_id": spec["id"],
|
||
|
|
"workplan": spec["workplan"],
|
||
|
|
"task": spec["task"],
|
||
|
|
"hub_task_prefix": spec["hub_task_prefix"],
|
||
|
|
"hub_decision": spec["hub_decision"],
|
||
|
|
"resolves": spec["resolves"],
|
||
|
|
"question": spec["question"],
|
||
|
|
"memo": memo_path.name,
|
||
|
|
"packet": packet_path.name,
|
||
|
|
"packet_hash": digest,
|
||
|
|
"required_highlight": f"{spec['id']}-h1",
|
||
|
|
}
|
||
|
|
)
|
||
|
|
intents.append(
|
||
|
|
{
|
||
|
|
"memo_id": spec["id"],
|
||
|
|
"create_client": "informed-decision-sitting-requester",
|
||
|
|
"binding": spec["binding"],
|
||
|
|
"hub_decision": spec["hub_decision"],
|
||
|
|
"resolves": spec["resolves"],
|
||
|
|
}
|
||
|
|
)
|
||
|
|
index = {
|
||
|
|
"kind": "informed-decision-batch",
|
||
|
|
"id": f"infd-batch-{SITTING}",
|
||
|
|
"review_group": REVIEW_GROUP,
|
||
|
|
"status": "draft-unsigned",
|
||
|
|
"submitted": False,
|
||
|
|
"one_question_per_memo": True,
|
||
|
|
"approve_all_forbidden": True,
|
||
|
|
"agent_disposition_forbidden": True,
|
||
|
|
"hub_decision": None,
|
||
|
|
"note": "Several hub decisions. Each ordinal names its own decision and whether an answer may resolve it. There is no batch verdict.",
|
||
|
|
"ordinal": ordinal,
|
||
|
|
"excluded": EXCLUDED,
|
||
|
|
}
|
||
|
|
(directory / "index.json").write_text(json.dumps(index, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||
|
|
scan_secret_markers(index)
|
||
|
|
create = {
|
||
|
|
"kind": "informed-decision-approval-create-intents",
|
||
|
|
"sitting_id": SITTING_ID,
|
||
|
|
"status": "not-posted",
|
||
|
|
"posted": False,
|
||
|
|
"requester_client": "informed-decision-sitting-requester",
|
||
|
|
"human_control": True,
|
||
|
|
"pdp_path": False,
|
||
|
|
"required_count": 1,
|
||
|
|
"note": "Intents only. Digests are computed by approval-engine at create; do not invent them here. Not posted.",
|
||
|
|
"intents": intents,
|
||
|
|
}
|
||
|
|
(ROOT / "approval-create-intents.json").write_text(
|
||
|
|
json.dumps(create, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"
|
||
|
|
)
|
||
|
|
sitting = {
|
||
|
|
"kind": "informed-decision-sitting",
|
||
|
|
"id": SITTING_ID,
|
||
|
|
"review_group": REVIEW_GROUP,
|
||
|
|
"principal": "pending-human-session",
|
||
|
|
"status": "draft-unsigned",
|
||
|
|
"submitted": False,
|
||
|
|
"hub_decision": None,
|
||
|
|
"batches": [index["id"]],
|
||
|
|
"memo_count": len(ordinal),
|
||
|
|
"excluded_count": len(EXCLUDED),
|
||
|
|
"bind_path": "not posted; human bind is still the attended review surface",
|
||
|
|
"note": "Agent draft only. No approval was created and no memo was loaded.",
|
||
|
|
}
|
||
|
|
(ROOT / "sitting.json").write_text(json.dumps(sitting, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
||
|
|
lines = [
|
||
|
|
"# Dependency-root sitting — operator packet",
|
||
|
|
"",
|
||
|
|
"Drafted 2026-10-05. Not posted. An agent may not accept, decline, or seal.",
|
||
|
|
"Review group: `net-kingdom-admins`. Surface, once a human opens the sitting:",
|
||
|
|
"https://decisions.coulomb.social/",
|
||
|
|
"Generator: `tools/prepare_dependency_root_batch.py`.",
|
||
|
|
"",
|
||
|
|
"This sitting groups separate hub decisions. There is no approve-all.",
|
||
|
|
"An answer on one memo does not answer the others. `resolves: never` means",
|
||
|
|
"the answer must not be written back as a resolve of the shared hub decision.",
|
||
|
|
"",
|
||
|
|
"| n | memo_id | task | resolves | question |",
|
||
|
|
"| --: | --- | --- | --- | --- |",
|
||
|
|
]
|
||
|
|
for row in ordinal:
|
||
|
|
lines.append(
|
||
|
|
f"| {row['n']} | `{row['memo_id']}` | {row['task']} | {row['resolves']} | {row['question']} |"
|
||
|
|
)
|
||
|
|
lines.extend(["", "## Excluded", ""])
|
||
|
|
for item in EXCLUDED:
|
||
|
|
lines.append(f"- `{item['task']}` ({item['hub_decision']}): {item['reason']}")
|
||
|
|
lines.extend(
|
||
|
|
[
|
||
|
|
"",
|
||
|
|
"## Not done by this draft",
|
||
|
|
"",
|
||
|
|
"No approval object was created. No memo was loaded into the review store.",
|
||
|
|
"No lifecycle review was requested. The founder binds on the review surface",
|
||
|
|
"after a human opens the sitting.",
|
||
|
|
"",
|
||
|
|
]
|
||
|
|
)
|
||
|
|
(ROOT / "OPERATOR.md").write_text("\n".join(lines), encoding="utf-8")
|
||
|
|
print(f"wrote {len(ordinal)} memos and {len(EXCLUDED)} exclusions under {ROOT}")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|