<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"><url><loc>https://jbnjs.com/</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/about</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/search</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2026</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2025</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2024</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2023</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2022</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/y/2021</loc><changefreq>weekly</changefreq></url><url><loc>https://jbnjs.com/notes/the-year-i-stopped-chasing-the-framework</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-framework.jpg</image:loc><image:title>The year I stopped chasing the framework</image:title><image:caption>Angular, React, whatever is next. Prototype where it adds value. Do not chase the logo.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/eleven-years-of-building-still-curious</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-eleven.jpg</image:loc><image:title>Eleven years of building, still curious</image:title><image:caption>A 2026 look back — fresher at Knowledge Lens, TPM at Rockwell, still learning by shipping.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/a-blog-i-actually-maintain</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-blog.jpg</image:loc><image:title>A blog I actually maintain</image:title><image:caption>Markdown, FastAPI, React. Own the archive. Not a SaaS theme.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/agents-edit-files-they-do-not-own</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-files.jpg</image:loc><image:title>Agents edit files they do not own</image:title><image:caption>Scope, secrets, PRs. The agent has no memory of the customer.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/what-i-still-verify-by-clicking</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-click.jpg</image:loc><image:title>What I still verify by clicking</image:title><image:caption>Generated UI that looks right. You still click empty, error, and mobile.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/still-full-stack-as-a-tpm</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-tpm.jpg</image:loc><image:title>Still full stack as a TPM</image:title><image:caption>Leading delivery without losing the ability to open the code.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-note-i-still-write-by-hand</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-hand-note.jpg</image:loc><image:title>The note I still write by hand</image:title><image:caption>Agents draft the recap. I still copy the decision into a notebook before I send it.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/performance-work-the-model-cannot-see</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-perf.jpg</image:loc><image:title>Performance work the model cannot see</image:title><image:caption>It suggested memoization. The cost was fonts and an unindexed query.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/you-still-need-the-map</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2026-map.jpg</image:loc><image:title>You still need the map</image:title><image:caption>Agents edit files. They do not know why billing is denormalized.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-demo-that-worked-on-the-laptop</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-demo.jpg</image:loc><image:title>The demo that worked on the laptop</image:title><image:caption>Staging data, a seed, and the network that was not my home Wi-Fi.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-summary-that-skipped-the-migration</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-migration.jpg</image:loc><image:title>The summary that skipped the migration</image:title><image:caption>A fluent write-up, no rollback, and a PR I almost trusted because it read so well.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/what-i-still-refuse-to-let-a-model-decide</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-refuse.jpg</image:loc><image:title>What I still refuse to let a model decide</image:title><image:caption>Auth, money, deletions, and anything I cannot undo in one deploy.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/a-team-that-uses-models-differently</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-team-models.jpg</image:loc><image:title>A team that uses models differently</image:title><image:caption>Shared hygiene: secrets, review, and the work we still do without a prompt.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-generated-ui-that-almost-compiled</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-generated-ui.jpg</image:loc><image:title>The generated UI that almost compiled</image:title><image:caption>Last year's component API, a green chat, and a screen that lied until I clicked it.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/shipping-with-an-agent-without-shipping-its-taste</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-agent-taste.jpg</image:loc><image:title>Shipping with an agent without shipping its taste</image:title><image:caption>I write the shape. It fills. Then I delete the tutorial voice.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/designing-is-the-heart-of-development</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2025-design.jpg</image:loc><image:title>Designing is the heart of development</image:title><image:caption>Empty states, permissions, and the failure path the mock never showed.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/they-asked-for-a-colour-and-the-schema-needed-a-state</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-schema-state.jpg</image:loc><image:title>They asked for a colour and the schema needed a state</image:title><image:caption>The stakeholder wanted orange. What they meant was a row we had never stored.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/databricks-in-the-delivery-loop</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-databricks.jpg</image:loc><image:title>Databricks in the delivery loop</image:title><image:caption>The web app sat on top of a warehouse. I had to get my hands in it, not only schedule the job.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/leading-multiple-web-application-projects</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-tpm.jpg</image:loc><image:title>Leading multiple web application projects</image:title><image:caption>TPM across tech, teams, customers, and delivery — context switching without dropping the thread.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/two-customers-one-calendar</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-two-customers.jpg</image:loc><image:title>Two customers, one calendar</image:title><image:caption>Both wanted that week. Neither was wrong. The calendar was the product.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/a-good-prompt-is-a-good-ticket</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-prompt.jpg</image:loc><image:title>A good prompt is a good ticket</image:title><image:caption>Context, files, what not to touch, and how we will know it worked — the same spec I already owed the team.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/copilot-made-me-faster-and-worse-at-explaining</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-copilot.jpg</image:loc><image:title>Copilot made me faster and worse at explaining</image:title><image:caption>I merged a function I could not walk through in standup. The tests were green.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/how-to-upskill-the-team</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-upskill.jpg</image:loc><image:title>How to upskill the team</image:title><image:caption>Pairing, a first ticket that is real, and reading the scary part of the stack together.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/how-to-encourage-the-team</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-encourage.jpg</image:loc><image:title>How to encourage the team</image:title><image:caption>Noticing the hard week, credit in the room that counts, and a small win that actually shipped.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/done-means-the-empty-state-too</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-empty-state.jpg</image:loc><image:title>Done means the empty state too</image:title><image:caption>Green pipeline, happy path on my laptop, and a first-time user staring at a blank table.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/leadership-qualities</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2024-leadership.jpg</image:loc><image:title>Leadership qualities</image:title><image:caption>Clarity, a Friday deploy that went quiet, and the next step written on the board.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-customer-call-that-rewrote-the-ticket</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-customer.jpg</image:loc><image:title>The customer call that rewrote the ticket</image:title><image:caption>The solution was already in the sprint. Then a stakeholder said how they actually work.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/elasticsearch-when-the-table-could-not-take-it</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-elasticsearch.jpg</image:loc><image:title>Elasticsearch when the table could not take it</image:title><image:caption>The dashboard was honest. The SQL was not fast enough to stay honest.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/docker-and-the-deploy-that-was-not-ftp</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-docker.jpg</image:loc><image:title>Docker and the deploy that was not FTP</image:title><image:caption>Compose, env per stage, a checklist, and a rollback that was not 'copy the old folder back'.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/same-work-a-different-badge</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-rockwell.jpg</image:loc><image:title>Same work, a different badge</image:title><image:caption>Knowledge Lens was acquired. The craft did not reset. The org chart did.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/collaboration</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-collaboration.jpg</image:loc><image:title>Collaboration</image:title><image:caption>Frontend, backend, and product in the same week — 45 minutes of contract, not eight hours of waiting.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-rollback-i-wrote-before-the-click</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-rollback.jpg</image:loc><image:title>The rollback I wrote before the click</image:title><image:caption>The migration was ready. The undo was not. That was the actual work.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/why-requirement-gathering-is-so-important</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-requirements.jpg</image:loc><image:title>Why requirement gathering is so important</image:title><image:caption>We built it right. It was still wrong. The states and the users were never in the ticket.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/estimates-that-died-on-the-frontend</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-estimates.jpg</image:loc><image:title>Estimates that died on the frontend</image:title><image:caption>Backend said two days. Then came empty, error, mobile, and the plant Wi-Fi.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/owning-one-vertical-button-to-migration</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2023-vertical.jpg</image:loc><image:title>Owning one vertical: button to migration</image:title><image:caption>Design, API, migration, and the rollback I wrote before I touched production.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/sql-that-scared-the-frontend-engineer</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-sql-scared.jpg</image:loc><image:title>SQL that scared the frontend engineer (also me)</image:title><image:caption>I loaded the table into the browser and filtered it. Then the table had real rows, and JavaScript was not a database.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-first-api-i-designed-from-the-screen-backward</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-screen-api.jpg</image:loc><image:title>The first API I designed from the screen backward</image:title><image:caption>I mocked the page first. Five round-trips later I admitted the endpoint should look like the screen.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/teaching-the-difference-between-state-and-storage</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-state-storage.jpg</image:loc><image:title>Teaching the difference between state and storage</image:title><image:caption>I called localStorage a cache. Two tabs taught me it is a shared disk with no opinions.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/auth-that-looked-like-a-checkbox-until-refresh-tokens</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-refresh-tokens.jpg</image:loc><image:title>Auth that looked like a checkbox until refresh tokens</image:title><image:caption>Remember me was a tick box. Safari, a dead logout, and a refresh token we could not kill.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/when-the-ui-was-honest-and-the-data-model-was-lying</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-data-model.jpg</image:loc><image:title>When the UI was honest and the data model was lying</image:title><image:caption>The badge said Approved. The row had two timestamps and no word for what we were showing.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/the-bug-that-lived-in-three-layers</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2022-three-layers.jpg</image:loc><image:title>The bug that lived in three layers</image:title><image:caption>UI said done, API said 200, the job said success. One request id showed they were lying together.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/authentication-vs-authorization</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-auth.jpg</image:loc><image:title>Authentication vs authorization</image:title><image:caption>Login is not permission. 401 is not 403. The endpoint still ran after we hid the button.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/rbac-system-implementation</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-rbac.jpg</image:loc><image:title>RBAC system implementation</image:title><image:caption>Roles vs permissions, a hidden button, and the admin shortcut I regretted.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/importance-of-responsive-web-design</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-responsive.jpg</image:loc><image:title>Importance of responsive web design</image:title><image:caption>The toolbar wrapped, the table overflowed, and I stopped designing only for my laptop.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/modern-web-application-development</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-modern-web.jpg</image:loc><image:title>Modern web application development</image:title><image:caption>In 2021 "modern" for us was SPA plus API, a real database, env files, and a deploy that was not FTP.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/hands-on-reactjs-project</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-react.jpg</image:loc><image:title>Hands-on ReactJS project</image:title><image:caption>After Angular, the page looked simple. Then the form submitted twice and the list showed yesterday's row.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/starting-a-new-project-with-angular</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-angular.jpg</image:loc><image:title>Starting a new project with Angular</image:title><image:caption>ng new, a fat src folder, and the first time I trusted the CLI more than my own folders.</image:caption></image:image></url><url><loc>https://jbnjs.com/notes/cors-issues-and-how-to-solve-them</loc><lastmod>2026-08-27</lastmod><changefreq>monthly</changefreq><image:image><image:loc>https://jbnjs.com/uploads/2021-cors.jpg</image:loc><image:title>CORS issues and how to solve them</image:title><image:caption>Working in my machine it was fine. Chrome on staging had other plans.</image:caption></image:image></url></urlset>