# Day 11: Production Security, Error Doctrine, Testing, Naming, and Daily Operations

**Onboarding track:** Alpine.js + htmx, co-equal architecture  
**Verified baseline:** Alpine.js 3.15.12 and htmx 2.0.10 (stable)  
**Verification date:** 2026-07-19  
**Compatibility boundary:** htmx 4.0.0-beta5 is a prerelease line and is not the syntax baseline for these lessons.

## Purpose

Turn the patterns into a maintainable production discipline with security boundaries, CSP choices, error policy, component contracts, test matrices, naming conventions, review procedures, and htmx-version controls.

## How to use this document

Budget a working day. Read the lessons in order, type the examples instead of copying them blindly, perform every mini-task, and finish the exit exercise without looking at the answer notes. The examples use a fictional server-rendered operations application, but the ownership rules are framework-neutral.

A successful day ends with three artifacts:

1. working markup or a small runnable page;
2. written ownership notes for each state value and DOM region;
3. answers to the comprehension check.

## Learning outcomes

You will be able to:

- identify what the browser can never authorize;
- protect against XSS, CSRF, unsafe raw HTML, and executable untrusted markup;
- choose a CSP-compatible Alpine strategy;
- distinguish validation, network, authorization, and unexpected errors;
- test full pages, fragments, lifecycle, races, history, and accessibility;
- use a standard component contract and code-review checklist;
- track htmx 2 versus htmx 4 migration risk.

## 1. Security authority

The server remains responsible for:

- authentication;
- authorization;
- CSRF enforcement;
- validation and normalization;
- escaping and sanitization;
- rate limits;
- transaction integrity;
- conflict handling;
- audit logging;
- file scanning;
- session policy.

A hidden or disabled control is not authorization. An Alpine permission flag is not authorization. An htmx request header is not authorization.

## 2. XSS and untrusted markup

Both Alpine and htmx make HTML more expressive. If an attacker can inject arbitrary HTML attributes, they may inject behavior.

Rules:

1. escape untrusted values in server templates;
2. sanitize deliberately allowed rich HTML with an allowlist;
3. remove dangerous script and behavior attributes during sanitization;
4. avoid `x-html` for untrusted content;
5. do not mark user HTML raw merely because it will enter through htmx;
6. consider `hx-disable` around intentionally inert untrusted HTML in htmx 2 as defense in depth;
7. consider `x-ignore` when Alpine must not process a trusted isolated widget, but do not mistake it for sanitization.

```html
<div hx-disable>
    <!-- escaped or sanitized user content -->
</div>
```

`hx-disable` does not repair unsafe server rendering. It only prevents htmx processing in that subtree.

Note: htmx 4 renames/reassigns some disable-related attributes; check the migration guide.

## 3. CSRF

Use the framework’s standard CSRF defense.

Preferred:

- hidden token in real forms when the framework supports it;
- same-site cookie policy;
- server token validation;
- explicit headers for non-form methods when required.

htmx can include a header:

```html
<body hx-headers='{"X-CSRF-Token": "SERVER_RENDERED_TOKEN"}'>
```

But request headers alone are not a complete CSRF design. Consider boosted navigation and whether the token-bearing ancestor is replaced.

Never expose a secret token through Alpine state unnecessarily.

## 4. Content Security Policy

The normal Alpine build evaluates attribute expressions in a way that conflicts with strict CSP policies that disallow `'unsafe-eval'`.

Options:

1. use Alpine’s CSP build;
2. use a project CSP that deliberately allows the required behavior;
3. extract behavior into registered components and follow CSP-build syntax limitations;
4. reduce inline scripting;
5. validate plugins against the chosen build.

The Alpine CSP build supports most common expressions but not every JavaScript feature. Test the actual application rather than assuming equivalence.

htmx also supports CSP-conscious operation, but inline `hx-on` scripting and injected raw HTML require review. Prefer semantic events and registered JavaScript listeners when strict CSP is a goal.

## 5. Error taxonomy

### Expected validation or business rejection

Return usable server-rendered HTML with:

- submitted values;
- field errors;
- summary where appropriate;
- accessible relationships;
- clear next action.

### Authorization or session expiry

Use a consistent global policy only if it is genuinely cross-cutting:

- redirect to login;
- replace a session-expired panel;
- show a global reauthentication dialog;
- preserve safe drafts;
- avoid replaying unsafe mutations automatically.

### Network failure or timeout

Define:

- retry eligibility;
- offline message;
- draft preservation;
- ambiguous mutation handling;
- status announcement;
- recovery action.

### Unexpected server error

Return a safe, traceable representation. Do not expose stack traces or secrets. Include correlation IDs where the server supports them.

### Alpine/local JavaScript error

A local error must not leave durable state ambiguous. Keep methods small, clean up resources, and avoid optimistic UI that cannot be reconciled.

