## AndrewDryga/emisar — v0.48.0…v0.49.0

_273+ commits._

### Fixes
- **Give contributors a Portal format-fix command that survives a foreign manifest** (8973b27)
- **Pin the describe scanner's multi-digit arity matcher with a regression** (ca083c5)

### Backend
- **Bring a tab to the front before capturing it** (78412f7)
- **Wait for the committed document instead of chromedp's navigation events** (5e7bb74)
- **Verify a published pack tarball by its archive, not its gzip bytes** (ea2c88b)
- **Judge a published pack tarball by its tar stream, not its gzip bytes** (2ef8a37)
- **Pull the MinIO fixture from quay.io and split the Spark row in two** (2a38c6e)
- **release: v0.49.0 — Approval receipts on the run and safer packs** (e730a86)
- **Pin the trusted release workflows at their action-bump commit** (2e55bd8)
- **Refresh the shared Postgres and Keycloak pins to 18.6 and 26.7.2** (740fec2)
- **Move infra to google provider 8.2.0 and current runtime images** (75c095c)
- **Bump the GitHub Actions, trivy, and MCP certification client pins** (a187612)
- **Update the Portal's hex dependencies and asset toolchain** (0acdf0a)
- **Move to Elixir 1.20.4, OTP 29.0.6, Go 1.27.1, and current Go modules** (71033a3)
- **Upgrade Debian security packages in the Portal and runner images** (15be187)
- **Record the LiveView settle-to-quiescence rule in the KB** (236dc99)
- **Give actionEvent back its own doc comment** (4512682)
- **Await every chained policy preview before asserting** (8e8185b)
- **Give test liveness assertions a budget the database can meet** (991699f)
- **Seed the API host's systemd descriptors from the shipped manifest** (7b2d8e7)
- **Mark a receipt-cut approval note on the console ledger** (8c8cd49)
- **Make isolated preview tooling self-contained** (4e5d291)
- **Let the release scratch schema outlive a killed run** (6309efd)
- **Resolve the Portal format check against the running checkout** (4cb6965)
- **Keep a pruned override out of the approval detail vote ledger** (de1f878)
- **Bound a fully voted review receipt to the MCP page frame budget** (e6f45ea)
- **Establish the ConnCaseTest first-owner stall as Postgres write contention** (a7ef5f5)
- **Retry the MFA regeneration submit only across a measured TOTP bucket seam** (301b292)
- **Record that decided requests without vote rows already carry a reviewer** (4fddb35)
- **Bound the MCP review command line in encoded bytes and measure the snapshot frame** (a32b94e)
- **Assert whole changes maps in the put_default_value/3 tests** (00af3c7)
- **Pin the pending preview against the release refusal when an executable vanishes** (a4fc7fa)
- **Record the crash-test flake as already fixed by a duplicate task** (8c9b2a9)
- **Settle every chained policy preview before comparing editor state** (9f1ba72)
- **Show approval votes and override provenance on the run page** (4be0607)
- **Seed the linux-core and postgres reads from the shipped pack manifests** (9d46f9f)
- **Scope approved_count_for_request's count query through Authorizer.for_subject** (a0915a6)
- **Widen the crashing-task supervisor test's cross-process windows** (859fb35)
- **Give ConnCase accounts a unique default slug across async owners** (2503e97)
- **Bound the masked review receipt text in encoded bytes and flag the cut** (5be80c1)
- **Move the Keycloak SCIM comment onto SSOProviderKind's keycloak entry** (c2aae63)
- **Enforce describe and caller coverage for Emisar.Jobs.Sweep** (5226602)
- **Describe the review fixtures as representative, not exhaustive** (314ba4d)
- **Cover Repo.Changeset.truncate_codepoints/3 and validate_json_value/3** (1ef12b0)
- **Report a refused browser sign-in from its response and batch shots in one session** (be7be88)
- **Improve batch-read assertions in sweep tests** — Enhanced the Jobs.Sweep deletion tests to verify that the batch-read loop stops at the correct boundary by introducing an ObservedQuery test helper that tracks every database query call made during deletion, ensuring the sweep reads exactly the right number of batches without over-fetching. (42d967b)
- **Test docs links for identity providers** — Added a test that verifies each single-sign-on provider's documentation link actually exists in the router and points to the marketing guide page, catching broken or removed docs routes at test time rather than shipping dead links to users. (7775dd5)
- **Consolidate dashboard reload logic** — The dashboard now uses the shared LiveTable.reload_drained helper to clear its reload flag, eliminating duplicate code that was handling this differently than the other list pages. (d3b4ce9)
- **Skip membership checks for ungated pages** — Optimized the approval review projection to skip unnecessary membership database queries when a page contains no gated runs. Since most pages don't require approvals, this eliminates redundant queries on run summaries and polling loops that were previously always refreshing the caller's membership before filtering. (63d959d)
- **Seed the restart descriptor from the shipped pack manifest** (ae6f7db)
- **Scope the batched approve tally through the approvals authorizer** (6aa76e4)
- **Say the named-volume fact once in the dev-containers panel** (43fe189)
- **Attach the runner picker only to a card that offers it** (bd6f0b5)
- **Resolve the review command preview without dispatch row locks** (9ccfaff)
- **Render the approval requirements help only when it exists** (676d380)
- **Name the denial-summary recovery test for the approver note it asserts** (280c9d5)
- **Name the invalid-settings approvals test for the help it refutes** (d8f31c6)
- **Reattach the SCIM lock-order comment to put_mapping_provider_lock/3** (bebfcec)
- **Name the pack linux-core in the how-it-works illustration** (6efe178)
- **Name the review receipt's free text as untrusted in the MCP instructions** (b519e45)
- **Upgrade codex lead effort to xhigh in frontier preset** (6fa0509)
- **Take the SSO directory copy helpers back out of the public surface** (5d3e70e)
- **Let the directory role drop the eyebrow that misnames its choice** (f986f80)
- **Accept the shared mt-2 rhythm for the invite form's access eyebrow** (f20f399)
- **Index the frozen-migrations rule in the Portal rule index** (ca23f8f)
- **Point the recent_runs review note at the section above it** (135ab7a)
- **Scan every umbrella module for audit types, not five named files** (51d1a67)
- **Stop suppressing two describes that no longer exist in a pair** (d7a7403)
- **Drop the ungrouped assertion the one event-type table made redundant** (96fa65e)
- **Delete SSOProviderKind.guided/0, which nothing reads** (ac540f4)
- **Write down why a run's review needs only view_runs** (3e0eefd)
- **Pin the pending and denied review receipts as published examples** (0222de8)
- **Give the review receipt a reason floor the encoder can meet** (6eb40d9)
- **Cover Repo.Changeset.castable/1 and correct its doc count** (0381495)
- **Cover Jobs.Sweep.delete_in_batches/4's two batch outcomes** (92db360)
- **Keep ssl-local's seven reads at low, on a measured emit boundary** (57963fe)
- **Require an allowlist when documenting pack path containment** (879c3b9)
- **Pin the four substitution-reached captures with runnable regressions** (17cb3a7)
- **Cover docker.compose_images against a real daemon** (d43cd7a)
- **Drain the producer behind docker.compose_images' 512 KiB bound** (44b9153)
- **Take the source's status in four substitution-reached pack captures** (dbe81a2)
- **Run the pack version lint from ./run check packs** (01afe50)
- **Move four packs-manual bullet bodies behind their rule owners** (8330400)
- **Pin the kafka leader_partitions aggregate to a whole uniq -c row** (868a03a)
- **Name FRR's own SYS_ADMIN need in the snmp fixture's cap comment** (a7c248e)
- **Diff-check twin pack actions in ./run check packs** (5b097d7)
- **Make the remaining bare-digit count probes assert an exact count** (0998b92)
- **Make the remaining zero-count probes assert an exact count** (c5901da)
- **Close a backtick scope before opening another one in the helper lint** (9346efb)
- **Make the rabbitmq and kafka absence probes fail on an unreachable broker** (e900372)
- **Attribute a helper binary to a command, not to a mention of one** (afedb91)
- **Carry docker.compose_config's own reader failures out of the capture** (e808bfe)
- **Declare jq in the docker pack and lint the undeclared-helper gap** (30134d9)
- **Bound each docker.compose_config section capture to 64 KiB again** (feb0be1)
- **Fail docker.compose_config on a compose config it could not read** (6363734)
- **Make the pipeline capture guidance safe under its own shell floors** (58d47fb)
- **Keep the reload-tier criterion consistent with its reloadssl exception** (1356c56)
- **Distinguish the current namespace inventory from published history** (6bf9dd0)
- **Describe policy decisions without implying the risk tier forces approval** (38e7fb3)
- **Name the iperf3 actions the listener and saturation floors explain** (c4b4e0d)
- **Assert the captured provider errors stay off action stdout** (798ce73)
- **Route the pack loader's validation dependencies to both pack gates** (22716d3)
- **Schema-validate the private admin pack in the infra gate** (fc1d6f9)
- **Write the emisar-admin erase timeouts in the duration style** (3997e5c)
- **Write every action duration in the same unit style** (3028b17)
- **Record why four reloads stay medium in the risk-tier rule** (8374185)
- **Say what actually gates a pack's target argument** (e857cfb)
- **Stop in-group pack-test children when the output drain fails** (af92d74)
- **Scope the pipefail prohibition to inline sh programs** (41b5693)
- **Bound the pack-test deadline and kill a timed-out command's group** (95b2618)
- **Print the provider error body at the curl capture sites** (b4871cd)
- **Make the FRR re-advertise probe fail when bgpd is unreachable** (7e90d4b)
- **Say why the FRR test SUT needs SYS_ADMIN** (48f2ce8)
- **Grandfather every published action-id namespace** (00d5df8)
- **Emit one pagination cursor spelling from stripe, braintree, and sentry** (f2e412f)
- **Drop the dead fallback on the pure-flasharray version probe** (76229b2)
- **Say that a private pack's floor is its apply, not retired_below** (24c91ae)
- **Count the packs README totals instead of trusting prose** (7c3b5d5)
- **Let a byte diff prove the twin pid reads still match** (c745bb4)
- **Restore the listener and link-saturation floor to the risk-tier rule** (7f5f193)
- **Say what the Studio instance condition actually withholds** (28329db)
- **Fail the infra gate when tflint is not the pinned release** (6895b41)
- **Keep launchd's reason when the failed runner cannot be stopped** (9935b4b)
- **Keep the operator's Studio binding out of the next apply** (c7076c1)
- **Decline: no text calls the emisar-admin pack registry-pinned** (26d474f)
- **Report a failed service stop truthfully during installer rollback** (c45628b)
- **Match detached serve and selected captures to their real dependencies** (8f57e61)
- **Keep the runner stopped when rollback cannot restore its binary** (c27a2f9)
- **Validate only the workspace dependencies each command needs** (35a6189)
- **Return an error instead of panicking on an icon with no svg wrapper** (8bdd1ba)
- **Require a complete operand group from every icon path command** (0ffd874)
- **Record the tenancy restoration in the security model's changelog** (67fdf05)
- **Name only real tone carriers in the design-system tone paragraph** (6024862)
- **Clean the installer's own staging on success and on refusal** (ec853e0)
- **Name the surfaces that ship where the design rules named deleted ones** (01f263f)
- **Name the number shapes that ship in the stat and migration rules** (b5c40a0)
- **Name the config preflight among the upgrade page's pre-stop checks** (62cfbe3)
- **Move install.sh's stderr note up to the helpers it describes** (b6b59d4)
- **Guard commit-msg on the line that parses, not its advice** (75aba36)
- **Gate that every build location is in the dependabot docker lane** (1612f1d)
- **Point design-system §4's inventory at the components that ship** (b04a57e)
- **Rewrite the HCP workspace pin to what the tree proves** (b8f5177)
- **Trim install-mcp.sh's confirm() header to one line** (9f18729)
- **Date the deployment runbook from its last content edit** (817e65d)
- **Replace the 0.2.0 console-flows bullet with the change it actually shipped** (a7a2833)
- **Reword the plugin changelog to the real installer checksum behavior** (0df1021)
- **Return an error instead of panicking on a malformed icon path** (d226e4a)
- **State the one-runner-one-account tenancy fact in the security model** (31bae49)
- **Lift chromedp out of the stdlib import block in two capture rigs** (9c2ba14)

### Tests
- **test(portal): stop the icon reachability scan from reading its own file** (210f1dc)

_Recap by [Repo Wrapped](https://repowrapped.com/gh/AndrewDryga/emisar?utm_source=github-action)._