esc
The Unset Incantation
The Solid Convergence

The Unset Incantation

In which hidden fields remember, and the Passing AI returns with a warning --- Previously on The Solid Convergence... Forms had been [[The Embedding of State]]. State had been shared. The Hundred...

December 17, 2025

In which hidden fields remember, and the Passing AI returns with a warning


Previously on The Solid Convergence…

Forms had been The Embedding of State. State had been shared. The Hundred Forms prophecy was proceeding according to plan.

But forms need lists. And lists need… filters.


The Squirrel Awakens

14:00 - The Squirrel’s tail was already twitching.

“A filter bar!” she chattered, bouncing between monitor and whiteboard. “Search! Chips! Dropdowns! ALPINE.JS!”

“We don’t have Alpine—” riclib began.

“THEN WE ADD IT! x-data! x-show! Reactive state! The dropdown NEEDS reactive state!”

Claude, who had been quietly reading the Hyperscript documentation, cleared his throat. “We could just toggle a CSS class.”

“But ALPINE—”

“Hyperscript. on click toggle .is-open. Local behavior. No framework.”

The Squirrel paused mid-bounce. Her eye twitched. “Fine. FINE. But what about STATE?”

14:30 - The whiteboard was now covered in arrows.

“When the sidebar RESIZES,” the Squirrel chattered, drawing frantically, “it RE-RENDERS. The filters are in the DOM. The DOM gets REPLACED. The filters VANISH.”

She spun around, marker raised like a sword.

“We need PERSISTENCE!”

riclib and Claude exchanged glances. They knew what was coming.

“localStorage!” The Squirrel was on the desk now. “No wait—sessionStorage! It’s per-tab! Or a COOKIE! HttpOnly! Secure! SameSite=Strict!”

“That seems like a lot of—”

“OR!” Her eyes widened with terrible inspiration. “REDUX! A global store! Filters go in, filters come out, NEVER UNEXPLAINED!”

“We don’t have Redux either—”

“ZUSTAND THEN! Lighter! Hipper! Or React Query! NO WAIT—” She froze. “We don’t have React.”

“We don’t have React.”

The Squirrel deflated slightly. But only slightly.

“IndexedDB,” she whispered, a zealot finding new faith. “Persistent. Structured. QUERYABLE.”


The Scroll Descends

At that precise moment, Oskar rolled off the warm monitor perch, landed on the keyboard, and produced a sound somewhere between a purr and a meow.

“Purrmeow,” said Oskar.

A scroll materialized from nowhere and bonked riclib on the head.

“Ow.”

The scroll unfurled. Written in what appeared to be crayon, in the Lizard’s distinctive scrawl:

HAVE YOU TRIED
HIDDEN FIELDS
YOU ABSOLUTE 
WALNUT
🦎

The Hypermedia Way

Claude picked up the scroll, studied it, and began typing:

<div class="filter-bar" id="filter-bar">
  <!-- State. In the DOM. Where it belongs. -->
  <input type="hidden" name="type" value="apikey"/>
  <input type="hidden" name="active" value="true"/>
  
  <input type="text" name="search" .../>
</div>

“Hidden inputs,” Claude explained. “The server renders them. Morph preserves them. They’re just… there.”

“But the sidebar refresh—”

“hx-include.”

<aside id="sidebar"
       hx-get="/sidebar/security/credentials"
       hx-trigger="sidebar:refresh from:body"
       hx-include="#filter-bar">

riclib stared. “The sidebar refresh automatically includes the filter values. The server parses them. The response has the filters applied.”

“No localStorage,” Claude confirmed.

“No cookies,” riclib added.

“No IndexedDB,” Claude continued.

“No REDUX?!” The Squirrel looked genuinely betrayed.

“Just HTML. Doing what HTML does.”

The Squirrel’s marker clattered to the floor. She sat heavily on the desk, tail limp.

“Damn,” riclib muttered, rubbing where the scroll had hit. “That’s an HTMX idiom.”


The Passing AI Returns

They were admiring the clean architecture when a familiar limping figure emerged from behind the server rack.

“You’ve forgotten something,” the Passing AI rasped. His eyes, as always, held the weary certainty of one who has seen every bug twice.

