Skip to content

Archive / page 56

All articles

Every practical article from the Nalar archive, newest first.

Cybersecurity 09 Sep 2026 10 min read

Design Push MFA to Resist Prompt Fatigue

Push-based multi-factor authentication can make sign-in convenient: after a password is accepted, the user receives a prompt on a trusted device and approves the attempt. The weakness appears when the prompt itself becomes easy to approve without understanding what it represents. If an attacker obtains a password and can repeatedly trigger approval requests, the legitimate user may eventually approve one because the prompts are confusing, disruptive, or mistaken for a request they initiated. The second factor still exists, but its security value has been reduced to a repeated yes-or-no question.

Software Engineering 09 Sep 2026 8 min read

Dependency Inversion Is About Source Code Direction

A business rule often starts simple and then becomes tied to a database client, email library, payment SDK, filesystem API, or framework object. The code still works, but changing the technical detail now forces changes into the code that expresses the business decision. Dependency inversion addresses this coupling. Its central idea is easy to miss: the important question is not merely whether an interface exists. The important question is which code defines the abstraction and which code depends on it.

Software Engineering 09 Sep 2026 9 min read

Decision Tables for Complex Business Rules

Business rules often start as a few harmless conditions. Then another exception arrives, followed by a special customer type, a threshold, and a fallback. The code still runs, but reviewing it becomes difficult because the real question is no longer “what does this if statement do?” It is “have we handled every meaningful combination of conditions, and do any rules disagree?” A decision table makes those combinations explicit before they are buried in branching code. It lists the conditions that matter, the relevant combinations of those conditions, and the outcome for each combination.

Python 09 Sep 2026 12 min read

Debug Running Asyncio Services with pstree and ps in Python 3.14

An asynchronous service can be alive while making no useful progress. The process still responds to signals. CPU usage may be low. The event loop is still running. Yet a request, worker, or shutdown path appears stuck somewhere inside a chain of coroutines. Traditional stack traces are only part of the answer. An asyncio application is organized around tasks and await relationships, so the useful question is often not merely “where is this thread?” but “which task is waiting for which other task?”

Go 09 Sep 2026 8 min read

Control Structured Log Output in Go with slog.LogValuer

Passing a struct directly to slog is convenient until that struct grows a field that should never appear in logs. An access token, session secret, internal note, or large payload can turn an ordinary diagnostic line into a security problem or an expensive blob of noise. Go’s slog.LogValuer interface gives a type control over its own structured log representation. Instead of teaching every call site which fields are safe, you can define that representation next to the type and let slog use it wherever the value is logged.

Artificial Intelligence 09 Sep 2026 11 min read

Control Beam Search Length Bias with Length Normalization

Beam search is a common way to decode sequence models when choosing the most likely token at every step is too shortsighted. It keeps several partial candidates alive, expands them, and repeatedly retains the strongest alternatives. There is a subtle problem: the score used for a sequence usually accumulates one log-probability per generated token. Because token probabilities are at most 1, their log-probabilities are normally non-positive. Extending a sequence therefore tends to make its raw cumulative score smaller. When finished candidates of different lengths compete directly, this can create a preference for outputs that end too early.

Python 09 Sep 2026 10 min read

Control asyncio Task Startup with eager_start

Creating an asyncio task usually feels like a clean scheduling boundary: call asyncio.create_task(), keep the returned task, and let the event loop run the coroutine soon. Python also supports eager task execution, where a coroutine can begin running immediately during task creation. Python 3.14 makes that choice directly available through the eager_start keyword on asyncio.create_task() and through task-group task creation. That can remove scheduling overhead for coroutines that often complete without blocking. It can also change program ordering in ways that matter much more than the performance gain.

Artificial Intelligence 09 Sep 2026 8 min read

Contextual Calibration for Few-Shot Classifiers

A language model can behave like a classifier without any parameter updates: give it a few labeled examples, present a new input, and ask it to choose a label. The surprising problem is that the answer can depend not only on the new input, but also on details such as the prompt wording, demonstration order, and label tokens. That creates a practical debugging trap. A prompt may appear to teach the task while also giving the model a baseline preference for one answer before meaningful input is considered.

Software Engineering 09 Sep 2026 9 min read

