# CS foundations rules

Apply these rules to every relevant file in this project.

- Saying an `O(n)` function takes “n milliseconds” mixes a growth class with a duration.
  Why: Different operations, constants, runtimes, hardware, caches, and workloads can reverse results at practical sizes.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- Calling a two-input join `O(n²)` hides the case where one side is bounded and the other grows, while calling it `O(n)` may hide a second unbounded dimension.
  Why: Using a numeric value instead of its encoded length can be exponentially misleading.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- “Average `O(1)` lookup” is incomplete when keys can be adversarial, the hash function is unknown, or a latency objective forbids rare long pauses.
  Why: Best-case behavior is not evidence for a normal-case distribution.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- Generated and handwritten code often puts `includes()`, `find()`, array spread, front removal, serialization, or a database query inside a loop.
  Why: The visible loop is linear, but its body may scan or copy growing data and make the whole path quadratic.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- A cache, memo table, or “seen” set can improve the time bound while retaining one entry per distinct input forever.
  Why: Under a long-lived process or user-controlled keys, the optimization becomes a memory-exhaustion path.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- Rewriting clear bounded code solely to change `O(n)` into expected `O(1)` can add allocations, synchronization, invalidation bugs, and worse tail latency.
  Why: The new bound may address an input size the product never reaches.
  Source: [Algorithmic complexity](https://codewiki.com/foundations/algorithmic-complexity/)
- A linked list can look better because insertion after a known node is `O(1)`, yet the workload may mostly scan, index, or allocate nodes.
  Why: Asymptotic notation omits cache behavior, allocation overhead, and the constant factors on every element.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- “Linked-list insertion is constant-time” is incomplete when the API accepts an index or value.
  Why: Walking to the predecessor is `O(n)`, and removing from a singly linked list may need that predecessor even when the target node is known.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- Do not assume this is safe: generated list code often removes the last node but leaves `tail` pointing at it, updates `next` without the matching `previous`, or decrements length twice.
  Why: The error may stay hidden until the list becomes empty or a reverse traversal runs.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- Repeatedly removing index `0` from an array exposes renumbering work and can turn a long queue drain into quadratic logical work.
  Why: Small test queues rarely reveal the growth pattern.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- A language's “array” may store values inline, references in a backing area, sparse properties, or several optimized element kinds.
  Why: Treating JavaScript `Array` as a stable C-style byte buffer makes memory and locality claims unreliable.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- An external map or caller can retain a node after the collection detaches it.
  Why: Reusing that handle for another insertion can reconnect dead structure, bypass ownership checks, or corrupt size metadata.
  Source: [Arrays and linked lists](https://codewiki.com/foundations/arrays-and-linked-lists/)
- Do not assume this is safe: a generated helper parses `2026-06-01T09:00:00` and later assumes the naive result is UTC.
  Why: Another machine treats the same fields as local time, so serialization changes the instant without an error.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- `value.replace(tzinfo=ZoneInfo("UTC"))` keeps every field and merely gives it a new label.
  Why: If `value` described Paris wall time, this silently creates a different instant.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- Do not assume this is safe: saving `-04:00` for a New York recurrence captures one offset, not New York's rules.
  Why: The schedule drifts by an hour in winter and cannot adapt to later rule changes.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- Do not assume this is safe: attaching `ZoneInfo` to `02:30` in a spring gap creates an object rather than rejecting the nonexistent local time.
  Why: During an autumn overlap, the default `fold=0` silently selects the first occurrence.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- "Add one day" is implemented as fixed seconds in one path and same-zone field arithmetic in another.
  Why: Both pass ordinary-date tests but disagree at clock changes, and month arithmetic adds a separate overflow question.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- A timeout computes `datetime.now(UTC) - started_at`.
  Why: Clock synchronization can move that source forward or backward, causing an early, late, or negative duration.
  Source: [Dates and time](https://codewiki.com/foundations/dates-and-time/)
- Do not treat every resolution failure as “host not found.” `NXDOMAIN`, NODATA, `SERVFAIL`, `REFUSED`, timeout, and local configuration errors describe different states and have different retry behavior.
  Why: Fix: log the queried absolute name, type, resolver, response code, latency, and extended error when available. Retry bounded transient failures; do not retry authoritative non-existence as if it were packet loss.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Caching an address forever in application state.
  Why: A process can outlive a deployment's DNS TTL and keep sending traffic to a retired endpoint even though the shared resolver has fresh data. Fix: prefer runtime connection APIs that resolve according to system policy, or implement an explicit cache policy that preserves TTLs, negative states, scope, and eviction. Re-resolve when the policy expires, not on every packet and not never.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Do not assume a low TTL; doing so makes a migration instantaneous.
  Why: Existing cache entries expire at different times, and connection pools, HTTP keep-alive, and application caches may continue using old endpoints. Fix: lower TTL before the migration, wait through the previous TTL, keep old and new endpoints healthy during overlap, and measure queries plus traffic at both destinations. Include long-lived connection lifetime in the cutover plan.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Replacing a hostname with an IP address when debugging.
  Why: The direct connection may bypass a DNS fault but can also change TLS SNI, certificate hostname validation, HTTP `Host`, load-balancer routing, and failover behavior. Fix: isolate each stage while preserving the original hostname semantics. Query the intended resolver, then connect to a chosen address while still sending the correct SNI and application host only in a controlled diagnostic tool.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Accepting an IP once and using it later for a security decision.
  Why: DNS rebinding or an ordinary record change can make validation inspect one destination while the connection reaches another. Fix: resolve and validate every candidate at the connection boundary, pin the validated address to that connection, and apply network egress controls. Reject private, loopback, link-local, and otherwise forbidden ranges after parsing IPv4 and IPv6 forms.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Do not assume this is safe: publishing an incomplete delegation or changing authoritative data without checking the parent.
  Why: Correct records on one server do not help if the parent lists different name servers, glue is stale, or authoritative replicas disagree. Fix: query the parent and every authoritative server directly for `NS`, `SOA`, and changed records. Confirm serial progression, glue, DNSSEC state, and answers from multiple networks before declaring the rollout complete.
  Source: [DNS resolution](https://codewiki.com/foundations/dns-resolution/)
- Do not assume this is safe: a calculation accepts decimal prices as `Number` values and assumes the source digits are preserved exactly.
  Why: Repeated additions, tax calculations, and midpoint rounding can then disagree with the domain's decimal rules.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- Generated comparison code often checks `Math.abs(a - b) < Number.EPSILON`.
  Why: That threshold describes spacing near `1`, so it is too strict for many large results and may still express no meaningful policy near zero.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- `Math.round(value * 100) / 100` looks like universal two-decimal rounding, but the multiplication and division are themselves binary floating-point operations.
  Why: A value such as `1.005` can reach the midpoint on an unexpected side.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- A division by zero, invalid operation, or overflow yields `Infinity` or `NaN`, and later arithmetic silently propagates it.
  Why: A JSON serializer may then reject it or convert it under rules far from the original failure.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- A refactor reassociates a sum, parallelizes a reduction, or replaces a stable formula with an algebraically equivalent one.
  Why: Real-number algebra says the expressions match, but intermediate rounding, overflow, or cancellation can change the floating-point result.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- A timestamp, database identifier, or byte count is stored in a `Number` merely because it contains no fraction.
  Why: Above `Number.MAX_SAFE_INTEGER`, adjacent integers can compare equal and increments can stop changing the value.
  Source: [Floating-point arithmetic](https://codewiki.com/foundations/floating-point-arithmetic/)
- Do not treat `git add` as continuous tracking; doing so makes a commit omit later edits.
  Why: The index only holds content read when the command ran.
  Source: [Git's internal model](https://codewiki.com/foundations/git-deep-dive/)
- Rebasing commits that other people use creates replacement commits, and the subsequent force push can remove the remote reference's path to their work.
  Why: `--force-with-lease` only checks that a remote reference matches an expected value; it does not prove that the team authorized the rewrite.
  Source: [Git's internal model](https://codewiki.com/foundations/git-deep-dive/)
- `reset`, `restore`, and `revert` operate on different layers.
  Why: In particular, `git reset --hard` makes the current branch, index, and affected tracked working-tree content match the target commit, and uncommitted content may be unrecoverable.
  Source: [Git's internal model](https://codewiki.com/foundations/git-deep-dive/)
- A commit object may remain locally after its last branch is deleted, but reflogs expire and garbage collection may remove the object.
  Why: Other clones, CI workspaces, and hosting services each have separate references and retention policies.
  Source: [Git's internal model](https://codewiki.com/foundations/git-deep-dive/)
- Do not assume this is safe: removing a token from the current file does not remove its blob from older commits, remote references, pull-request caches, or other clones.
  Why: Rewriting history cannot make an already exposed credential safe again.
  Source: [Git's internal model](https://codewiki.com/foundations/git-deep-dive/)
- Do not assume this is safe: a hash narrows the search; it does not prove equality.
  Why: Different keys can have the same hash, so code that stores only `hash -> value` can silently overwrite an unrelated entry.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- Do not assume this is safe: custom equality that ignores case while hashing the original case makes equal keys select different search paths.
  Why: A mutable key has the same failure when fields used by its hash or equality change after insertion.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- “Hash lookup is `O(1)`” drops the assumptions.
  Why: Concentrated collisions can make a chain or probe sequence approach `O(n)`, and hashing a key of unbounded length is not constant work.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- Copying bucket arrays by position during growth leaves entries at indices chosen for the old capacity.
  Why: A later lookup reduces the same hash with the new capacity and may search a different bucket.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- APIs that return `undefined`, `null`, zero, or another ordinary value for a miss become ambiguous when that value is also valid data.
  Why: A truthiness check additionally misclassifies stored `false`, `0`, and empty strings.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- In JavaScript, a normal object's prototype and special property names create semantics beyond a key-value bag.
  Why: Generated code that writes untrusted keys and later merges or reads properties can enable prototype-related bugs.
  Source: [Hash maps](https://codewiki.com/foundations/hash-maps/)
- Do not assume this is safe: a timeout does not prove that the server skipped the operation.
  Why: Blindly replaying a payment-style `POST` can perform the side effect twice, while never retrying a `GET` makes harmless transient failures unnecessarily visible.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- A JSON field such as `{ "success": false }` inside `200 OK` hides authentication, conflict, missing-resource, and overload outcomes from generic clients, caches, gateways, and observability tools.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- Do not assume this is safe: `Content-Type` does not say what response a client wants, and `Accept` does not describe the bytes already sent.
  Why: Negotiating variants without `Vary` can make a shared cache serve one language or content coding to the wrong request.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- Do not assume this is safe: a `304 Not Modified` response intentionally has no content.
  Why: Replacing a stored object with that empty body destroys the cached representation, while sending a body on `304` violates message semantics.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- A personalized response with a long freshness lifetime and an incomplete cache key can be reused for another user by a shared cache.
  Why: Cookies alone are not a substitute for an explicit response cache policy.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- Do not assume one connection equals one message breaks persistence and multiplexing.
  Why: Hand-written parsers that disagree about `Content-Length` and `Transfer-Encoding` can also expose request-smuggling paths between intermediaries.
  Source: [HTTP semantics](https://codewiki.com/foundations/http-semantics/)
- Do not treat “supports HTTP/2” as “this request used HTTP/2” hides downgrades caused by TLS, ALPN, or proxy configuration.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Creating a new session for every request discards multiplexing and HPACK's connection state while increasing socket and handshake pressure.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Running unbounded `Promise.all()` over an input collection can create substantial work before the peer advertises its stream limit, and can merely move the bottleneck into databases or memory.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Neither reading a response body nor cancelling its stream lets the stream, window credit, and listeners outlive the caller.
  Why: This leak is especially easy to miss with streaming responses.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Copying HTTP/1.1 fields such as `Connection: keep-alive` or `Transfer-Encoding: chunked` into HTTP/2 creates a malformed message.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Do not depend on server push for correctness fails when the peer disables push, a library exposes no push API, or an intermediary drops pushed resources.
  Source: [HTTP/2](https://codewiki.com/foundations/http2/)
- Assigning English to every Canadian IP address and inferring CAD from `en-CA` overrides user choice and can't represent travel, cross-border billing, or multilingual regions.
  Why: Fix: Store interface locale, time zone, and transaction currency separately. Detection provides only an initial suggestion; explicit user and business choices win, and each value has its own fallback.
  Source: [Internationalization](https://codewiki.com/foundations/i18n/)
- Joining a name, number, and translated fragments in English order prevents translators from changing word order, plural branches, or grammar.
  Why: Every English test may pass while another language remains unreadable. Fix: Create messages for complete semantic units and pass named, typed values. Let the message system handle plurals, selections, and rich-text structure instead of business code.
  Source: [Internationalization](https://codewiki.com/foundations/i18n/)
- `1,234` may mean one thousand two hundred thirty-four or one point two three four under different conventions, and `04/09/2026` has no unique date meaning.
  Why: Parsing such text back into business values creates silent data errors. Fix: Store structured numbers, currency codes, instants, or calendar dates, and format only at the display boundary. Parse input with controlled field rules rather than assuming an output format is naturally reversible.
  Source: [Internationalization](https://codewiki.com/foundations/i18n/)
- Unconditional English fallback makes missing keys look usable in development and can mix languages on one page.
  Why: Displaying the erroneous key itself can also expose internal naming to users. Fix: Compare catalog keys and placeholders in CI, and make missing keys fail visibly in development. Production fallback should be deterministic and observable, recording the requested locale, selected catalog, and missing key.
  Source: [Internationalization](https://codewiki.com/foundations/i18n/)
- Setting `dir="rtl"` on the root doesn't fix `margin-left`, wrongly mirrored icons, or an unisolated order number inside a sentence.
  Why: Bidirectional text bugs can also place punctuation and neighboring characters in misleading positions. Fix: Update `lang` and `dir` together, use CSS logical properties, and isolate dynamic fragments of unknown direction with ``. Review mirroring per icon class, then test keyboard and reading order with real RTL content.
  Source: [Internationalization](https://codewiki.com/foundations/i18n/)
- Recursively running `chmod 777` after an authorization error expands write, read, and execute permissions across files and directories.
  Why: It can let an untrusted user replace content that a privileged process will later consume.
  Source: [Linux](https://codewiki.com/foundations/linux/)
- Generated cleanup scripts often pass an empty variable, unquoted path, or broad glob to `rm`, `find -delete`, or `chown -R`.
  Why: One bad expansion can cross the intended directory boundary.
  Source: [Linux](https://codewiki.com/foundations/linux/)
- Do not assume this is safe: hard-coding Ubuntu package names, `systemd` unit names, log paths, and network-interface names as universal Linux facts fails on other distributions, containers, and minimal images.
  Source: [Linux](https://codewiki.com/foundations/linux/)
- Parsing `ls`, interactive `top`, or localized error text as machine input breaks on spaces, newlines, locale changes, and output-version changes.
  Source: [Linux](https://codewiki.com/foundations/linux/)
- Do not treat `kill -9` as a normal stop command skips the process's signal handlers and user-space cleanup.
  Why: Forced termination also hides why the service could not stop on time.
  Source: [Linux](https://codewiki.com/foundations/linux/)
- Do not treat one `recv()` as one complete message.
  Why: Short loopback messages often arrive in one read, hiding half a header, half a payload, or multiple coalesced frames. Fix: parse incrementally according to the protocol. Tests should split every header and payload boundary deliberately and feed several frames in one chunk.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- Ignoring partial writes or blindly replaying a business operation after connection failure.
  Why: `send()` may accept only part of its input; even a successful `sendall()` says only that the local call completed, not that the business transaction committed. Fix: use `sendall()` for a complete buffer in blocking Python code. Nonblocking code retains the unwritten slice and waits for writability again. Retry only when application semantics allow it, with idempotency protection for operations that may have side effects.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- Trusting a peer's declared length or setting only a per-read timeout.
  Why: An attacker can announce a huge frame or drip bytes slowly enough that the connection never reaches a complete message. Fix: validate the frame limit before allocation, and bound the accumulated buffer, idle time, and total operation time. Oversize, timeout, and malformed-input paths need observable and testable shutdown behavior.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- Do not assume this is safe: binding to `0.0.0.0` or `::` for convenient testing without authentication or encryption.
  Why: TCP reliability and UDP checksums neither authenticate the peer nor keep application data confidential. Fix: bind local tools to loopback by default. When a service must be exposed, define the network boundary and use a maintained TLS or application-protocol implementation. Do not invent a cryptographic handshake.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- Trying only the first IPv4 address returned by DNS or caching a host's resolution forever.
  Why: The first candidate path may be unreachable, and service addresses can change while a process runs. Fix: preserve the address-family information from `getaddrinfo()`, use the library's multi-address connection policy, and set one overall connection deadline. Caches must honor the resolver and deployment environment's update policy.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- Do not assume this is safe: closing sockets without defined ownership.
  Why: One task can close a descriptor still used by another and cause intermittent faults; stopping a read loop without releasing the socket eventually exhausts process resources. Fix: make one component responsible for close and cancellation, while other components signal it to stop. Test orderly EOF, reset, timeout, cancellation, and process shutdown, and confirm that every path releases listening and connected sockets.
  Source: [Network programming](https://codewiki.com/foundations/network-programming/)
- `command 2>&1 | parser` sends diagnostics into the parser along with result data.
  Why: A warning that looks almost like a record can corrupt a count, checksum, import, or generated configuration without causing a syntax error.
  Source: [Pipes and redirection](https://codewiki.com/foundations/pipes-and-redirection/)
- Do not assume this is safe: in default Bash behavior, `download | unpack | verify` can report success when `download` failed but `verify` accepted partial or empty input.
  Why: A nonempty output file also does not prove that the producer completed.
  Source: [Pipes and redirection](https://codewiki.com/foundations/pipes-and-redirection/)
- Swapping `>file 2>&1` and `2>&1 >file` changes where standard error goes.
  Why: Generated scripts often reorder these tokens during cleanup because both versions look like they mention the same descriptors.
  Source: [Pipes and redirection](https://codewiki.com/foundations/pipes-and-redirection/)
- Command substitution removes trailing newline characters, and shell variables cannot preserve NUL bytes.
  Why: Unquoted expansion later performs splitting and filename generation, changing one captured value into several arguments.
  Source: [Pipes and redirection](https://codewiki.com/foundations/pipes-and-redirection/)
- A consumer such as `head` may close its read end after enough input.
  Why: The producer can then receive the `SIGPIPE` signal or an `EPIPE` error, which `pipefail` can surface even when early termination was the intended query.
  Source: [Pipes and redirection](https://codewiki.com/foundations/pipes-and-redirection/)
- A generated worker updates a shared map or typed array because all threads can reach it, but no ownership or synchronization rule protects a multi-step invariant.
  Why: Tests pass until a different interleaving loses an update or exposes partial state.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- Code sleeps for a guessed interval before reading a result or shutting down.
  Why: Faster machines waste time, while slower or loaded machines still race because elapsed time does not establish completion or memory visibility.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- Do not assume this is safe: a function starts a child or thread and returns without defining who joins, cancels, times out, or closes inherited resources.
  Why: The work can outlive its request, hold the process open, or leave an exit status uncollected.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- A thread is described as an isolated sandbox for untrusted or crash-prone work.
  Why: It shares the host process's authority and resources, and a native memory fault or unrecoverable runtime error can terminate or corrupt the entire process.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- Generated code maps an unbounded input array directly to processes or threads.
  Why: Creation consumes stacks, handles, memory, scheduler time, and downstream capacity, so a burst can make every worker slower or prevent new workers from starting.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- One path locks `accounts` then `ledger`, while another locks `ledger` then `accounts`.
  Why: Each mutex works as designed, but the two paths can wait forever for each other.
  Source: [Processes and threads](https://codewiki.com/foundations/processes-and-threads/)
- Code handles `n == 0` but accepts negative `n`, or checks for a leaf only after reading its children.
  Why: The nominal base case exists, yet some valid or admitted inputs can never reach it safely.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- Do not assume this is safe: an interval search recurses on `[middle, high)` when `middle` can equal `low`, or a parser retries without consuming a token.
  Why: The same state returns, so the call chain grows until a runtime guard stops it.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- A direct translation of a recurrence can branch into the same states repeatedly.
  Why: Naive Fibonacci looks faithful to its definition but does exponential total work, and recursive path counting can repeat even larger subtrees.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- Do not assume this is safe: generated search code appends a choice to one shared list and returns early without removing it.
  Why: Later branches inherit stale choices, so results depend on traversal order.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- A tree with few thousand nodes may be balanced in tests but chain-shaped in production.
  Why: A cyclic object graph has no finite structural depth at all. Average shape does not protect the call stack from adversarial shape.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- Increasing Python's recursion limit can postpone `RecursionError`, but it neither proves termination nor reduces memory per frame.
  Why: An excessively high limit can trade a controlled exception for process failure.
  Source: [Recursion](https://codewiki.com/foundations/recursion/)
- A date, email address, URL, or identifier can match a plausible regex and still be invalid in its domain.
  Why: Increasing pattern size to encode every semantic rule often makes the contract harder to inspect.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- Do not assume this is safe: `test()` succeeds when any permitted substring matches unless the pattern and calling code demand full consumption.
  Why: In JavaScript, `$` can match before a final line terminator, and `m` deliberately changes anchors to line boundaries.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- Interpolating a tenant name, file extension, or search term directly into `new RegExp()` lets punctuation alter grouping, repetition, or alternatives.
  Why: Handwritten backslash replacement is easy to get wrong across two parsing layers.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- Dot, `\d`, string offsets, Unicode property escapes, and user-perceived characters use different units or sets.
  Why: Adding `u` fixes several code-point behaviors but does not make dot consume a whole grapheme cluster or make `\d` match every decimal script.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- Nested quantifiers and overlapping alternatives can create many equivalent ways to consume a prefix.
  Why: A near match that fails late may force a backtracking engine to revisit those choices, making attacker-controlled input a denial-of-service risk.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- A shared regex with `g` or `y` carries `lastIndex` between `test()` and `exec()` calls.
  Why: Code that first tests and then executes may skip the desired match, while concurrent-looking consumers can interfere through the same object.
  Source: [Regular expressions](https://codewiki.com/foundations/regular-expressions/)
- Do not assume this is safe: `for item in $items` and `command $path` do not preserve values as arguments.
  Why: Whitespace, empty strings, `IFS`, and wildcard characters can change the argument count based on both input and directory contents.
  Source: [Shell basics](https://codewiki.com/foundations/shell-basics/)
- Building `command="tool --name $name"` and executing it with `eval "$command"` treats data as shell source.
  Why: Quotes or substitutions inside untrusted data gain syntax on the second parse, creating command injection and boundary bugs.
  Source: [Shell basics](https://codewiki.com/foundations/shell-basics/)
- Logging, assigning through a command, or running `[` before saving `$?` replaces the status you meant to inspect.
  Why: A pipeline can also look successful because its last command succeeded after an earlier command failed.
  Source: [Shell basics](https://codewiki.com/foundations/shell-basics/)
- Do not assume this is safe: `set -e` does not mean “exit after every nonzero status.” Bash suppresses or changes its effect in several testing and list contexts, and a later refactor can move the same command across one of those boundaries.
  Source: [Shell basics](https://codewiki.com/foundations/shell-basics/)
- Do not assume this is safe: quotes keep a path in one argument, but they do not prove the target is authorized, nonempty, below an intended root, or safe across symbolic links.
  Why: `rm -rf -- "$target"` is still dangerous when `target` resolves too broadly.
  Source: [Shell basics](https://codewiki.com/foundations/shell-basics/)
- Generated and handwritten code often uses `(a, b) => a.price > b.price`.
  Why: That returns only `false` or `true`, which become `0` or `1`; it never reports that `a` belongs before `b`, so the comparator contract is broken.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- JavaScript's default array sort compares string forms.
  Why: The numeric array `[2, 11, 3]` therefore becomes `[11, 2, 3]`, which is valid lexicographic order but usually the wrong numeric order.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- Do not assume this is safe: a binary search can look reasonable and still be wrong when its comparison differs from the sort.
  Why: Case folding, locale collation, ascending versus descending direction, null placement, and key normalization all belong to the same contract.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- A textbook exact-match binary search may return whichever equal element it encounters first.
  Why: That is not necessarily the first, last, newest, cheapest, or only matching record.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- JavaScript's `sort()` rearranges the array it is called on.
  Why: A view that sorts a shared array can silently change arrival order for audit logs, caches, or another component.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- Do not assume this is safe: sorting before every lookup can cost more than scanning, while sorting once and ignoring later updates makes results incorrect.
  Why: Quoting only the `O(log n)` search cost hides both failure modes.
  Source: [Sorting and searching](https://codewiki.com/foundations/sorting-and-searching/)
- Options such as `rejectUnauthorized: false`, an always-successful verify callback, or a permissive command-line flag remove peer authentication.
  Why: Traffic may still look encrypted while an active attacker terminates a separate TLS connection and reads or changes everything.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- Connecting to a pinned IP and then verifying that IP can break the intended hostname check and omit the SNI needed by virtual hosting.
  Why: Replacing an HTTPS hostname with a resolved address is not an equivalent request.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- A server can send a self-signed root or an unrelated private chain, but presentation doesn't make that root trusted.
  Why: Trusting every root supplied by the peer lets the peer choose the authority that vouches for itself.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- Exact leaf-certificate pinning can turn normal renewal, emergency reissuance, or a key change into an outage.
  Why: A backup pin that has never been deployed and tested may fail at the moment it is needed.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- Do not assume this is safe: a server may work on a developer machine because its store already contains the missing intermediate, then fail on a clean device.
  Why: Serving the root doesn't reliably compensate for omitting the issuer needed to connect the leaf.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- A valid server channel doesn't prove that a request is allowed, and a valid client certificate doesn't automatically define a user or role.
  Why: TLS also can't protect plaintext after a terminating proxy or keep secrets out of endpoint logs.
  Source: [TLS connections](https://codewiki.com/foundations/tls-connections/)
- Do not assume this is safe: following every `children` or neighbor reference recursively without visited state assumes unique parents and no cycles.
  Why: Shared records are processed repeatedly, while a back-link can recurse until the runtime throws or the process exhausts resources.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- If a vertex becomes seen only when removed from the queue, several vertices can enqueue it first.
  Why: The traversal may still find reachable vertices, but it wastes frontier space and can overwrite or duplicate parent information.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- Repeated `shift()` calls move the logical front of an array through index operations.
  Why: On a large frontier, queue maintenance can dominate the simple edge work the traversal was meant to perform.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- BFS minimizes the number of edges.
  Why: It does not minimize travel time, latency, price, or any other unequal edge weight, even when it returns a plausible-looking route.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- A DFS visit sequence can place a dependent before its prerequisite, and a cyclic dependency graph has no topological order at all.
  Why: Reversing the visit array does not repair an algorithm that never tracked completion or cycles.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- Recursive traversal consumes one call frame per active level.
  Why: A valid but adversarial chain can exceed the runtime stack even though the total graph easily fits in memory.
  Source: [Trees and graphs](https://codewiki.com/foundations/trees-and-graphs/)
- `text.slice(0, 20)` cuts at a UTF-16 code-unit boundary.
  Why: It can leave an unpaired surrogate or detach a combining mark, emoji modifier, or joiner sequence from the cluster a user entered.
  Source: [Unicode text](https://codewiki.com/foundations/unicode-text/)
- Do not assume this is safe: a decoder with the wrong encoding produces mojibake, while a replacement decoder silently turns malformed byte sequences into `U+FFFD`.
  Why: The resulting string no longer proves what bytes arrived.
  Source: [Unicode text](https://codewiki.com/foundations/unicode-text/)
- Do not assume this is safe: nFC or NFKC does not remove scripts, control characters, bidirectional behavior, markup, or visually confusable characters.
  Why: NFKC also merges compatibility distinctions, so applying it globally can change identifiers and user content.
  Source: [Unicode text](https://codewiki.com/foundations/unicode-text/)
- `collator.compare(a, b) === 0` means the strings tie under one locale and option set.
  Why: With base sensitivity, differences in accents or case may disappear, and runtime locale data can change across upgrades.
  Source: [Unicode text](https://codewiki.com/foundations/unicode-text/)
- Replacing stored user text with a lowercased, normalized, or accent-stripped search key makes the transformation irreversible.
  Why: It can alter display, legal names, audit evidence, and later migrations to a better comparison policy.
  Source: [Unicode text](https://codewiki.com/foundations/unicode-text/)
- A dashboard labels virtual size as "memory used," and an alert fires when a runtime reserves a large sparse arena.
  Why: The range may be mostly untouched, file-backed, shared, or protected guard space.
  Source: [Virtual memory](https://codewiki.com/foundations/virtual-memory/)
- Generated code treats a non-null allocation as proof that all requested bytes are physically available.
  Why: It then touches the range during a latency-sensitive request and encounters page-fault stalls or a memory-limit kill.
  Source: [Virtual memory](https://codewiki.com/foundations/virtual-memory/)
- Low `free` memory leads an operator to drop caches or restart a healthy service.
  Why: The system was using otherwise idle RAM for file data that it could reclaim.
  Source: [Virtual memory](https://codewiki.com/foundations/virtual-memory/)
- A `SIGSEGV`, `std::bad_alloc`, major-fault spike, and cgroup OOM event are reported as one "out of memory" condition.
  Why: These outcomes have different causes and repairs.
  Source: [Virtual memory](https://codewiki.com/foundations/virtual-memory/)
- Disabling swap, forcing huge pages, locking memory, or changing overcommit globally is offered as a universal performance fix.
  Why: The change shifts failure modes and can harm unrelated services.
  Source: [Virtual memory](https://codewiki.com/foundations/virtual-memory/)
- Calling `send()` while `CONNECTING`, or putting every message produced during an outage into an unbounded array.
  Why: The first raises a state error; the second consumes more memory for as long as the network remains slow.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
- Reconnecting immediately and replaying every unacknowledged message unchanged.
  Why: The server may have committed the last command while its acknowledgement was lost on the return path, so replay can duplicate a payment, post, or job.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
- Do not treat the browser handshake's `Origin` as user identity, or skipping origin checks because the request has a cookie.
  Why: A hostile page can induce a signed-in browser to make a cross-site WebSocket, while a non-browser client can forge `Origin`.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
- Do not assume this is safe: using traffic alone to decide that a connection is healthy, or assuming browser code can send protocol Ping.
  Why: A connection can fail in a proxy, NAT, or half-open TCP state, and browsers expose no Ping API.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
- Calling `JSON.parse()` on each `message` and trusting its `type`, identifiers, and payload.
  Why: A valid WebSocket peer can still send malformed JSON, an oversized message, or a command that the current user may not perform.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
- Marking client state as "synchronized" when a `close` event arrives.
  Why: The close handshake says how the connection ended, not how far business consumption progressed.
  Source: [WebSocket](https://codewiki.com/foundations/websocket/)
