Agent Skills: Erlang/OTP Knowledge Patch

Erlang/OTP

UncategorizedID: nevaberry/nevaberry-plugins/erlang-otp-knowledge-patch

Install this agent skill to your local

pnpm dlx add-skill https://github.com/Nevaberry/nevaberry-plugins/tree/HEAD/plugins/knowledge-patch/patches-codex/erlang-otp-knowledge-patch

Skill Files

Browse the full folder contents for erlang-otp-knowledge-patch.

Download Skill

Loading file tree…

plugins/knowledge-patch/patches-codex/erlang-otp-knowledge-patch/SKILL.md

Skill Metadata

Name
erlang-otp-knowledge-patch
Description
Erlang/OTP

Erlang/OTP Knowledge Patch

Use this skill when upgrading Erlang/OTP, changing Erlang language or runtime code, operating BEAM services, or configuring OTP networking, cryptography, shells, builds, and test tooling. Read the relevant topic reference before depending on historical defaults, serialized runtime terms, protocol behavior, or application-level patch compatibility.

Reference index

| Reference | Topics | | --- | --- | | build-operations.md | Release artifacts, embedded dependencies, runtime flags, platform support, crash dumps, and vulnerability metadata | | crypto-tls-certificates.md | TLS and certificate validation, post-quantum algorithms, OCSP, crypto failures, and hardening | | language-runtime.md | Comprehensions, types, compiler diagnostics, runtime APIs, collections, regular expressions, and serialization | | networking-services.md | DNS, TCP and sockets, HTTP, SSH/SFTP/FTP, distribution, epmd, Diameter, Megaco, and SNMP | | shell-io-testing.md | Shell modes, standard input, terminal styling, Common Test, documentation tests, abstract forms, and tar/ZIP extraction |

Upgrade-critical changes

Replace serialized array terms

OTP 29 changes the internal array representation. Do not carry values serialized by term_to_binary/1 on an earlier release across the upgrade; rebuild them from an application-owned format.

Require SANs in certificates

Hostname validation no longer falls back to a certificate subject common name. Certificates must have a matching subject alternative name. Error handling may also see separate subject-name and subject-alternative-name constraint errors.

Harden extraction boundaries

Use erl_tar's {max_size, Size} option to cap extracted data. Current ZIP extraction rejects relative entries such as ../x/y that escape the target directory; treat rejection as a security boundary, not an archive compatibility problem.

Audit default code loading

The current directory is last, rather than first, in the default code path. Local BEAM files no longer shadow OTP or application modules unless the code path is changed explicitly.

Opt in to SSH daemon services

ssh:daemon/2 no longer enables shell, exec, or SFTP by default:

ssh:daemon(Port, [
    {shell, {shell, start, []}},
    {exec, erlang_eval},
    {subsystems, [ssh_sftpd:subsystem_spec([])]}
    | Options
]).

Enable only the services the daemon needs.

Check ordered inputs

gb_sets:from_ordset/1 and gb_trees:from_orddict/1 now reject unordered input with badarg instead of constructing invalid data structures.

Account for bounded HTTP retries

After a Retry-After response, httpc:request/4,5 retries once by default and then returns the error response. Configure {autoretry, Timeout} or implement an application retry policy when one retry is insufficient.

Deprecations and diagnostics

Migrate old-style catch

The warning for catch Expr is enabled by default. Prefer targeted try ... catch clauses. Use nowarn_deprecated_catch only as a temporary module-level migration escape hatch.

Prepare for removals

Old-style guard type tests such as integer and atom, the odbc application, and the ftp and ct_ftp modules are deprecated and scheduled for removal in OTP 30.

Review new compiler warnings

The compiler warns by default for variables exported from subexpressions and match aliases that unify constructors. Temporary suppressions are nowarn_export_var_subexpr and nowarn_match_alias_pats.

Enable warn_obsolete_bool_op to find eager and/or expressions that should generally use andalso/orelse, or ,/; in guards.

Find unsafe calls