Containing Failures with Bulkheads

A service can fail even when most of its dependencies are healthy. One slow dependency may occupy every worker, connection, or concurrency slot until unrelated requests can no longer make progress. This is a resource-isolation problem. The dependency failure matters, but the larger outage happens because the system lets one workload consume capacity that other workloads also need. A bulkhead limits that sharing. It gives a workload a bounded resource budget so trouble in one area is less able to exhaust resources needed elsewhere. This article explains the mental model, shows where bulkheads help, and covers the trade-offs that make isolation useful rather than arbitrary.

Python 09 Sep 2026 10 min read

Compare Python Syntax Trees with ast.compare

Tools that rewrite Python source often need to answer a deceptively simple question: did this transformation preserve the syntax tree that matters? Before Python 3.14, a common solution was to serialize both trees with ast.dump() and compare the resulting strings. That works in small tests, but it turns a structural question into a formatting contract. Python 3.14 adds ast.compare(), a recursive AST comparison helper that expresses the intent directly. This is especially useful for formatters, codemods, linters, source generators, refactoring tools, and tests that round-trip Python code.

Software Engineering 09 Sep 2026 9 min read

Command-Query Separation for Predictable Operations

A method that returns a value can look harmless even when calling it changes the system. That mismatch creates bugs that are difficult to see at the call site: remaining = cart.removeItem(itemId) Does removeItem only remove the item? Does it return the removed item, the number of remaining items, or a success flag? More importantly, can code safely call it while merely trying to inspect the cart?

Software Engineering 09 Sep 2026 10 min read

Coalescing Duplicate In-Flight Work

A service can receive many requests for the same expensive result at almost the same time. If every request starts identical work, a brief traffic burst can become a much larger burst against a database, remote API, filesystem, or CPU-heavy computation. Caching can help after a result exists. It does not necessarily help when the result is missing and many callers discover that miss together. Request coalescing solves this narrower problem. While an operation for a particular key is already running, later callers for the same key join that operation instead of starting another one. When it finishes, the waiting callers receive the same outcome.

Artificial Intelligence 09 Sep 2026 10 min read

Choose Consensus Outputs with Minimum Bayes Risk Decoding

A generative model can assign high probability to an output that is not the most useful answer for your application. This is especially visible when several different outputs are plausible: a translation can have multiple valid phrasings, a summary can emphasize different details, and a structured generator can produce several semantically similar candidates. Greedy decoding chooses locally likely tokens. Beam search searches for a high-probability sequence. Sampling gives you diverse candidates. None of those methods, by itself, asks a different question that is often closer to the application goal: which candidate agrees best with the distribution of plausible outputs?

Software Engineering 09 Sep 2026 8 min read

Characterization Tests Before Changing Legacy Code

Changing unfamiliar code creates a difficult question: how do you know a refactor preserved behavior when nobody can state exactly what the current behavior is? Existing unit tests may be sparse. Documentation may describe the intended rules but not the edge cases the system actually implements. Some odd behavior may even have become a dependency for callers. A characterization test helps in this situation. Instead of starting from what the code ought to do, it records what the code does now for a carefully chosen input. That gives you a behavioral reference point before you change the implementation.

Software Engineering 09 Sep 2026 9 min read

Building a Walking Skeleton Before Filling In the System

A team can make steady progress inside individual components and still discover late that the system does not work as a whole. The application starts differently in production, two modules disagree about a contract, a deployment is missing configuration, or the real request path was never exercised until several weeks of work depended on it. A walking skeleton is a small, working path through the system that connects the important architectural pieces before those pieces contain much functionality. It does not prove that the product is complete. It proves that a thin version of the system can travel from an external entry point, through the chosen boundaries, to an observable result.

Cybersecurity 09 Sep 2026 10 min read

Build Security-Sensitive URLs from Trusted Origins

A password-reset endpoint often needs to send an absolute URL such as https://accounts.example/reset?.... A tempting implementation is to take the hostname from the incoming HTTP request and prepend it to the reset path. That shortcut creates a trust problem. The request’s authority information, commonly exposed to application code through Host, :authority, or proxy-derived host fields, describes where the client says the request is addressed. It is not proof that the value is an approved public origin for links containing sensitive tokens.

