The middleware resolves the plugin's csrf block ONCE at registration, and
this key is how the helper reads that resolution instead of re-deriving the
name from its own argument — which is how it came to render '_csrf' on a
form the same plugin verified under a configured fieldName, 403-ing every
post (X47-2). Written before the middleware's ignoreMethods/exclude
short-circuits, because the GET that renders the form is itself an ignored
method.
The published value is a FROZEN, request-local PublishedCsrfConfig
carrying only fieldName — deliberately not the middleware's own
ResolvedCsrfConfig. That object is resolved once at registration and shared
by every request, so publishing it handed a reference to the verifier's own
configuration to any handler holding the context: measured, one
ctx.state.get(CSRF_CONFIG_STATE_KEY).ignoreMethods.add('POST') turned a
403 into a 200 for every LATER request in the process, with a fresh state
map each time. A per-request copy closes that, and narrowing to the one
member the helper reads makes it structurally impossible rather than merely
detached — a string cannot be mutated — while leaving no published member
without a reader.
Keyed per the M71 state-key convention (<owner-package>:<kebab-key>).
The
ctx.statekey under whichcsrfFormMiddlewarepublishes the field name it will verify, forcsrfTokenFieldto render.The middleware resolves the plugin's
csrfblock ONCE at registration, and this key is how the helper reads that resolution instead of re-deriving the name from its own argument — which is how it came to render'_csrf'on a form the same plugin verified under a configuredfieldName, 403-ing every post (X47-2). Written before the middleware'signoreMethods/excludeshort-circuits, because the GET that renders the form is itself an ignored method.The published value is a FROZEN, request-local
PublishedCsrfConfigcarrying onlyfieldName— deliberately not the middleware's ownResolvedCsrfConfig. That object is resolved once at registration and shared by every request, so publishing it handed a reference to the verifier's own configuration to any handler holding the context: measured, onectx.state.get(CSRF_CONFIG_STATE_KEY).ignoreMethods.add('POST')turned a403into a200for every LATER request in the process, with a fresh state map each time. A per-request copy closes that, and narrowing to the one member the helper reads makes it structurally impossible rather than merely detached — a string cannot be mutated — while leaving no published member without a reader.Keyed per the M71 state-key convention (
<owner-package>:<kebab-key>).