You Don't Have an AI Problem You Have a Thinking Problem.
I used to think AI was making me lazy. I was wrong. AI wasn't making me lazy I was using AI as an...
找到 271 篇相关文章
I used to think AI was making me lazy. I was wrong. AI wasn't making me lazy I was using AI as an...
Angular v22, Google's TypeScript-first framework, has introduced API stabilizations, ergonomic templates, and tooling enhancements for AI integration. Key developments include the stabilization of Signal Forms, improved change detection strategies, and a new @Service() decorator for dependency injection. The release supports TypeScript 6 and removes deprecated features. By Daniel Curtis
The AI policies across the Linux ecosystem are very heterogeneous, ranging from the GCC’s restrictiveness, the Linux kernel’s pragmatism, to the more open disclosure-based utility model of Kubernetes' landscape. From core infrastructure to high-level orchestration, these distinct approaches highlight a shared commitment: ensuring the human maintainer remains the indispensable guardian of the code. By Olimpiu Pop
Originally published on hexisteme notes . A predecessor note diagnosed three production features that passed every dedicated unit test and never executed at all, and why a unit test structurally can't see that gap. That note answered three cases I already knew about, because I'd already tripped over them. It didn't answer the question that matters once you've found three: how do you find the rest — the ones nobody happened to notice yet? This is that search: the tool that actually works, what it found across seven projects, and a fourth failure shape that the predecessor note's two fixes don't reach at all, because in that fourth shape the code was never the thing that was broken. The query, before the argument Before any of the specifics, here is the shape of the query, so you can run something like it against your own tables in under a minute: SELECT COUNT ( * ) AS total , SUM ( some_column IS NOT NULL ) AS filled FROM some_table ; If that comes back near 100%, this note may simply not apply to your codebase, and that's a real result, not a failure to reproduce it. Keep that in mind through the rest of this — every finding below is downstream of a query shaped like this one, not downstream of reading code and guessing. Grep is not the detector My first instinct, the same one the predecessor note's fixes point toward, was to grep for the failure shape — a default value, an unpopulated argument, a call site missing a keyword. In one afternoon it produced both a false positive and a false negative. The sharper miss: a literal grep for a write path failed to find an INSERT OR REPLACE statement that was, in fact, live and doing exactly the writing I was looking for. Grep matched the shape of the bug I expected walking in, not the shape the code actually had. Everything that survived scrutiny below came from asking a database a question, not from asking a shell how a string was spelled. The question that works is: of all the rows that exist, how many have this column fi
Originally published at https://ninadpathak.com/articles/technical-documentation-template/ . Creating documentation often forces several decisions at once: where readers begin, how they complete the first task, where exact details belong, and how they recover when a step fails. A template reduces that first pass to a structure you can inspect and adapt. I built this template to solve a narrow problem: an empty documentation repository leaves every contributor to invent navigation, page responsibilities, and release checks again. It provides five focused pages, a local validator, and a strict build path so the structure is useful before the product-specific writing begins. Download the technical documentation template Download the template Unpack the archive, then replace the placeholders with evidence from your product. The remaining sections show what belongs in each page and how to verify the result. What a technical documentation template should include A technical documentation template is a reusable starting structure for product or engineering documentation. It should tell a contributor where a reader begins, where they complete a task, where they look up stable details, and where they recover from a known failure. A table of contents alone cannot do that work. It can label a page “Getting started” without establishing prerequisites, a tested command, an expected result, or a recovery path. The starter contains five pages because they create a complete first route without pretending every product needs the same collection. Page Reader job Evidence to add before publishing index.md Choose the first useful task A direct route to the right starting page getting-started.md Complete first setup Prerequisites, a tested command, expected output guides/send-a-request.md Perform one bounded task A full request and response or observable state reference/configuration.md Look up stable details Names, types, defaults, and constraints troubleshooting.md Recover from a know
My expense app finally has a point of view on what I'm spending money on. No AI yet — just honest keyword rules, a nullable column, and one interface that means I can bolt an LLM on later without ripping anything out. Here's the build, three "empty value" bugs that bit me, and the habits that kept it clean. Index Where we left off The plan: rules first, AI behind the same door Step 1 — A nullable column (and why nullable matters) Step 2 — The migration: generate → review → apply Step 3 — A dumb-but-working categorize() Step 4 — Wiring it into create (with override precedence) Step 5 — The seam: extracting behind a Categorizer interface Step 6 — The UI loop: show, add, edit 🐛 The war story: three ways "empty" lied to me Thinking like an attacker Learning shortcut vs. production Key habits to keep Next up: Phase 7b Where we left off Phase 6 gave me the receipts — date-range reports and CSV export. I ended that post with a promise: Next up: Phase 7, where categories finally enter the schema and the app starts to get opinionated about what I'm spending on. This is that. But it turned into a bigger beast than one post, so I'm splitting it: Phase 7a (this post): the schema, a rules-based categorizer, the interface seam, and the full UI loop. Phase 7b (next): the actual LLM — an LLMCategorizer that slots in behind the same interface, with caching and a rules fallback. Doing rules first isn't a cop-out. It's the whole strategy. The plan: rules first, AI behind the same door The temptation with "AI categorization" is to reach straight for the API key. I didn't. Here's the order I actually built in, and why: Step What Why this order 1 Nullable category column The app needs somewhere to store a category before it can fill one 2 Rules categorize() A working, free, offline fallback — and a baseline to test against 3 Extract behind an interface So the LLM can slot in later without touching call sites 4 UI loop (show / add / edit) Give the human final say, no matter how smart the
I'm a few months into a job search after a layoff, and I kept running into the same two problems: I was spending too long deciding whether a job listing was worth my time, and my resume was drifting out of sync with what was actually landing in interviews. So I built two Claude Code skills , reusable, file-based instructions Claude Code follows every time I invoke a slash command, to close both gaps. This is a walkthrough of how they work, why they're structured the way they are, and what I learned building them. If you haven't used Claude Code skills before: a skill is just a markdown file with YAML frontmatter ( name and description ) that lives in .claude/skills/{skill-name}/SKILL.md . The description field is what Claude uses to decide when to trigger the skill automatically, and you can always invoke it explicitly with /skill-name . The problem Job searching produces a lot of repetitive judgment calls: Is this listing worth 20 minutes of my time? Every JD needs to be read against my actual background, not against wishful thinking. Once I've scored 30+ listings, what do they add up to? Patterns emerge: the same gap gets flagged five times, the same bullet gets written from scratch in every cover letter, but nobody's collecting those patterns into resume improvements. Two skills, one for each problem: /score-job and /resume-sharpener . They're designed to work as a pair, the first generates raw signal, the second mines it. Skill 1: /score-job Input: paste a JD or give a URL. Output: one markdown file, job-search/scored-listings/YYYY-MM-DD-{company}-{role}.md . Reading the right context every time The skill starts by reading a fixed set of source files in parallel: my resumes (I keep four: engineering, PM, FDE/presales pivot, and a PeopleSoft-specific one), a profile doc, a skills inventory, and a filters doc that encodes what counts as a disqualifier. Critically, it re-reads these every run rather than caching anything, because they evolve as I update my resume o
Cloudflare has introduced Cloudflare Computer, a new open-source runtime designed to give AI agents something closer to a real "computer" instead of just ephemeral containers. It leverages Cloudflare isolates for fast serverless execution, making agents cheaper, faster, and more scalable, according to the company. By Sergio De Simone
Uno Platform 6.6 introduces Native AOT publishing across five target platforms, an optional Vulkan rendering backend, and automatic registration for the framework’s Model Context Protocol servers. The release also reduces XAML boilerplate, expands cross-platform WinUI API coverage, and improves accessibility and multilingual text handling. By Edin Kapić
npm has introduced staged publishing for Node.js, requiring maintainer approval before a version is installable. Versions are queued and must pass a two-factor authentication challenge for release. This feature aims to enhance security amid rising supply chain threats. It is available in npm CLI 11.15.0+ and Node 22.14.0+, alongside new configurable permission flags. By Daniel Curtis
📑 Table of Contents Introduction Why We Created ValidX? Why Choose ValidX? 5-Minute Quick Start Multilingual Support Important: Null/Empty String Handling Thread Safety Supported Validation Annotations Quick Reference Table Basic Validation Identity Validation Financial Validation Education/Professional Qualification Network Validation China-Specific Validation Automotive Validation Book-Related Validation Mobile Device Validation More Validation Annotations Contribution Introduction ValidX is an open-source Java validation library focused on Chinese business scenarios, making validation simple, elegant, and reliable. Built on JSR-380 standards with 90+ specialized annotations for Chinese identity cards, phone numbers, bank cards, and more. 💡 Why We Created ValidX? When developing applications for Chinese users, we frequently encountered these challenges: Pain Point 1: Java Has Too Few Built-in Validation Rules, Far Less Than Other Language Frameworks If you've used web frameworks in other languages, such as PHP's ThinkPHP or JavaScript's Validator.js, you'll notice they come with incredibly rich built-in validation rules: mobile , idcard , zip , alphaNum , etc.—ready to use out of the box, simple and convenient. But in the Java world, standard Bean Validation only provides a handful of generic annotations like @Email and @Pattern . For common Chinese business scenarios—identity cards, phone numbers, bank cards, unified social credit codes—there's absolutely no support. This forces every Java project to reinvent the wheel: Writing complex regular expressions yourself Implementing Luhn algorithm for bank card validation Handling identity card check digit calculations Copy-pasting validation code found online Why can't Java validation be as ready-to-use as other frameworks? This is why ValidX was born. Pain Point 2: Scattered Validation Logic Difficult to Maintain As projects grow, validation logic becomes scattered across: Manual validation in Controller layer Busine
We had a checkout test at my last job that everyone called "the coin flip." Green for a week, red twice on a Tuesday, green again. Someone eventually wrapped it in a retry and it sat like that for eight months before anyone looked at it again. Turned out the real bug was a webhook that occasionally fired before the order record finished writing to the DB - a two-hundred-millisecond gap that only showed up under load. The test wasn't broken. It was the only thing in the entire pipeline that noticed. That's usually the story. Someone blames the test - bad selector, missing wait, a sleep(2) some intern left in there three years ago, and half the time they're right. But when a test flakes repeatedly and nobody can explain why, the test is rarely the actual problem. It's just the part of the system rude enough to say something. A few places I keep finding the real cause hiding. Tests that quietly depend on each other Test A writes a row, Test B reads it and never knew it needed to. Run B by itself, it passes. Run the suite in a different order, or in parallel, and B fails for no reason anyone can point to. I've lost a full afternoon to this exact thing more than once - a cache value from Test 12 leaking into Test 47. The actual fix is annoying and unglamorous: every test gets its own fixtures, its own scoped data, no assumptions about what ran before it. If your suite only goes green in one specific order, you don't have a flaky test. You have an undocumented dependency graph, and it's going to bite someone eventually. The app is racing, not the test Click a button, immediately assert on the result - that's a bet that the UI update lands the instant the click handler returns. It usually does, on your machine, on a good day. Add a debounce, a background job, or just enough network latency and that bet stops paying off. This one's frustrating because the test isn't being paranoid. The app genuinely has a race condition. The test just runs the interaction often enough, acro
Vercel Labs has introduced Zero, an experimental systems programming language aimed at AI rather than human users. It employs unique features like a specific toolchain contract and structured error messages. Reaching version 0.3.4, it compiles to native binaries for major operating systems. The language prioritizes size, speed, and agent usability, though it is still in development. By Daniel Curtis
🎯 What a “Stacked PR” Is (and Why You’ll Want One) A stacked pull request (sometimes called a stacked PR , stacked diff , or dependent PR ) is a series of PRs that build on top of each other, each one containing a small, logically‑isolated change. main ──► A ──► B ──► C │ │ │ │ │ └─ PR‑C (depends on B) │ └─ PR‑B (depends on A) └─ PR‑A (directly on main) A is based on main . B is based on A (its head). C is based on B , etc. When you eventually merge the stack in order (A → B → C), each change lands cleanly, and reviewers can focus on one cohesive piece at a time. Why Stack PRs? Problem Stacked PR Solution Huge, monolithic PRs that are hard to review & cause long CI times Break the work into bite‑size PRs (e.g., “feature flag”, “data model”, “UI”) Inter‑dependent changes (e.g., a new API + its consumer) Each dependent change lives in its own PR, but they still get tested together because they are built on top of each other Rebasing on main constantly drags in unrelated changes Only the bottom PR needs to be rebased onto main ; the rest stay on top of it Need to ship part of a larger change early Merge the first PR in the stack; the rest stay pending until they’re ready CI resources Only the bottom PR runs the full suite against main ; higher PRs can run a lighter subset because they already passed lower‑level tests 📦 The Landscape of Tools (as of 2026) Tool / Service Key Features Installation / Setup Typical Workflow ghstack (GitHub CLI plugin) - Creates stacked PRs automatically from a series of commits. - Handles base‑branch updates, resolves merge conflicts, and can re‑stack after rebases. - Works with GitHub's GraphQL API, so you get “dependent PR” links in the UI. pip install ghstack (or brew install ghstack ). Requires a personal access token with repo scope. bash git checkout -b feature/stacked\n# create many commits …\nghstack push\n# later, after rebasing on main\nghstack rebase . | | GitTown (aka git-town ) | - git town ship can ship a stack of dependent br
Microsoft and Uno Platform have released the first stable versions in the SkiaSharp 4 series, beginning with SkiaSharp 4.148.0 and followed shortly afterward by 4.150.0. A 4.151.0 prerelease line is also available, demonstrating the project’s new approach of aligning package versions and release cadence with upstream Skia milestones. By Edin Kapić
I built a free tool that checks a supplier before you pay them. The part that took most of the work, and taught me most, was reading ten national company registers instead of relying on the EU's own VIES service. This is what I found out, mostly so the next person doesn't have to. The problem with "the VAT number is valid" VIES — the European Commission's VAT Information Exchange System — answers one question: is this VAT number currently registered. That sounds like the question you want answered. It isn't. A company that has gone into liquidation keeps a cleanly resolving VAT number in VIES. So does one that has been struck off the register. Deregistration and insolvency are run by different authorities on different timetables, and the gap between "this company has stopped being a going concern" and "the VAT number stops validating" can be months. So you can check a supplier, get a green tick, and be looking at an insolvency estate. The national registers know. VIES doesn't ask them. Ten registers, and what each actually gives you I found free, public, machine-readable-enough sources for ten countries: Bulgaria, Czechia, Estonia, Finland, France, Greece, Latvia, Poland, Romania and Slovenia. They are not equivalent, and this is the thing I'd have liked written down somewhere before I started: Six of them report company *state * — inactive, in liquidation, bankrupt, insolvent, terminated, ceased, struck off: Romania, Estonia, France, Greece, Bulgaria, Latvia. This is the valuable one. Three report whether the company is actually VAT-active — Poland, Romania, Slovenia. That matters more than it sounds, because VIES does not distinguish "this is a real company that isn't VAT-registered" from "this number belongs to nobody". The rest give you a name and not much more. Czechia, for instance, is in the ten but in neither of the other two groups. It confirms a name. That's it. Worth knowing before you build a feature around it. Poland is the interesting one Poland is the
Quotient CEO Lizzie Matusov explains why soaring AI spend often fails to improve software delivery. She presents a research-backed AI maturity framework designed to help engineering leaders move beyond vanity metrics like token usage, align organizational AI adoption, and address critical bottlenecks across the software development life cycle to deliver measurable business outcomes. By Lizzie Matusov
Version 5.0.0 of eslint-rspack-plugin has been released as a pure ESM package, aligning with the Rspack ecosystem and removing its CommonJS build. The plugin continues to integrate ESLint in the build process but may affect build times. Users are advised to consider separate linting commands for efficiency. The project is open source and available via npm. By Daniel Curtis
Problem Description Merge multiple structurally similar tables with different column names into a wide table using full outer joins by common ID. Four tables have similar structures, each with two fields. The fields have the same meaning but different names (id, id2, id3, id4 all represent ID). The goal is to merge the four tables into single rows by ID, with each ID appearing in exactly one row. When an ID is absent in a table, the corresponding columns take NULL. Source Data T1 table: T2 table: T3 table: T4 table: * Expected Result * For example, ID=555 appears in both T1 and T2 but not in T3 or T4, so id, colA, id2, colB have values, while id3/colC/id4/colD are NULL. ID=222 only appears in T3, so only id3 and colC have values; all other columns are NULL. ID=10 appears in T2 and T4 but not in T1 or T3, so id2, colB, id4, colD have values; all other columns are NULL. SQLazy Step-by-Step Implementation Core Idea: First use derive to unify the ID column names of each table to ID_main, making subsequent merging easier. Then start from the first table and perform full outer joins one by one: use join to full outer join the current result with the next table on ID_main, then use derive and nvl to merge the new ID into the ID_main column, appending tables one by one to get the final result. [ Click to run this example online ] The steps are explained below. Steps 1-4: Unify ID Column Names Across Tables derive id as ID_main, id, colA Use derive on T1-T4 to rename their respective ID column names (id/id2/id3/id4) uniformly to ID_main. Step 5: Full Outer Join T1 and T2 join ID_main; with t2; ID_main; take id2, colB; full Use the join function to full outer join t1 and t2 on ID_main. Step 6: Merge NULLs in ID Column derive nvl(ID_main, id2) as ID_main, id, colA, id2, colB If a record comes from t2 but is not present in t1, its ID_main is NULL. This step assigns t2.id2 to ID_main in such records, ensuring the ID_main column always has a value. Different SQL implementations u
In a recent Azure Architecture blog article, Azure lead engineer Kishorekumar Pattabiraman outlines practical criteria for choosing between skills, sub-agents, and other approaches when building AI systems, emphasizing reusability, simplicity, and long-term maintainability. By Sergio De Simone