You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of the neutral-network-tiers epic (patterns ADR 0002 isolation / patterns PR #299).
Scope
Consume the neutral network.tier (strict|balanced|open) + the curated balanced baseline (patterns data file, SHA-pinned) in the acq adapters, so both backends apply the same tiered egress.
Adopt existing work — feat/msb-balanced-egress (ADR-0018)
The msb half already exists and is default-on: vendored acq.backends/msb-balanced-hosts.txt + _acq_msb_balanced_rules_into (--net-default deny + translated --net-rule allow@…, DNS grant, crl* widening logged, SI-10 hardening, ACQ_MSB_BALANCED_EGRESS toggle). Adopt/rename this emitter under the neutral network.tier contract — do not re-implement. Decide the canonical baseline location (ADR-0018 anticipates migrating the vendored list into a patterns kit / #301).
Requirements
kit-translate.sh / adapters: compute the effective allowlist = tier baseline (balanced) ∪ per-kit caps.network.allow ∪ per-sandbox user additions. Deny-by-default preserved.
msb (acq.backends/msb.sh): tier balanced → the ADR-0018 emitter path; strict → kit-hosts-only (ACQ_MSB_BALANCED_EGRESS=0 behavior); reconcile the toggle with the tier selector so they don't conflict.
sbx (acq.backends/sbx.sh / kit-translate): map the tier to the appropriate sbx policy posture + merged allow hosts. Note sbx policy is currently a manual user step / passthrough — decide whether acq now drives it or documents it.
Default:network.tier: balanced (matches the msb default ADR-0018 already ships and the sbx baseline the project recommends). strict and open explicitly selectable; GFE / high-assurance SHOULD pin strict.
open tier gated/warned (testing only; never GFE).
Tests in scripts/test-acq: strict = kit-hosts-only; balanced = baseline ∪ kit hosts emitted; per-sandbox add still works; omission → balanced; parity asserted across both backends.
Docs: BACKEND_GUIDE + QUICKSTART explain the tiers, the default, and how to change tier / add a domain. Fold ADR-0018 into this neutral framing.
Depends on the patterns schema (#300) + baseline data (#301). AI-assisted (OpenCode); consensus-reviewed. Requires human review.
Design proposal — network.tier adapter migration (held for maintainer sign-off)
Ran the migration approach through a 7-voter higher-order consensus: 7/7 approve, 100%. Because this edits acq.backends/msb.sh (mogul's actively-iterating file) and changes a shipped user-facing toggle, I'm posting the design for sign-off rather than surprise-PRing it — especially the msb-emitter half.
Decision: Option A — neutral selector + deprecated alias (no silent flip)
ACQ_NETWORK_TIER — the single neutral selector, values strict | balanced | open, default balanced (unchanged posture; backend-consistent with the shipped msb default + the sbx baseline).
ACQ_MSB_BALANCED_EGRESS becomes a deprecated ALIAS: if set, map 1 → balanced, 0/empty → strict, and print a one-time deprecation notice pointing at ACQ_NETWORK_TIER. ACQ_NETWORK_TIER wins when both are set. Remove the alias in a future major.
Fail-safe (the panel's key point): old-on users stay balanced; old-off users move to strict (more restrictive, not looser). No upgrade silently loosens egress. This is why we reject a hard-replace (would silently flip a security-relevant setting).
open tier is gated: requires explicit confirmation (ACQ_NETWORK_TIER_CONFIRM_OPEN=1 or interactive), warns on every invocation, is logged, and is never a default / never for GFE — treated like --privileged.
sbx backend (the one split in the vote)
Consensus resolution: document the tier→sbx-policy mapping now + provide an explicit override escape hatch, but defer actually driving sbx policy to its own follow-up PR (enforcement path = bigger blast radius, deserves dedicated tests). So PR1 maps + documents; a follow-up makes acq drive sbx policy.
Rollout — split into two PRs (unanimous)
PR1 (I own, no msb.sh churn):ACQ_NETWORK_TIER selector + the alias/deprecation shim + the open gate + documented sbx mapping + tests. Lives in common.sh / kit-translate.sh. The neutral layer reads the tier and, for msb, calls the EXISTING _acq_msb_balanced_rules_into emitter unchanged (translate, don't rename) — so it does not conflict with mogul's active msb.sh work.
PR2 (coordinated with @mogul): rename/retire ACQ_MSB_BALANCED_EGRESS + _acq_msb_balanced_rules_into internals to consume the tier directly, after PR1 lands and the deprecation window opens.
Tests (PR1)
Alias table (unset→balanced, 1→balanced+notice, 0→strict+notice, ACQ_NETWORK_TIER wins over alias, notice fires exactly once); tier→emitted-rules per backend; open without the confirm token fails fast; parity asserted across sbx/msb.
Held for sign-off
@mogul — this touches your msb.sh emitter + the ACQ_MSB_BALANCED_EGRESS toggle you shipped default-on. I'll implement PR1 (neutral selector, no msb.sh changes) once you're OK with the alias mapping + the split, and we coordinate PR2 (the msb rename) against your branch cadence. Flag anything you'd map differently.
@mogul — this touches your msb.sh emitter + the ACQ_MSB_BALANCED_EGRESS toggle you shipped default-on. I'll implement PR1 (neutral selector, no msb.sh changes) once you're OK with the alias mapping + the split, and we coordinate PR2 (the msb rename) against your branch cadence. Flag anything you'd map differently.
Grooming: PR1 landed (neutral ACQ_NETWORK_TIER selector, strict|balanced|open default balanced; deprecated ACQ_MSB_BALANCED_EGRESS alias with fail-safe 0→strict; open-gate; sbx tier→policy mapping documented). Remaining scope for this issue is PR2: rename/retire the msb balanced-egress emitter internals to consume the tier directly, and make acq actually drive sbx policy from the tier (PR1 documents the mapping but defers enforcement). Coordinated with @mogul against the active msb work. Recommend relabeling this issue to 'PR2 only' so it accurately reflects what's left.
This issue depends on the kit field from GSA-TTS/agentic-coding-patterns#300 (GSA-TTS/agentic-coding-patterns#313: "Unblocks … quickstart #294 (adapter mapping)"), but nothing in acq reads caps.network.tier, and it isn't in the PR2 scope above. On msb the tier comes only from ACQ_NETWORK_TIER or the deprecated ACQ_MSB_BALANCED_EGRESS (acq.backends/msb.sh:487-520); sbx reads no tier yet. So on msb a kit with tier: strict gets balanced unless the operator also sets the env var.
Checked offline on main (8e6160c) with the agentic-coding-playbook kit from patterns 5d1a877. I didn't start a sandbox.
kit_translate_to_sbx output is byte-identical with and without tier: strict. Control: changing one allow host changes it.
kit_validate (acq.backends/kit-translate.sh:1216) OKs the strict copy with no warning. Control: removing name: fails.
msb.sh sourced in a clean env resolves balanced, and resolves strict only through one of those two env vars.
None of the 8 kits at that ref sets a tier, so nothing is misconfigured today. On the question in GSA-TTS/agentic-coding-patterns#300 about one kit strict and another balanced: today neither is read.
The design comment above calls ACQ_NETWORK_TIER "the single neutral selector", so this may be deliberate. Either way one side needs to change:
Read the field in PR2 and let a kit only tighten: the sandbox takes the most restrictive of the operator's tier and each kit's, so a kit's open never loosens anything. The cost is that one strict kit drops the baseline for every kit in that sandbox.
Keep the env var as the only selector: have kit validate warn when the field is set (same shape as the block-volume floor warning tested at test/bats/110-volumes.bats:133), and change the patterns schema description, which says each backend maps it.
Happy to open the PRs for 2 if that's the direction.
Activity
mogul commentedon Aug 7, 2026
This branch is now in a PR.
wz-gsa commentedon Aug 12, 2026
Design proposal — network.tier adapter migration (held for maintainer sign-off)
Ran the migration approach through a 7-voter higher-order consensus: 7/7 approve, 100%. Because this edits
acq.backends/msb.sh(mogul's actively-iterating file) and changes a shipped user-facing toggle, I'm posting the design for sign-off rather than surprise-PRing it — especially the msb-emitter half.Decision: Option A — neutral selector + deprecated alias (no silent flip)
ACQ_NETWORK_TIER— the single neutral selector, valuesstrict | balanced | open, defaultbalanced(unchanged posture; backend-consistent with the shipped msb default + the sbx baseline).ACQ_MSB_BALANCED_EGRESSbecomes a deprecated ALIAS: if set, map1 → balanced,0/empty →strict, and print a one-time deprecation notice pointing atACQ_NETWORK_TIER.ACQ_NETWORK_TIERwins when both are set. Remove the alias in a future major.balanced; old-off users move tostrict(more restrictive, not looser). No upgrade silently loosens egress. This is why we reject a hard-replace (would silently flip a security-relevant setting).tier baseline (balanced) ∪ per-kit caps.network.allow ∪ per-sandbox additions, deny-by-default preserved.strict= kit hosts only.open= unrestricted.opentier is gated: requires explicit confirmation (ACQ_NETWORK_TIER_CONFIRM_OPEN=1or interactive), warns on every invocation, is logged, and is never a default / never for GFE — treated like--privileged.sbx backend (the one split in the vote)
Consensus resolution: document the tier→sbx-policy mapping now + provide an explicit override escape hatch, but defer actually driving
sbx policyto its own follow-up PR (enforcement path = bigger blast radius, deserves dedicated tests). So PR1 maps + documents; a follow-up makes acq drive sbx policy.Rollout — split into two PRs (unanimous)
ACQ_NETWORK_TIERselector + the alias/deprecation shim + theopengate + documented sbx mapping + tests. Lives incommon.sh/kit-translate.sh. The neutral layer reads the tier and, for msb, calls the EXISTING_acq_msb_balanced_rules_intoemitter unchanged (translate, don't rename) — so it does not conflict with mogul's activemsb.shwork.ACQ_MSB_BALANCED_EGRESS+_acq_msb_balanced_rules_intointernals to consume the tier directly, after PR1 lands and the deprecation window opens.Tests (PR1)
Alias table (
unset→balanced,1→balanced+notice,0→strict+notice,ACQ_NETWORK_TIERwins over alias, notice fires exactly once); tier→emitted-rules per backend;openwithout the confirm token fails fast; parity asserted across sbx/msb.Held for sign-off
@mogul — this touches your
msb.shemitter + theACQ_MSB_BALANCED_EGRESStoggle you shipped default-on. I'll implement PR1 (neutral selector, no msb.sh changes) once you're OK with the alias mapping + the split, and we coordinate PR2 (the msb rename) against your branch cadence. Flag anything you'd map differently.Consensus record: 7/7 approve (architect/security/devex/ai_ml/pm/catfish/scope_steward). AI-assisted (OpenCode).
mogul commentedon Aug 12, 2026
Go for it.
feat(msb): neutral ACQ_NETWORK_TIER egress selector + deprecate ACQ_M…
wz-gsa commentedon Aug 18, 2026
Grooming: PR1 landed (neutral
ACQ_NETWORK_TIERselector, strict|balanced|open default balanced; deprecatedACQ_MSB_BALANCED_EGRESSalias with fail-safe 0→strict; open-gate; sbx tier→policy mapping documented). Remaining scope for this issue is PR2: rename/retire the msb balanced-egress emitter internals to consume the tier directly, and make acq actually drivesbx policyfrom the tier (PR1 documents the mapping but defers enforcement). Coordinated with @mogul against the active msb work. Recommend relabeling this issue to 'PR2 only' so it accurately reflects what's left.Santoshkumarpuppala commentedon Sep 23, 2026
This issue depends on the kit field from GSA-TTS/agentic-coding-patterns#300 (GSA-TTS/agentic-coding-patterns#313: "Unblocks … quickstart #294 (adapter mapping)"), but nothing in acq reads
caps.network.tier, and it isn't in the PR2 scope above. On msb the tier comes only fromACQ_NETWORK_TIERor the deprecatedACQ_MSB_BALANCED_EGRESS(acq.backends/msb.sh:487-520); sbx reads no tier yet. So on msb a kit withtier: strictgetsbalancedunless the operator also sets the env var.Checked offline on
main(8e6160c) with theagentic-coding-playbookkit from patterns5d1a877. I didn't start a sandbox.kit_translate_to_sbxoutput is byte-identical with and withouttier: strict. Control: changing oneallowhost changes it.kit_validate(acq.backends/kit-translate.sh:1216) OKs thestrictcopy with no warning. Control: removingname:fails.msb.shsourced in a clean env resolvesbalanced, and resolvesstrictonly through one of those two env vars.None of the 8 kits at that ref sets a tier, so nothing is misconfigured today. On the question in GSA-TTS/agentic-coding-patterns#300 about one kit
strictand anotherbalanced: today neither is read.The design comment above calls
ACQ_NETWORK_TIER"the single neutral selector", so this may be deliberate. Either way one side needs to change:opennever loosens anything. The cost is that onestrictkit drops the baseline for every kit in that sandbox.kit validatewarn when the field is set (same shape as the block-volume floor warning tested attest/bats/110-volumes.bats:133), and change the patterns schema description, which says each backend maps it.Happy to open the PRs for 2 if that's the direction.