## 6. Central listeners: narrow and cross-cutting

Reasonable global htmx lifecycle uses:

- request tracing;
- analytics;
- session-expiry handling;
- network banner;
- focus policy for boosted navigation;
- third-party teardown;
- security logging.

Unreasonable:

- “after every request, inspect text and decide which business workflow succeeded”;
- global store mutation for every response;
- feature routing hidden in a listener.

Scope by target, marker, status, or declared event.

## 7. Testing layers

### Server tests

Verify:

- authorization;
- validation;
- transaction and conflict behavior;
- full-page response;
- htmx fragment response;
- response status policy;
- response headers;
- OOB fragments;
- cache variation;
- direct route behavior;
- escaped output.

### Alpine unit/component tests

Verify:

- local state transitions;
- keyboard behavior;
- focus entry/restoration;
- provisional calculations;
- event dispatch/reaction;
- store queue behavior;
- `init()` and `destroy()` cleanup.

### Browser integration tests

Verify:

- stable shells survive;
- disposable roots reset;
- swapped-in Alpine components initialize;
- Alpine-created htmx markup is processed;
- indicators and disabling;
- races;
- validation loops;
- OOB updates;
- fact-event timing;
- polling stop;
- Back/Forward;
- no-JavaScript path where required;
- keyboard and screen-reader-critical behavior.

## 8. Failure matrix

For each feature, test at least:

| Case | Expected |
| --- | --- |
| success | canonical HTML installed |
| validation failure | values/errors preserved |
| authorization denied | safe consistent policy |
| stale conflict | explicit resolution UI |
| network offline | recoverable message |
| timeout | retry policy |
| rapid repeated action | synchronized/idempotent |
| history restore | correct route representation |
| component removed | cleanup runs |
| JavaScript unavailable | baseline route/form works |

## 9. Naming and organization

Suggested project structure:

```text
templates/
  pages/
  components/
  fragments/

static/
  js/
    alpine-components/
    htmx-integration/
    islands/
  css/

tests/
  server/
  browser/
```

Name server targets by domain role:

- `#cart-contents`;
- `#search-results`;
- `#profile-form`;
- `#job-status`.

Name Alpine components by local behavior:

- `remoteDialog`;
- `filterPanel`;
- `toastCenter`;
- `combobox`.

Name events by domain meaning:

- `profile-saved`;
- `cart-updated`;
- `filters-committed`.

Avoid public names such as `alpineThing`, `htmxSwapNow`, or `rightDiv`.

## 10. Standard component contract

Every mixed component should document:

### Identity

- server resource ID;
- DOM target IDs;
- OOB IDs;
- preservation or generated local IDs.

### State ownership

- durable;
- URL;
- control;
- request;
- Alpine local;
- derived/provisional;
- third-party island.

### Replacement

- target;
- swap;
- Reset/Survive/Preserve/Reconcile;
- response root.

### Requests

- method and route;
- triggers;
- inputs;
- concurrency;
- indicators;
- disabling;
- idempotency.

### Events

- command/fact;
- producer/listener;
- payload;
- timing;
- failure.

### History

- push/replace/none;
- direct visit;
- cache;
- sensitive snapshots.

### Accessibility

- labels/roles;
- focus;
- keyboard;
- announcements;
- reduced motion.

### Errors and cleanup

- validation;
- network;
- authorization;
- conflict;
- destroy/teardown.

## 11. Code review SOP

Review in this order:

1. **Server truth:** Is authorization and validation complete?
2. **Native semantics:** Are links, forms, controls, and headings correct?
3. **State inventory:** Is every value owned once?
4. **DOM boundaries:** Is every writer explicit?
5. **Request contract:** Method, trigger, inputs, target, swap, response root?
6. **Concurrency:** What wins under overlap?
7. **Lifecycle:** Reset or survive? Cleanup?
8. **Events:** One-way, semantic, documented?
9. **History:** Direct URL and Back/Forward?
10. **Accessibility:** Focus, keyboard, announcement?
11. **Security:** Escaping, CSRF, CSP, untrusted HTML?
12. **Failure:** Validation, network, session, conflict?
13. **Complexity:** Could HTML/CSS or a smaller boundary replace the cleverness?
14. **Version:** Is htmx 2 syntax accidentally mixed with htmx 4?

## 12. Anti-pattern catalog

### Alpine shadow backend

Symptoms: entities, permissions, routing, business rules, and reconciliation in stores.

### htmx for local trivia

Symptoms: requests for dropdowns, already-present tabs, or local previews.

### Two loading systems

Symptoms: `loading` boolean and htmx indicator disagree.

### Two form models

Symptoms: input, Alpine object, and request parameter differ.

### Broad swaps

Symptoms: unrelated focus and local state vanish.

