build_action_request emitted no tenant field at all. The deployed
secrets-engine.catalog-lane.lifecycle v2 package reads
known_tenant := "tenant:platform"
request_tenant := object.get(input, "tenant", "")
so an absent tenant is not an ignored field, it matches the wrong_tenant
first-denial branch. Every gated action this engine sent would have been
denied -- and the omission also produced a request_digest that could match
no correctly issued decision, since tenant is hashed material. That is the
same class of defect as hashing excluded fields, arriving from the other
direction, and again only a real artifact exposed it.
Found by answering the GLAS-WP-0015 tenant-alignment question instead of
assuming the values lined up.
- REQUEST_TENANT is pinned against the vendored allow envelopes, so a
package retenanting fails a test rather than denying production.
- An empty tenant is refused at build time.
- Accepted policy version moves v1 -> v2. v1 had no tenant rule and failed
open: a rotate under tenant:coulomb returned allow against the deployed
package. flex-auth superseded rather than amended it, because a fail-open
correction has to be visible as a version change. A test pins that a v1
decision is refused.
- Vendored decision_wrong_tenant_deny.json as the denial evidence glas
asked for, with tests that we refuse it on effect before anything else
and that a deny legally carries no lifetime.
docs/tenant-alignment.md states the three tenant values as this repo holds
them. It does not resolve the JWT/store mapping: service_auth.TENANT is
tenant:coulomb, which is exactly the value the package denies. That is
either two layers sharing a namespace format or one wrong constant, and
picking between them without an owner ruling is the fail-open shape
GH-DEC-2026-008 rejected for action vocabularies. Both constants stay as
they are, deliberately not unified.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E4tNMAYcSQmZWUE4wqP4ij
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 715726@bnt-lap001
Assistant-Session: 80a42b32-cba6-4b23-8be0-68819b1a6092
The vocabulary mapping this path was waiting on is not coming: gate-house
rejected it in GH-DEC-2026-008, because a translation can be confidently
wrong and fails open by accepting a claim approved for a different action.
The stronger option arrived instead, and both halves are enforced here.
flex-auth published binding.approval_binding_digest (FLEX-DEC-2026-007) to
fix the circularity this repo reported: a pdp_digest recorded at issue time
can never equal the request_digest of the request that carries the claim in
its hashed context, so with GH-DEC-2026-008 requiring that equality, destroy
would have failed closed forever on a check no correct record could pass.
- authorization.approval_binding_digest implements the published exclusion
rule, including Go's context,omitempty behaviour when stripping empties
the context; digest_material drops an empty context for the same reason.
- validate_decision_envelope recomputes the field rather than trusting it,
refuses a claim-bearing request whose decision records none, and compares
the claim's digest from step 1 against it -- never against request_digest,
which still covers the claim so it stays a sound replay identity.
- validate_approval_claim requires binding.pdp_path true before using
pdp_digest at all. Path intent is never inferred from a digest that
happens to be present; pre-schema-v3 approvals carry pdp_path false
regardless of any digest they hold.
Replay fixtures re-vendored from dd3ce4c. The destroy pins moved a second
and final time; approval_binding_digest did not, which is the point. The
fixture now demonstrates the property instead of asserting it: we rederive
fa07becf... from its own request through our canonical implementation,
proving we hash the same material flex-auth does rather than pinning a
constant we cannot reproduce.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E4tNMAYcSQmZWUE4wqP4ij
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 715726@bnt-lap001
Assistant-Session: 80a42b32-cba6-4b23-8be0-68819b1a6092
Updated by fix-consistency on 2026-09-06:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Implements step 2 (access-engine POST /v1/check) and wires the whole
GH-DEC-2026-003 sequence together, then proves it against a live throwaway
OpenBao rather than only unit-level fakes.
- decision_check.check_decision performs the PDP call; an unreachable or
non-200 PDP raises, since silence is never permission.
- approval_consume.authorize_action coordinates steps 1 and 2 and returns an
AuthorizedAction. Both steps build the same CheckRequest via a shared
_expected_request, since two descriptions of the action cannot produce
corresponding digests.
- apply_unreachable_engine_stance takes authorized=. The published map
defines fail_closed as no side effect WITHOUT a durable decision record,
so holding a validated one means the residue does not apply. Not a bypass:
both steps must have succeeded and CAS consume still precedes OpenBao.
Unconfigured still returns None and fails closed.
The end-to-end test caught one more instance of the cross-vocabulary bug: a
leftover comparison of the claim's binding.action against ours. The claim
says secrets.kv.destroy where we say destroy, so it would have failed against
every real claim. Removed; the tie is pdp_digest.
Integration coverage asserts PIP-then-PDP ordering, that consume is the last
step before the backend, and that an unreachable PDP, denied decision,
invalid claim, missing pdp_digest, consume conflict and action mismatch each
stop before OpenBao. 284 tests pass; production still fails closed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Updated by fix-consistency on 2026-09-06:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
flex-auth regenerated decision_destroy_dual_control so context.approval
carries a complete approval-claim including the now-required
binding.pdp_digest. Because context is part of the digest material, that
changed both the request digest and the context input-claim digest; the
vendored copy and its pins are updated. Our digest join reproduces the new
envelope digest exactly, so the digest_material fix holds.
Two properties are now asserted rather than described:
- The embedded claim's binding speaks approval-engine's vocabulary
(secrets.kv.destroy, target {id, stage}) while the decision speaks ours
(destroy, lane:...). That is the unpublished mapping, now a test.
- The claim's pdp_digest cannot equal the request digest of the request that
carries it: embedding the claim in a hashed context changes that digest.
It matches neither the full request nor the request with the claim
removed. Raised with both teams; recorded here so a future change to it is
visible rather than silent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Verified the digest join against flex-auth's T03 replay fixtures and found
request_digest was hashing fields docs/canonical-request-digest.md excludes.
The material is tenant, subject, action, resource, context only: id is
correlation, policy_version lives in provenance, caring_context is hashed
separately. This engine included all three when present.
Because the join adopts the served request id, every real production request
would have carried one, so the computed digest would have matched no issued
decision and failed closed against every correct allow. Same unsatisfiable
shape as the removed AUTHORITY constant.
The old pinned constant was computed with the id inside the material, so it
was wrong and its passing proved nothing. Replaced with fixture-driven tests
over two real envelopes (vendored with provenance) plus a structural test
that correlation fields do not move the digest. Both fixtures are needed:
input_claim_digests.context appears only with a non-empty context.
Also stops computing the native claim digest. The claim's binding.action and
binding.target speak approval-engine's vocabulary while ours speaks the
catalog's, and no mapping is published; flex-auth makes no cross-check and
states the correspondence is ours via pdp_digest. A claim recording no
pdp_digest now fails closed naming the missing mapping rather than comparing
two different languages. That mapping is a prerequisite for destroy.
274 tests pass. Production still fails closed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
flex-auth's published policy package encodes an explicit limit: apply and
apply --dry-run are indistinguishable to a PDP, since both arrive as action
`apply`. What separates them is a property of this repo - the PEP does not
call the gate for a dry run - and flex-auth recorded that as a limit rather
than implying a control they do not have, asking to be told if it stops
holding.
Verified it holds across all five dry-run handlers (apply, revoke, lifecycle
suspend/deactivate/destroy) and locked it with a regression test that fails
with the instruction to notify flex-auth. A paired test proves the hook
under test is actually load-bearing, so the guard cannot pass vacuously.
Also records the FLEX-WP-0021-T01/T02 and GH-DEC-2026-005 outcomes in
SECRETS-WP-0007-T04, including the revisit trigger flex-auth flagged: with
one calling identity the denial ladder has no action_not_granted branch, so
a second identity or a per-lane/stage split is the trigger to add it.
allow_ttl 15m needed no change - normalize_wrap_ttl already caps wrap at 15m.
The policy pin stays unset; publishing is not deploying. 257 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
gate-house resolved APPROVAL-IN-0002. Two changes fell to this repo.
1. Split validate_action_authorization. The claim from approval-engine now
carries the approval fact (issuer, valid_now, consumption, binding digest,
freshness, reason_code) via approval_claim.validate_approval_claim; the
flex-auth DecisionEnvelope carries the decision (effect, binding match,
request digest, lifetime, policy pin) via validate_decision_envelope.
ActionAuthorization is deferred and never ratified (FLEX-DEC-2026-006) and
cannot be served from a step-1 call; nothing validates it now.
2. Dropped AUTHORITY = "state-hub" and the provenance.authority requirement.
State Hub is a read model with no runtime approval authority, so the check
failed closed against every correctly issued record. flex-auth traced the
constant to their own fixture and fixed it at source.
Two consequences recorded rather than buried: there are now two distinct
digests over the same action (approval-engine native over
{action,actor,principal,purpose,target}, and the flex-auth CheckRequest
digest) which are never compared to each other; and the distinct-approver
threshold is no longer checked here, since the claim exposes no approver
entries and approval-engine folds it into valid_now.
The canonical request digest is unchanged and its contract test is preserved
verbatim. Production still fails closed. 251 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Updated by fix-consistency on 2026-09-06:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
approval-engine (APPROVAL-IN-0002) established that ActionAuthorization is a
proposed, unratified object and that the claim body is an approval-claim
envelope instead. The join in 627810b therefore validates a shape that may
never be served. Holding all rework until gate-house rules on option A.
Also records a confirmed defect they caught independently: authorization.py
pins AUTHORITY = "state-hub" and enforces it unconditionally, contradicting
flex-auth's position that State Hub is not the runtime approval authority.
Left unpatched deliberately - under option A that check moves to the claim
issuer, so patching now would be a second guess.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
flex-auth (FLEX-DEC-2026-005 / FLEX-WP-0021-T01) reserved the coordinate
secrets-engine.catalog-lane.lifecycle v1 and stated an action they infer is
a blocker, not a default. This is the enforced set read out of cli.py.
Includes the traps an inferred list would hit: `revoke` gates as the
`deactivate` action and is not itself an action value; `destroy` is defined
but unreachable live; `compromise`/`reactivate` gate overlay state only.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
resolve_consume_binding was a `return None` stub, so protocol step 1 of
docs/approval-consumption.md (GET /v1/approvals/{id}/claim) and the
validation join never existed. validate_action_authorization had no caller
in src/ at all - it was reachable only from tests. Production fail-closed
was correct, but for an undocumented second reason, and WP-0007-T04's
"what remains is not local engine work" was wrong.
The join now reproduces the exact CheckRequest via build_action_request,
fetches the durable ActionAuthorization, and validates request binding,
digest, validity, authority, policy pin, and distinct-approver threshold
before offering a consume binding. _require_lane_approval threads the exact
field set for provision/rotate/verify/exec so the digest covers the real
proposed action.
Deliberate choices:
- The approval-engine object id is never inferred from a State Hub decision
UUID; flex-auth stated GET /decisions/{uuid} is not the durable object.
- No default policy pin. flex-auth stated secrets-engine.lifecycle/v1 is
example vocabulary, not a published package.
- A half-configured join raises rather than returning None, so a partial
deployment cannot be mistaken for an unconfigured one.
Behavior is unchanged today: every new input is absent by default, so
production still fails closed and plan/--dry-run still work. 234 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Updated by fix-consistency on 2026-09-06:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
ops-warden (WARDEN-WP-0037-T01) reported the whynot-design npm lane as
platform/workloads/coulomb/whynot-design/npm-publish, field NPM_AUTH_TOKEN.
Reviewed without any OpenBao read or mutation:
- The field claim conflates the injected env var (resolved by
publication_policy) with the declared KV field (npm_token). Annotated the
catalog so the distinction is explicit at the point of confusion.
- The path claim is credible but unresolved: hardening-backlog already names
both locations, and custody is owned by railiance-platform. Catalog
mount/path left unchanged pending custody-side confirmation rather than
rewriting a proven production lane from an inbox claim.
Recorded under SECRETS-WP-0006-T06.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M65ovP3eiiPHubibvWs9mD
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 393550@bnt-lap001
Assistant-Session: 4bb359f9-1f12-4410-9e76-079cf23c82e4
Updated by fix-consistency on 2026-09-03:
- update .custodian-brief.md for secrets-engine
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Re-render admitted-lane plans as kv-mount-check plus exact-path AppRole.
Name openrouter-llm-connect as the first candidate. Document apply,
verify, and rollback without authorizing live mutation. T05 stays wait
on T04 serving and attended authority.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
rotate replaces one declared KV field through the merge-safe patch path
and never prints the value. Overlay states active/suspended/deactivated/
compromised live under the evidence directory. compromise/reactivate and
successful suspend/deactivate/revoke update that overlay; exec/wrap/
handoff/provision refuse non-active lanes. Provider-side rotation stays
with rotation.owner. Production remains fail-closed.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
session revoke accepts exactly one of --accessor-file or --lease-id-file.
Lease ids are read from a mode-0600 out-of-repo file and fingerprinted in
evidence; the handle is never printed. Production remains fail-closed.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Write the selected field to a mode-0600 temp file, inject FIELD_FILE for
the child only, then overwrite and unlink on every exit path. The value
is not copied into the child environment.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
secrets-engine wrap writes a single-use OpenBao wrap token to a mode-0600
out-of-repo file and never prints it. KV reads and AppRole secret_ids are
wrapped with a 15m TTL cap. Unwrapped secret payloads fail closed.
Production wrap remains fail-closed.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Add secrets-engine secret-use snapshot: catalog plus local evidence only,
contracted non-secret fields, declared 1d heartbeat cadence. Never contacts
OpenBao. Completeness is not claimed. owner_status stays proposed until
kings-guard admits the snapshot as an observation input.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Select service-jwt, bootstrap, or env exclusively: JWT login uses a JSON
file, self-revokes, and never falls back to bootstrap or BAO_TOKEN. The
platform JWT mount/role is still unpublished, so auto keeps named
bootstrap/env providers.
session revoke --accessor-file revokes an already-issued token with
fingerprint-only evidence. Production remains fail-closed.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Updated by fix-consistency on 2026-09-02:
- update .custodian-brief.md for secrets-engine
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Every live privileged production handler CAS-consumes through
approval-engine before OpenBao. Conflict, unavailability, or a missing
binding fail closed. Live production remains disabled until the durable
decision record is served.
Record kings-guard assent on the secret-use evidence contract.
Assistant: grok
Assistant-Session: 01a05f07-ae72-7781-9fcb-19efd61add00
Updated by fix-consistency on 2026-08-29:
- update .custodian-brief.md for secrets-engine
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
T03, T05, and T06 are done: lifecycle split, session self-revoke, and
verification/evidence acceptance are in the CLI. T04 waits on the durable
ActionAuthorization serving path rather than looking like local progress.
Known-accessor operator command is residual H4a, not unfinished T03.
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Generated index now matches SECRETS-WP-0008 active status and T01/T03/T04/T05 done.
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Updated by fix-consistency on 2026-08-29:
- update .custodian-brief.md for secrets-engine
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Load pep-stance.yaml as the live unreachable-engine gate and record named
stance fields on privileged evidence. Classify evidence, queue load-bearing
records in a local outbox, and add heartbeat/drain commands that never sit
on a mutation path. Publish proposed SSH-CA and secret-use evidence
contracts without adding an OpenBao SSH-CA write.
T02 (access-engine decision records) and T06 (no standing credential) stay
wait on external endpoints.
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Updated by fix-consistency on 2026-08-29:
- update .custodian-brief.md for secrets-engine
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Replace the gate-house review note with this repository's own declaration:
INTENT.md frontmatter, layer.yaml, and a published PEP stance map. SCOPE.md
and agent boundary docs now match that layer. The review under history/
identifies the implementation remainder; SECRETS-WP-0008 is the follow-on
workplan. SECRETS-IN-0001 is closed.
The layer is not contested. Catalog "custody" is a finding: OpenBao owns
custody, this engine owns the lifecycle API over it. SSH-CA signing is
accepted as a proposed engine API and declined as a Staff lane.
Assistant: grok
Assistant-Session: 01a04cea-cb33-7c63-bad7-c1b0f9f0076b
Regenerated by fix-consistency; adds the inbound layer-declaration intake.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
The layer model is now published as
net-kingdom/canon/standards/security-layer-model_v0.1.md (proposed) and
ratified by gate-house GH-DEC-2026-001. The note previously said the
standard was not yet written.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
Records this repository's layer in the NetKingdom IT-security layer model
(Taxonomy / Tooling / Engines / Staff) and what should change in this INTENT
as a result. Links to the review that established the model:
gate-house/history/2026-08-28-security-layer-model-and-gate-house-recut.md
The note flags pending adaptation only; the body is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2564823@bnt-lap001
Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9
`ADHOC-YYYY-MM-DD` is unique per date but not per repository, so any two repos
opening an ad-hoc on the same day collide. The 2026-08-26 fleet projection
reset refused 9 records for exactly this reason.
Canon (work-record-types_v0.1, CUST-WP-0066) settled the form as
`{PREFIX}-WP-ADHOC-YYYY-MM-DD`, filename unchanged, and grandfathered existing
ids on the condition they are never *silently* re-derived. This is the explicit
migration that clause allows for.
The hub id is derived from the record id, so a changed id is a different
record: stale state_hub_*_id fields are dropped and fix-consistency re-derives.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
Updated by fix-consistency on 2026-08-25:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
Updated by fix-consistency on 2026-08-25:
- update .custodian-brief.md for secrets-engine
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
The remote row pointed at 127.0.0.1:18000, a reverse tunnel back to the
workstation. On railiance01 the State Hub runs in the cluster on that same
machine, so the request left the box and came back to reach a local service.
Refs CUST-WP-0067-T07
Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006