AI 资讯
Most Of Your "Nudges" Are Just Interruptions In Costume
In 2008, Richard Thaler and Cass Sunstein needed an example simple enough to explain the whole of economic theory from a single application. They used a cafeteria menu. By moving the fruit to eye level and sending the fries to the periphery, they demonstrated that a slightly adjusted environment could convince thousands of students to make healthier choices. No one is stopped from choosing fries and the fries-loving student still chooses fries. But the undecided student chooses the apple, simply because it is now right in front of him. In 2017, Thaler was awarded the Nobel Prize in Economics for his body of work, including the development of “The Nudge Theory” with Sunstein. In the years that followed, product teams building mobile applications have taken to referring to any call-to-action on-screen as a nudge. The design of an effective nudge There are two requirements for a nudge to work reliably. The user should have an apparent desire for the thing they are being nudged toward, and the nudge should appear at the moment when this desire is at its peak. The first requirement ensures the user has a mental model of the target action, meaning they understand roughly what they are supposed to do. The second requirement serves to remove any extraneous context, ensuring the nudge does not fail due to poor timing. A checkout confirmation modal shown straight after launching the application will fail miserably as a nudge. The desire to checkout is non-existent at the launch moment, and the context of the action has little to do with the action itself. A tooltip shown after a specific number of unsuccessful attempts to checkout after viewing the cart, however, is a nudge. It has the desired behavior and the right timing. Why the difference shows up in the numbers In the example with Duolingo, the product team has effectively used the framing of an existing streak as a reference point for the next level of engagement. The players who saw streak-based progress notifications
AI 资讯
Every change to an Entra extension is a Control Plane event: the monitoring contract
Parts 1 and 2 of this series ( Microsoft Entra extensibility is a gift. It is also Control Plane. and Securing the code that decides who Entra trusts ) made two static decisions. Where the code lives: a dedicated Control Plane subscription, directly under the root management group or under a dedicated Control Plane management group, never in the platform identity subscription or an application landing zone. What credential it uses to call out: a managed identity by default, federated identity credentials when the call must leave Azure, certificates as a tolerated middle step, and static symmetric keys never. Both decisions are one-time. You make them, you walk away, you do not touch them for months. The third decision is not like that. It is continuous, and it is the one most teams quietly skip: how do you know the deployed code on that Function App is still the code your reviewers approved? How do you know the Logic App workflow definition has not been rewritten since last Tuesday? How do you know nobody added a federated identity credential to the managed identity at 3 a.m. on a Saturday? The answer is monitoring. Not "we have Log Analytics turned on." Monitoring with a specific operating contract attached. The posture inversion For most Azure workloads, the default operating posture is reasonable trust. Engineers deploy. Pipelines run. Configuration drifts a little. The team reviews changes weekly. Anomalies are caught eventually. For a Microsoft Entra extension, that posture is wrong. The default has to be inverted. Once an Entra extension lands in production, every change to it is suspicious by default. Not "needs review." Not "let's check first." Suspicious. The default state of an alert firing on a Function App that hosts a custom claims provider is "the SOC is investigating, prove this was approved." If you cannot prove the change was approved within the team's response SLA, the change is treated as an incident and rolled back. That posture is harsh on purpo
AI 资讯
I gave an LLM agent write access to my cloud drive. Three bugs taught me how to constrain it.
I wanted a media library that knew the difference between what should exist and what does. Most automation I tried picked one side. Some tools search well and never track what you already have. Others move files and assume the move worked. I wanted the gap between those two things to be the thing the software acted on. So I built Mediary Scout . You name a movie or a show. An LLM agent searches your indexers, transfers the best match into your own cloud drive, then reads the drive back to confirm what landed and what is still missing. It runs self-hosted. You bring your own drive, your own model, your own metadata key. There are desktop builds for Mac and Windows if you just want to double-click and run it, and a read-only demo if you want to watch one acquisition play out first. The drives it speaks today happen to be Chinese cloud storage (115, Quark, GuangYaPan). That detail does not matter for the rest of this post. The part that took real work was different: handing an LLM tools that move and delete files, and stopping it from doing something dumb with them. Three bugs taught me most of what I now believe about that. The shape of the thing The web app does almost nothing interesting. It writes a row to a Postgres queue and returns. A long-running worker picks up the row and starts a sandboxed agent. The agent gets a small set of tools: search resources, transfer a candidate, list a directory, move files into a season folder, mark episodes as obtained. Every tool runs through a deterministic workflow that owns the actual side effect. The agent proposes. The workflow decides whether the proposal is allowed, performs it, and reads the world back. That split is the whole design. The model is the part I cannot fully predict, so it gets the smallest possible blast radius. The deterministic code around it holds every irreversible action and every check. When I violated that split, things broke. They broke in the order below. Bug 1: the agent searched sixteen times and
AI 资讯
Syncing a wholesaler's API into WooCommerce without overselling or melting the server
A common WooCommerce brief looks like this: the store does not own its inventory. A distributor does. The shop is a storefront on top of a wholesaler whose catalog, stock levels, and prices change daily, exposed through some REST or XML web service. The job is to make the store reflect the supplier's reality automatically, and to never sell something the supplier cannot ship. We shipped exactly this for an automotive-parts store recently (client and supplier stay anonymous). Tens of thousands of indexes, a wholesaler REST API, and a hard requirement: no manual catalog work, and no orders for parts that are not actually in stock. Here is what the architecture looks like and the traps worth knowing before you start. The store is a view, the wholesaler is the source of truth The first mental shift is that WooCommerce is not the system of record for products. The distributor is. WooCommerce is a cache with a checkout attached. Once you accept that, the design falls out: a sync layer pulls from the supplier and writes into WooCommerce on a schedule, and you treat the WooCommerce product data as derived, not authored. The integration answers three questions, and you should answer them explicitly before writing code: What syncs - catalog, attributes, media, stock, price. Which direction - here it is one-way (supplier to store); orders stay in WooCommerce. How often - split it. Stock and price are cheap and change constantly, so poll them frequently. Full catalog and media are expensive, so refresh them rarely. Map fields declaratively, or you will rewrite it every month The supplier describes a product its way (its own index, EAN, attribute names, HTML description blobs, image URLs). WooCommerce wants its way (product, attributes, variations, media library). The bridge between them is a field map, and the single best decision we made was keeping that map declarative - a data structure, not a pile of if statements. When the wholesaler adds a new attribute, you extend the ma
AI 资讯
Chrome for Developers a Berlino: cosa aspettarsi dall’ecosistema web nel 2026
Tra performance, piattaforma e toolchain: i temi che contano davvero per chi costruisce frontend oggi. Il frontend nel 2026 è diventato una disciplina sempre più “di prodotto”: non basta far funzionare l’interfaccia, serve che sia veloce, stabile, accessibile e misurabile in produzione. E quando l’ecosistema Chrome parla di “connessione” tra developer e piattaforma, il messaggio utile per chi lavora sul web è semplice: capire dove investire tempo per ottenere impatto reale sugli utenti . Di seguito, una lettura pratica dei temi che continuano a emergere come prioritari per chi costruisce applicazioni e siti moderni. 1) Performance: meno benchmark, più realtà La performance non è più un esercizio di ottimizzazione a fine progetto. È un requisito continuo che va gestito con strumenti, metriche e processi. Cosa significa “misurabile” oggi Metriche di campo (real user monitoring) : le prestazioni che contano sono quelle che arrivano dai dispositivi reali, su reti reali. Metriche di laboratorio : restano utili per regressioni e CI, ma vanno interpretate come “segnali” e non come verità assolute. Implicazione pratica Imposta una pipeline dove: le metriche sintetiche bloccano regressioni evidenti (build/PR), le metriche reali guidano le priorità (release e backlog). 2) DevTools: dal debug al controllo qualità Gli strumenti di sviluppo non servono più solo a “trovare il bug”, ma a ridurre il rischio : regressioni di layout, memory leak, risorse inutili, dipendenze pesanti. Abitudini che fanno differenza Profilare prima di ottimizzare: CPU, rete e rendering hanno colli di bottiglia diversi. Isolare i cambiamenti: una variazione di bundling o di immagini può ribaltare il profilo prestazionale più di una micro-ottimizzazione in JS. 3) La piattaforma web continua a crescere (e chiede scelte più consapevoli) La Web Platform oggi offre API potenti, ma la parte difficile non è “usarle”: è scegliere quando usarle. Un criterio utile Se una feature riduce complessità (meno librerie,
AI 资讯
P Watched an AI That Only Looked One Way. The 99.97% Was Real. It Just Missed Everything That Mattered.
"Show nothing, hold everything." — The Thirty-Six Stratagems, Create Something Out of Nothing Previously on this series: #4: P Walked Into an AI Monitoring POC. P Didn't Run a Single Test. — P found an ACL business card in an abandoned POC archive. P didn't tell anyone. P just pocketed it. White walls. Fluorescent hum. A FortDefender quarterly report sat open on the table, the cover printed in bold: Zero missed detections. 99.97% detection rate. The CTO slid it across. "The day the leak happened," he said quietly, "this system said everything was fine." "Which client?" " MedTech . Medical data breach. Their internal AI monitoring didn't catch it either. The quarterly report called it 'client-side issue.' I don't buy it." P didn't look at the report first. P looked at the CTO's eyes first. "You didn't bring me here to validate his numbers." The CTO didn't deny it. " FortDefender won't give you production access," he said. "Read-only logs. Sandbox. Public docs. You signed the NDA." "What do you want me to do?" "Find what's hiding inside 'everything was fine.'" P nodded. P didn't ask "what if I find it" — P knew the answer. "One condition: full internal penetration test access. No advance notice to anyone." The CTO was quiet for three seconds. "Done." P stood up. The CTO added one more thing as P turned: "I've heard about the FirmCore thing. That's why I called you." P didn't look back. Week One FortDefender 's public documentation was beautiful. Architecture diagrams. Whitelist rules. Alert thresholds. Response times. All in a technical whitepaper so polished you'd think it was written to raise funding. P spent three days reading every page. In the sandbox, P ran three rounds of tests. FortDefender 's detection system hit every single one. The 99.97% wasn't a lie — at least not inside the sandbox. But P noticed something. FortDefender 's whitelist rules were too complete. They covered everything — down to "penetration tests with valid internal certificates" being pre-
安全
Configuration as Code is a liability for security
submitted by /u/Happycodeine [link] [留言]
开发者
Top 7 Featured DEV Posts of the Week
Welcome to this week's Top 7, where the DEV editorial team handpicks their favorite posts from the...
产品设计
Compendium
Keeping your team, agents, and data on one page Discussion | Link
开发者
ExploreYC
Open-source API for Y Combinator & a16z company data Discussion | Link
AI 资讯
Presentation: Designing AI Platforms for Reliability: Tools for Certainty, Agents for Discovery
Aaron Erickson explains how NVIDIA designs and tests purpose-built AI agent hierarchies. For senior developers and architects, he outlines why balancing deterministic tools with agentic discovery is crucial. Discover how to leverage rare context, implement LLM-as-a-judge test pyramids, and avoid the paradox of choice to build highly reliable, production-grade AI systems at scale. By Aaron Erickson
开发者
How HubSpot Scaled Semantic Search to 20 Billion Vectors
SaaS software vendor HubSpot has described how its semantic search platform grew from a proof of concept into an internal service that now manages more than 20 billion vectors across 38-plus teams. The company says the system now supports agents, RAG, and contact deduplication, and that the increase in agent usage has made retrieval quality and latency more important than before. By Matt Saunders
开发者
Drunk Post: Things I’ve Learned as a Senior Engineer
submitted by /u/fagnerbrack [link] [留言]
产品设计
RAG at 10 Million Documents — System Design
submitted by /u/lucian-12 [link] [留言]
AI 资讯
The Troubles of Working with a Database at a Hackathon (AidStream Story)
When people talk about hackathons, they talk about the demo. The pitch, the UI, the "aha" moment on stage. Nobody really talks about the person who spent the whole weekend making sure the data didn't fall apart. That was me on AidStream, a blockchain-based aid distribution platform we built in a weekend and trust me it wasnt that easy as it seems. At a normal project, you can revisit your data model whenever.But during a hackathon you cant since when teamamtes start working on top of your tables it means both codes may start breaking . Serverless Postgres was the right choice for a hackathon: no local DB setup, no "wait, whose laptop has Postgres installed" problem. Everyone could connect to the same instance immediately. The gotcha was connection limits — with multiple people hitting the same database while testing features simultaneously, we ran into connection issues at the worst possible time (an hour before demo). So next time you watch a hackathon demo go off without a hitch, remember — someone probably spent the whole weekend quietly making sure the database didn't have a say in it. If you're the one holding the schema together at 2am, know this — it's not the flashy role, but it's the one that decides whether anyone else's code even runs.
开发者
Node.js 26: Temporal API Enabled by Default, V8 14.6, and a Round of Deprecations
Node.js 26 has been released, featuring the Temporal API enabled by default, an updated V8 engine to version 14.6, and the Undici HTTP client upgraded to 8.0. The release also removes deprecated legacy APIs. Developers should note migration points related to NODE_MODULE_VERSION changes. Node.js 26 is current for six months before entering long-term support. By Daniel Curtis
AI 资讯
The Session ID That Wouldn't Stop Changing
I was implementing a feature where the session container would track a lastActivity timestamp, updated on every authenticated request. Standard stuff. I wrote it, tested it locally with curl, and noticed something odd: I kept getting a new Set-Cookie header value on every response. Not occasionally. On every single one. A week later I was sending a pull request to mezzio/mezzio-session-cache . The Setup: Two Backends, One Session Our system had a constraint: two backend applications, written in different languages, sharing a single user session. One was the main PHP/Mezzio app. The other was a service in a different stack that needed to read from, and update the lastActivity timestamp on, the same session container. There are a few ways to make polyglot session sharing work. We landed on a shared cache backend (Redis) with a well-defined session structure. Both apps could read and write through their own libraries, as long as they agreed on the storage format and the cookie name. The session ID was the contract. That contract is the part that quietly broke. A Missing Escape Hatch My first instinct was the usual list of suspects. Was something calling regenerateId() in a middleware I didn't know about? Was there a logout being triggered somehow? Was a misconfigured cache layer evicting and recreating sessions? After a bit of digging through the call stack, I ended up in the library itself. And there it was: CacheSessionPersistence was regenerating the session ID whenever the session data changed . Not on login. Not on privilege escalation. On every write . That's when the real question hit me: why on earth would a library do that by default? Reading Code Before Changing It When you find behavior that surprises you in someone else's code, the wrong move is to immediately label it broken. The right move is to assume the maintainers had a reason, and find out what it was. The reason, in this case, is session fixation . Session fixation is a class of attack where an atta
AI 资讯
Cheapest Residential Proxies That Actually Work in 2026 (A Developer's Buying Guide)
"Cheapest residential proxy" is a search query with a hidden trap: the lowest price per GB and the lowest cost per successful request are not the same number. This post breaks down ten budget-to-mid-tier residential proxy providers from a cost-and-reliability angle, plus a script for measuring the metric that actually matters before you commit real traffic. The trap: price per GB vs. cost per success A proxy at $0.50/GB that fails half your requests is more expensive than one at $1.40/GB with a 98% success rate, because you're paying for retries, wasted bandwidth, and engineering time spent debugging "random" failures. Before comparing sticker prices, calculate: real_cost = traffic_price + failed_request_overhead + retries + setup_time + support_delays Concretely, here's a quick way to model it: def cost_per_success ( price_per_gb , success_rate , avg_response_kb = 50 , retry_overhead = 1.3 ): """ price_per_gb: advertised price success_rate: 0.0-1.0, measured against YOUR target site, not the vendor ' s claim retry_overhead: multiplier for bandwidth wasted on failed/retried requests """ effective_price = price_per_gb * retry_overhead gb_per_request = avg_response_kb / ( 1024 * 1024 ) cost_per_request = gb_per_request * effective_price return cost_per_request / success_rate # Example: cheap provider, mediocre success rate print ( cost_per_success ( 0.50 , 0.75 )) # looks cheap, isn't once failures are priced in # Example: pricier provider, high success rate print ( cost_per_success ( 1.40 , 0.98 )) # often cheaper in practice Run this with your own measured success rate (see the test harness further down), not the vendor's advertised uptime number. What to actually compare Before looking at price, check whether the provider covers: IP pool size and quality (pool size alone tells you nothing about freshness or block rate) Country vs. city-level targeting Sticky session support (for anything stateful) Rotation controls (for scraping/data collection) HTTP(S) and SOCKS5
AI 资讯
Meet HTTP QUERY: The New HTTP Method You've Probably Been Waiting For
For years, developers have faced the same dilemma when implementing complex search APIs: GET is the correct semantic choice for read-only operations, but query parameters can become extremely long and difficult to manage. POST allows sending a request body, but it's intended for operations that may change server state, making it a poor semantic fit for searches. To bridge this gap, the IETF has introduced a new HTTP method: QUERY (RFC 10008). Why was QUERY introduced? Modern APIs often require complex filtering: nested JSON filters GraphQL-like requests advanced search criteria large lists of IDs geospatial or analytical queries Encoding all of this into a URL is cumbersome and can exceed practical URI length limits. Developers have traditionally worked around this by using "POST" for read-only searches. The problem is that "POST" doesn't express the intent of the request very well. The new QUERY method solves this by allowing clients to send a request body while keeping the operation explicitly safe and idempotent. Key benefits ✅ Request body support Unlike "GET", "QUERY" allows sending structured request data in the message body, making complex searches much easier to model. ✅ Safe by design Like "GET", a "QUERY" request must not modify server state. It clearly communicates that the request is read-only. ✅ Idempotent Repeating the same "QUERY" request produces the same result without additional side effects, allowing clients and intermediaries to safely retry requests after transient failures. ✅ Cache-friendly Unlike the common "POST"-for-search pattern, "QUERY" is designed to work with HTTP caching, enabling better performance and more efficient network usage. ✅ Better API semantics Instead of overloading "POST" for read operations, APIs can now express their intent more accurately: "GET" → simple resource retrieval "QUERY" → complex read operations with a request body "POST" → operations that create or modify state Example Instead of forcing everything into a lo
AI 资讯
Python's Memory Model Is Not What You Think It Is
Python's Memory Model Is Not What You Think It Is Ask most Python developers how Python stores a variable and they will say "it stores the value." This is imprecise in a way that causes real bugs and real confusion in interviews. A precise mental model of how Python stores and retrieves data changes how you read and write code. Python does not store values in variables. Python binds names to objects. The distinction sounds philosophical until you trace code that involves mutation, function arguments, or aliasing. Then it becomes the most practically useful concept in the language. Names Are Not Boxes The box metaphor, which says a variable is a box that holds a value, is how most introductory programming courses explain variables. In many languages this metaphor is close enough to accurate that it does not cause problems. In Python it is wrong in ways that matter. A more accurate metaphor: a Python name is a label attached to an object. The object exists independently in memory. Multiple labels can be attached to the same object. Attaching a new label does not move or copy the object. x = [ 1 , 2 , 3 ] y = x print ( id ( x ) == id ( y )) # True (same object, two labels) When you write y = x , you are not copying the list. You are creating a second label that points to the exact same list object. The Four Operations You Must Distinguish 1. Assignment creates a new binding x = [ 1 , 2 , 3 ] x = [ 4 , 5 , 6 ] # x now labels a completely different object The first list still exists in memory until garbage collected. The name x simply stops pointing to it and now points to the second list. 2. Mutation modifies an existing object x = [ 1 , 2 , 3 ] x . append ( 4 ) # the object x labels is modified in place Any other name pointing to the same object will instantly reflect this change because they look at the same memory location. 3. Augmented assignment on mutable types mutates x = [ 1 , 2 , 3 ] y = x x += [ 4 , 5 ] print ( y ) # [1, 2, 3, 4, 5] (same object, mutated) The