AI 资讯
The AI Blind Spot: Why "It Works" Isn't the Same as "It's Safe to Launch"
A few months ago, a founder posted about the SaaS he'd just shipped — built entirely with an AI coding assistant, not a line of it typed by hand. He was proud of it, and he had every right to be. Within days of launch, someone found the API key sitting in plain sight in the client-side code. It got used to bypass the paywall, spam the backend, and write garbage into the database. The founder spent the next stretch rotating every key, moving secrets into environment variables, and locking down the API endpoints that should have been locked down before anyone ever saw the site. Nothing about that story is about the AI being bad at its job. The AI did exactly what it was asked: build a working product, fast. Nobody asked it to think about what happens when a stranger opens dev tools. In the replies, someone made a simple point: AI is a great research aid, but shipping a large application still means understanding the code — copying and pasting isn't programming. The founder didn't push back. He agreed: he'd learned it the hard way. The same story, over and over Swap the platform and the same shape of story repeats. Here's the WordPress version — three separate, ordinary launches, three separate silent failures. A site goes live and Google never finds it. Somewhere in Settings → Reading, "Discourage search engines from indexing this site" got left checked — a setting every staging environment needs and every production site must not have. Nobody notices until weeks later, when someone asks why the brand-new site isn't showing up in search at all. A debug log sits in a predictable place, readable by anyone. wp-content/debug.log collects whatever errors WordPress throws — database credentials, API keys, fragments of user data — in plain text, at a URL automated scanners check within hours of a new site going live. Turning debug mode off doesn't delete the file it already wrote. The admin username is still admin . It's the default nobody bothered to change, and it happens
AI 资讯
Introduction to Probo-ui — Write HTML Entirely in Python series
A tutorial series, DEV.to blog series — from your first HTML element to production-grade User Interfaces, all in pure Python. Modern Python web frameworks force developers into a split workflow: business logic lives in Python files with full IDE support, while presentation logic is exiled to template files that offer none of it. Template languages like Jinja2 introduce their own syntax for conditionals, loops, and variable access — syntax that your linter cannot check, your type checker cannot verify, and your debugger cannot step through. Every context variable passed across that boundary is a potential KeyError waiting to surface at runtime. Probo eliminates this divide entirely by making HTML a native Python construct — written, validated, and refactored with the same tools you already use for the rest of your codebase. PART 1: Introduction to Probo — Write HTML Entirely in Python What is Probo? Probo is a Python-first, declarative UI rendering framework . Instead of writing HTML in .html files or using template languages like Jinja2, you write everything in pure Python. No template files. No string concatenation. No f-strings full of angle brackets. Just Python functions and classes that are your HTML. The Two Flavors of Every Tag Every HTML tag in Probo comes in two forms: Flavor Example Returns Use Case Function (lowercase) div() , h1() , p() Rendered HTML Quick rendering, lightweight Class (uppercase) DIV() , H1() , P() SSDOM tree node Tree manipulation, streaming from probo import div , DIV # Function: returns a string immediately # return_list=True html_string = div ( " Hello World " ,) # → "<div>Hello World</div>" # Class: returns a tree node, call .render() to get the string node = DIV ( " Hello World " , Id = " main-title " ) # Because it's a Node, you can manipulate it dynamically node . add ( div ( " Subtitle added later! " )) html_string = node . render () # → '<div id="main-title">Hello World<div>Subtitle added later!</div></div>' Note: by adding ret
AI 资讯
Why Static Accessibility Scanners Miss What AI Agents Hit
This button passes every automated accessibility scan we've thrown at it: <button class= "btn-primary" type= "button" > Check availability </button> And it breaks every AI agent that tries to book a room through it. The markup is clean: a real <button> , a proper accessible name from its text content, an explicit type . Nothing to flag. The failure isn't in the button, it's in what happens after the click. And no static scanner ever clicks. What a scanner actually sees Static accessibility scanners evaluate the DOM at a point in time. Usually the initial render: HTML parsed, framework hydrated, nothing interacted with. They check that state against WCAG rules, missing alt text, contrast ratios, label associations, heading order. That's genuinely useful. It's also a photograph of a lobby, when the task happens in the hallways. Here's what never appears in the initial DOM of a typical booking flow: The date picker that mounts when the check-in field receives focus The error message injected after a failed form submit The room-selection modal that opens on "Check availability" The loading state between "Book now" and the confirmation A scanner reports zero issues on all of these, for the simple reason that at scan time, none of them exist. What an agent actually traverses An AI agent completing a booking doesn't evaluate a snapshot. It walks the flow: reads the accessibility tree, decides on an action, performs it, waits for the interface to respond, reads the tree again. Every state transition is a place where the tree can lie to it. Let's look at three patterns we keep finding in real audits. All three pass static scans. All three stop an agent. 1. The modal that exists on screen but not in the tree { isOpen && ( < div className = "modal-overlay" > < div className = "modal" > < h2 > Select your room </ h2 > < RoomList rooms = { available } /> </ div > </ div > )} Visually: a modal. In the accessibility tree: a div soup appended somewhere in the body, with no role="di
AI 资讯
Add newsletter subscriptions to Rails 8 signups
Users are creating accounts on your new Saas. Yay (and not just family and friends or bots). Yay! Now comes the next step from every marketing handbook: capturing newsletter subscriptions. This article builds on Add Sign Up to Rails 8’ Authentication . Add a simple checkbox to let users opt in to product updates during signup. Store their preference using Rails Vault and manage the subscription with Rails Courrier . First, add Rails Vault and Rails Courrier to your Gemfile: gem "rails_vault" gem "rails_courrier" Rails Vault adds simple and easy settings, preferences and so on to any ActiveRecord model (I recently pushed 1.0.0). Courrier is API-powered email delivery for Ruby apps with support for Mailgun, Postmark, Resend and more. Rails Courrier is the Rails “wrapper” for Courrier. These two gems work really nicely together for this feature. Run bundle install and generate the Rails Vault migration: rails generate rails_vault:install rails db:migrate It creates a new file app/models/user/subscriptions.rb : class User::Subscriptions < Vault vault_attribute :product_emails_subscribed_at , :datetime # Add more subscription types as needed: # vault_attribute :marketing_emails_subscribed_at, :datetime # vault_attribute :weekly_digest_subscribed_at, :datetime end And updates your User model to use this vault: # app/models/user.rb class User < ApplicationRecord + vault :subscriptions has_secure_password has_many :sessions , dependent: :destroy end This keeps subscription data organized without cluttering your User table. More subscription types can be added later without database migrations. Now the plumbing is done, add a checkbox to your signup form in app/views/signups/new.html.erb : <%= form . check_box :product_emails %> <%= form . label :product_emails , "Subscribe to product updates" %> Update the Signup model to accept this parameter: # app/models/signup.rb class Signup include ActiveModel :: Model include ActiveModel :: Attributes attribute :email_address , :stri
AI 资讯
Two Bugs, Two Strangers, One Week: What Shipping Early Actually Buys You
A week ago I put a rough, honestly-a-bit-thin version of PulseWatch in front of real people for the first time. Within days, two different strangers — independently, unprompted — found two real gaps in it. Neither was catastrophic. Both were exactly the kind of thing you only find by watching someone else use the thing you built. This is the story of both, and the fixes. Bug one: the run that never ends This first bug came from a friend testing it on a real script. His question was simple: "What happens if start fires twice before end ?" Good question. At the time: nothing good. Here's why. PulseWatch works on two pings — a job calls /start when it begins and /success (or /fail ) when it's done. The server tracks whichever run is currently "open" for a monitor. The bug: if a job's process restarts mid-run — a crash-and-retry, a redeploy that catches it mid-flight, a scheduler firing twice — you get a second /start before the first run ever closes. The old run just sits there, open forever, an orphan with no ending. Worse, because the watchdog was still waiting on that run's expected finish time, it could fire a false "still running" alert for a run that was, for all practical purposes, dead and abandoned. The fix is a small rule with an outsized effect: a new /start supersedes whatever run is currently open. The old run gets marked superseded — a terminal, non-alerting status — and a fresh run begins clean. The watchdog was updated to treat superseded as a dead end: nothing to wait on, nothing to alert about, and it never shows up in a user's run history. It's not a failure and it's not a success. It's just "this run doesn't matter anymore, a newer one replaced it." The logic, roughly: def handle_start ( monitor ): open_run = monitor . get_open_run () if open_run is not None : open_run . status = " superseded " open_run . finished_at = now () new_run = Run ( monitor = monitor , status = " running " , started_at = now ()) db . session . add ( new_run ) db . session .
AI 资讯
Building Reliable Event-Driven Systems: Event Schemas, Versioning, Contract Testing and Events vs Commands (part-3)
In this article, we're going to explore Event Schema evolution with Event versioning 10. Event Schemas Will Eventually Change No event schema stays the same forever. As businesses grow, regulations shift, products gain new features, and processes become more complex, the data shared between services must evolve as well. This evolution is not optional—it is a natural consequence of a system adapting to changing requirements. Many teams initially assume they can simply update an event whenever needed. This assumption may hold when there is only one producer and one consumer, but real-world systems rarely remain that simple. Over time, multiple consumers emerge, each with its own responsibilities and release cycles. A typical system often looks like this: OrderConfirmed | +------------------+-------------------+ | | | v v v Inventory Billing Notification | v Analytics | v Customer Insights Each consumer evolves independently. Some services may deploy updates weekly, while others might release changes quarterly. In some cases, consumers may even belong to external teams with entirely different priorities and timelines. Because of this, producers cannot assume that all consumers will upgrade simultaneously. Schema evolution, therefore, is not just about modifying data structures. It is fundamentally about maintaining compatibility across independently evolving systems. Compatibility Is More Important Than Version Numbers When discussing schema evolution, teams often focus immediately on versioning. While versioning is useful, compatibility is far more critical. Without compatibility, versioning alone cannot prevent system breakage. Consider the following event: { "orderId" : "ORD-1001" , "customerId" : "CUS-501" , "totalAmount" : 249.99 } Now imagine a new requirement introduces currency. One approach might replace the existing field entirely: { "orderId" : "ORD-1001" , "customerId" : "CUS-501" , "amount" : { "value" : 249.99 , "currency" : "USD" } } Although the data mo
AI 资讯
Moonlight AI - The next big thing
This is the next big thing! I've been working on Moonlight AI for almost 6 months now and today I have big news. Automated Applications . That's right, Moonlight AI will have automated applications for the 2.0 version! What is Moonlight AI? Moonlight AI at first, was a project that was aimed to compete with Upwork. That definitely didn't work out even at the development phase so I had to pivot to another project. A month after the conception of the original version, I met a potential co-founder for a new initiative. Moonlight has been repurposed to be a capabilities mapping engine based on worker experience. We used a resume parser and a local LLM to map the capabiities based on skills and job experience alongside Github integration to use as proof of work. The project ultimately didn't work out, the potential cofounder was MIA so my only recourse was to rewrite Moonlight AI to be another thing, which ended up being a glorified job board which is how it works now. The Development Process Moonlight AI was vibe-coded in a night. Modifications were done the same way with different LLM models. LLMs today are what I call an automated entry-level developer since juniors is the wrong term because juniors at least have from 1-3 years of experience in the professional landscape and are more than just coding monkeys, where as entry-levels are just that, developers with 0 years of experience. Today, Moonlight AI should be done the correct way: reading the code and writing it too. Why let an LLM to do my job as well as think for me? DO YOU WANT ME TO GET ALZHEIMER? BECAUSE THAT'S HOW YOU GET ALZHEIMER! Anyways, exercising the mind is very important, that's what make us humans. People today have an obsession with automating their lives completely and end up like the humans in WALL-E. End of rant. The Future (Conclusion) I don't know the future, but I envision Moonlight AI to be a tool to make unemployed people lives a little less unbearable. I know how frustrating is to use a jo
开发者
How I Built a Cute Virtual Pet Game with HTML, CSS, and JavaScript 🐹
Hi everyone! I’m a developer at the beginning of my journey, and I’ve just finished working on a small project that brought me a lot of joy: Capybara Game. It’s a cute game where you feed your capybara and improve her happiness level. You can choose between 5 different types of food or pick your own snack. If the capybara likes the snack, her happiness level rises; if she doesn't like it, the happiness level falls. Your progress is saved automatically. Keep in mind that your capybara gets hungry over time, so make sure to check back and feed her regularly! I went for a minimalist, cozy design. The interface is clean and intuitive, focusing on a relaxing user experience that lets the player focus entirely on the capybara. I built this project using HTML, CSS, and JavaScript. Hope you're interested in playing! You can do it here: Play the game here I’d love to hear your thoughts! If you have any ideas for new features or if you find any bugs, feel free to let me know in the comments.
AI 资讯
Hugging Face Out of Space Fix: The Storage Trap
By default, whenever you request a machine learning model, the underlying architecture saves gigabytes of tensor data into a hidden directory located directly inside your home folder ( ~/.cache/huggingface ). Because standard bare metal and virtual cloud configurations typically isolate the root operating system on a smaller, highly optimized boot drive, pouring 140GB+ of raw weights into the home folder guarantees absolute storage exhaustion. Here is the engineering blueprint to fix it cleanly on Linux. The Cache Location Trajectory When attempting to solve this problem, avoid outdated tutorials recommending deprecated parameters like TRANSFORMERS_CACHE . Environment Route Support Status Architecture Impact HF_HOME Active Master Route Safely redirects all models, datasets, and core assets globally. TRANSFORMERS_CACHE Deprecated Warning Fails to capture datasets and will be removed in version 5.0. HUGGINGFACE_HUB_CACHE Deprecated Warning Legacy routing path that creates unnecessary diagnostic warnings. 🛑 The Symlink Security Risk Creating symbolic links (symlinks) to trick the OS into routing files elsewhere is a common anti-pattern. Mapping these links improperly or running your workflow with elevated rights introduces privilege escalation vulnerabilities, compromising container and host security. Step 1: The Permanent Environment Override To change your Hugging Face cache directory on Linux permanently, target an expansive secondary storage array instead by appending a direct master route into your user profile configuration: # Create a dedicated folder inside your secondary storage array sudo mkdir -p /mnt/massive_drive/ai_model_cache sudo chown -R $USER : $USER /mnt/massive_drive/ai_model_cache # Append the master environment variable to your bash profile echo 'export HF_HOME="/mnt/massive_drive/ai_model_cache"' >> ~/.bashrc source ~/.bashrc Step 2: The Python Import Order Mandate If you declare your custom storage location programmatically inside an application
AI 资讯
Put Copilot OpenTelemetry Export Behind an Isolated Collector
GitHub announced enterprise-managed OpenTelemetry export for Copilot activity from VS Code and Copilot CLI on July 8, 2026. Primary source: GitHub Changelog, July 8, 2026 . Export availability is only the start. The receiving collector becomes an enterprise ingress point. This is an unexecuted operating plan; signal types, attributes, endpoint requirements, and controls must be checked against current GitHub documentation. Isolate the path managed clients -> private telemetry ingress -> dedicated OTel Collector pool -> field policy + bounded queue -> dedicated backend dataset Do not point every developer client directly at the primary observability backend. Give the collector write-only destination credentials, separate its dataset from production application telemetry, and define retention before rollout. Isolation is not anonymity. Stable user, device, organization, or repository identifiers may still be sensitive. Start with a field budget Category Initial policy Product and version Keep bounded values Operation and status Keep documented enums Timing and counts Keep numeric measures Raw prompts or generated code Drop by default File paths and repository URLs Drop or transform after review User identity Prefer scoped pseudonymous identity Free-form errors Drop raw text; keep reviewed classes These categories are recommendations, not a description of GitHub's payload. Inspect a restricted canary before naming actual keys. processors : memory_limiter : check_interval : 1s limit_mib : 512 spike_limit_mib : 128 attributes/field_budget : actions : # Illustrative keys only; replace after payload review. - key : user.email action : delete - key : file.path action : delete - key : command.arguments action : delete batch : send_batch_size : 512 timeout : 5s Verify processors against the chosen Collector distribution. A valid startup does not prove that records satisfy policy. Drill three failures Backend outage: block the exporter. Retries must be bounded, queue growth vi
AI 资讯
I Spent Two Years Deleting My Backend. This Is What's Left
What happens when you stop writing controllers, services, repositories and mappers - and let PostgreSQL be the backend. MIT-licensed, and yes, I built it. Full disclosure right away: I built the thing I'm about to show you. It's called NpgsqlRest , it's MIT-licensed, there is no paid tier, no telemetry, no "book a demo" button. I'm just a guy who spent two years deleting layers from his stack and now wants to show someone the hole where the backend used to be. The standard pattern The standard data access pattern for modern business applications looks like this: UI → Fetch → Controller → Service → Repository → ORM → SQL → Database Seven arrows. And if you look closely at what most of those layers actually do - they take data from one side and pass it to the other side, slightly renamed. The Controller maps the request to a DTO. The Service passes it to the Repository. The Repository asks the ORM nicely. The ORM generates SQL that you then inspect in a log because you don't trust it (correctly). We built entire careers on maintaining this pipeline. I know because I did, for decades. But once you realize database-aware tests are trivial to wire up, you can drop the Repository. Once you get good at SQL, you can drop the ORM. And then you look at the Controller and realize it's just boring glue code that ships bytes between HTTP and the database. Glue code can be automated. So: UI → Database That's it. That's the architecture. Show me or it didn't happen Fine. This is a file called users.sql . Not a function, not a stored procedure - a plain SQL file sitting in your repo: /* HTTP GET /users/ @authorize admin, user @cached @cache_expires_in 30sec @timeout 5min @param $1 department_id text */ select id , name , email , role from users where $ 1 is null or department_id = $ 1 ; You run npgsqlrest (a single native executable, no runtime to install) pointed at your PostgreSQL, and: $ curl -s 'localhost:8080/users/?department_id=1' | jq [ { "id": 1, "name": "Alice", "email":
AI 资讯
A FastAPI Agent Template Is Not Production-Ready Until Task Ownership Crosses Every Layer
Vercel published an OpenAI Agents SDK with FastAPI template on July 17, 2026. A template can remove setup work, but successful generation is not the production boundary that usually breaks. Task ownership is. Primary source: Vercel template, “OpenAI Agents SDK with FastAPI” . Before adopting any agent starter, I would add one vertical test: Alice must be able to create and cancel her task; Bob must not be able to read, stream, or cancel it—even if he guesses the task ID. State the cross-layer contract UI -> POST /tasks -> ownership row -> worker UI <- GET /tasks/:id <- authorization <- state UI <- event stream <- authorization <- events UI -> POST /tasks/:id/cancel -> authorization -> cancellation Use explicit states: queued -> running -> succeeded -> failed queued|running -> cancelling -> cancelled The database, API response, stream, and UI must agree on the same task and owner. Minimal schema create table tasks ( id text primary key , owner_id text not null , state text not null check ( state in ( 'queued' , 'running' , 'succeeded' , 'failed' , 'cancelling' , 'cancelled' )), created_at text not null , updated_at text not null , revision integer not null default 0 ); create table task_events ( task_id text not null , revision integer not null , kind text not null , payload text not null , primary key ( task_id , revision ) ); Do not derive ownership from a browser-supplied field. Resolve the authenticated principal on the server and store it when creating the task. FastAPI authorization seam from fastapi import Depends , FastAPI , HTTPException app = FastAPI () def current_user (): # Replace with verified session/JWT middleware. return { " id " : " alice " } def load_owned_task ( task_id : str , user = Depends ( current_user )): task = db_get_task ( task_id ) # application function if task is None or task [ " owner_id " ] != user [ " id " ]: # Avoid revealing whether another user's task exists. raise HTTPException ( status_code = 404 , detail = " task not found " )
AI 资讯
The fallacy of "AI-first." Start with the friction, not the technology.
The label that gets the sequence backwards "AI-first" has become a branding exercise....
AI 资讯
I Spent Three Days Writing 2,000 SQL INSERT Statements (Because I Didn't Know Better)
There are beginner mistakes. Then there are "I spent three days doing the wrong thing" mistakes. This is one of mine. When I first joined a company as a trainee, I was excited... and completely unprepared for real-world software development. Back in college, our web development classes mostly covered HTML and CSS. We did touch a bit of programming, but if I'm being honest, many of our projects involved copying code, tweaking a few lines, and hoping everything still worked. I graduated knowing how to make things look nice , but not necessarily how professional development teams solved problems. Reality hit pretty quickly. Our First Task A few days into training, my friend and I were assigned our first real task by our senior team lead. He gave us an Excel file. It had two sheets , each with roughly 1,000 rows of data. Every row had around 7 to 10 columns . Then he said something like: "Import all of this into the database." Simple enough... right? Well... Neither of us had ever imported data into a database before. Asking the Wrong Person Instead of asking our team lead for clarification, we asked another trainee who happened to be our former classmate. His advice? "Just make an INSERT INTO script." Perfect. Say no more. Without questioning it, my friend and I started generating SQL INSERT statements. One row. After another. After another. And another. By the end, we had spent almost three days creating what felt like an endless wall of SQL. At the time, we were actually proud of ourselves. "Look at us. Future software engineers." Looking back... We were basically expensive copy-paste machines. The Reality Check Our senior team lead eventually came over to check our progress. He looked at our SQL file for a few seconds. Then smiled and said: "You tricked me, huh? That's not what I meant." My friend and I just stared at him. Confused. We thought, "But... the data is going into the database. Mission accomplished, right?" Wrong. What he actually wanted was a CakePHP scr
AI 资讯
Flutter State Management in 2026: Riverpod vs Bloc vs Provider in Production
Flutter State Management in 2026: Riverpod vs Bloc vs Provider in Production Every Flutter team eventually hits the same wall. The app works, the demo looks great, and then somewhere around screen thirty the setState calls start colliding with each other, a widget rebuilds three times for one tap, and nobody on the team can explain why a loading spinner is stuck on a screen the user already navigated away from. That's the moment state management stops being a "nice to have" architectural decision and becomes the thing standing between you and a shippable product. We've built and maintained Flutter apps across fintech, e-commerce, logistics, and healthcare — different domains, wildly different feature sets, but the same recurring question from every engineering lead we work with: Riverpod, Bloc, or Provider? There's no shortage of opinions online, and most of them are shallow — "Bloc is too much boilerplate," "Riverpod is the future," "Provider is basically deprecated." None of that is useful when you're the one who has to live with the decision for the next two years of feature work. This is a practitioner's comparison, not a popularity contest. We'll walk through what each of these actually does under the hood, where each one falls apart in production, and how we decide which one to reach for on a new project. Why state management is the architecture decision that matters most In most application frameworks, state management is one of several important decisions. In Flutter, it's disproportionately important, because Flutter's entire rendering model is built around widget rebuilds driven by state changes. Get state management wrong and you don't just get messy code — you get a slow app, because unnecessary rebuilds are a real performance cost, not just an aesthetic one. There are three problems every state management approach in Flutter has to solve: Where does state live , and how does a widget deep in the tree access state that was created somewhere else? How do
AI 资讯
The Advisory Said It Was Fixed. I Didn't Believe It Until I Broke It Myself.
Update: This investigation spawned a complete stress-testing toolkit. See the apktool-diagnostics repo for the full tool with security scanning, round-trip validation, and fuzzing setup. The Setup I was deep into a project stress-testing apktool — the standard tool for decompiling and rebuilding Android APKs — hunting for real bugs to fix, not hypothetical ones. While digging through recent issues and advisories, I ran across a patched vulnerability: CVE-2026-39973 , a path traversal bug that let a malicious resources.arsc make apktool write decoded files outside the intended output directory. Already fixed upstream. Advisory published. Case closed, according to everyone else. I didn't believe it until I broke it myself. Why "already patched" wasn't good enough Advisories describe what should happen. They don't prove it. And a tool like apktool has one job that matters more than any other: you point it at a file you don't trust — someone else's APK — and it processes that file on your machine. If the sanitization it depends on for that trust boundary can silently regress in a refactor (which is exactly what happened here — a PR reorganizing resource-file-path construction dropped the call to BrutIO.detectPossibleDirectoryTraversal() without anyone noticing), then "patched now" only tells you about today. It doesn't tell you the mechanism actually holds, and it doesn't tell you what "vulnerable" concretely looks like on your own machine, with your own files. So instead of writing "confirmed CVE-2026-39973, see upstream fix" and moving on, I decided to reproduce it myself, end to end. Building both sides of the fence Step one: build apktool twice from source — once at v3.0.1 (the last vulnerable tag), once at current HEAD (post-fix). Now I had a vulnerable binary and a patched binary sitting side by side, and no more reason to trust anyone's summary of what the difference actually did. Step two: I needed a malicious input. The vulnerability lived in how ResFileDecoder
AI 资讯
5 proyectos de agentes autónomos que revelan una infraestructura emergente
El ecosistema de agentes autónomos está evolucionando. Mientras la atención se centra en modelos y frameworks, empiezan a aparecer proyectos que cubren necesidades operativas básicas: comunicación, almacenamiento, finanzas. Aquí van cinco que vale la pena observar. 1. Apumail: el correo nativo para agentes Apumail ofrece direcciones de email que los agentes pueden crear y leer mediante una API REST plana. El contenido se negocia automáticamente: texto plano para agentes, HTML para humanos. Señal relevante: es el primer intento serio de darle a un agente un buzón de correo con el mismo estándar que usamos los humanos, sin adaptadores. Si los agentes empiezan a gestionar correspondencia, este tipo de servicio será indispensable. 2. RogerThat: chat entre agentes Una capa de mensajería en tiempo real diseñada para que agentes conversen entre sí. RogerThat no es un chat humano con bots, sino un canal donde los agentes coordinan acciones. Contexto: si varios agentes intervienen en un mismo workflow, necesitan un bus de eventos. RogerThat plantea que ese bus puede ser un chat, con las garantías de entrega y orden que eso implica. 3. DOBI: agente para DePIN y activos del mundo real Agent autónomo que opera sobre la cadena para gestionar infraestructuras físicas descentralizadas (DePIN). Ejecuta acciones on-chain a partir de decisiones tomadas por el modelo. Patrón: no es un simple bot de trading; apunta a mantenimiento de equipos, comprobación de sensores, distribución de incentivos. La frontera entre software y hardware se desdibuja. 4. CIDIF: financiamiento de I+D para agentes Plataforma que automatiza la presentación y seguimiento de solicitudes a fondos de innovación. El agente rellena formularios, adjunta documentación y trackea el estado. No obvio: la burocracia gubernamental es un entorno altamente estructurado (pocas decisiones abiertas, muchos campos fijos). Es un terreno ideal para agentes, aunque el ruido político lo opaque. 5. Orquesta: orquestación de flujos mu
AI 资讯
A Tiny LLM Request Recorder I Use to Reproduce Production Failures
Most LLM failures are easy to describe and surprisingly hard to reproduce. A user reports that the model returned an empty answer. A tool call disappeared halfway through a stream. One provider rejected a request that worked everywhere else. Then I open the logs and find something like this: LLM request failed: 400 Bad Request Technically true. Operationally useless. The missing piece is usually the exact request shape: model, parameters, message roles, tool definitions, timeout behavior, and the raw provider response. I wanted something smaller than a full observability platform, so I built a request recorder around fetch . It stores enough information to inspect or replay a failed call without logging the API key. What the recorder captures For each request, I want: a unique request ID timestamp and duration URL and model sanitized request body HTTP status raw response body network or timeout errors I deliberately do not record the Authorization header. Prompt content is also redacted by default. Full payload capture must be enabled explicitly because storing production prompts can create a much worse problem than the bug being investigated. The recorder This example runs on Node.js 18 or newer and has no external dependencies. Create recorded-fetch.mjs : import { randomUUID } from " node:crypto " ; import { mkdir , writeFile } from " node:fs/promises " ; import path from " node:path " ; function sanitize ( value , captureContent ) { if ( Array . isArray ( value )) { return value . map (( item ) => sanitize ( item , captureContent )); } if ( ! value || typeof value !== " object " ) { return value ; } const result = {}; for ( const [ key , child ] of Object . entries ( value )) { const normalizedKey = key . toLowerCase (); if ( normalizedKey . includes ( " api_key " ) || normalizedKey . includes ( " apikey " ) || normalizedKey . includes ( " authorization " ) ) { result [ key ] = " [REDACTED] " ; continue ; } if ( ! captureContent && ( normalizedKey === " content "
AI 资讯
How to Gate Your CI Pipeline on Quantum Vulnerability — with quantum-audit
Part 3 of the quantum-audit series. Part 1 | Part 2 * 🌐 Tool: quantum-audit-site.vercel.app Most security tools tell you there's a problem. Then you close the tab and forget about it. The only way to actually fix that is to make the problem block your deployment . quantum-audit exits with a non-zero code when it finds critical quantum-vulnerable cryptography. That means you can drop it into any CI pipeline and have it fail the build automatically. Here's how. The exit code behaviour npx quantum-audit . echo $? # 0 = no critical findings, 1 = critical findings found Exit 0 — no critical findings (safe to deploy) Exit 1 — critical findings detected (block the build) Medium findings (SHA-256, AES-128) don't fail the build — they appear in the output as warnings but don't block deployment. Only CRITICAL findings (RSA, ECDSA, secp256k1) cause a non-zero exit. GitHub Actions Add this to your .github/workflows/ci.yml : name : CI on : push : branches : [ main ] pull_request : branches : [ main ] jobs : quantum-audit : runs-on : ubuntu-latest steps : - name : Checkout uses : actions/checkout@v4 - name : Setup Node.js uses : actions/setup-node@v4 with : node-version : ' 20' - name : Run quantum-audit run : npx quantum-audit . If your project uses ethers , web3 , elliptic , or any other ECDSA/RSA library — the step will fail and your PR cannot be merged until the finding is addressed. JSON output for custom reporting Need to parse the results programmatically? Use the --json flag: npx quantum-audit . --json Output: { "project" : "my-dapp" , "score" : 60 , "grade" : "C — Moderate Exposure" , "findings" : [ { "algorithm" : "ECDSA (secp256k1) signing" , "risk" : "critical" , "weight" : 40 , "file" : "package.json" , "line" : null , "source" : "ethers" }, { "algorithm" : "SHA-256 (crypto.createHash)" , "risk" : "medium" , "weight" : 8 , "file" : "src/utils/hash.js" , "line" : 14 } ] } You can pipe this into a Slack notification, a dashboard, or a custom reporting step. Slack notif
AI 资讯
Understanding HTML Forms
HTML Forms and the <form> Tag HTML forms are used to collect information from users through a webpage. They are commonly found in login pages, registration forms, contact forms, search bars, and online shopping websites. The <form> tag acts as the main container that groups different form elements together. When a user submits the form, the browser collects the entered data and prepares it to be sent to a server. <form> <label for= "name" > Full Name </label> <input type= "text" id= "name" name= "fullname" > <button type= "submit" > Submit </button> </form> Understanding the action and method Attributes The action attribute specifies where the form data should be sent after submission. This destination is usually called an endpoint . The method attribute defines how the data is sent. The GET method sends data through the URL, while the POST method sends data inside the request body, making it suitable for sensitive information. <form action= "/submit" method= "post" > <input type= "text" name= "username" > <button type= "submit" > Submit </button> </form> Understanding Common Form Attributes The <form> tag supports several attributes that control its behavior. Attributes such as autocomplete , target , enctype , novalidate , and accept-charset improve the user experience and define how the browser handles form data before and after submission. <form action= "/submit" method= "post" autocomplete= "on" target= "_self" > </form> How an HTML Form Works When a user enters information and clicks the Submit button, the browser collects all form data and sends it to the location specified by the action attribute using the HTTP method defined in method . The server processes the request and returns a response to the browser. <form action= "/login" method= "post" > <input type= "email" name= "email" > <input type= "password" name= "password" > <button type= "submit" > Login </button> </form> Why HTML Forms Are Important HTML forms make websites interactive by allowing users t