Functions may have -unsafe attributes, and calls to always-unsafe OTP functions warn by default. Enable warn_possibly_unsafe_function for conditional cases such as atom creation. The xref analyses unsafe_function_calls, undocumented_function_calls, and private_function_calls support wider audits.

Language quick reference

Strict generators

Use <:- for strict list and map generators and <:= for strict binary generators. A pattern mismatch raises instead of silently skipping the value.

[X || {ok, X} <:- [{ok, 1}, error, {ok, 3}]].

Zip generators

Join generators with && to consume their inputs in parallel rather than forming a Cartesian product:

[{X, Y} || X <- [1, 2] && Y <- [a, b]].

Any number of list, binary, or map generators can participate, alongside ordinary generators and filters.

Comprehension assignment

A match used as a qualifier is a compile error by default. Enable compr_assign to make P = E behave like the strict generator P <-:- [E]:

-feature(compr_assign, enable).

Comprehensions can also emit multiple comma-separated values per iteration, such as [I, -I || I <- lists:seq(1, 3)].

Native records

Native records are experimental runtime types, not tagged tuples:

-record #vec{x = 0.0, y = 0.0}.
-export_record([vec]).

Definitions are private by default. Other modules need -export_record for construction or field-aware matches, though a field-free match is permitted. Because early compiler, runtime, Dialyzer, and formatting defects were fixed in 29.0.1 and 29.0.2, update the full installation before experimenting with them.

Bounded integer guards

is_integer(Term, LowerBound, UpperBound) succeeds only when all three arguments are integers and the term is within the inclusive bounds. It avoids range guards that accidentally accept floats.

Nominal types

Use -nominal when structurally identical types must remain distinct in Dialyzer specifications:

-nominal meter() :: integer().
-nominal foot() :: integer().

A nominal type remains compatible with a non-opaque, non-nominal type of the same structure.

Runtime quick reference

Priority signals

Create a priority-capable alias and use the priority send option:

PrioAlias = alias([priority]),
erlang:send(PrioAlias, Message, [priority]).

Priority messages go ahead of ordinary messages while signal order is preserved. Sending through the alias without the option remains ordinary, and unalias/1 revokes the capability. Priority exits use exit(Alias, Reason, [priority]); event-generated links and monitors opt in through erlang:link/2 and erlang:monitor/3.

Hibernate without discarding the stack

erlang:hibernate/0 minimizes the calling process while it waits for the next message but, unlike erlang:hibernate/3, preserves the call stack.

Insert persistent terms idempotently

persistent_term:put_new/2 returns quickly when the same key and value already exist. It raises badarg when the key exists with a different value.

Use consistent map iteration carefully

Standard map traversal functions now return a given map's elements in a consistent order, including keys, values, list conversion, default iterators, and comprehensions. The order is still undefined, unsorted, and not stable across maps or releases.

Security and protocol quick reference

Treat patch hardening as compatibility-sensitive

Recent patch fixes tighten certificate paths, TLS handshakes and tickets, SSH Diffie-Hellman and packet validation, SFTP/FTP confinement, ETF decoding, archive extraction, epmd, Diameter, Megaco, and crypto input validation. Retest negative cases and error matching instead of relying on former silent disconnects, crashes, or permissive behavior.

Handle unsupported crypto structurally

When EdDH or EdDSA is unavailable, crypto:compute_key/4 and crypto:generate_key/2,3 raise:

error:{notsup, Info, Description}

Catch that tuple when fallback is valid; do not match an unstructured failure.

Recheck post-quantum negotiation

Hybrid ML-KEM groups and ML-DSA/SLH-DSA signatures are integrated into TLS, SSH, public_key, and crypto. They become preferred defaults where supported, while retaining fallback for peers that cannot negotiate them. Confirm the linked OpenSSL capabilities and the certificate/key material.

Further guidance

Open the reference that matches the task before changing production behavior. The references preserve exact API names, flags, dependency constraints, protocol limits, and migration consequences that this quick reference omits.