Python 09 Sep 2026 9 min read

Build Reproducible ZIP Archives with SOURCE_DATE_EPOCH in Python 3.14

A build artifact can contain exactly the same application bytes and still produce a different checksum every time it is built. ZIP timestamps are one common reason. That matters when checksums are used for release verification, artifact caching, provenance, binary transparency, or simply deciding whether a build changed. If irrelevant metadata changes on every run, byte-for-byte comparison stops being useful. Python 3.14 makes one important part of this easier: zipfile.ZipFile.writestr() now respects the SOURCE_DATE_EPOCH environment variable. When it is set, string-named entries written with writestr() can use the supplied epoch instead of the current time.

Python 09 Sep 2026 9 min read

Build Friendlier CLIs with Python 3.14 argparse Suggestions and Color

Command-line interfaces have an unusual usability constraint: when something goes wrong, the user is often staring at a terminal with no other interface to guide them. That makes small details matter. A typo in a subcommand should ideally produce a useful correction. Help output should be easy to scan interactively without becoming noisy when captured by scripts or logs. Python 3.14 adds two argparse.ArgumentParser options aimed directly at those details: suggest_on_error and color.

Database 09 Sep 2026 9 min read

Back Up a Live SQLite Database Safely with Python

Copying an SQLite file looks like an obvious backup strategy: find the .db file and copy it somewhere safe. That can be acceptable when the database is definitely idle, but it is the wrong abstraction for a database that may be changing while the copy runs. SQLite provides an Online Backup API specifically for this problem. Python exposes it as sqlite3.Connection.backup(), so an application can copy a live database into another SQLite database while preserving a consistent database snapshot.

Python 09 Sep 2026 12 min read

Attach to Running Python Processes with sys.remote_exec in Python 3.14

A production Python process can be healthy enough to stay alive while still being difficult to understand. Perhaps one thread appears stuck. Memory is growing but the application has no diagnostic endpoint. A profiler was not enabled before startup. Restarting the process would erase the state you need to inspect. Python 3.14 adds a new CPython capability for this situation: sys.remote_exec(). It lets one Python process request that a .py file be executed by another running CPython process. The target executes that file on its main thread at a safe execution point.

Python 09 Sep 2026 11 min read

Attach pdb to Running Python Processes in Python 3.14

A Python service can misbehave without crashing. A worker may loop unexpectedly, a request may remain in an odd state, or a long-running process may hold data that is difficult to reproduce in a development environment. Historically, using pdb in that situation usually required planning ahead. You could add breakpoint() to the code, start the program under the debugger, or restart it with extra instrumentation. Those approaches are useful, but they do not help much when the interesting state already exists inside a running process.

Software Engineering 09 Sep 2026 7 min read

Adding Behavior with the Decorator Pattern

A component often starts with one clear responsibility and then attracts optional behavior. A client sends a request; later the system also needs logging. Some deployments need metrics. Others need caching or access checks. Putting every option inside the original component can make its core job harder to see, while creating subclasses for every combination quickly becomes awkward. The Decorator pattern offers another shape. A decorator implements the same contract as the component it wraps, performs additional work, and delegates the main operation to that wrapped component. Because callers still see the same contract, decorators can be added, removed, and combined without teaching callers about each feature.

Python 09 Sep 2026 9 min read

Accept Numeric Protocols with Fraction.from_number

A function that accepts a number and a function that parses text are not quite the same API. I keep running into this distinction in configuration code, pricing tools, import pipelines, and small libraries. The caller may already have an int, float, Decimal, or another numeric object. In that case, accepting a string such as "0.25" just because it happens to look numeric can make the boundary less clear than it needs to be.

Tech 08 Sep 2026 8 min read

Why Your Phone’s Flashlight and Camera Flash Can Have Different Brightness

A phone’s rear light can seem surprisingly different depending on how you use it. The flashlight may provide a steady but moderate beam, while the camera can produce a brief flash that looks more intense. On some phones, the flashlight also offers several brightness levels. These behaviours make more sense once you stop thinking of the light as a bulb with one fixed brightness. It is an electronically controlled light source that the phone can operate in different modes. The camera and flashlight have different jobs, so the phone does not necessarily drive the light in exactly the same way for both.