### Competing collection writers

Symptoms: `x-for` and htmx both manage server records.

### Event maze

Symptoms: hidden multi-hop chains.

### OOB sprawl

Symptoms: one response choreographs unrelated page regions.

### Blanket preservation or morphing

Symptoms: identity magic compensates for a poor target.

### Attribute overload

Symptoms: a single tag contains endpoints, long expressions, business rules, and DOM algorithms.

Repair with registered Alpine components, template helpers, server partials, or a JavaScript island.

## 13. htmx 2 / htmx 4 version gate

Verified on the package date:

- stable htmx documentation identifies 2.x as latest stable and shows 2.0.10;
- htmx 4 is beta;
- htmx 4 changes event names;
- inheritance becomes explicit by default;
- `4xx`/`5xx` swapping defaults change;
- disable-related attribute names change;
- extension mechanics change.

Repository controls:

1. pin htmx version;
2. record version in architecture docs;
3. keep lifecycle listeners in a dedicated module;
4. prohibit mixed major-version syntax;
5. run the htmx 4 upgrade checker before migration;
6. test error swapping and inheritance during migration;
7. update every onboarding example when the project baseline changes.

## 14. Operational troubleshooting sequence

When a mixed component fails:

1. reproduce without Alpine if the problem is server request/swap;
2. reproduce without htmx if the problem is local interaction;
3. inspect actual request method, URL, parameters, status, and response;
4. inspect target and response root;
5. confirm which nodes were removed;
6. confirm Alpine root reset/survival;
7. log htmx lifecycle events narrowly;
8. inspect duplicate listeners/timers;
9. test a direct route;
10. test slow network and repeated action;
11. check version-specific syntax;
12. reduce to the smallest ownership conflict.

## 15. Day lab: production review

Take one feature from Days 5–10 and produce:

- component contract;
- threat review;
- CSP decision;
- status-code policy;
- failure matrix;
- server test list;
- Alpine test list;
- browser test list;
- accessibility test;
- code-review report;
- htmx 4 migration notes.

Then intentionally inject three faults:

1. target the stable Alpine root;
2. return the wrong `outerHTML` root;
3. add a duplicate Alpine loading flag.

Diagnose them using the troubleshooting sequence.

## Mini-tasks

### Task A: threat boundary

Explain why a hidden Delete button does not prevent unauthorized deletion.

### Task B: raw HTML

Design safe handling for user-authored rich text.

### Task C: global listener review

Classify five lifecycle listeners as cross-cutting or feature-specific.

### Task D: version audit

Find every htmx event name and inherited attribute in a sample component and mark migration risk.

## Comprehension check

1. What can the browser never authorize?
2. Why is `x-html` dangerous with untrusted content?
3. What does `hx-disable` provide?
4. What CSP issue does standard Alpine raise?
5. What four major error categories should be separated?
6. What makes a global listener acceptable?
7. What must server tests cover beyond JSON/data?
8. What must browser tests prove about lifecycle?
9. Name three htmx 4 migration changes.
10. What is the first troubleshooting split?

## Cheat sheet

```text
AUTH / VALIDATION / TRANSACTION  -> server
ESCAPE UNTRUSTED CONTENT         -> server template/sanitizer
CSRF                             -> framework + server policy
STRICT CSP                       -> Alpine CSP strategy
EXPECTED VALIDATION              -> usable form HTML
NETWORK FAILURE                  -> retry/ambiguity policy
GLOBAL LISTENER                  -> narrow + cross-cutting
MIXED COMPONENT                  -> written contract
MIGRATION                        -> pin, audit, test defaults
```

## Exit exercise

Perform a production readiness review for a bulk financial approval workflow. Include authorization, CSRF, idempotency, conflict handling, OOB totals, success fact, focus, retry ambiguity, audit logging, direct routes, lifecycle cleanup, and htmx 4 migration risk.

## Exit criteria

You pass when another engineer can operate, review, test, and migrate the feature from the written contract without relying on tribal knowledge.

## Official reference shelf

Use these as the authority when a project version or behavior is uncertain:

- Alpine.js documentation: https://alpinejs.dev/
- Alpine.js directives: https://alpinejs.dev/directives/
- Alpine.js `Alpine.data()` lifecycle and `destroy()`: https://alpinejs.dev/globals/alpine-data
- htmx 2.x documentation: https://htmx.org/docs/
- htmx 2.x reference: https://htmx.org/reference/
- htmx 2.x events: https://htmx.org/events/
- htmx 4 migration guide: https://four.htmx.org/migration-guide-htmx-4/

> Version note: These exercises use htmx 2.x event names such as `htmx:afterSwap` and `htmx:afterSettle`. htmx 4 changes event naming and several defaults. Do not mechanically port the examples without the migration guide.
