-
habiting the net
A detailed summary of technical work I delivered for HistoryPin.org, a project of Shift Collective
Wednesday October 22, 2025At the start of 2025 I embarked on a rewrite of HistoryPin.org for Shift Collective, an Exygy Client and important place on the web where communities self-determine their stories. After being impressed with Cursor’s ability to create a meaningful contribution summary gleaned from the git commit history for SF’s Our415.org code, I let Cursor loose again. Strung together, these terse paragraphs form a pretty reasonable narrativization of my work on the rewrite. Although some categories of features are bundled a little funky – like “Development Workflow & Maintenance,” and the reductionism spurred by my instruction to “briefly summarize” clearly collapses PR descriptions to the point of omission. There’s barely a mention of the test harnessing I established with pytest, FactoryBoy, and playwright. That said, the breadth and depth of my impression on the project still feels substantial. In 9 months I drove the rewrite from greenfield to the wholesome organized entropy of near feature parity, and am proud of what I achieved with no (significant) previous experience in greenfield projects of this scope, the Django framework, or python programming. Infra, schema, frontend, backend, test harness, devx – these parts were me and I was these parts.
Collection Management & Customization Features
You’ve been instrumental in building out a comprehensive collection customization system. You added support for nested collections with an
is_nestablefield and updated forms to create collections within existing ones, leveraging query parameters for navigation. You implemented collection banner functionality including video URLs and image uploads using Django’s form utilities, along with sponsor logos with ManyToMany relationships and dropzone file uploads. You also added background color customization and visibility toggling for various collection fields, with proper permissions management for paid features.User Account Management & Security
You implemented a complete account deletion system with proper cascade deletion starting from the user level, including form templating and view logic to handle both self-deletion and superuser deletion scenarios. You also worked on username logic for members, ensuring proper username creation through Google social login adapters and migrating routes to use member primary keys instead of usernames.
Search & Discovery Functionality
You built out member search capabilities by refactoring code to support a
MembersDiscoveryview with query parameter handling similar to collection searching. You implemented collection theme searching with support for multiple theme selections using comma-separated query parameters, including proper database indexing with Gin indexes for array operations. You also added location searching support to theDiscoverCollectionViewwith Google Place ID integration and location autocomplete functionality.Form Architecture & Data Handling
You made significant improvements to form handling patterns by refactoring complex relationship management during form submission, moving more logic to model form handlers to avoid overlapping operations between views and forms. You implemented tag support for collections using Django Taggit, enabling thematic tag filters and creating reusable
TagComboboxcomponents. You also added proper permissions management for paid features, ensuring correct access controls for members and collection owners.Database & Performance Optimization
Your work included several database optimizations including adding indexes on
featuredcolumns for Collections and Members, implementing Gin indexes for array searching, and optimizing deletion queries using cascades. You also worked on image handling improvements, fixing conditions that allowed setting empty pin images and implementing proper image optimization.UI/UX Enhancements
You implemented responsive design patterns using CSS queries and inline JavaScript to manage UI state, particularly for collection customization forms. You created reusable components like the
TagComboboxthat can be used for both Pins and Collections. You also worked on template refactoring to separate page containers from list rendering logic, making the codebase more maintainable.Development Workflow & Maintenance
You contributed to development experience improvements by adding seeds to database reset processes, creating new ADRs (Architecture Decision Records) addressing testing and form logic, and implementing script loading optimizations with
deferandDOMContentLoadedto prevent blocking the critical path.Paid Features & Monetization
You worked on paid feature integration by refactoring the Donation Block toggling to use generic relationships, removing confusing admin configurations in favor of seed scripts, and implementing CSS-based show/hide functionality for donation input fields based on toggle states.
Code Quality & Architecture
Your contributions emphasized better separation of concerns and reusable component design. You refactored paid features to use generic relations, created more maintainable form handling patterns, and implemented proper permission checks by comparing evaluated object IDs. You also worked on template organization to make paginated lists more flexible and reusable.
Overall, your contributions demonstrate a strong focus on user experience, data management, search functionality, and maintainable architecture. You’ve been particularly effective at building complex features like collection customization and search/discovery systems while maintaining code quality and implementing proper security measures.
-
habiting the net
A detailed summary of technical work I delivered for San Francisco's public benefits portal Our415.org
Wednesday October 22, 2025In the fall of 2024 I joined the Consulting division of Exygy, an agency that delivers web tech solutions for civic and non-profit organizations. My very first assignment was getting a project of the Deparment of Youth and Families – Our415.org – launch-ready. Having a direct impact on families in SF was a very rad proposition, being a resident myself. Bringing a project home that’s close to home.
In short time I completed a gaggle of technical work on Our415.org’s legacy React codebase, which had been forked from a similar benefits portal called the SF Service Guide. While pondering how I might proudly tell the tale of my work for the city to would-be interested parties like my mom or recruiters, I realized I might enlist the help of an LLM. Might Claude be able to make sense of all those commits? I don’t remember the exact instructions I put in the prompt, something like “go to
and briefly summarize all the commits by author @rosschapman”. Cursor did not disappoint. It output the well-organized summations you see below, clearly extrapolating from my own characterizations of the work gleaned from commit messages and PR descriptions. And then enhancing with brand-marketing expletives. What surprised me most about these commits-cum-words, is the volume of accumulated work that is reflected back. It’s a lesson in the sheer mass of meaningful impressions a senior software engineer can have on a project’s formation in short time. And, perhaps, equally revelatory of how much we downplay our steady stream of achievements during a project’s speed-run to launch. To me this feels like a valuable narrativization of the private lives and material impact of senior engineers that is often relegated to archive, work diaries, 1:1 notes, as stakeholders and end-users merely avail themselves to the gestalt of these parts in production. To shouting the minutiae from the rooftops!
Development Infrastructure & Workflow Improvements
You were a key contributor to modernizing the development process. You implemented pre-commit hooks using Husky and lint-staged to catch lint errors before CI, significantly reducing build failures. You established Jest testing infrastructure with React Testing Library, migrating existing tests and setting up a proper testing foundation. You also configured Dependabot for automated dependency management and updated the target branch to
developmentfor better workflow integration.Performance Optimization & Bundle Management
Your work focused heavily on bundle size reduction and dependency optimization. You reduced the lodash dependency burden by approximately 50% by switching to modular lodash functions instead of loading the entire bundle. You used tools like
npx knipto identify and remove unused dependencies and components, including ShelterTech auth code, unused Homepage components, and WeGlot translation service code that wasn’t being used.Search & Map Functionality Fixes
You addressed several critical bugs in the search and mapping functionality. You fixed incorrect marker location labels by properly moving marker label computation logic into the new transform. You resolved incorrect map markers on pages > 1 by establishing a new
TransformedSearchHitview type/model that provides a canonical representation of search data with proper typing. You also removed algorithmic sorting of search results by urgency that was specific to SF Service Guide and not needed for the MVP.UI/UX Enhancements & Navigation
You implemented significant navigation improvements including a new header navigation system and secondary navigation bar for listing pages. You created a
SecondaryNavigationLayoutcomponent withBackNavigationfunctionality that uses smart routing. You also decoupledSiteSearchfromNavigationand established conventions for wrapping route-level page components with secondary nav bars, including distinct mobile and desktop layouts.Data Handling & Error Resilience
You improved data handling by adding proper null case handling for
service.long_descriptionand implementing optional lookups for missing image data to prevent page failures. You updated the homepage query to fetchcalendar_eventdata and fixed date/time rendering issues. You also refactored Event/Opp card components to accommodate newcalendar_eventdata from Strapi.Code Quality & Architecture
Your contributions emphasized better component architecture and separation of concerns. You extracted the
SearchResultcomponent fromSearchResultsto reduce complexity and colliding terminology. You removed whitelabeling and tenant code, renamingwhiteLabeltowebsiteConfigfor clearer naming conventions. You also cleaned up old test cruft and established better naming conventions for search and map-related variables.Internationalization & Translation
You worked on translation functionality by fixing Google Translate language switching issues and removing unused WeGlot translation service code. You also removed algorithmic sorting that was specific to certain tenants and not needed for the current implementation.
Development Experience
You contributed to developer experience improvements by adding VSCode gitignore directives and creating pull request templates. You also worked on removing technical debt and unused code that was causing confusion and maintenance overhead.
Production & Deployment
You updated the production build workflow with Strapi keys and worked on various fixes that required backend coordination, such as updating frontend queries to match deployed backend changes.
Overall, your contributions demonstrate a strong focus on code quality, performance optimization, user experience improvements, and maintainable architecture. You’ve been particularly effective at identifying and addressing technical debt while implementing modern development practices and fixing complex bugs in the search and mapping functionality.
-
Saturday December 21, 2024
Loud clattering of can By co-living sub-tenant
-
poetry
Sunday September 1, 2024Sarah Hurwitz has a Zen “don’t know” before-thinking enlightenment moment on a hitbodedut retreat. I love this.
That’s all I could say: “I don’t know. I don’t know.” I was saying that over and over again until I said, “I don’t know, but I can’t do this alone.”
It was a moment of openness, of some surrender. I was so astounded that I started to cry and I thought, “I don’t know what that was about.”
Warmth in my chest as I hear her vocal audio bits through my WH-1000MX4s.
-
rutabagas
Rutabagas vol. 4: Notes from the other week
Sunday September 1, 2024- There are too many people to listen to out there. (Not sure why I wrote this. Was I overwhelmed by my podcast feed?)
- The vulnerabilities of the supply chain undo software’s hard surface. (Also, as Thomas Depierre intones in the hurdy-gurdy of I am not a supplier)
- These first two things are about overwhelm, not being able to squeeze the gestalt in your fingers.
- My body is a wispy cloud all this content flows through.
- Ambient women.
- Shze-Hui Tjoa’s remarks from Between the Covers:
Well, I don’t want to generalize but for me, certainly I feel like fiction and non-fiction feel like they’re the same thing a lot of the time because as you said, for me, my experience of the world incorporates a lot of fiction and if I were to try and tell somebody what it feels like to be me, the most authentic thing to do would be to also tell them about the many fantasies I have in my head and that I’m brewing up all the time, sometimes without my own control or without consciously trying to do it. But they’re always there like a parallel stream of thought that’s happening in my head.
-
speculative nonfiction
End products, habiting difference
Sunday July 21, 2024Chapter 1
It’s Wednesday evening. Incandescence lazes out from the rectangle in the southeast corner of my home work station. Zen Master Bon Seong, a fiery bushel on screen, a big circle face in the biggest square. He is using the figurative Zen Stick to short-circuit our cognition. He is fond of saying things like “You are stardust” or “What is I?”.
Jeff breathes hot air through the broom on his face. Those bits go through audio processing and seem to emanate from nowhere around the work station. “The infinite expansion of the same thing” is uttered. We’re discussing how people can interpret the same phenomena differently. As we say: “The whole world is made by mind alone.” And: “The whole world is a single flower.” As the Heart Sutra says: “form is emptiness, emptiness is form”. You cough. I’m startled. I freeze. I think you have COVID. I think I’m going to get it. Then get long COVID. Someone else sees you cough, they think it’s a sneeze and continue on. Perhaps it is.
The dharma talk continues. There’s nothing wrong with our kaleidoscope of perspectives. They are regular. This is the human mind being itself, resting in its station, but painting a tale on snake, coloring it’s ridiculous karma all over “the small box” that is our little piece of understanding of the universe.
Gosh, we’re talking about boxes from within boxes. Our thinking creates this separate, enclosed being. (Consciousness bound by a skin sack? Not today, the microbiome field transforms you. (Sigh. No help lugging our sacks and their biomic nerve fields closer together. We have decades of men making the Bay car-friendly, but I can’t get across conveniently. I can’t get to Berkeley from Potrero without spending as much time commuting as the duration sitting meditation with the other sacks for Wednesday night dharma talks.)) The problem is getting attached to difference. Not understanding our “universal substance” – what we say as a convenience. That’s why Zen is about returning to before thinking, accessing the truth before difference. So maybe instead: you cough, then I hand you a tissue.
I don’t want this post to be about the negatives of the human mind’s proclivity to be a multiversal agent. It’s not really a negative, is it? It’s a matter of fact about our minds as atoms floating in space. Space dust. So, instead: let’s relish in the generative creativities that difference making unleashes when multiple human minds are applied to a problem of interpretation.
Zen students say: “All things return to the one.” Once again, I have returned to software. One of my favorite ones for organizing and observing life’s exposures, like Scrabble tiles. Despite the one, I’m thinking about difference. The way the one refracts and playfully escapes. Our turn here will be akin to Jewish monotheism – a personal return to spiritual foundations – a spiritual tradition where the only official doctrine claims one god but there’s no consensus about what that means.
An often-cited medieval midrash asserts that each of the Israelites at Mount Sinai heart God’s revelation differently according to their own capacity to understand it. They each had their own individual experience of the Divine. – Sarah Hurwitz, Here All Along
A long time passed but the Buddha did not open his mouth to say a single word. He then reached down, picked up a flower and, without a word, held the flower aloft. Nobody in the assembly understood what the Buddha meant by this action. Only Mahakasyapa, sitting at the far back, smiled. – Gye Mun Sunim JDPS, The Birth of Zen
But not everyone smiled!
This “problem” of software:
The epistemological endeavor to solve challenges in the world, happening out there, with(in) reason. Then squeezing all that into binary logics and electrical pulses. Holding a shared thought among humans – sometimes only the wispy thrust of a thought – and making it instructions for the computer.
Zen Master Seung Sahn used to say you have to “digest your mind meal." He meant your understanding. Making software is a kind of digestion of understanding. Pushing thought stuff through a cheese cloth named Divine. A streetcar named Desire.
The software process is messy, from beginning to middle to end.
As a Zen student, I must declare: Where does the one return? Software’s interpretive act is a mix up, a Deleuzian differencing that flies a-face a unifying core concept. Software is never completed, and is not easily located anywhere in particular. Is it those words on the screen, dormant? You could print them. Is it the code as it runs, sonic or electrical (im)pulses amidst fibers, plastics, and metals. Is it what the mouse clicked? When was it conceived? Was it the idea?
Not the cleanest of lines, but lines in flight.
I want to argue here that the distinction between the software system and its development–that is, between the process and product–is another “point of opacity” of software engineering since, albeit necessary, it cannot be kept up at all times. – Federica Frabetti, Software Theory
Software is subversive to hard-dick narratives. It’s feminist, it’s counter-cultural in its essence. That’s why the gate-keepers are relentless trying to wrest it away from the hacker collective with a trademark.
The wisp of generative artificial intelligence hallucinatory resonance is hardly surprising. It’s a re-run run amok. Where does the one return inside your stolen nebula of documents? No citations, indeed. Where is your mind, Algorithm?
Messy. Material. Just as digestion is wont to be, from mouth mashing through shitting. The physical body process is mostly obscured by our containment sacks. But it leaks. It’s hacked.
The metaphor is apt. The world is messy as it is, and software is in it, made from it, made for it. This is why the end product of the software process inspires programmers of acrimonious humor, sometimes of low emotional intelligence, or of self-deprecatedness, or simply exasperated, exhausted… these programmers must declare that which comes from the butt. “This code is crap.” “Who wrote this shit code?”
It’s generally a pessimistic view to call code crap. I’d offer compost to lift us out of the sour sap to a corresponding brownish, molten tree sappy substance. A brighter horizon. Effluent cream - a regenerative solar punk version. Or something like “the best with what we had.” We need less snark in the industry, more heart, don’t you think?
Thankfully (we can breath a sigh) there are loving defenders of our end products out there. (Com)posters on the Net. Rachel Kroll is one, synonymously online as rachelbythebay. She emancipates some lines (of code) and litigates her own “crap code” through a simulated trial judged by such an exasperated panel, and then performs my favorite type of “if I knew now what I knew then” refactor blogging with a procedural splunk. It’s a beautiful example of husbanding thought stuff a second time through.
Chapter 2
Regarding playful escapings of difference.
Like verbalized language, programming languages provide multiplicities for getting thoughts out. In English spoken about town, adults will be overheard in conversation to utter variations on simple themes such as bipedal reversal, for example, with such enriched phrases as “they retraced their steps”, or “they went back”, or “they returned to”. Similarly, the general purpose Ruby programming language invented by Yukihiro “Matz” Matsumoto toward the end of the last century was composed with a syntax of including many lexical pathways to express its computer instructions. Of course, while these variations may not be imbued with the rich cultural context of spoken English idioms, they demonstrate what I’ve always found to be a never gets old trait of modern programming languages used in heterogeneous postmodern programming environments: there is creative choice!
Like English speakers, Ruby programmers will follow contextual precedence and are bounded by syntax constraints. And when going about telling a computer to execute a simple command, they can still do so in ways that delight and surprise us.
Let’s say a Rubyist wants to reverse a word. In programming parlance we refer to that word as a “string” which represents any sequence of characters including letters, numbers, or symbols. Such a rubyist might reach for an implementation using “primitive,” “imperative” syntax constructs like a
while loop,indexed lookups, andstring concatenation. These expressions are common across different programming languages. Additionally, they yield more control and flexibility back to the programmer. To wit:counter_index = original_word.length # create empty string to contain new reversed word reversed_word = "" # start processing reversal while counter_index > 0 # decrement the counter counter_index = counter_index - 1 current_letter = original_word[counter_index] # add letter to the result reversed_word << current_letter endSo that’s one option. But looping over a string is such an everyday procedure that Ruby provides conveniences to do this with less code. In place of a while loop, index references, esoteric symbols like
<<, the Ruby language includes higher order methods: a bit of logic slurped behind a human-readable name. Likeeach_char, which means “loop over each character”. Andprepend, add something to the beginning of a string. Under the hood, Ruby implements these methods with its own primitives, likely similar to what we’ve written above. Let’s try reversal using theeach_charmethod and see how it fits:reversed_word = "" original_word.each_char do |letter| # optional debuggers # puts letter # puts reversed reversed_word.prepend(letter) endThis code is considered easier to read by many programmers because the method names makes the code’s intent obvious. Less code to mash in the mouth also means less information to pack into the brain’s working memory.
Above we see Ruby’s
do blocksyntax in action. It creates a syntactical wrapper that logically bounds each letter in a semantically associative workspace. Somewhat different than the unhinged free jazz of a while loop block with throw-away variables.Generally, declarative methods for strings can play nice together. They can be “chained” together and called sequentially. This makes it easy for a Rubyist to write concisely and fit a complete reversal procedure into one line. No need for instantiating a variable. Just push the word through multiple operations down an assembly line. Programmers verbalize this into one lining:
original_word .chars .each_with_object("") { |index, reversed_word| reversed_word.prepend(index) } .joinIt’s subtle, but there’s actually some extra processing in the above statement by transforming the original word string back and forth from an array to feed the
each_with_object. It’s conceptually funky, but since the complicatedness is hidden behind the alluring veil ofeach_with_object, the statement is still pleasantly terse.Of course, who even has all this time on their hands to f*** around. Let’s just make Ruby do all the work for us:
original_word.reverseWell, in reality, that quotidien commercial workplace, we often have more time. Because we need to build software to last. Which mean it’s uncommon to see these concise computational lines of code registered into a higher order architecture of collaborators. Our reversal code becomes a member of a reversing machine – a Ruby object – that can receive messages for requests with commands like
reverse_my_word:class WordReverseMachine def initialize(word) @word = word end def reverse_my_word @word.reverse end end # Somewhere else in my system... WordReverseMachine.new(word).reverse_my_wordAlthough, maybe my
WordReverserMachineshouldn’t be so opinionated in how it reverses things. Perhaps I want to borrow a reverse engine from other distant cyberscapes. Let’s allow our machine to swap engines as needed:class WordReverseMachine def initialize(word, reverse_engine) @word = word @reverse_engine = reverse_engine end def reverse_my_word if reverse_engine? @reverse_engine.new(@word) else word.reverse_my_word end end def reverse_engine? @reverser.nil? end end # Somewhere else in my sytem... WordReverseMachine.new(word).reverse_my_wordReversing a word is a simplistic task, which is why languages like Ruby come with a
reversemethod on allStringobjects out of the box. And yet, programmers can dream wildly different expressions as demonstrated above.Let’s take a look at the diversity of expression that unfolds from interpreting a task in a more culturally rich and relevant problem space. This is one is from an actual mess in the wild – unruly realism – where the task at hand is to look at all the products currently on sale in a restaurant website product inventory database that are not assigned to any particular menu.
Ok: so imagine this shop management software lets managers add products, but wait till later to figure out what menus those products go in. After all, does a croissant go in Breakfast or Pastries? It may not be obvious at first. Splitting up the administration of products this way creates efficiency for product inventory management and menu design. Which allows for more general flexibility and adaptability of a restaurant’s ordering experience. It lets a shop not use menus at all, or have some products in menus and some just floating on their own as standalone products.
These requirements imply that software developers working with this database will need to care about querying for products in a few different ways. Let’s play with a use case where a restaurant manager wants to display a website menu with products that are both in menus as well as a section for all other products. For example, there might be menus for Breakfast, Lunch, Dinner, and then a general list of other products under an…“Other” heading.
The software that supports this shop management software implements this data model for relating products to menus:
Marketplace Productshave manyMarketplace Tags, and these two data types are associated with each other through a bridge table ofMarketplace Product Tags. This is a fairly typical way of modeling a tagging system in a Ruby on Rails project with a relational database. Here’s what the model definitions might look like in Rails code leveragingActiveRecordas an ORM:# Product Model class Marketplace::Product has_many :tags, through: :product_tags, inverse_of: :products end # Tag Model class Marketplace::Tag has_many :product_tags, inverse_of: :tag, dependent: :destroy has_many :products, through: :product_tags, inverse_of: :tags scope :menu_tag, -> { where(is_menu: true) } scope :not_menu, -> { where(is_menu: false) } endOk: so menus, or groups of products, are formed by products sharing a
Marketplace Tagwhere a special boolean field calledis_menuis set to true on that tag.For our case, where this restaurant’s ordering page lists both products in menus and the rest beneath an “Other” heading, querying the right content for our others is the tricky part. This system allows shop managers to tag products freely. There is no restricted set of tags, or other constraints for product and tag associations. Therefore we’ll need to join across three different tables,
marketplace_products,marketplace_products_tags, andmarketplace_tags, and then collect anyMarketplace Productswhere none of their associatedmarketplace_tagshave anis_menuflag set toTRUE.Lets start the beautiful differencing!
With the help of my fellow coders at Zinc Coop with whom I workshopped this problem, I’ve cooked three ways to query our postgres database for products without a menu tag with both postgres-flavored SQL and ActiveRecord ORM. (More ways left to be discovered.)
Even if you’ve got a mature ORM like ActiveRecord at hand, it can be pragmatic to express your query in SQL so the selection logic you enshrine in code is blatantly evident. What if, for our initial cook, we code with oneness. Get the data with a single select statement. Not necessarily bravado, or premature consideration for performance characteristics just yet. Let’s see what we can do with that generative single origin
selectstart point.Mario Kart starting line count down anticipation…
select mp.* from marketplace_products mp full join marketplace_product_tags mpt on mpt.product_id = mp.id full join marketplace_tags mt on mt.id = mpt.tag_id where mp.marketplace_id = '#{id}' group by mp.id having not 't' = any(array_agg(mt.is_menu));The cleverness on the last line creates a collection of boolean markers for each
Marketplace Product–torf– representing whether the correspondingMarketplace Tagis a menu tag. The resulting row would look like{f, f, t, f}. Moving out left from the aggregate function, a filter computation is applied against the collection for any existence of a TRUE/tflag. The lispy parentheticals are sleek!Thought: while the above option foregoes a subquery, I find the combination of
group byandhavingclauses with the aggregating semantics notionally similar to a subquery insofar as we are selecting over a secondary “view” into the data.It’s dawning on us: getting all the products without menu tags is not complex, although it may have seemed tricky at the jump. We’re only narrowing the product result set based on a single condition, it’s just that the condition happens to live a distance away. Let’s try again without the single select cleverness and consider nested queries:
select mp.* from marketplace_products mp where mp.marketplace_id = '#{id}' AND mp.id not in( select mp.id from marketplace_products mp inner join marketplace_product_tags mpt on mpt.product_id = mp.id inner join marketplace_tags mt on mt.id = mpt.tag_id where mt.is_menu = true);Because we now know that this query is shallow, both wide across only a few tables, and deep with only a single subquery, let’s see if Active Record’s query interface can provide similar conveniences like we achieved above with Ruby in our toy string reversal fractals. As it turns out, we can one-line all that SQL!:
Marketplace::Product.where.not(id: joins(:tags).merge(Tag.where(is_menu: true)))This is slick, but might not be easy to come by without our previous work or deep knowledge of ActiveRecord. Our subquery version is informative for getting a mental handle on this terseness. We can reverse engineer. Notice how the entire subquery is captured in the outer parens pair. Now: the need for
mergeand passing in theTagmodel as the argument is a bit elusive because we might expect to be able to simplyjoins(:tags).where(is_menu: true). But this would error because Active Record would think we were applying thewhereclause toProductinstead ofTag, despite chaining on the join.mergeis a logical separator that let’s us filter across these two relations with more discreet semantics.Refine. Refine.
We can utilize the
is_menuscope on our Tag class, hiding ourwhere(is_menu: true)filter behind a shorthand that minimizes keystrokes:Marketplace::Product.where.not(id: joins(:tags).merge(Tag.is_menu))Ruby on Rails scopes are a brevity blessing. You can imagine where this might be going. Adding a scope for
without_menu_tagon Product will make querying and displaying results on our restaurant odering page a triviality. Dropping into the view layer we can grab the data and splat it into components with human-readable phrasing:<h1>Other</h1> <div class="grid lg:grid-cols-3 gap-3"> <%- marketplace.products.without_menu_tag.each do |product| %> <%= render Marketplace::Menu::ProductComponent.new(product:, cart:) %> <%- end %> </div>The
without_menu_tagscope can play well with other chainable scopes for quick prototyping and iteration for restaurant managers.<h1>Other</h1> <div class="grid lg:grid-cols-3 gap-3"> <%- marketplace.products.unarchived.without_menu_tag.sort_alpha.each do |product| %> <%= render Marketplace::Menu::ProductComponent.new(product:, cart:) %> <%- end %> </div>How shitty is that?
Mind meal tests your mind: do you go for the bait? If you check the Ten Gates, the ten kong-ans, does hungry mind, desire mind, not-enough-mind appear? If so, you must eat your mind meal. You must completely digest your understanding. Then finishing your mind meal is possible. Then you get enough-mind, no-hindrance mind, no I-myme mind. Enough-mind does not go for the bait, so everything is clear and you can perceive any situation in your life and kong-an clearly, and save all beings. – A DOG’S “WOOOF WOOF” IS BETTER THAN ZEN MASTER JOJU, Only Don’t Know by Zen Master Seung Sahn
-
poetry
Tu B'shvat
Sunday June 2, 2024Having made the journey from the front yard to the back, beneath the weight of the second story where morning light was filling rooms, I was comfortable with the progress of our adolescent wildflowers. Then, between the backdoor and backfence, light filled me up. The poppies are stubbornly refusing to bloom. Mild flakes of disappointment crawled up my temples. For a moment I considered the preposterous notion of watering the Redwood Tree. There, erect and looming, concentric symmetrics, wheels of blades spiraling over our rental house. Me, corrected, sighing; sharing the embarrassment with the pointed bamboo that have lived partially in the Redwood’s shadow. I decided to step into this shadow. I gazed up into the vortex of leaves. You don’t need tepid municipal sink juice. (But I’ll get some for you, over there beyond the glass. You potted co-dependents that dot the interior landscape, scrubbing and smoothing the nervy corners of brutal Puritan design. You little fuckers, in comparison.) I remember where Dottie scratched your delicate conifer skin, loomer. When she was given a chance to roam wild. Too few moments with that champion, I miss you.
I push on that spot with my imagination from a mile away through this keyboard, where Dottie, me, Redwood, and microbes have a chance encounter on earth in space. I’m reminded of one time I tried striking the Redwood. The way that you do as a martial artist who’s curious about surfaces and transfer. There had been a sharp, uneven slap from the sketched conifer texture, unwilling to participate. Or unnoticeably. More impenetrable than cement, completely full of form. Not the satisfying feedback of leather wrapped compressed textile. There are few living things that are so dense to human body sacks, I suspect.
-
poetry
Guy outside Ritual Coffee on 5/27/24, I had a hot chocolate inside
Monday May 27, 2024The guy in combat boots with adorned with a skull. He’s reading Love In the Time of Cholera, headphones crowning his head into a phone call. He’s got coffee.
-
poetry
Seung Sahn's Dropping Ashes on the Buddha, and chat with Seraph and Marshall
Monday May 20, 2024
Good morning
A man came into the Zen center and dropped ashes on the Buddha.
One hundred and fifty years ago men put metal penises in the earth and started burning fuel in earnest, beginning to fill the atmosphere with ash.
There are other men, same same men, who claim “Buddha is everything.” They are very strong and will hit you if you say otherwise. How do you fix their minds?
In a stroke of brilliance, I piped the morning meditation’s Zoom call audio through the Sonos. It’s quite silly that I’ve taken so long to figure this out. The Morning Bell Chant is now screeching across Clifford’s vocal chords.
Felicitous: pausing the onslaught on my geriatric iPhone’s speakers eliminated the rheumatic gargles and burps.
Good evening
There was a moment yesterday, around the routine crepuscular slide, when Seraph mentions how the diaspora broke us. (Sambal moves around the gums.) We broke, to assimilate. We discontinued mentions of the moon cycle’s importance in our rituals. We cleared the forest from the imagination. My chest balled up. I could cry. It had been a tough Sunday already in one of those classic disorientations of a fleeting weekend. Just as a week or two of life pressures edged to the pinnacle for a breath and place to lookout with a panoramic view. (I’m thinking of the top of Bernal hill.)
I don’t love the language of broken and fixed because it’s hard, phallic. It makes me think of split wood. (I have too many planks, not enough logs to build Atul’s workshop!) My own notional machine of my mind body conjures gushier platelets. Like a pre-cum immured into being across a white plane with a left-to-right, slightly downward stroke of a palette knife squishing a wave of paint across a plain surface. I love the way paint breaks. How air bubbles create a torn moon surface. Within this mode perhaps I’m become dabs and waves. Uneven, partial, preparation for art, art substance, also a soothing transitioning item from globular mound to wave. So that’s why it’s hard to feel broke, or whatever the reverse, some architectural rebar. Nonetheless, the near-tears I felt at the invocation of brokenness are a clear indication that the door has been shut on joy before.
-
poetry
How to read A Hacker Manifesto
Tuesday April 16, 2024McKenzie Warks' A Hacker Manifesto is so bergizi (trans from indonesian: nutrient-stuffed). So I skipped to the end notes, sue me. Reading ass backwards might be the trick here. Or spin a bottle to choose an entry point. As you make progress, reprint and scatter the individuated sections that you’ve read, then affix them to posts along Triton’s surface.
“A free yet not merely random productivity”: this sentence gets me thinking about open source collaborations.
-
poetry
The kind of extro, outside RItual coffee on Valencia
Tuesday April 16, 2024Being around people Benching just outside the coffee shop Heads pointing down Talking Tap clink Passersby entering and exiting Entering and exiting is the point
-
poetry
Machinery: Eva Hesse, her machinery
Sunday March 24, 2024
-
poetry
From Amy Kurzweil at The Ruby in San Francisco on February 29th, 2024
Monday March 4, 2024The room was cold. The light a little caustic. Acoustics wan. From the back row I had to squirm to the side to see Kurzweil’s full face. Like 17 people there, maybe? Intimate, secret, and in on it. Rugged cool!
“Paper is pleasurable.”
“My life for a while was in pages.”
“My visual secret is that all my characters look like me.”
-
poetry
Two drinks max or else
Tuesday February 20, 2024The bartender at Berreta is asking if I like bitterness and I answer yes. At this point I’m open to interpretation and open to interpretations. I get Cynar, a hefty portmanteau that smoothes out my technologies of resistance across the bar plane. An incubation space for monsters. To the right of my glass, an open challah bag is a gaping hole.
-
poetry
Sunday Prayer before heading to altitude
Sunday February 4, 2024Saying no to Lucy Ives everywhere and hitchhiking Leather Blvd. sipping cool aid
Kita anak-anak keren
-
poetry
Hangry
Wednesday January 24, 2024Can you eat here
Can you get food here
I can get food here
I will get food here
This place is too expensive for you
I will eat at this place
There is another food for you over there -
poetry
Relationships in this economy
Wednesday January 24, 2024“I didn’t realize what we had.”
He couldn’t see from the view, from within his stomach. His nerves are too high.
Well, brother, you work full-time; overtime, frequently, because it’s only a five-day work week. Your hands are full cutting a path through what the racists made today.
And brother, your Yeezies are barely scuffing the stacked monomers. Where did you come from? There are dicks the size of city blocks clouding your view. Same-day tsukumogami are drilled into the soil and rock and you trip on them.
You weren’t taught to realize her/they from the muscles between your shoulder blades, reaching behind you to turn it around, reaching in all four directions like a somaticist. Need I remind you that we only had one chance to spin the title track. (Ascenseur pour l’échafaud). You barely perceived the record pops, blocked from view. And the time that remained didn’t leave us one breath to talk about the sound before the rich were on the ballot again.
Written at the kitchen counter. My overcooked omelette lays on the cutting board. The sangha relaxing down into the sunrise and into memory.
-
2170
Kelsey Blackwell's Race and the Body: Why Somatic Practices Are Essential for Racial Justice
Thursday January 18, 2024“Racism is a visceral experience” - Coates
&&
“Including the body…towards social justice…is the primary path forward” - Blackwell
&&
“We focused our efforts in the wrong direction…white supremacy doesn’t live in our thinking brains…it lives and breathes in our body.” - Resmaa Menakem
&&
“The only path forward requires dismantling who we think we are.” - Blackwell
&&
“The body…says, this is true…this is happening…this is honest.” -Blackwell
“Few skills are more essential than the ability to settle your body.” - Menakem
{ This one. A superpower. Also, settle your body vs settle on your body or your land vs settle an argument. }
“There’s a saying in Guinea that ‘knowledge is only rumor until it’s in the muscle.'” - Blackwell
“Rocking, humming, and making physical contact with each other…” - Blackwell
{ Sitting, bowing, chanting, walking, eating, cooking, cleaning. To retreat, to practice. To leap like a tiger while sitting. }
-
2170
Class warfare on Duolingo 🌹
Tuesday January 2, 2024
-
speculative nonfiction
My sparse margin note couplet from Jon Bentley's Programming Pearls, also bit of a book review, and a whole ass
Friday December 22, 2023
In 2015 I bought this book. 7, or 8 years ago. Year one into my software career. This book is canon. I've had little use for its studies of algorithms. # thus far, see below I don't think Bentley would be offended. First sentence: "Computer programming has many faces."I’m sure I glanced at its pages before entering the corporate interview gauntlet to get in the vigilante mood. To shake out the shoulders, find some relaxment, whilst staring down a twenty two minute treadmill run or pile of laundry Sunday evening. You must to armor up for the algos in the kingdom of men.
While Bentley’s pearls are the type of polished wisdom earned through real life experience we get on the job, this book never became the vade mecum for my quotidian affairs. Is it for others? What comes after Part I was too metallic for an early-career front-end Rails dev.
Yet, the book can be pragmatic for all ages – see 3.2 Form-Letter Programming!. The fantastic headings are pedagogically caring. It is sensually satiated with geeked thoroughness. The cases are actually well-situated within the real-world: Bentley spoils you with further readings and sidebars, journalistic first-hand-accounts that remind you of how the metal has been worked over by a person’s hands.
It reminds you that software is not lonely, which is important.
But beware: there’s a modest amount of myth-making for his contemporaries and mentors. Yet, they are the most honest plagiarisms. Yes/and: he’s humbler than many. (Perhaps it is worth another pass now that I have more years in the rear view).
I am a visual learner and thinker: logical word-problems were always a pain. In recent years I tend to reach for Bhargava’s Grokking Algorithms for a refresher on binary search or walking trees. It has cute pictures. It’s stacked next to other faves like Land of Lisp and Why’s (Poignant) Guide to Ruby.
Hmmm (thinking emoji, I will not look you in the eye as I cock my head buried in thoughts). After all, the solstice konmari of my bookshelf – which I thought would elicit a reflection on some forgotten paper taking up space – has become the discovery of lost treasure. And yet, I’m still tickled by the scant amount of notes taken. I can’t read without a pen. Perhaps we’re time-traveling, then.
It's year one. Young Rails dev. He makes only two liner notes in a book considered staple grocery. I don't remember if I even read the whole thing. I bet I got through Part 1's wider lens, then started to gloss over.One note is an exaggerated check mark next to this principle listed on p29 (Second Edition, published 2000):
Rework repeated code into arrays. A long stretch of similar code is often best expressed by the simplest of data structures, the array.
With “the array” also underlined from the outer left edge of the “t” to the outer right edge of the last “a.”
This one has stuck. Arrays, especially maps, can be more durable when staring down change. Before long any thoughtful software developer will realize that the components of a software system will become ordered and/or multiple.
There is no lonely software.
Data, whether as scalar, “bags” of properties, even subroutines and processes, even the manual lever pulling human tasks must be sequenced, serial, bound, reversed, indexed, sorted. The maintenance cost of housing data in ordered collections is generally low.
[<anything>, <anything>]Whole ass languages, like Clojure, were designed to favor ordered, associative arrays. As I learned after finding Hickey’s seminal talk Simple Made Easy. Richly simple and luxurious as Hockney’s bathers.
A second mark: a vertical line next to the opener for section 12.2 One Solution. This was (yet another moment in my lifetime) I learned that we never have to go it alone when staring down the void of what we’re building next:
As soon as we settled on the problem to be solved, I ran to my nearest copy of Knuth’s Seminumerical Algorithms (having copies of Knuth’s three volumes both at home and at work has been well worth the investment).
This has also stuck, reified after seasons.
-
rutabagas
Rutabagas Vol. 3: The Softest Ware: Is
Friday December 15, 2023-
What are probably appropriate attacks on assigning calamity to the hand-wavy concept of “human error”. Lorin strengthens his theory that human error probably doesn’t exist by considering complex, fault-tolerant systems like Amazon S3 incapable of receiving “human error” as apology or eulogy when there’s a hard drive failure.
-
WHAT. Secret guerrilla human rights interventions by the artist collective GALA Committee on Melrose fucking Place.
For three years, as the denizens of the Melrose Place apartment complex loved, lost, and betrayed one another, the GALA Committee smuggled subversive leftist art onto the set, experimenting with the relationship between art, artist, and spectator. The collective hid its work in plain sight and operated in secrecy. Outside of a select few insiders, no one—including Aaron Spelling, Melrose’s legendary executive producer—knew what it was doing.
- There are widely acknowledged “hard things” in software development, but the pith used to describe them usually falls short or flat for me. But in less than 100 words jenniferplusplus achieves serious depth:
It’s a little bit shitposty, but it’s 100% true. People think cache invalidation is hard because it has no right answer, so it’s a question of iterating until you get a right-enough answer.
People think naming things is hard because it’s about communicating with each other.
People don’t even think about managing dependencies. It’s invisible. It’s about cooperating across time and organizations to do maintenance chores. It’s so hard and so unglamorous that people can’t even see it.
What’s important to observe here is (the appropriate, warranted, overlooked) framing of these software problems as social problems, not logical puzzles or struggles with language and framework semantics. Even cache invalidation, despite being a requirement in nearly any useful application that nearly every developer must address, escapes a general solution – meaning developers must continuously arrive at socially acceptable, technically sufficient solutions – but not total – as the seasons change and the desires of forces and actors in the system change. There is always more than one person at large in negotiating the solution, if even only a developer and a single someone using the software.
- jenniferplusplus again, but this time bringing Peter Naur’s lasting insights into the AI conversation: programming is theory building. Software developers are quickly discovering the usefulness of LLMs trained on code to assist in some of their more menial daily work – especially when working with common constructs (languages, frameworks) that are personally unfamiliar – but it’s hard to imagine LLMs replacing the core intellectual work which requires understanding: like the socially syrupy hardness they discuss in the above toot. Although we might imagine a generative computer program giving semi-useful suggestions for the complex|complicated|sophisticated|confusing real-world development scenarios if trained on the correct historical inputs for that milieu; and if you were stuck in a vacuum somewhere without recourse to more senior colleagues who possess similar tokens of guidance to steer you toward the right away to handle background jobs (without such an exhaustive cataloging as you’ll see ChatGPT 3.5 vomit below):
Handling background jobs is a common requirement in software development, especially in scenarios where certain tasks need to be executed asynchronously or in the background to avoid blocking the main application thread. There are various ways to handle background jobs, and the choice often depends on the specific requirements and the technology stack being used. Here are some common approaches: Task Queues: Message Queues: Use message queuing systems like RabbitMQ, Apache Kafka, or Redis to enqueue and dequeue tasks. Popular libraries for this approach include Celery (Python), Sidekiq (Ruby), and Resque (Ruby). Job Queues: Platforms like AWS Simple Queue Service (SQS) or Google Cloud Tasks can be utilized to manage queues of tasks. Asynchronous Programming: Async/Await: In languages that support asynchronous programming (e.g., Python with asyncio, JavaScript with Node.js), you can use async/await to perform tasks concurrently without blocking the main thread. Multithreading/Multiprocessing: Use threads or processes to run background tasks concurrently with the main application. Be cautious with shared resources and synchronization. Background Job Processing Frameworks: Delayed Job Processing: Libraries like Sidekiq, Delayed Job (Ruby), or Hangfire (.NET) allow you to schedule and execute background jobs at a specified time or after a certain delay. Job Scheduler: Tools like cron (Unix/Linux) or Windows Task Scheduler (Windows) can be used to schedule recurring background jobs. Serverless Computing: Functions as a Service (FaaS): Platforms like AWS Lambda, Azure Functions, or Google Cloud Functions enable you to run individual functions in the cloud without managing the underlying infrastructure. Database-backed Queues: Database Queues: Store tasks in a database table and have worker processes periodically check for and process these tasks. This approach can use a library like Active Job (Ruby on Rails) or Hangfire (C#). Container Orchestration: Kubernetes: Container orchestration platforms like Kubernetes can be used to deploy and manage background job processing containers. Job Management Services: Job Management Platforms: Use specialized services like Jenkins, CircleCI, or GitLab CI/CD for scheduling and executing background jobs. Webhooks and Event-Driven Architectures: Event-Driven: Design your system as an event-driven architecture, where background tasks are triggered by events. Webhooks can be used to notify the system of events. Choose the approach that aligns with your application's architecture, scalability requirements, and the specific nature of the background tasks you need to handle. Keep in mind factors such as reliability, scalability, and ease of maintenance when making your decision.Quoting Nauru’s seminal vintage paper (1985, the year my brother was born):
The fundamental task of software development is not writing out the syntax that will execute a program. The task is to build a mental model of that complex system, make sense of it, and manage it over time.
So anyway this post is both a big “thank you” to the many nerds who are chill and easygoing and joyful, and an exhortation to others to free yourself of contemptuous, competitive attitudes, and re-embrace the intellectual curiosity that presumably once brought you into programming in the first place.
-
-
2170
Goings on about town: Iowa teen grew 7,000 pounds of veggies, then gave them all away
Friday December 15, 2023Over morning coffee, mixed with used iron goddess king tea leaves. Questions about things in paper.
kopi pagi tambah daun teh raja dewi besi
Why ya why ya why ya why ya why ya wanna why ya wanna
- Some people just have acres of arable land lying around to play with
- Why didn’t Lauren work with her family to give this land back to indigenous tribes? In 2022 tribes finally won 7 acres back after 200 years. If the Schroeder’s gave back their 2 acres, they would increase the footprint of sovereign native lands in Iowa by 30%.
- What happens if Lauren loses interest in this project? Or goes off to college? Will the people served by the food banks and other orgs she’s supporting suffer as a result?
- How is hunger an issue in a heavily agricultural state?
- Is this an acceptable form of child labor, especially with her two siblings also working with her?
- I wonder if Lauren offered the unnamed domestic violence survivor a chance to help with the project and give her kids a chance to grow their own food again.
Why did Dr. J shave his beard and mustache?
-
poetry
Modern cities are inhuman: Vol 1
Wednesday December 13, 2023 -
poetry
Le Guin on write what you know
Monday December 4, 2023
-
poetry
I slept pretty well last night
Monday December 4, 2023

