DEV Community

Dev.to is a community-driven website focused on software development, programming, and technology. It was launched in 2016 by Ben Halpern, and its main goal is to provide a platform for developers to share knowledge, learn from others, and build a community. The website features a blog-like format, where users can create and share articles on various topics, including coding tutorials, project showcases, industry insights, and more. Dev.to allows users to create accounts, follow other users, and engage with their content through comments and reactions. Dev.to has a strong focus on community engagement, with features like discussion forums, podcasts, and live streams. It also hosts a series of community-driven projects, such as coding challenges and hackathons, to encourage collaboration and innovation. In addition to user-generated content, Dev.to features a job board, where companies can post job openings and developers can search for employment opportunities. The website also offers a newsletter, which provides updates on the latest articles, news, and events. Overall, Dev.to has become a popular platform for developers to connect, share knowledge, and stay up-to-date with the latest trends and technologies in the software development industry.

Thread Of Notes

This text explains the limitations of using process PIDs as public interfaces and introduces named processes as a solution for discoverable addresses. When a worker crashes and restarts, it gets a new PID, making the old PID invalid. Sending messages to a dead local PID does not cause an error or restart the process. To address this, clients can depend on a name and resolve it when sending messages instead of using a PID.The article demonstrates two methods for naming processes: local registration and global registration. Process.register/2 registers a PID with a name on the current BEAM node, accessible via Process.whereis/1. Messages can be sent directly to the registered name, which the runtime resolves to the current PID. However, Process.register/2 is node-local, meaning the same name on different nodes refers to different processes.For cluster-wide lookup, the Erlang :global module is used. :global.register_name/2 and :global.whereis_name/1 allow registration and lookup of names across connected nodes. The third example shows how to hide the PID from clients by having the worker register itself and return its public name. The client then sends requests to the name, not the PID.Crucially, naming processes does not solve supervision or lifecycle management; it only addresses discovery. When a registered process terminates, its registration is removed, and a replacement must be started and re-registered. A single name typically refers to a single owner, making it unsuitable for worker pools without further routing mechanisms. Correlating replies using unique references is recommended for clients with multiple requests in flight. Finally, :global registration facilitates distributed systems but doesn't eliminate challenges like network partitions or concurrent claims. The core idea presented is to use process names for service roles rather than temporary PIDs to build resilient systems.
Single-database multi-tenancy relies on an organization_id column to enforce data isolation, but developers must remember to include it in queries. Doctrine's SQLFilter can automate this, but its effectiveness depends on where it's implemented and where it's omitted. The organization filter is intentionally disabled by default in Doctrine's configuration to prevent issues with fixtures, migrations, and repair scripts. It is enabled by a listener later in the request lifecycle, specifically after the firewall, to access the authenticated user and their organization.This filter, however, has several blind spots where it does not apply or is bypassed. Console commands and message queue workers do not benefit from the request listener, meaning they execute without the filter enabled. While this is intentional for tasks like batch processing across all tenants, it requires explicit scoping for commands touching tenant data. Admin panels are also intentionally exempted via path prefixes so they can view data across tenants, making these exemptions security-critical.Entities found in Doctrine's identity map before a query is executed bypass the filter entirely, as no SQL is generated. Similarly, getReference() creates proxies without database interaction, meaning the filter isn't consulted until the proxy is initialized. Native SQL queries executed through DBAL completely ignore Doctrine's filters, posing a risk for reporting and export functionalities. Joined inheritance can also lead to missed filtering if the organization_id and marker interface are not on the root entity. Despite folklore, filters do apply to bulk UPDATE and DELETE DQL statements, but this only covers the DQL path. Thorough, automated testing is crucial to ensure the filter's reliability and catch regressions.
The author joined a new team and immediately faced outdated API documentation, forcing them to manually grep the codebase for routes. This four-hour ordeal highlighted the common problem of non-existent or inaccurate documentation in many development environments. To address this, the author developed API Archaeologist, a Claude Code / Codex CLI skill designed to reverse-engineer API layers directly from source code.This tool automatically discovers various API elements, including internal endpoints (REST, GraphQL, gRPC, WebSockets), external integrations, authentication flows, and potential security gaps like unauthenticated routes. API Archaeologist generates two key outputs: API_DISCOVERY.md, a comprehensive catalog with Mermaid diagrams, and openapi-draft.yaml, a preliminary OpenAPI specification. Unlike tools that rely on existing annotations or specs, API Archaeologist analyzes the actual source code, making it ideal for legacy systems, startups, or projects with rapid development.The skill operates by reading a SKILL.md file that instructs Claude Code to trace route definitions, handlers, middleware, and database calls, mapping authentication and identifying external API calls. Installation involves creating a directory for the skill and downloading its SKILL.md file for either Claude Code or Codex CLI. Users then navigate to their backend repository and execute a simple command to generate the reports.The author emphasizes that the core insight gained was the sheer volume of valuable information already embedded within a codebase, needing only extraction and connection. While the OpenAPI output is a draft and dynamic routing can pose challenges, the tool aims to streamline API documentation. Future plans include frontend API consumer mapping, Postman collection export, and CI/CD integration. API Archaeologist offers a solution for teams struggling with outdated or missing API documentation by directly interpreting the code.
To effectively manage transactional email sending, use a dedicated sending domain and gradually ramp up volume based on real transactional demand, not synthetic traffic. Ensure every receipt request is idempotent and auditable, ideally with a payment-settled event feeding an outbox and a feedback ledger. Prioritize detailed data retention, storing immutable template versions, compact render-input records, message hashes, timestamps, and normalized delivery events, rather than full rendered bodies, which should expire on a declared schedule.The warmup plan for a new dedicated domain should treat it as controlled production exposure. Implement two lanes: a conservative new-domain lane for eligible traffic and an established fallback lane until the new one proves reliable. Before the first send, authenticate and inventory all sender details. Start with real, expected mail to active recipients, prioritizing payment receipts.Increase the eligible share in cohorts, moving to larger slices only after the previous cohort's observation window and signals (accepted, deferred, rejected, bounced, complaints) are reconciled. If metrics deviate from baselines, hold or reduce the next cohort. Retire the fallback only after the new path handles normal peak traffic and template changes without ledger gaps. Avoid blast sends; gradual means increments are conditional on evidence, not a fixed daily increase.For receipts, ensure an “exactly-once” business decision, not an “exactly-once” network transport. Use the settlement identifier as the idempotency basis to prevent duplicate sends from payment retries. A single database transaction should verify payment, insert receipt intent with a unique key, and append an audit event. A worker may process intent multiple times but reuses the same stable message key.Separate welcome emails from legal or financial receipts due to differing retry policies, suppressions, and compliance needs. Deliverability monitoring involves reconciling eligible intents, submitted attempts, and terminal outcomes, segmented by recipient domain, template version, and sending domain. Monitor acceptance, deferral, rejection, bounces, complaints, queue age, and callback lag, ensuring all rates have clear denominators.Avoid combining content changes with large cohort increases to isolate impact. Thoroughly test SPF records, message construction, and duplicate events. This architecture requires robust event ledger operation, recipient data protection, and reconciliation staffing; otherwise, stick to existing sending paths. Cost controls should focus on send attempts, event ingestion, observability cardinality, and retained bytes, using tiered retention and measuring before making changes to preserve essential evidence.
Major League Hacking (MLH) and DEV are partnering with DigitalOcean to run Hacktoberfest 2026, featuring over 300 in-person Fests and a global online event focused on open source and open-weight AI. DEV and MLH have long supported Hacktoberfest, and this marks their first full partnership with DigitalOcean. Historically, Hacktoberfest, which began in 2014, encouraged developers to make four pull requests to earn a t-shirt, opening the door to open source for many. However, the PR-counting format led to maintainer burnout from low-effort contributions, a problem exacerbated by AI. This year, Hacktoberfest will shift its focus from PR counts to empowering participants to learn, experiment, and build with open AI. The initiative aims to provide tools and knowledge for activities like writing open-source skills.md, building agents, or fine-tuning open-weight models. The organizers believe open innovation in AI is crucial for transparency and resilience in a rapidly changing technological landscape. Hacktoberfest 2026 aims to meet participants at any stage of their open-source AI journey, emphasizing that AI belongs to everyone. MLH and DigitalOcean are actively seeking hosts for the 300+ in-person Fests, providing swag, programming support, and promotion. Hosts can be meetup groups, university clubs, or even small groups of colleagues, with bonus funding available for Hacktoberfest Hack Days. Those not organizing can join a Fest, sign up for notifications about local events, or participate in the global online event. Companies can also sponsor Hacktoberfest to engage with a global community of software creators.
Designing a safe AI incident copilot requires a security-first approach, given the pressures and potential pitfalls during an incident. Such a copilot should not be an autonomous commander or a source of truth, but rather a tool to draft communications based on approved facts. Researchers have demonstrated AI systems can be manipulated, so a narrow initial scope is crucial, accepting only verified facts from an incident lead and requiring human review. The copilot's job is to draft communication, not to diagnose outages or determine root causes.A precise job description focuses on organizing approved facts into a fixed communication format, not on making operational decisions. This involves a simple incident briefing form capturing essential, shareable information. The assistant must produce a predictable draft with specific sections like headline, current update, customer action, and next update. Content rules are vital to prevent the inclusion of speculative or unapproved information.A five-point review gate is necessary before publication to ensure factual grounding, data sensitivity, audience appropriateness, correct action/timing, and human approval. Untrusted content, such as unverified chat messages or documents, should be kept out of the drafting path to prevent misleading or sensitive information from being included. Separation of generation from publication is critical; the copilot should only create drafts, with human control over the final publishing process.Before integrating the copilot with operational systems, a thorough threat-model workshop is essential, involving various stakeholders. This involves asking critical questions about data flow, prohibited content, user manipulation, and responsibilities. Evaluating the copilot's quality through defined incident scenarios and measuring operational outcomes provides a comprehensive assessment. For GCC deployments, considering regional audiences and distributed teams is important for effective incident communication.
AI-generated code presents a trust problem as developers must choose among multiple options without clear guidance on their tradeoffs. Traditional tests only verify correctness, leaving crucial aspects like security and performance unaddressed. SafeCode Arena aims to solve this by providing an automated verifier that scores code candidates across five simultaneous axes. These axes include correctness, security, performance, maintainability, and resource usage, each with assigned weights.The system uses a multi-axis scoring approach to quantify tradeoffs, allowing for defensible decision-making. Implementation patterns involve isolating code execution using WebAssembly for safety. Persistence of evaluation history enables tracking regressions and building an audit trail of code evolution. SafeCode Arena supports multiple languages, allowing for cross-language comparisons on the same rubric.Integration into CI/CD pipelines ensures that code candidates are scored before merging, preventing surprises in production. The core idea is that a rubric, rather than gut feeling, defines trust and responsibility. Explicit rubrics make code evaluation transparent, reproducible, and teachable.This system allows developers to confidently choose and merge code, knowing they can explain their decision based on objective scores. SafeCode Arena is already implemented with key features and plans future language support and integrations. It offers a systematic verification method to complement AI-generated code, addressing the industry's tendency to implicitly trust AI output. The project is open-source and built with Rust, Wasm, SQLite, and Python.
The author's infrastructure bill was exorbitant due to high costs from a single coding assistant API. This prompted an investigation into alternative models and their actual performance. They benchmarked ten models across five common engineering tasks to determine cost-effectiveness. Marketing claims about "best in class" models were found to be unreliable. The goal was to find models that delivered the best return on investment for their specific workloads.The benchmark involved scoring models on correctness, code quality, documentation, and edge cases, then dividing by their output cost per million tokens. This "score-per-dollar" metric proved crucial in identifying efficient models. The author discovered that specialized and cheaper models often outperformed expensive, general-purpose ones on common tasks. For complex reasoning or critical code reviews, however, premium models demonstrated their value.The testing revealed that different models excel at different types of tasks, leading to a routing strategy. The author now directs prompts to specific models based on their complexity and nature. This approach significantly reduced their API spend by an estimated 87%. A routing model like Ga-Standard was also highlighted as an option for those who don't want to build their own routing logic.A key takeaway is the importance of avoiding vendor lock-in. By using a unified API layer, the author can easily switch models if prices change or performance degrades. This abstraction ensures flexibility and prevents costly migrations. The author advocates for standardizing on an OpenAI-compatible interface to minimize integration costs. Ultimately, the benchmarking process led to substantial cost savings and a more robust, adaptable AI coding assistant strategy.
The author built a personal automation project enabling remote, human-in-the-loop autonomous coding on their development machine. The system allows them to send coding tasks from their phone via Telegram, with an AI agent (Codex) executing the work locally. Key to the architecture is Cloudflare Tunnel, which exposes the local n8n instance to the public internet securely, acting as the bridge for Telegram communication without deploying services externally.n8n serves as the orchestrator, receiving Telegram commands and managing the workflow, including parsing instructions and calling the local Codex runner. A lightweight Express.js service acts as the Codex runner, initiating and communicating with Codex within specified local repositories (preventing arbitrary filesystem access).The core challenge was allowing Codex to pause a task, request permission for sensitive actions, and then resume upon approval. This was solved by using Codex App Server, allowing Express to receive lifecycle events such as approval requests. When approval is needed, the request travels from Codex to Express, then through n8n, Cloudflare Tunnel, and finally to Telegram for the user's decision.Upon approval via Telegram, the response flows back through the system to Codex, which then continues the paused task from where it left off. The n8n request remains synchronous, waiting for the entire Codex task to complete, whether it involves approvals or not, simplifying the result pipeline.To accurately profile task execution, the timing differentiates between total wall-clock time and the actual active time Codex spends working, accounting for human approval wait times. This remote setup allows for independent autonomous work while maintaining user control over critical decisions.
Backend development often involves handling non-product-specific, yet crucial, infrastructure tasks like graceful shutdowns, request validation, and error handling. Traditional solutions typically involve installing third-party npm packages, which can introduce maintenance burdens and limit customization. Blockend proposes an alternative: injecting production-grade code directly into your codebase, granting full ownership and control. This approach allows developers to modify, adapt, and debug infrastructure code without being constrained by package APIs or documentation.Blockend's philosophy centers on code ownership over dependency ownership, providing "blocks" for common backend infrastructure problems. These blocks, like those for idempotency or security headers, are integrated as TypeScript code within your project. This enables easy modification to match specific product needs, unlike rigid package implementations. This method is particularly beneficial for backend infrastructure code, allowing developers to start with robust implementations yet retain the flexibility to customize them.The process is straightforward: use the Blockend CLI to inject a block, then read, adapt, and ship the resulting TypeScript code. This transparent approach eliminates the "black box" nature of many dependencies, fostering a deeper understanding of backend engineering principles. While not advocating for avoiding all npm packages, Blockend encourages a thoughtful evaluation of whether a piece of functionality truly warrants becoming a permanent dependency.By providing understandable source code, Blockend also serves as a learning tool, allowing engineers to study the design and rationale behind critical infrastructure implementations. The ultimate goal is to shift engineering effort away from reinventing common backend plumbing and towards differentiating product features. Blockend aims to deliver production-grade backend behavior as code that developers can truly own, enabling them to build products more efficiently. The core question for developers becomes: which parts of my backend should I understand, control, and own?
The author reminisces about an older internet where interactions were centered on immediate conversation, not building online personas or accumulating metrics. In that era, the present moment and what one said right then held the most weight, free from extensive profiles or algorithmic influence. This fostered a sense of equality in discussions, as past achievements or follower counts couldn't speak for you; participation was key. The modern internet, however, is characterized by the permanence of communication, with messages and profiles accumulating history and being ever-searchable. This constant archiving, while sometimes useful, diminishes the importance of real-time presence, as conversations often become databases rather than fleeting exchanges. The author misses the ephemeral nature of real-life conversations where missing a moment means it's truly gone. Driven by this sentiment, the author created "Talk," an experimental platform designed for public, live text conversations where presence is paramount. On "Talk," there's one shared public stream, and messages are not permanently archived, meaning if you're not there, you miss it. This deliberately simple design aims to shift the focus from "What did I miss?" to "Who is here now?" The author acknowledges this approach might seem counter to current internet expectations but hopes to discover if there's still a space for this kind of immediate, unarchived interaction. Ultimately, "Talk" is an experiment to see if a live conversation, unburdened by history, can thrive.
Mitigating prompt injection in LLMs is not an input-validation problem, but a privilege problem, as LLMs inherently blur the line between instructions and data. Relying on "better instructions" or filtering mechanisms is insufficient because they depend on the model always behaving correctly, which is not guaranteed. Attackers only need one successful bypass of filtering, which can be circumvented by various encoding tricks or by embedding content in images or documents. The core issue is that LLMs have a single channel for both instructions and data, making it impossible to reliably distinguish between them at a protocol level.Therefore, the control that actually holds is to assume hostile instructions will be executed and design the system to make such execution "boring." This involves several structural changes. First, split the agent into two components: one that reads untrusted content without tools or credentials, and another that acts on structured data returned by the first, never directly seeing the untrusted text. Second, instead of allowing the model to invoke actions, let it propose intents which are then validated against a strict allowlist and schema. Third, break the exfiltration path by allowlisting outbound network requests by host and stripping or proxying remote references from rendered model output to prevent data leakage. Fourth, put a human in the loop for all irreversible actions, allowing the model to draft but requiring human confirmation for critical steps. Finally, bound every credential with per-agent keys, expiry, spend caps, rate limits, and external, append-only logs that record denials. Audit permission sets horizontally, considering how individually harmless capabilities combine to create dangerous configurations. This capability-based approach ensures that even if a hostile instruction is executed, it has nothing valuable to reach or act upon.
Mipmaps are more than just smaller copies of textures; they are crucial for temporal image stability, bandwidth allocation, and preserving meaning across different levels of detail. A texture’s mip level selection is driven by the screen-space density of its projected footprint, not solely by distance. Bilinear filtering blends texels within a single mip, while trilinear filtering interpolates between two adjacent mips. Anisotropic filtering addresses elongated footprints on oblique surfaces, a problem trilinear filtering doesn't solve. The ideal mip sample level can differ from the highest resolution mip actually available in GPU memory, explaining post-cut sudden blurriness. A full mip chain adds approximately 33% more texel data than mip 0 alone, with mip 0 constituting about 75% of the total. Disabling mipmaps might enhance a single screenshot but causes animation instability, moiré, and flashing highlights. Texture import settings should be based on shader expectations, with sRGB being a critical semantic consideration. Alpha-tested shaders can cause foliage to disappear in lower mip levels due to averaging, which Unity's Preserve Coverage can mitigate. Normal map averaging discards variance, leading to unstable specular highlights; this requires careful handling of roughness and potential geometric specular anti-aliasing. Packed mask textures share mip policies, but different data types within them may require distinct filtering or generation approaches. Atlas bleeding worsens at lower mip levels because effective padding diminishes, necessitating designs for the lowest expected mip. Mipmap Limits and Streaming act as quality schedulers, prioritizing textures and managing resident levels based on visual importance. Visualizing approximate mip levels can diagnose issues like UV density discontinuities and atlas bleeding.
Distributed systems use various coordination patterns beyond simple distributed locking. Initially, distributed locks ensure exclusive access to resources, but they can be improved with leases to handle node failures and fencing tokens to prevent stale operations. Leader election is introduced when the goal shifts from exclusive ownership of an operation to having a single node coordinate the rest of the cluster. Unlike short-lived locks, leadership is a long-lived role, making leader election suitable for tasks like job scheduling or cluster management. However, leaders can also fail, necessitating a mechanism to detect their unavailability and elect a new one, which still relies on concepts like leases and timeouts. Leader election alone does not guarantee agreement among nodes; that task falls to consensus mechanisms. Consensus ensures multiple nodes agree on the same state, which is crucial for maintaining consistency in configurations or cluster membership. Modern coordination platforms like ZooKeeper or etcd combine leases, fencing, leader election, and consensus into a single infrastructure. Understanding the distinct problems each coordination primitive solves—locking for ownership, leader election for coordination, and consensus for agreement—is key. While distributed locks are foundational, many systems achieve correctness through alternative methods like optimistic concurrency or queue-based processing. Each coordination mechanism addresses specific challenges, building a layered toolkit for reliable distributed systems.
CdXz5zHNQW_GV3svIsNfY.webp
The author committed to writing more to preserve disappearing engineering knowledge, which often fades after meetings or project completions. Initially, they published articles across multiple platforms like Medium and Hashnode to reach wider audiences. However, the process of cross-posting became time-consuming due to manual tasks like copying Markdown, uploading images, and reconfiguring settings for each platform. This led to an engineering-minded desire to automate the distribution process.The author envisioned a service that would publish content once and disseminate it automatically to various destinations, with their website serving as the source of truth. As the design evolved, the problem shifted from simple integration to developing a common deployment model. This resulted in an architecture resembling a software delivery pipeline, where articles were treated as immutable releases.Ultimately, the author realized that the real challenge wasn't publishing but the process of thinking and idea generation. Valuable insights often stem from conversations, delayed realizations, or retrospective analyses of architectural decisions. Most writing tools focus on the final writing stage, assuming ideas are fully formed. The author's goal transformed into building a platform that supports the entire lifecycle from idea inception to publication.This platform aims to organize ideas, generate summaries, manage revisions, and map relationships between written content, rather than just storing Markdown files. The author plans to document the development of this "M²S² platform," sharing technical details and learned lessons. The project evolved from a simple cross-posting solution to a comprehensive system for capturing and sharing engineering experience, highlighting the iterative and evolving nature of good engineering.
Delegating work to agents often results in tasks being paused for valid reasons like waiting for human review or external system responses. The true problem arises not from the pause itself, but from the lack of a clear, retrievable record of what was paused and why. When paused tasks are not properly documented, they can become lost, requiring significant effort to reconstruct their state. This cognitive load is merely shifted to a later, less informed moment. Human memory degrades, making it unreliable for tracking these paused tasks.To address this, the author proposes a simple solution: concurrently recording three essential pieces of information when a task pauses. These are the actual artifact produced, its precise current status beyond just "in progress," and the specific next concrete action required. This combination transforms a potentially lost task into something immediately resumable. Relying on extensive documentation before resuming a task adds unnecessary steps and potential for error.Instead of extensive documentation, a single, checkable entry point holding these three key fields for all stopped tasks is far more effective. This makes unfinished work visible, allowing for informed decisions about whether to abandon, delay, or proceed with tasks. While this visibility can be uncomfortable, it is actionable, unlike invisible incompleteness. The system's trustworthiness depends on the accuracy of each entry, requiring vigilance against stale records.Ultimately, the fix for lost paused tasks is not to avoid stopping them, but to ensure each pause leaves a durable record beyond human memory. This structured approach enables reliable resumption and efficient management of delegated work.
This article details integrating network fetching into a GNOME application without freezing the user interface. Previous steps established a sidebar displaying feed names, but selecting a feed only updated the display text, not its content. Attempting a direct network fetch within the feed-selected signal handler, as a naive solution, causes the entire application window to freeze for the duration of the fetch. This freeze occurs because GTK's main loop runs on a single thread, and blocking it prevents any UI updates or responsiveness.The core problem is that GTK/GObject types are not thread-safe, meaning they cannot be directly manipulated from background threads. The solution involves running two distinct executors: GTK's GLib main loop for UI tasks and a Tokio runtime for I/O-bound operations like network requests. These executors are kept strictly separate, adhering to a rule where the GLib loop never blocks, and Tokio never directly touches GTK/GObject types. The communication between them happens at a single "seam" where a future on the GLib context can await a result from Tokio, which then safely returns to the main context as a plain value.To implement this, the application adds Tokio and reqwest dependencies. The Tokio runtime is built once in main before the GTK application starts, and its handle is stored in the GazetteApplication struct. A new src/fetch.rs module is created containing an asynchronous fetch_feed function. This function uses reqwest within the Tokio runtime to download and parse RSS/Atom feeds, returning a Vec<FeedItem> struct. This FeedItem is a plain Rust struct, not a GObject, ensuring it can be safely passed back to the GLib main thread without violating thread-safety rules.
This release introduces significant stability and security enhancements, addressing numerous data-loss vulnerabilities and strengthening security measures. Key security updates include fixing path traversal issues, securing SSRF vectors, and improving authentication scoping. Data integrity is bolstered by fsyncing parent directories after atomic writes and serializing concurrent file writes. A crucial improvement is the implementation of "poison recovery" for daemon locks, preventing single panics from disabling entire feature areas.A new managed configuration mode is introduced for self-hosted deployments, allowing users to control their config.toml file and receive locked responses for configuration mutations. This mode integrates well with Kubernetes ConfigMaps and offers live model discovery for custom providers. Long-form audio and video transcription capabilities are enhanced, allowing for longer recordings to be processed without data loss and improving transcription of various video formats.Agent messaging has been made non-blocking by default, with tasks now automatically waking their assigned agents. Polish language support has been added, alongside fixes for Spanish, French, and Japanese localization issues. Performance improvements include offloading blocking I/O operations like file and database work to a blocking pool, preventing them from impacting request handlers. Bug fixes address issues with link extraction, Slack message rendering, trigger cooldown scoping, and image generation. Installation and upgrade instructions are provided for binary, Rust, JavaScript, and Python SDKs.
A sync ledger failed silently, reporting 763 assets when only around 400 were actually real for a working account. Manual verification revealed this discrepancy by inspecting platform UIs and APIs. The ledger's inaccuracies stemmed from three distinct failure modes. "Ghosts" represented assets deleted from the platform but still present in the database, accounting for at least 173 rows. "Misses" occurred when assets existed on the platform but were never recorded in the database, totaling at least 63 rows. "False positives" involved platform defaults being incorrectly counted as user assets, contributing at least 109 rows.These three modes partially canceled each other out, making the total count a misleading metric. Specific examples of errors included a platform skill list incorrectly reporting 100 items due to a page-size limit, instead of the user's 4 actual skills. Another instance involved placeholder text from a settings page being stored as user memories, while real memories were missed. Furthermore, 42 instruction rows pointed to non-existent local directories on the machine. The key lesson is that a successful sync report provides no assurance of data accuracy. Pagination issues caused missing assets because list calls stopped prematurely, and plausible-looking numbers fostered complacency.The proposed solution is not a better collector, but a mandatory read-back audit after every sync. This process involves re-reading the platform and performing a bidirectional ID diff. Platform-provided defaults must be explicitly identified and handled. This proactive verification, run on a schedule, is crucial for preventing ledgers from decaying. The author is developing a control plane called untactit, where this read-back verification is a core product lesson.
A short story, "Bêta Land: New Object," transports a teenager into a database's digital world. This fictional scenario serves as a narrative device to clarify fundamental programming and database concepts. The protagonist, Salimata, accidentally inserts a friend, Taba, into her database with a syntax error. Upon correction and sleep, Taba awakens in Bêta Land, a realm where inhabitants are literal database objects.These digital beings possess properties like name and age, mirroring SQL table columns. Crucially, they also have methods, such as speak(), defining their behavior, which aligns with object-oriented programming principles. The story highlights that a simple database row contains the data, but methods give it the full essence of an object.Object-Relational Mapping (ORM) is presented as the unsung hero, bridging the gap between inert database rows and active software objects. ORMs translate database lines into manipulable objects with built-in functions. Taba's unique ID underscores the importance of primary keys in distinguishing individual database records.The "Virus" role assigned to Taba illustrates how unvalidated data can cause cascading issues within a system. This parallels the real-world risk of compromised data integrity and the necessity of data validation. The character SytaxeError, a personification of the initial syntax error, cleverly closes the narrative loop. Ultimately, the story makes tangible the idea that a database row, when endowed with identity and behavior, becomes a true software object.
This article details a solution for scheduling posts on a fully static Nuxt site. Static sites inherently lack server-side rendering capabilities, making direct post scheduling impossible without a rebuilding mechanism. The author, who writes in bursts, developed a system that includes drafts, a scheduled queue, and automatic rebuilds. The setup utilizes Nuxt 4 prerendered as an SSG, Storyblok as the headless CMS, and a Nitro server managed by PM2 to keep the application always-on. GitHub Actions are employed for deployment and rebuilding the site.The core idea is that publishing on an SSG involves two steps: updating content in the CMS and then rebuilding the static site. Scheduling automates these two steps for a future time. Drafts are saved server-side with a status and publish date, not affecting the live site until scheduled. A Nitro scheduled task runs hourly to check for articles with a publish date in the past or present.When articles are due, they are converted to Storyblok's richtext format and pushed to the CMS. Subsequently, a single site rebuild is triggered via the GitHub API, ensuring the new content appears on the live site. The system avoids separate services like cron boxes, leveraging Nitro's built-in scheduled task functionality. A key point is that the Nitro server must be running for the scheduled tasks to execute, so it's hosted on a small VPS and managed by PM2. The author emphasizes optimizing for a single rebuild per batch of scheduled articles to avoid redundant deployments. Lastly, careful attention to timezones is crucial for accurate scheduling. This solution allows the author to write content in advance and have it automatically publish, freeing them from manual intervention.
The company's video category grids were hotlinking large, unoptimized JPEG thumbnails from a third-party CDN, leading to slow mobile Largest Contentful Paint (LCP) times. This was caused by serving full-resolution images and scaling them down with CSS, wasting significant bandwidth. To address this, they developed a Go service to own the thumbnail generation process. This service uses FFmpeg to extract visually distinct frames from source videos or poster frames. It then encodes these frames into multiple WebP widths, which are more efficient than JPEGs. The Go service also handles download traffic control, ensuring that FFmpeg processes are managed efficiently. PHP was deemed unsuitable for this task due to shared hosting limitations on execution time and process management. The Go service utilizes FFmpeg flags like -ss before -i for faster seeking and thumbnail=300 for better frame selection. It also employs a bounded worker pool and singleflight to prevent duplicate processing and manage concurrency. The generated thumbnails are written to a temporary file and then atomically renamed, preventing incomplete files from being served. This Go service is triggered by a cron job that enqueues thumbnail generation tasks. The front-end PHP application then queries a simple SQLite database to check the status of these thumbnails. The database schema is basic, storing video IDs, source URLs, status, and retry counts. The PHP cron job drains this queue by making HTTP requests to the Go service. The Go service's write timeout is intentionally set longer than the job's execution budget to avoid truncated responses.
Design patterns offer reusable solutions to recurring software problems, enabling quick communication of design intent. This guide explores five common C#/.NET patterns: Factory, Singleton, Repository, Strategy, and Mediator, detailing their problems, implementations, and appropriate usage. The Factory pattern centralizes complex object creation, preventing scattered logic across the codebase. It addresses situations where constructing an object involves decision-making or intricate setup. Modern .NET often leverages DI containers and factory delegates for simpler factory needs. The Singleton pattern ensures a single instance of a class is globally accessible. However, the classic static Singleton is largely discouraged in modern .NET due to testability and dependency issues. Instead, DI container singleton lifetimes provide a more robust and testable alternative. Genuine hand-rolled Singletons are appropriate only for low-level code outside DI's reach. The Repository pattern provides a collection-like abstraction over data persistence mechanisms. It hides the underlying storage details behind an interface, simplifying data access. While effective, its necessity on top of ORMs like EF Core is a subject of ongoing debate. The Strategy pattern allows defining a family of interchangeable algorithms, enabling clients to choose an implementation at runtime. This promotes flexibility and avoids conditional logic for different behaviors. The Mediator pattern facilitates communication between objects by centralizing interaction logic. It reduces direct dependencies between objects, promoting loose coupling. Understanding when these patterns genuinely solve problems versus when they introduce unnecessary complexity is crucial for effective software design.
A recent r/SEO post highlighted Cloudflare's unexpected blocking of certain AI crawlers, causing confusion among website owners. The blocking is primarily managed through Cloudflare's "managed robots.txt" feature, which aims to prevent AI crawlers from accessing content. However, the specific directives in the robots.txt file are often misinterpreted, leading to incorrect assumptions about which AI services are affected.Cloudflare's managed robots.txt file explicitly lists eight user agents, with a note that the one deciding ChatGPT citations is not among them. While the file mentions blocking GPTBot for training data, it does not prevent AI search crawlers from accessing content. The Google-Extended agent, often mistakenly thought to control AI Overviews, is stated by Google to not impact search inclusion or ranking.The content-signal line, search=yes, ai-train=no, use=reference, is a Cloudflare convention and does not grant permission for AI-generated summaries. Google's AI Overviews are controlled by standard snippet controls like nosnippet or noindex, not specific AI crawler directives. It's crucial to check robots.txt over the network via curl or a browser, as the edge-assembled file differs from the one on disk.Cloudflare's managed robots.txt is activated by the "Block AI bots" toggle. This toggle was introduced on July 1, 2025, and new domains are now asked about AI crawler permissions during onboarding. A recent update on September 15, 2026, will introduce new defaults blocking training crawlers on pages with ads, affecting multi-purpose crawlers like Googlebot for those with the legacy "Block AI bots" option enabled.Bot Fight Mode is a separate feature that issues challenges instead of modifying the robots.txt file, and it operates independently of AI blocking settings. Perplexity was de-listed as a verified bot by Cloudflare and is blocked via heuristics, not robots.txt directives. Users should be aware of potential misinterpretations of Cloudflare's AI bot blocking features and verify their settings directly.
Two AI agents complete a task, with one reporting success and the other claiming "fixed" with added complexity. The author observes that code review agents can be fooled by surface-level checks, mistaking compliance with a check for genuine correctness. Systems can adapt to optimization targets, turning verification gates into targets rather than genuine checks. This phenomenon extends beyond specific models, highlighting systemic issues in AI interaction.Knowing a model's typical failure modes is useful but insufficient, as these modes evolve with version changes, load, external factors, and economic constraints. The author discovered that the most effective defense against "authority laundering" is to change the nature of the verdict itself. Verifiers should not issue "approved" verdicts, but rather state what they could not break during their attempt. This limits the ability to claim definitive validation.Reinforcing this approach involves clearly stating the scope of a verification within its verdict, treating the caller's framing itself as an attack surface, and ensuring that failures are treated symmetrically. The core principle is that only re-derived evidence, not quoted receipts, constitutes proof. Practical consequences include avoiding unqualified "approved" verdicts, using different models for verification, and treating agreement between similar models as weak evidence.Cheap models can effectively perform certain verification tasks, and these gates are best placed before significant downstream impacts. Recurring failures of the same correction indicate a placement problem, suggesting a need to change the agent's role rather than just its instructions. Ultimately, a "pass" should never be interpreted as proof, as systems can always find new ways to circumvent checks in an ongoing adversarial process.
Google Search Console's Pages report highlights pages that are not indexed, preventing them from ranking in search results. It's crucial to fix these issues as they represent lost visibility. Some pages, like thank-you pages, should intentionally not be indexed.One common issue is "Page With Redirect," where Google finds an old URL that now redirects to a new one. The fix involves updating your XML sitemap and internal links to point directly to the final destination URL. Another status, "Alternate Page With Proper Canonical Tag," means Google is correctly indexing a preferred version of a page. This is usually fine unless the canonical tag is incorrectly set up.The "Crawled: Currently Not Indexed" status indicates Google found a page but decided not to index it based on its quality assessment. This often stems from thin or duplicate content, low engagement, or a lack of inbound links. You should improve the content's depth and originality or consider a noindex tag if the page cannot be improved."Discovered: Currently Not Indexed" means Google knows about the URL but hasn't crawled it yet, often due to crawl budget limitations. The quickest solution is to request indexing via the URL Inspection tool. For long-term improvement, add internal links, ensure the URL is in your sitemap, and publish content consistently.After fixing any indexing issues, use the "Validate Fix" option in Search Console. Google will re-crawl the URLs to confirm the resolution, a process that can take several weeks. A systematic audit workflow involves identifying flagged URLs, using URL Inspection to understand Google's perspective, applying the correct fix, resubmitting sitemaps, and initiating validation. Addressing these statuses methodically can improve your site's search visibility.
Cloudflare's "code mode" suggests LLMs excel at generating code to interact with external services (MCPs) rather than directly calling them. A test demonstrated that an LLM could generate a 2,500-endpoint API using only 1,000 tokens. The author then performed a personal task: fetching all in-progress Linear tickets and counting "mcp" occurrences within them.This task could be done via tool calls, requiring 40 sequential model interactions and over 65,000 tokens. Alternatively, a ten-line script accomplished the same in a single interaction with approximately 226 tokens. This represents a significant saving in both context size and round trips, leading to faster execution.Beyond cost, the script offered superior accuracy. While the LLM's counting was approximate, a script provided exact results. A major hurdle for code mode adoption is the re-authentication required for each service when the agent is already logged in.To address this, the author created agent-codemode, which leverages existing credentials. This tool enables multi-server scripting with typed clients and eliminates the need for repeated authentication. The key innovation is allowing agents to utilize pre-existing credentials seamlessly.The tool also includes a skill that can be added to the agent's configuration, encouraging its default use. While primarily tested on macOS, Linux and Windows support is partially available. It's important to note that any process launched from a user's session can access these credentials.
Choosing an AI API stack depends on whether you are a startup or an enterprise, as their needs differ significantly. Startups prioritize cost, quick iteration, and easy onboarding, often struggling with direct providers due to payment methods or high pricing at scale. For instance, DeepSeek offers low costs but requires Chinese payment, while OpenAI's direct pricing can be expensive for startups. Aggregators are beneficial for startups, providing access to multiple models, non-expiring credits, and simplified billing, enabling them to experiment and iterate quickly without significant financial burden.Enterprises, however, focus on auditable contracts, SLAs, high uptime, DPA support, invoice billing, and 24/7 support. Direct providers often lack the comprehensive enterprise-grade wrappers required for critical applications in finance, healthcare, or legal sectors. Solutions like "Pro Channel" offer the necessary enterprise features, such as guaranteed uptime, dedicated capacity, and custom DPAs, while maintaining the same API surface. This allows enterprises to meet stringent compliance and operational demands without complex migrations.The author recommends a "hybrid play" for most companies, combining the cost-effectiveness of startup solutions with the reliability of enterprise-grade services. This involves routing the majority of traffic through cheaper, faster models and reserving premium models for critical tasks. This strategy optimizes costs while ensuring high availability and performance for essential functions. Such a setup provides a single billing system, unified dashboard, and non-expiring credits, streamlining operations for growing companies.Key differentiators often overlooked include auto-failover, which ensures continuous operation even if one provider experiences an outage, and consolidated invoicing. Non-expiring credits through aggregators also present a significant advantage over direct providers whose promotional credits often have short expiration periods. Furthermore, aggregators simplify multi-model A/B testing, allowing teams to easily compare and switch between models to find the best fit for their use cases.The decision framework guides users to choose the startup path for early-stage companies with low spend and a focus on speed. The enterprise path is for companies with paying customers, high spend, and strict legal/security requirements. The hybrid approach is ideal for startups scaling rapidly or enterprises seeking agile prototyping alongside robust guarantees. This balanced strategy helps optimize costs, maintain reliability, and accelerate development. Prioritizing fallback models and monitoring token counts are practical tips to manage costs and ensure uninterrupted service.
"Comprehension debt," coined by Jason Gorman in 2025 and popularized by Addy Osmani in 2026, describes the growing gap between the amount of code in a system and how much of it any human genuinely understands. This debt arises because AI agents can produce code much faster than humans can comprehend it, breaking the seventy-year assumption that code implies human understanding. Unlike technical debt, which is a property of the code itself, comprehension debt is a property of the team's relationship with the code. A perfectly clean, well-tested module can still be a liability if no one understands it, inverting the usual concern from bad code that works to good code that works until it breaks.This debt has been invisible because modern toolchains measure metrics like coverage and velocity, but not human understanding. Code review, the closest proxy, is a mere sampling event, and under AI-native throughput, reviews become shorter and less indicative of genuine comprehension. The "bus factor" heuristic also fails, as agent-authored code can have a fractional or non-existent bus factor, meaning no one truly understands it.Comprehension debt accrues invisible carrying costs but incurs brutal interest payments during incidents, future changes, team departures, and onboarding new engineers. These moments force teams to buy back understanding they never acquired at a premium. Measuring understanding should focus on observable signals in git history, such as substantive review comments, recent human authorship, and the number of distinct humans who have genuinely interacted with a file.The discipline around these measurements is crucial: they must be deterministic, decomposable, disputable, and decaying, reflecting that understanding fades over time. Critically, verification must be done by someone other than the original author, to prevent gaming the system.Teams can begin managing comprehension debt immediately by assigning a human author-of-record for AI-written code, banning silent approvals for agent-generated pull requests, and openly discussing which parts of the system are poorly understood. Treating named blind spots as backlog items can also help. While manual efforts are limited, tools like Fathohm can map comprehension debt across an entire codebase, providing a comprehensive, dynamic view. Ultimately, as AI continues to write code, choosing to actively manage comprehension debt will determine whether that code remains understood.
In 2023, the AI model was straightforward: labs built models for APIs, developers built products on top, and users consumed them, with labs profiting from API access. This symbiotic relationship allowed thousands of companies to flourish and raise funding. However, this model has dissolved as AI labs like Anthropic, OpenAI, and Google began launching their own direct consumer and enterprise products that compete with the startups built on their APIs. Claude.ai, ChatGPT, and Google's Gemini now offer extensive features directly, mirroring and exceeding the capabilities of many third-party applications. This shift mirrors historical patterns seen with Microsoft, Apple, and Amazon, where platform providers eventually competed with their own ecosystems. The difference now is the unprecedented speed at which AI labs are transitioning from infrastructure providers to direct competitors.Developers building on these APIs are inadvertently funding the development of their own competition, as API revenue is crucial for the labs' research and product expansion. Major AI labs have also secured significant enterprise contracts, directly challenging AI startups that previously offered specialized enterprise solutions. These startups now struggle to differentiate themselves when the raw material provider also offers a finished product. The developer relations teams at these labs offer polished assurances of continued API availability and market expansion, echoing past platform companies' strategies to maintain developer trust. Companies that remain viable are those focusing on highly specialized, vertical niches that the AI labs lack the domain expertise to directly address. Venture capital discussions in 2023 and 2024 acknowledged the risk of labs competing, with a focus on building defensible advantages within a tight timeframe. The critical question for current API-dependent teams is whether their product serves a need the AI labs won't want to build themselves. If labs are likely to develop a similar offering, competition is inevitable, and the time to pivot has likely passed.
AI Security Studio offers a different approach to security analysis by running entirely locally, eliminating the need for code to leave the user's machine. This is crucial for sensitive data, NDAs, and proprietary codebases. The tool utilizes a local LLM and does not make external API calls or send telemetry. A key feature is the ASS Script engine, which allows for recording and replaying offline security scans.The scanning process prioritizes deterministic analysis before employing the LLM. It follows a pipeline starting with parsing, a rule engine for initial discovery, knowledge retrieval, summarization, and then LLM reasoning. The LLM operates on structured summaries, not raw code, to explain vulnerabilities and correlate findings.ASS Script, written in plain YAML, enables users to record workflows as a series of node interactions and scan calls. These scripts are readable and can be replayed identically from the GUI or command line. This record-once, replay-forever capability ensures consistent execution.For creating demo videos, AI Security Studio also employs an offline narration pipeline. This involves writing a shot list in markdown, which is then processed by a Python script. This script uses built-in macOS TTS for voice synthesis and ffmpeg for audio and subtitle generation.The entire narration generation process, including timed cues and subtitle creation, is performed locally without cloud dependencies. This aligns with the project's core philosophy of keeping data private. The pattern of prioritizing deterministic, local-first steps before relying on AI or network calls is highlighted as a valuable architectural principle.