Developer-Dashboard

 view release on metacpan or  search on metacpan

doc/problem-report.txt  view on Meta::CPAN

corrected with `script/sync-readme-from-pod`. A fresh complete-suite and
four-metric coverage result, release build, image build, security audit,
blank-container install, and commit reference will be recorded here after the
final release gates.

Problem 27: Restore `of` content grep and complete Perl `@INC` lookup
(git ref: this delivery commit) (status: done; 2026-10-02)
Expected happy path: `d2 of grep -nr needle <dir>` searches file contents recursively and opens each matching file once; `d2 of --print grep -nr needle <dir>` prints the unique paths without starting an editor. `d2 of Foo::Bar` finds source files und...
Reproduction: create a nested source file containing `needle`, a second matching file, and a non-matching file; run both grep forms above. Put the same `Foo/Bar.pm` fixture under two independent `@INC` roots and resolve `Foo::Bar`. Before the fix, gr...
Root cause: path-regex search and file-content grep shared a resolver path, so grep's flags were parsed as path patterns. The Perl module search already traversed `@INC`, but regression coverage did not assert all roots. Red-first tests now check rec...
Verification: the Docker regression harness passed the CLI/open-file/collector tests; the full suite, four-metric coverage, release metadata, security tests, package build, image build, and blank-container install results are recorded below.

Problem 28: Resolve collector working-directory path aliases
(git ref: this delivery commit) (status: done; 2026-10-02)
Expected happy path: a collector's `cwd` accepts a configured `path_aliases` key or `<skill>.<Folder.pm method>`; a configured alias wins on name collision. The built-in `home` accessor remains unchanged.
Reproduction: configure a collector with `cwd` set to a configured alias whose target is an existing directory, then run it. Repeat with an installed fixture skill containing `lib/Folder.pm` whose method returns an existing directory and use `<skill>...
Root cause: `CollectorRunner::run_once` dispatched only the fixed accessor allowlist and never loaded configured aliases or the secured skill Folder alias provider. Red-first tests now exercise both alias sources, invalid aliases, and the registry co...
Verification: the Docker regression harness exercised both alias sources and unknown-alias failure; full-suite, coverage, security, and packaging results are recorded below.

Problem 29: Collector stop propagation (status: needs investigation)
The user asked whether `d2 stop`, `d2 stop collector`, and stopping a named
collector terminate collector-spawned child processes. The historical report
does not contain the requested Docker reproduction result or a final status.
Do not infer that dispatcher shutdown also stops child processes without
checking the current implementation and reproducing it in the isolated Docker
container.

Problem 30: Repair config.json collector cron scheduling (status: complete; release 5.44)
Expected happy path: a collector with a valid five-field `cron` expression in
the effective config.json runs once in each matching local-time minute, follows
normal crontab date matching, and does not run on non-matching minutes.
Missing or malformed cron configuration must produce a visible start error,
not an every-second job.
Reproduction: in a Docker development container, call `_cron_due` with a
five-field expression whose day-of-week matches the current date while its
day-of-month does not; also exercise `JAN`, `MON-FRI`, and `1-15/2`, and attempt
to start a collector with `schedule: cron` but no expression. Before the fix,
the date case was rejected, the named/range-step fields were unmatched, and a
missing expression was due every scheduler tick. The new regression also loads
a wildcard cron entry from config.json and verifies same-minute deduplication.
Root cause: the parser only matched numeric exact values, bare numeric ranges,
and wildcard steps; `_cron_due` incorrectly required both restricted date
fields to match; and its empty-expression fast path returned due immediately.
Red-first evidence: new assertions in `t/103-collectorrunner-coverage.t`
failed on all five identified behaviors in the isolated Docker service.
Implementation: validate exactly five fields and expand supported values into
bounded sets; accept case-insensitive month/weekday names, lists, ranges,
range steps, and `*/step`; apply crontab's OR rule when both date fields are
restricted; return not-due for invalid/missing expressions and reject them at
loop startup before fork. Document the format in the collector reference and
main user documentation. Focused Docker verification passes
`t/103-collectorrunner-coverage.t` (335 tests). The clean full coverage gate
passes 257 files / 22,259 tests with 100.0% statement, branch, condition, and
subroutine coverage.

Problem 27/28 shared delivery verification:
Docker reproduction/verification: `d2 docker compose --project-name dd-problem2728-regression -f /tmp/dd-p27-28-compose.yml up --build --abort-on-container-exit --exit-code-from regression regression` passed the focused CLI/open-file/collector regres...

Full host regression: `prove -lr t` passed (257 files, 22,806 tests). Its tarball-dependent guard was skipped because the tarball had not yet been built. After packaging, `t/44-smart-router-two-stage.t` was retried and skipped with the exact reason `...

Post-version targeted checks: `prove -lv t/15-release-metadata.t t/98-cli-openfile-coverage.t t/103-collectorrunner-coverage.t t/69-cli-complete-coverage.t` passed (4 files, 5,928 tests). Required web/security checks passed (3 files, 459 tests). Requ...

Release verification: the first 5.40 archive audit found root `cover_db_*` databases in the tarball; the previous gather rule excluded only the exact `cover_db` name. Added a red-first release-metadata assertion and extended both gather exclusion and...

Delivery commit: the Problem 27/28 code was committed as `78d6573d`. The 5.41 archive-hygiene follow-up is committed separately. No push was requested.

Problem 31: Honor Docker service markers at every layer (status: complete; release 5.44; selected-home marker write rule reconfirmed 5.45)
Expected happy path: any active `config/docker/<service>/disabled.yml` marker
disables that service; any `develop.yml` marker enables its development overlay.
`docker enable <service>` removes every matching `disabled.yml`, and
`docker development disable <service>` removes every matching `develop.yml`.
New marker files are always created under the selected home runtime.
Reproduction: put a marker in the home service folder and create a deeper
project service folder without a marker. Before the fix, the resolver consulted
only the deepest matching folder, so the shallower marker had no effect. Add
both marker files at multiple depths, then run the corresponding enable/disable
command; before the fix, only the deepest marker was removed. Marker creation
also previously followed the deepest runtime layer instead of the selected
home runtime.
Root cause: `_service_folder_is_disabled` inspected only the last lookup root,
`_service_folder_is_development` returned the deepest marker state immediately,
and toggle commands unlinked one calculated path. `_service_toggle_root` used
the deepest runtime layer. Red-first evidence: new tests in
`t/10-extension-action-docker.t` failed in the isolated container for both
shallower-marker resolution cases and all-layer cleanup. The implementation
now scans every discovered service root, removes markers from every matching
layer with visible errors, and creates markers under `PathRegistry`'s selected
home runtime name. The focused Docker regression `t/10-extension-action-docker.t`
passes; `t/361-dockercompose-coverage.t` covers both marker-presence branches,
including dangling symlink cleanup. The clean full coverage gate passes 257
files / 22,259 tests at 100.0% for all four metrics. Required web/security
tests pass (3 files / 459 tests); package and image evidence is recorded after
the release build below.

Problem 12/25/30/31 final delivery evidence (2026-10-03)
The full Docker coverage gate passed 257 files / 22,259 tests with 100.0%
statement, branch, condition, and subroutine coverage across `lib/`. Focused
Docker tests passed 8 files / 7,894 tests. Required web security tests passed
3 files / 459 tests. `git diff --check` passed. Security scans found expected
policy assertions, test fixtures, and documentation references only; no
prohibited production dependency use or newly exposed secrets. `perlsec` was
reviewed from the installed POD source because the container lacks a POD
formatter (`perldoc -T perlsec` cannot run there).

Release sequence: `dzil clean` removed the previous local build; `dist.ini`,
the main module POD, and all 76 Perl modules use version 5.44; `t/15` verified
version synchronization. `dzil build` produced
`Developer-Dashboard-5.44.tar.gz`, the only root tarball. The archive reports
POD version 5.44 and contains no `cover_db` paths. `d2 docker.images.build`
succeeded, and an isolated run of the resulting image printed `5.44`. The
blank Perl 5.44 container installed the 5.44 tarball with plain `cpanm` (no
`--notest`); dependency and distribution tests passed and the integration
harness reported `Blank-environment integration run passed`. Its unique
Compose project exited 0 and was removed. Post-push Scorecard verification is
not recorded because no push was requested; the repository-side verification
above does not claim that external status.

Problem 12 follow-up: Resolve dotted workspace names as tmux session names
(git ref: pending) (status: functional regression passes; release pending)
Expected outcome: `d2 workspace ch.docker -c` changes to the configured alias
directory and attaches to the tmux session created for logical workspace

doc/problem-report.txt  view on Meta::CPAN

client is absent, so actual engine-backed build/up/down was not attempted; a
stub Compose executable verified for each action that the real operational
call uses one existing merged file, retains `--project-directory`, streams
output, and returns the operation status. `doc/problem-report.md` now records
this distinction instead of implying the prior `run()` tests covered public
dispatch.

Current-cycle final audit (2026-10-03): `t/90`, `t/91`, and `t/94` passed in
Docker (3 files / 359 assertions); the added completion defensive-branch test
passed `t/69` (71 assertions); corrected `t/590` passed 17 assertions. The full
instrumented suite passed 257 files / 22,371 tests. Initial four-metric gate
result: statement/branch/subroutine 100%, condition 99.9%, exit 1. After the
new `t/69` case ran under Devel::Cover using the same database, the aggregate
checker reported 100.0% for all four library metrics and no stale annotations.
This is a combined full-suite plus focused instrumented-test result, not a
successful clean exit from a single full gate invocation. Devel::Cover emitted
warnings about ephemeral skill fixtures deleted before report generation and
the custom database marker; these warnings remain visible and are not
described as warning-free verification.

The Markdown index `doc/problem-report.md` is maintained in numerical order;
this text file preserves the longer chronological audit. Keep status and
verification facts consistent between the two files.

Final release-gate correction (2026-10-03): after that earlier audit, the full
5.48 instrumented suite was rerun with the defensive completion assertion
included and passed 257 files / 22,372 tests. The four-metric checker exited
successfully at 100.0% statement, branch, condition, and subroutine coverage
(45,335 detail rows, no stale annotations). Devel::Cover still emitted
warnings for temporary skill fixture files removed during tests; this result
is not described as warning-free. `dzil build` produced
`Developer-Dashboard-5.48.tar.gz`; `d2 docker.images.build` completed and a
fresh image returned `d2 version` 5.48. The blank-environment Compose run then
installed the host-built tarball with `cpanm` without `--notest`, ran the
distribution test suite, and completed the integration script successfully.
The Compose project needed an explicit `--project` directory and a temporary
network override to use the existing shared network; no unrelated container
was inspected or changed. Problems 12, 32, 33, and 34 now have completed
functional, coverage, packaging, image, and blank-install evidence; commit
remains pending.

Documentation/release refresh (2026-10-03): the numbered Markdown report had
been behind the current verification state, so its Problem 12, 32, 33, and 34
statuses and completed 5.48 evidence were brought current. Because the report is
included in the release archive and the Docker image helper rejects rebuilding
an already-used version, the report refresh moved release metadata to 5.49.
All 76 library module versions and dist.ini were aligned; Changes, FIXED_BUGS,
README/POD synchronization, and the report were updated. The 5.49 full Docker
coverage run passed 257 files / 22,732 tests. All four library metrics were
100.0% (45,335 detail rows, no stale annotations). Devel::Cover emitted the
same known warnings for temporary fixture files removed before digesting.
The 5.49 archive was built, `d2 docker.images.build` completed, and a fresh
image returned version 5.49. The blank-container rerun installed that archive
using `cpanm` without `--notest`, passed its distribution suite, and ended with
“Blank-environment integration run passed.” Thus the 5.49 release gates and
problem fixes are committed; no push was performed.

Problem 35: Configure a real Dist::Zilla releaser for dzil release
Expected outcome: `dzil release` must find a real Dist::Zilla Releaser plugin
instead of exiting with “you can't release without any Releaser plugins.” The
release action must be an explicit PAUSE upload, and no credentials may be
stored in the repository.
Reproduction: run `dzil release` with the existing dist.ini. It exits before
building or uploading because the config contains build/gather plugins only
and no class with the Dist::Zilla::Role::Releaser role.
Red test: `t/15-release-metadata.t` asserted that dist.ini contains the real
`[UploadToCPAN]` stanza; before the fix this assertion failed (1 of 5,396).
Fix: configure `[UploadToCPAN]`, document that `dzil release` uploads to PAUSE,
and keep credentials in user-owned `~/.dzil/config.ini` or `~/.pause` only.
The test now passes. Host `dzil authordeps` lists
`Dist::Zilla::Plugin::UploadToCPAN`; direct Dist::Zilla configuration
inspection finds `UploadToCPAN (Dist::Zilla::Plugin::UploadToCPAN)` under
`-Releaser`; and `dzil build` succeeds. We did not execute `dzil release`,
because that would upload externally.
The initial full gate found stale 5.49 artifacts and correctly failed the
single-archive hygiene assertion. `dzil clean` was run against the prior
version configuration to clean generated artifacts; after rebuilding only
5.50, `t/36-release-kwalitee.t` passed 7/7. The clean 5.50 full Docker gate
passed 257 files / 22,733 tests and all four library metrics at 100.0% (45,335
detail rows, no stale annotations). Devel::Cover reported digest warnings for
temporary test fixtures deleted during coverage; these remain visible and the
run is not described as warning-free.
The 5.50 archive was installed in a fresh blank Docker environment with
`cpanm` and tests enabled (no `--notest`); the distribution suite and complete
integration script passed. The matching `d2 docker.images.build` completed,
and a fresh image returned `d2 version` 5.50. `dzil release` was deliberately
not run because it would upload the distribution to PAUSE.

Problem 25 and Problem 36 verification cycle (2026-10-03):

Problem 25's external-help regression was reproduced as
`d2 tira.tasklist.prune --help` being claimed by the dashboard's private
`skills _exec` help route and failing with an unknown `_exec` action. The fix
keeps help detection from taking ownership after that private dispatch
sentinel; a fake installed skill CLI verifies `--help`, `-h`, and `help` are
passed through unchanged. Problem 36's pre-fix Docker fixture had the same
skill name in project and home runtimes but completion returned only
project-local command names. The fix enumerates all discovered skill roots in
their established precedence order and emits each dotted name once; the
project layer remains the runtime winner for actual execution.

Focused Docker verification passed 4 files / 1,693 tests, including both
problem regressions. After installing the optional author-gate dependencies in
the isolated `dd-problem36` development container and setting its Git
safe-directory for the `/work` bind mount, `prove -lr t` passed 258 files /
22,959 tests. `t/158` skipped because operator-local `.claude` tooling is not
part of this checkout; Windows QEMU and Chromium-only browser tests skipped
because those optional tools are unavailable. The release-archive guard tests
also skipped in this pre-build run because the 5.52 tarball does not yet exist.
The all-metric coverage gate passed 258 files / 22,897 tests with 100.0%
statement, branch, condition, and subroutine coverage (45,356 detail rows, no
stale annotations). Devel::Cover emitted warnings for temporary fixture
modules removed before digesting; these warnings are recorded and were not
caused by the completion change. Archive kwalitee, final package tests,
blank-environment install, and image build were pending at the time of that
coverage run.

Final 5.52 package verification: `dzil clean` and `dzil build` completed.
There is exactly one root tarball, `Developer-Dashboard-5.52.tar.gz`; all 76
library modules and `dist.ini` declare 5.52, the embedded main module declares
5.52, and archive inspection found no `cover_db`. The Docker release-focused
tests passed 6 files / 6,228 assertions, including kwalitee, POD syntax,
archive inspection, both numbered regressions, and the smart-router package
guard. A fresh blank Docker install used `cpanm` with its default test behavior
(no `--notest`) and finished with “Blank-environment integration run passed.”

The required `d2 docker.images.build` was attempted against 5.52. BuildKit
failed at the Dockerfile's first `RUN curl ... | sh` with `mount options is too
long`. The wrapper then disabled the development marker, installed the tarball

doc/problem-report.txt  view on Meta::CPAN

user-supplied `-f` options without calculating the operation argv position
from a number of generated file pairs.

Root cause: `resolve()` selected isolated service compose files before Docker
Compose had resolved the base config. It used raw local YAML, command-line
service inference, and an ecosystem-wide enabled service scan; consequently
the initial `config` call could contain unrelated service overlays. Then
`_materialized_command` sliced `@full` at `2 + 2 * number_of_files`, which
assumed every generated `-f` pair was a contiguous argv prefix and broke when
other compose-global options or user file arguments were present.

Reproduction steps: a new hermetic fixture is built inside the project dev
container. Its source base names `source_only` and `blocked`; a project
non-service overlay defines `present`; runtime files provide home and nested
skill layers for `present`; the `blocked` service is disabled; and `present`
has a development marker. Call `run()` with an explicit project directory,
one additional `-f` base file, and `build ghost`. The docker stub's first
`config` output lists `present` and `blocked`. The test makes
`_local_compose_services` die if execution calls it, then checks the first
invocation has no runtime service overlay, the next config contains only
matching enabled overlays (including opted-in development), and the last
operation uses the merged file while retaining its arguments and project
directory.

A follow-up red test covered a project without a conventional Compose filename
where the only base is supplied through `-f`. Before the correction, the first
config call preloaded runtime service folders and omitted the selected skill
environment; two assertions failed. `resolve()` now parses leading Compose
options to detect explicit `-f`/`--file` inputs and defers service lookup for
that case too. The fixture passes with the explicit base alone in the first
call, matching overlays in the later config, and service environment applied
only after Compose returned the service map.

Red-before-fix evidence: the first Docker run of the new regression failed
four assertions. It observed two calls rather than three; the initial config
already contained `config/docker/ghost/compose.yml` and
`config/docker/present/compose.yml`; the later config lacked the selected
`present` overlay; and the expected operation log entry was absent. This
matched the reported incorrect order. After the fix, the focused red/green
regression passed with the full resolver file. The six changed focused
regressions (`t/05`, `t/10`, `t/11`, `t/30`, `t/94`, and `t/266`) first passed
2,105 assertions; after version alignment, all seven focused files including
`t/15-release-metadata.t` passed 7,540 tests. The resolver file independently
passed 305 assertions, including the explicit-file-only base case.

Implementation: execution now passes an internal deferred-discovery flag
through the private Docker helper. `_materialized_command` explicitly splits
global compose options, explicit `-f` base files, project-directory, and the
requested operation; no file-count argv slicing remains. It runs base config,
parses the service mapping, gathers the matching service files using the
existing layered disable/development rules, then runs a final config when
service overlays were selected. Existing base/project/service/addon/mode
precedence is maintained. Compose-returned service names must be non-empty
single path segments; `.`/`..` and names containing path separators are
rejected before filesystem lookup. Dry-run remains non-executing and is
documented as a source-based preview.

Security review for this change: the command still passes argument vectors to
`system` and does not compose a shell string; config-derived service names only
select existing runtime-root paths. No new dependencies, SQL, HTTP routes,
credentials, or authentication behavior were introduced. The fresh full Docker
gate passed 258 files / 22,609 tests at 100.0% statement, branch, condition,
and subroutine coverage (45,787 detail rows and no stale uncoverable
annotations). The required focused web-security trio passed 459 tests.
`perlsec` was reviewed from the container's `perlsec.pod` with `pod2text`
because `perldoc` has no formatter. The 5.65 archive passed CPANTS kwalitee
(100%, 7/7 assertions) and POD syntax (348 source files, 355 assertions).
`dzil build` produced `Developer-Dashboard-5.65.tar.gz`; its image reported
version 5.65 in a one-off Compose run. A blank-environment container installed
the archive with `cpanm` without `--notest` and passed the full integration
script. Required security searches found no Problem 40 shell-string execution
or production use of a forbidden library; broad matches were existing audit
strings and test fixtures. Devel::Cover warnings for temporary generated
fixtures removed during tests remain visible, while the coverage gate exits
successfully with all four metrics at 100.0%.

Problem 41: Remove Docker from built-in indicators (status: done, version 5.67)

Expected outcome: core indicator refresh does not probe for the docker
executable and does not create a Docker status indicator. Docker status remains
available when the user explicitly configures a Docker collector. A previously
persisted core Docker record is removed, while customized and collector-owned
records named docker are preserved.

Root cause: refresh_core_indicators() called command_in_path('docker') and
persisted a Docker indicator at priority 20. A configured collector named
docker then shared that record, which made Docker appear first in the prompt.

Reproduction: run d2 ps1 without tmux indicator suppression. The old path
probed the Docker executable and created a whale indicator even in a runtime
without a Docker collector. In the Docker dev service, t/95 was changed first
to make the executable probe fatal; its red run exited at that probe. The test
also seeds the old built-in record and verifies migration cleanup while keeping
an explicitly configured collector-owned docker record.

Implementation removes the Docker probe and write from core refresh and adds
signature-based cleanup for the old core record only. Shared-lock cleanup
passes both focused Docker test files (1,042 assertions), preserving custom and
collector-owned statuses.
Three additional red assertions exposed missing writer-lock protection and
lock-failure reporting. Shared-lock cleanup now passes both focused Docker test
files (1,042 assertions), including layered/custom ownership preservation.
The first full run failed four tracked-document assertions because container
Git rejected the /work bind mount's ownership. A disposable test Compose file
sets safe.directory only inside the container. The affected integration asset
and indicator tests passed 491 assertions, and the full gate was restarted.

Final verification: all 258 Docker test files passed (22,645 tests); Devel::Cover
reported 100.0% statement, branch, condition, and subroutine coverage across
the library (45,841 detail rows, no stale uncoverable annotations). Its report
included missing-digest diagnostics for temporary generated helpers already
removed by their tests; the canonical gate exited successfully. The focused
web/security tests passed 459 assertions. Kwalitee, POD, and release metadata
passed 5,783 assertions, including 100% CPANTS kwalitee. The final 5.67 archive
excluded cover_db. The blank Docker environment installed the same 5.67 release
code through cpanm with tests enabled and passed the complete installed-runtime
integration runner. Perl's perlsec documentation was reviewed inside the
runtime container. No new executable, dependency, SQL, endpoint, credential,
or authentication surface was added.

Problem 42: Let skill environment values override home defaults (status: done, 5.68)

doc/problem-report.txt  view on Meta::CPAN

source, runs install.sh, creates a Dist::Zilla archive, installs and tests that
archive with cpanm, and publishes both the X.XX version tag and latest to
Docker Hub. The image supports Linux amd64/arm64; Apple Silicon uses Linux
arm64 under Docker Desktop, not a macOS-kernel container.

Cause: install.sh bootstraps from MetaCPAN, which may lag behind fixes on
master. No image workflow replaced that installed CPAN package with a tarball
built from the checked-out source.

Red-first regression: t/228-dockerhub-image-workflow.t checks secret wiring,
the master/manual triggers, tag derivation, multi-platform build, and the
install.sh -> dzil build -> cpanm sequence. It also guards the shared Docker
context exception needed to retain the archive for d2 docker.images.build. It
skips from source archives because Dist::Zilla intentionally excludes .github
workflow assets.

Implementation: a pinned-action workflow in `.github/workflows/dockerhub-image.yml`
uses the `release` environment, validates the distribution version, and pushes
versioned and `latest` tags for Linux amd64/arm64. The Dockerfile bootstraps
through `install.sh`, builds the checked-out source with Dist::Zilla, then
installs/tests that exact archive. `.dockerignore` excludes local state and
secrets; README, main POD, integration plan, Changes, FIXED_BUGS, and this
problem report document the behavior.

Verification: the Docker dev-container full suite passed (259 files, 23,312
tests) with statement, subroutine, branch, and condition coverage all 100%.
The image build and its plain cpanm archive installation/test passed (259
files, 16,985 tests); the image smoke test returned `d2 version` 5.81. The
focused release/security gate passed (8 files, 6,438 tests), including
kwalitee, POD syntax, and CPAN audit checks. Perl security guidance was reviewed
and repository security scans passed. GitHub secrets are only available to
the `release` environment, so Docker Hub publication and remote multi-platform
manifest verification remain pending the workflow running after push/manual
dispatch. The first local image attempt exposed that `.dockerignore` excluded
the archive required by the repository's d2 image Dockerfile; the new
regression assertion failed, then an exception rule fixed it. The local D2
project-layer `.env.pl` had selected the prior build marker as `D2D_VERSION`;
providing that marker as `D2D_LAST_BUILT_VERSION` made it choose the current
5.81 archive without modifying local environment configuration. The corrected
`d2 docker.images.build` completed, and a fresh isolated container returned
5.81. Host `dzil clean` then `dzil build` completed for 5.81; archive inspection
confirmed the workflow contract test is included and no coverage database is
packaged. README/POD parity and all 76 library module versions were verified.

Post-push Scorecard found the Dockerfile's Ubuntu tag was not digest-pinned
(Pinned-Dependencies 9/10). t/228 now requires the Ubuntu reference to include
an immutable manifest digest; it failed before the Dockerfile change and
passed afterward. The base now uses Scorecard's reported multi-platform
manifest digest. This corrective follow-up is version 5.82. Rerun Scorecard
after the next push and record the remaining external governance checks. The
5.81 push started the Docker Hub workflow; its completion and the 5.83
multi-platform run remain to be verified after the package and local image gates
pass.

Security review for Problems 46-47 (ASVS 5.0): V1, V4, V5, V7, V8, V10, V11,
V12, and V14 were applicable. The workspace service name is fixed, user aliases
remain argv values rather than shell source, the private overlay rejects
symlinks and non-owner directories, and startup/exec errors remain visible.
The image workflow requests read-only repository contents, pins every external
action to a full commit SHA and the Ubuntu base to its multi-platform digest,
and passes Docker Hub credentials only to the login action from the `release`
environment; credentials are not build arguments or context files. V2, V3, V6,
V9, and V13 (authentication, sessions, cryptography, transport, and application
API) have no changed runtime surface. OWASP A03, A04, A05, A08, and A09 were
reviewed for command construction, container reuse, workflow configuration,
source/image integrity, and visible failure reporting. A01, A02, A06, A07, and
A10 do not gain a changed access-control, cryptography, dependency, identity,
or request-forgery surface. Required security scans and web/static/SSL tests
passed in Docker; post-push Scorecard governance findings are tracked separately
from code-side security controls.

Problem 47 timeout correction (2026-10-10; release version 5.84)

Expected outcome: the GitHub multi-platform publish completes inside its
120-minute job limit and installs the current tarball into both runtime image
architectures. Full test and coverage gates still run before packaging; image
assembly must not repeat the full suite under QEMU.

Reproduction and root cause: pushed commit aed8ab8d triggered Actions run
38078551920. Setup, checkout, version validation, QEMU/Buildx setup, credential
validation, and Docker Hub login passed. The image build stayed in progress
until the 120-minute timeout cancelled it. The Dockerfile's final cpanm
installation had no --notest, rerunning the 23,000+ test suite for each
emulated target architecture despite separate full repository and coverage
gates.

Red test: t/228-dockerhub-image-workflow.t was first updated to require
cpanm --notest --reinstall for installing the generated archive. In the Docker
dev service it failed against the old Dockerfile (31 passed, 1 failed),
reproducing the duplicate suite.

Fix: install the newly built, version-matched tarball with cpanm --notest
--reinstall in the runtime image. Full repository and coverage gates remain
mandatory, and the blank-container integration gate installs the archive with
tests enabled. The contract test then passed all 32 assertions in the Docker
dev service. The post-fix 5.84 full suite passed in Docker (259 files, 23,284
tests); statement, branch, condition, and subroutine coverage each measured
100.0%. The focused release/security/workflow gate passed 5,625 tests, and the
required web/static/SSL gate passed 459. dzil clean and dzil build produced
only Developer-Dashboard-5.84.tar.gz; archive inspection confirmed 5.84,
inclusion of workflow/release tests, and no cover_db. The standard local image
build and a fresh one-off container both returned d2 version 5.84. A direct
local build of the workflow Dockerfile also completed and its one-off image
returned 5.84. Finally, the blank Perl 5.44 Docker environment installed that
archive with cpanm tests enabled and completed the integration harness. The
corrected 5.84 GitHub publish and post-push Scorecard remain pending this
version's push.

Problem 46 follow-up: tmux cannot start in the Docker workspace (2026-10-11–12; runtime verified, packaging gates pending)

Expected outcome: `d2 workspace -c <alias> -d` attaches the caller's terminal to
a live tmux session inside the Compose workspace container. Tmux uses a socket
directory writable by the container user, and a later workspace command
reconnects to that same session.

Reproduction: in a uniquely named Compose project, map host alias `foobar` to
the checked-out project and run `d2 workspace -c foobar -d` with the workspace
service running. Before the fix, tmux reported `couldn't create directory
/tmp/tmux-1000 (Permission denied)` after alias registration. The container ran
as uid 1000; bound `/tmp` was mode 0755, owned by root, and not writable, while
`/dev/shm` was mode 1777 and writable. In addition, the final Compose exec was
captured instead of inheriting the interactive terminal.



( run in 1.106 second using v1.01-cache-2.11-cpan-3f962061493 )