Uncategorized

  • Consent is a record with a timestamp, not a boolean

    A marketing_opt_in column stores the current answer and nothing else, and the question that gets asked is always “when, and to what exactly did they agree”. Append-only is…

  • webpack 4 needs almost no configuration

    One line replaced about eighty. The defaults are almost always right, and the cost is that they are invisible when they are not.

  • The build cache misses on a file mode change

    A build that rebuilds from scratch on CI while being fully cached locally is usually not a Docker problem — it is that the checkout produced different file…

  • Model events do not fire on a mass update

    An observer that keeps a search index in step works perfectly until somebody writes a query builder update, at which point the rows change and nothing notices. This…

  • A backup you have not restored is not a backup

    A nightly dump that has run successfully for two years proves that the dump command exits zero, which is a different claim from the data being recoverable. The…

  • An error code is a contract, an error message is not

    A client matching on the text of an error breaks when somebody improves the wording, translates it, or fixes a typo — and every one of those will…

  • A DNS-01 challenge needs an API token scoped to one zone

    A wildcard certificate can only be issued through the DNS challenge, which means whatever renews it can write records in your zone — and the default API token…

  • A Redis container without persistence is a deliberate choice

    The official Redis image saves to disk by default, and a cache that survives a restart is occasionally what you want and usually a way to carry a…

  • Deactivating a plugin does not undo what it did

    Options, tables, scheduled events, user meta and post meta all survive deactivation and deletion unless the plugin explicitly removes them, and most do not. The constant check is…

  • nginx -t before every reload, in the deploy script

    systemctl reload nginx with a broken configuration leaves the old one running and reports success in a way that is easy to miss, right up until the next…