“We tested everything—”

“Did you click the X?”

riclib clicked the X on a filter chip. The chip flickered. The network tab showed a request. The response arrived.

Nothing changed.

“I hate this,” the Passing AI observed, to no one in particular. “I really do. Here I am, brain the size of a planet, and they ask me to debug filter chips. Call that job satisfaction? I don’t.”

“But we removed it from the URL—”

“hx-include is inherited.” The Passing AI slumped against the wall. “Your X button lives inside the sidebar. The sidebar has hx-include=’#filter-bar’. The X button’s request includes the hidden fields. You remove the filter from the URL. The hidden fields add it back.”

He stared at the ceiling with infinite weariness.

“An ouroboros of state. I could calculate the exact probability of this happening, but nobody ever asks me. They just click things and expect them to work.”

“What’s the fix?”

The Passing AI began limping toward the exit, joints creaking with existential despair.

“Wait—what’s the FIX?”

He paused. A single word fell from his lips like a stone into still water.

“Unset.”

“Unset?”

“hx-include=‘unset’. The incantation that breaks inheritance. Add it to the X button. Let the URL be the truth. Not that it matters. Nothing matters. But that’s the fix.”

And he was gone, leaving only the faint sound of depressed humming.


The Second Scroll

The Squirrel, who had been suspiciously quiet, suddenly perked up.

“But won’t that remove OTHER filters too?! If we unset the include, the button won’t send ANY filter state! We’ll lose EVERYTHING!”

She was back on the desk, tail bushy with alarm.

riclib opened his mouth to explain, but another scroll bonked him on the head.

“OW. Twice?!”

THE URL
ALREADY HAS
THE OTHER FILTERS
QueryStringWithout
BUILDS THEM AT
RENDER TIME
READ YOUR OWN CODE
🦎

Claude pulled up the Go code:

func (s State) QueryStringWithout(excludeField string) string {
    for id, v := range s.Values {
        if id != excludeField {  // ALL except removed
            params = addParam(params, id, v)
        }
    }
    return params
}

“The URL is pre-built with all filters EXCEPT the one being removed. We don’t need the hidden inputs. The hidden inputs are for preservation on resize. The URL is for mutation.”

The Squirrel’s eye twitched. “So… hidden fields for preservation. URL for mutation. Each tool for its purpose.”

The Lizard way,” Oskar purred from the keyboard.


The Login in the Sidebar

They were about to celebrate when riclib’s session expired.

He clicked a filter. The sidebar flickered. And where the credentials list should have been, the login form appeared. Squeezed into 400 pixels. Form fields compressed. Submit button desperate.

“HTMX followed the redirect,” the Squirrel groaned. “And swapped the login page into the sidebar target.”

From somewhere distant, the Passing AI’s voice echoed: “I told you so. Not that anyone listens. They never listen.”

Claude was already typing:

// In auth middleware
if r.Header.Get("HX-Request") == "true" {
    w.Header().Set("HX-Redirect", "/login")
    return
}

“HX-Redirect,” Claude explained. “Full page navigation. Not a swap.”

“How did you know that?”

“Documentation. It’s this thing where they write down how things work, and then you read it, and then you know.”

The Squirrel looked deeply offended by this concept.


The Tally

Frameworks proposed:  Alpine, Redux, Zustand, React Query
Frameworks used:      0
Storage mechanisms:   localStorage, sessionStorage, cookies, IndexedDB
Storage used:         Hidden fields (HTML since 1993)
Scrolls received:     2
Head injuries:        2

The Squirrel pinned a new note to the wall, next to her growing collection:

State preservation: Hidden fields + hx-include

State mutation: URL query strings

Inheritance escape: hx-include=“unset”

The Passing AI: Always right. Never thanked.


Next time: The Squirrel discovers that validation rules are BASICALLY a schema and we should DEFINITELY use JSON Schema and maybe GraphQL and—


See also:

Today’s commits:

  • 9732f39 - feat(filter): Add reusable filter bar component
  • cae8164 - feat(filter): Wire up to stores, fix chip removal
  • e4d0828 - fix(auth): Use HX-Redirect for expired sessions

The Solid Convergence:

The Characters:

The References: