Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
25031cc
fix: loosen constraint matching to the documented free-taxa contract
ms609 Aug 5, 2026
bf11273
test: pin the collapse pass's constraint protection
ms609 Aug 5, 2026
720e423
fix: size the exact solver's guards to the work its gate admits
ms609 Aug 5, 2026
57ee380
fix: address review of the loosened constraint contract
ms609 Aug 5, 2026
f8eab96
red-team(area 13): opus finder sweep, 12 findings filed (#61-#72)
ms609 Aug 5, 2026
74d901d
docs: denominate the profile-scoring gate in work, not seconds
ms609 Aug 5, 2026
99ca3f0
fix: close the review's remaining gaps in the constraint contract
ms609 Aug 5, 2026
cdb21ee
fix: keep the 2 s budget as the binding limit; scale it only for sani…
ms609 Aug 5, 2026
e81354f
red-team(area 1): version-bump opus sweep, 8 findings filed (#76-#83)
ms609 Aug 5, 2026
688ec05
Merge branch 'cpp-search' into feature/constraint-loosen
ms609 Aug 5, 2026
51dfe38
red-team: enact area 14 (statistics/support-metrics) + first-ever opu…
ms609 Aug 5, 2026
1fb915d
Merge remote-tracking branch 'origin/cpp-search' into feature/asan-quiet
ms609 Aug 5, 2026
3fa12e9
fix: scatter free taxa when building a random constrained start tree
ms609 Aug 5, 2026
17d7aaa
Merge cpp-search: resolve the two area-14 definitions in #57's favour
ms609 Aug 5, 2026
7b1a96a
red-team: restore the area-14 leads the merge resolution dropped
ms609 Aug 5, 2026
e0629be
Merge pull request #75 from agent-issues/claude/red-team-07b219
ms609 Aug 5, 2026
2e50743
Merge branch 'cpp-search' into feature/constraint-loosen
ms609 Aug 5, 2026
3d5701f
Merge branch 'cpp-search' into feature/constraint-loosen
ms609 Aug 5, 2026
58d119c
Guard zero-length memcpy in StateSnapshot save/restore
ms609 Aug 5, 2026
9566d23
@
ms609 Aug 5, 2026
64bebf4
fix: sample every constraint-permitting topology, not one corner of them
ms609 Aug 5, 2026
f250b91
ci: add libstdc++ hardened-assertions leg to agent-check.yml
ms609 Aug 5, 2026
60a9a67
@
ms609 Aug 5, 2026
ba39c53
Merge pull request #84 from agent-issues/feature/constraint-loosen
ms609 Aug 5, 2026
867eb28
Merge pull request #123 from agent-issues/feature/asan-quiet
ms609 Aug 5, 2026
3e5cfc3
Fix six red-team findings in ClusterStrings.R and ParsSim.R
ms609 Aug 5, 2026
5409268
Fix four Consistency.R bugs: token-remapping, cache collision, matrix…
ms609 Aug 5, 2026
177f991
Fix seven small R-API bugs: #98, #114, #115, #116, #117, #119, #120
ms609 Aug 5, 2026
25ce60b
ci: gate the new leg's install failure and separate its cache
ms609 Aug 5, 2026
c72494e
Merge cpp-search: keep #59's constraint docs, add the sampler's
ms609 Aug 5, 2026
cd991cb
Merge pull request #127 from agent-issues/feature/expected-mi-underflow
ms609 Aug 5, 2026
5441b55
Merge branch 'cpp-search' into feature/clusterstrings-parssim
ms609 Aug 5, 2026
85b0dc9
Merge pull request #129 from agent-issues/feature/clusterstrings-parssim
ms609 Aug 5, 2026
b633968
Merge cpp-search into feature/tbr-memcpy-nonnull
ms609 Aug 5, 2026
3d647c1
Add 'etc' to inst/WORDLIST
ms609 Aug 5, 2026
b0a0461
Widen expected-MI cache keys to the full integer range
ms609 Aug 5, 2026
6b30f5c
Fix .SortTokens() crash for states only seen inside a polymorphism
ms609 Aug 5, 2026
0b5ca4f
Fix eight Concordance.R bugs from red-team area 14
ms609 Aug 5, 2026
304e389
Reword NEWS/test comments to avoid nonstandard "errored"/"erroring"
ms609 Aug 5, 2026
172fa82
Merge pull request #134 from agent-issues/feature/tbr-memcpy-nonnull
ms609 Aug 6, 2026
cb5540c
Guard ts_bench_tbr_phases against zero Fitch words
ms609 Aug 6, 2026
960dd7d
Fix fractional character weights truncated to zero before resampling
ms609 Aug 6, 2026
de8b397
fix(rearrange): break the root edge in all_tbr()
ms609-agent Aug 6, 2026
ffb4bf0
Fix copy-paste error in SPRMoves() roxygen @return
ms609-agent Aug 6, 2026
5710409
Fix Ratchet() early-exit bookkeeping (A15-04)
ms609-agent Aug 7, 2026
6b6b004
Merge pull request #175 from agent-issues/claude/issue-136-assignment…
ms609 Aug 7, 2026
19ed719
Merge pull request #172 from agent-issues/claude/issue-139-a4d9d1
ms609 Aug 7, 2026
5169d04
Merge branch 'cpp-search' into feature/tbr-root-edge
ms609 Aug 7, 2026
de519af
Merge pull request #142 from agent-issues/feature/sorttokens-orphan-s…
ms609 Aug 7, 2026
85981b8
Merge branch 'cpp-search' into feature/consistency-fixes
ms609 Aug 7, 2026
9a62481
Merge branch 'cpp-search' into feature/r-api-fixes
ms609 Aug 7, 2026
abcc67e
Merge branch 'cpp-search' into feature/concordance-fixes
ms609 Aug 7, 2026
e0e4f42
Write the wider cache key through a pointer, not by appending
ms609-agent Aug 7, 2026
34e50b2
Canonicalize the ExpectedLength() cache key
ms609 Aug 7, 2026
de256de
Nest the length cache per tree, and document rhi's NA case
ms609 Aug 7, 2026
3a4fcdf
Merge pull request #133 from agent-issues/feature/ci-glibcxx-assertions
ms609 Aug 7, 2026
bff1937
Merge branch 'cpp-search' into feature/r-api-fixes
ms609 Aug 7, 2026
877efc7
Merge remote-tracking branch 'origin/cpp-search' into feature/mi-key-…
ms609-agent Aug 7, 2026
fd42a13
Record why the length cache keys on topology, not tree shape
ms609 Aug 7, 2026
33ecbe8
docs: correct the sampler's rationale; guard two boundaries
ms609-agent Aug 7, 2026
d7e3fcf
Key the length cache on tree shape rather than labelled topology
ms609 Aug 7, 2026
9f1018d
Merge pull request #173 from agent-issues/feature/tbr-root-edge
ms609 Aug 7, 2026
247a66f
Merge pull request #146 from agent-issues/feature/concordance-fixes
ms609 Aug 7, 2026
fea64d2
Merge pull request #140 from agent-issues/feature/r-api-fixes
ms609 Aug 7, 2026
72f595c
Merge pull request #174 from agent-issues/feature/bench-zero-words
ms609 Aug 7, 2026
a973fa8
Merge branch 'cpp-search' into feature/consistency-fixes
ms609 Aug 7, 2026
3c57427
Merge pull request #176 from agent-issues/feature/fix-sprmoves-doc
ms609 Aug 7, 2026
2aa25c6
Merge pull request #141 from agent-issues/feature/mi-key-cache-aliasing
ms609 Aug 7, 2026
8afbd73
Merge pull request #122 from agent-issues/feature/constraint-random-tree
ms609 Aug 7, 2026
73e96c1
Merge pull request #130 from agent-issues/feature/consistency-fixes
ms609 Aug 7, 2026
d6096b6
Re-audit degenerate-container UB, and put the class under CI
ms609-agent Aug 7, 2026
2774dad
Record what was checked about L3b, and what was not
ms609-agent Aug 7, 2026
5e6396b
Merge pull request #178 from agent-issues/feature/ub-class-audit
ms609 Aug 8, 2026
089b851
Follow the MaxMin -> Coreset package rename
ms609 Aug 17, 2026
fa703e4
Merge agent-issues/cpp-search into cpp-search
ms609-agent Aug 18, 2026
db894a7
Merge pull request #180 from agent-issues/claude/coreset-rename
ms609 Aug 18, 2026
0331a5c
Comment bla
ms609 Aug 18, 2026
ec079d2
-blather
ms609 Aug 18, 2026
4f25dfd
-blather
ms609 Aug 18, 2026
2b84f2f
Simplify
ms609 Aug 18, 2026
7b94145
Merge latest agent-issues/cpp-search into the sync branch
ms609-agent Aug 18, 2026
0c66278
test(constraint): match the reworded free-taxa warnings; fix Igoring …
ms609-agent Aug 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion .AGENTS/memory/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,49 @@ Profile mode sets `ds.concavity = 1.0` (finite sentinel) so existing

## Constraint enforcement

- A constraint split names **two disjoint groups** plus a FREE remainder. A tree
satisfies it iff some edge separates the groups; free tips may fall either
side. This is what `?MaximizeParsimony`'s `constraint` documents and, since
agent-issues/TreeSearch#54, what every entry point enforces. `ts::node_displays_split()`
(`ts_constraint.h`) is THE shared predicate — `map_constraint_nodes()`,
`wagner_tree_displays_constraint()` and `ts_collapse_pool()` all call it.
Reintroducing an exact-clade test at any one of them freezes replicates.
- `build_constraint()` reads R split matrix with **column-major** indexing:
`split_matrix[s + n_splits * t]`.
`split_matrix[s + n_splits * t]`. Values: `1` = together-group, `0` =
apart-group, **anything else (`NA_INTEGER`) = free**. A hand-built 0/1 matrix
therefore means "no free tips" and reduces to the exact-clade behaviour, which
is what `build_constraint_from_bitsets()` (consensus constraints) relies on.
- `ConstraintData` carries `split_zeros` (the apart-group) alongside
`split_tips`, and both ends of the displaying-node chain:
`constraint_node` (tightest, used for "must land outside") and
`constraint_node_hi` (highest, "must land inside"). Any writer of one must
write the other — `ts_wagner.cpp` pins hi to the tight anchor.
- `.PrepareConstraint()` drops (and warns about) a character whose `1` **or**
`0` group holds fewer than two taxa: vacuous under the documented contract,
since every tree separates such a group from the rest.
- A user constraint binds at three boundaries besides the per-move filter
(agent-issues/TreeSearch#59): the start tree is repaired by `impose_constraint()`
before it is scored, each replicate's finished tree is gated by
`capture_satisfies_constraint()` on its way into the pool, and the enforced
split is kept out of the final collapse. `impose_constraint()` is heuristic and
can fail, so every caller re-verifies. The collapse protects a realising node
only when no other realising node already survives — protecting
unconditionally would resolve a branch the constraint never asked for.
- `random_constrained_tree()` (`ts_wagner.cpp`, the `RANDOM_TREE` start
strategy) has TWO samplers. No free tips → the old group-nesting backbone,
which is then complete and uniform. Any free tip → tip-at-a-time insertion:
rejection first (uniform when it lands), then legality-filtered insertion
(always lands), then unnamed tips unfiltered. The backbone alone reaches only
15 of 35 compliant trees on 6 taxa / 1 character, and 105 of 1155 on 8 taxa /
2 characters; insertion reaches all. The filter is
`regraft_violates_constraint()` with a one-tip clip, over masks restricted to
the placed tips — unrestricted masks make every edge look illegal. Probe via
`ts_random_constrained_tree()`, not `MaximizeParsimony()`: TBR rearranges the
start, so the returned tree says nothing about the generator. The rejection
pass is wasted work when it cannot land (agent-issues/TreeSearch#128).
- A compliance checker built on `as.Splits()` MISSES pendant edges, so a
constraint whose group has one taxon reads as violated when every tree
satisfies it. Add the trivial splits before testing.
- Wagner uses LCA-based constraint mapping (`wagner_map_constraint_nodes`)
since splits aren't fully present during incremental construction.
- Wagner has a posthoc retry loop (up to 100 random addition orders) as a
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ASan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ jobs:
# (two vignettes + the Shiny consensus module) is requireNamespace-
# guarded and skips cleanly when absent.
#
# MaxMin is GitHub-only (Remotes: ms609/MaxMin); pak::pkg_install()
# Coreset is GitHub-only (Remotes: ms609/Coreset); pak::pkg_install()
# resolves the vignettes leg's Suggests as plain CRAN refs and can't
# see the local DESCRIPTION's Remotes mapping, so it fails the whole
# dependency solve with "Can't find package called MaxMin". All
# MaxMin use (WideSample()) is requireNamespace-guarded and skips
# dependency solve with "Can't find package called Coreset". All
# Coreset use (WideSample()) is requireNamespace-guarded and skips
# cleanly when absent.
exclude-packages: Rogue,MaxMin
exclude-packages: Rogue,Coreset
28 changes: 14 additions & 14 deletions .github/workflows/R-CMD-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,17 @@ jobs:
# is used only by inst/Parsimony/tests, which is .Rbuildignore'd and
# so absent from the tarball R CMD check sees, and those tests run in
# the dedicated `shiny` job on Windows.
# MaxMin isn't on CRAN, so without this pak fetches and compiles it
# Coreset isn't on CRAN, so without this pak fetches and compiles it
# from source on every cache miss -- ~67 s of the ~174 s dependency
# step (measured on this exact leg, run 30697330564). This URL is a
# prebuilt binary for this exact platform/R combo (aarch64,
# release), published by ms609/packages' build-maxmin workflow.
# The URL has no version/commit in it -- it always points at
# whatever MaxMin build is current -- so it never needs updating
# here when MaxMin changes.
# whatever Coreset build is current -- so it never needs updating
# here when Coreset changes.
extra-packages: |
shinytest2=?ignore
url::https://ms609.github.io/packages/bin/linux/aarch64-release/MaxMin_latest.tar.gz
url::https://ms609.github.io/packages/bin/linux/aarch64-release/Coreset_latest.tar.gz
# cache-version bumped to 2: the v1 caches were built while a
# project-level .Rprofile shadowed ~/.Rprofile, so every package
# in them was compiled from source. Retire them once.
Expand Down Expand Up @@ -237,19 +237,19 @@ jobs:
needs: |
check
coverage
# MaxMin url:: -- this is the Windows leg, so it cannot use the Linux
# Coreset url:: -- this is the Windows leg, so it cannot use the Linux
# tarball the `runner.os != 'Windows'` step below selects. Without a
# url:: reference the solve fails outright ("Can't find package called
# MaxMin"): pak does not read `Additional_repositories`, so the drat's
# Coreset"): pak does not read `Additional_repositories`, so the drat's
# indexed contrib/ layout is invisible to it. See ms609/packages'
# tools/publish-maxmin.R, which publishes this flat alias for exactly
# this purpose.
extra-packages: |
url::https://ms609.github.io/packages/bin/windows/MaxMin_latest.zip
url::https://ms609.github.io/packages/bin/windows/Coreset_latest.zip
# install-pandoc must stay explicit -- see the long note in
# agent-check.yml's windows leg. Auto-detect runs a second, fresh
# `pak::pkg_deps(".")` solve that cannot see extra-packages, so it
# fails on MaxMin by name; the branch only fires when pandoc is off
# fails on Coreset by name; the branch only fires when pandoc is off
# PATH, which is why only the non-Linux legs hit it.
install-pandoc: true
# cache-version bumped to 2: the v1 caches were built while a
Expand All @@ -270,13 +270,13 @@ jobs:
# their dev branch). Remove once a fixed highs reaches CRAN.
# shinytest2=?ignore: see the note on the sense-check leg -- its
# chromium sysreq costs ~70 s of apt per run and no Linux leg needs it.
# MaxMin url:: -- see the note on the sense-check leg: a prebuilt
# Coreset url:: -- see the note on the sense-check leg: a prebuilt
# binary from ms609/packages' build-maxmin workflow, picked per
# this matrix's (arch, R version) combo (x86_64+4.1 vs aarch64+devel).
extra-packages: |
phangorn=?ignore-before-r=4.1.0
shinytest2=?ignore
${{ matrix.config.r == '4.1' && 'url::https://ms609.github.io/packages/bin/linux/x86_64-4.1/MaxMin_latest.tar.gz' || 'url::https://ms609.github.io/packages/bin/linux/aarch64-devel/MaxMin_latest.tar.gz' }}
${{ matrix.config.r == '4.1' && 'url::https://ms609.github.io/packages/bin/linux/x86_64-4.1/Coreset_latest.tar.gz' || 'url::https://ms609.github.io/packages/bin/linux/aarch64-devel/Coreset_latest.tar.gz' }}
${{ matrix.config.r == '4.1' && 'url::https://cran.r-project.org/src/contrib/Archive/highs/highs_1.12.0-3.tar.gz' || '' }}
# cache-version bumped to 2: the v1 caches were built while a
# project-level .Rprofile shadowed ~/.Rprofile, so every package
Expand Down Expand Up @@ -342,14 +342,14 @@ jobs:
with:
needs: |
check
# MaxMin url:: -- same reason as the core Windows leg. Added
# Coreset url:: -- same reason as the core Windows leg. Added
# pre-emptively: this job was skipped in the run that diagnosed the
# failure (it is gated on `detect app changes`), so unlike the core leg
# it is not yet observed failing -- but it resolves the same
# `needs: check` Suggests on the same platform, so it would.
extra-packages: |
local::.
url::https://ms609.github.io/packages/bin/windows/MaxMin_latest.zip
url::https://ms609.github.io/packages/bin/windows/Coreset_latest.zip
# install-pandoc explicit for the same reason as the core Windows leg
# (auto-detect's `pak::pkg_deps(".")` solve cannot see extra-packages).
# `false` here: this job runs shinytest2, not vignettes.
Expand Down Expand Up @@ -435,15 +435,15 @@ jobs:
with:
needs: |
check
# MaxMin url:: -- same mechanism as the Windows and Linux legs, picked
# Coreset url:: -- same mechanism as the Windows and Linux legs, picked
# per architecture (macOS-latest is arm64; macos-15-intel is x86_64).
# Added pre-emptively and NOT yet observed failing: this job is
# `needs: core`, so it was skipped while the Windows leg was red.
# Fixing that leg unskips this one, which would then hit the identical
# unresolvable-Suggests error -- note `_R_CHECK_FORCE_SUGGESTS_: false`
# does not help, since it governs R CMD check, not pak's solve.
extra-packages: |
${{ matrix.config.os == 'macos-15-intel' && 'url::https://ms609.github.io/packages/bin/macosx/big-sur-x86_64/MaxMin_latest.tgz' || 'url::https://ms609.github.io/packages/bin/macosx/big-sur-arm64/MaxMin_latest.tgz' }}
${{ matrix.config.os == 'macos-15-intel' && 'url::https://ms609.github.io/packages/bin/macosx/big-sur-x86_64/Coreset_latest.tgz' || 'url::https://ms609.github.io/packages/bin/macosx/big-sur-arm64/Coreset_latest.tgz' }}
# install-pandoc explicit for the same reason as the Windows legs; also
# pre-emptive, since whether a macOS runner ships pandoc on PATH is
# exactly the condition that decides whether the bad branch fires.
Expand Down
97 changes: 88 additions & 9 deletions .github/workflows/agent-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,14 @@ jobs:
# shinytest2=?ignore: its chromote/chromium system requirement makes
# pak add the ppa:xtradeb/apps PPA and install Chromium on every run
# (~70 s, not cached). No Linux leg needs it -- see R-CMD-check.yml.
# MaxMin isn't on CRAN, so without this pak fetches and compiles it
# Coreset isn't on CRAN, so without this pak fetches and compiles it
# from source on every cache miss (~67 s). This URL is a prebuilt
# binary for this exact platform/R combo (aarch64, release),
# published by ms609/packages' build-maxmin workflow -- see the
# note on R-CMD-check.yml's sense-check leg.
extra-packages: |
shinytest2=?ignore
url::https://ms609.github.io/packages/bin/linux/aarch64-release/MaxMin_latest.tar.gz
url::https://ms609.github.io/packages/bin/linux/aarch64-release/Coreset_latest.tar.gz
# cache-version bumped to 2: the v1 caches were built while a
# project-level .Rprofile shadowed ~/.Rprofile, so every package
# in them was compiled from source. Retire them once.
Expand All @@ -92,6 +92,85 @@ jobs:
"
shell: bash

glibcxx-assertions:
runs-on: ubuntu-24.04-arm
name: libstdc++ hardened assertions

# libstdc++'s -D_GLIBCXX_ASSERTIONS turns container out-of-bounds *address
# formation* (e.g. `vec[n]` where n == vec.size(), with no load or store)
# into a hard abort. That class is invisible to plain builds, to the R CMD
# check leg above, and to ASan itself (which watches accesses, not address
# arithmetic) -- see agent-issues/TreeSearch#60 and #51. Runs independently
# of `ubuntu` for the fastest possible feedback, and skips vignettes/manual
# since it only needs testthat, not a full R CMD check.
env:
NOT_CRAN: "true"
# Cover the same tier-3 paths (long TBR/ratchet/resample searches) as
# `ubuntu`, since that's where a container out-of-bounds is most likely
# to be formed.
TREESEARCH_EXTENDED_TESTS: ${{ inputs.extended }}
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
RSPM: "https://packagemanager.posit.co/cran/__linux__/noble/2026-07-30"

steps:
- name: Checkout git repo
uses: actions/checkout@v6

- name: Set up R
uses: r-lib/actions/setup-r@v2
with:
r-version: "release"

- name: Set up R dependencies
uses: r-lib/actions/setup-r-dependencies@v2
with:
needs: check
extra-packages: |
shinytest2=?ignore
url::https://ms609.github.io/packages/bin/linux/aarch64-release/Coreset_latest.tar.gz
# A cache-version distinct from `ubuntu`'s: that job's cache is
# saved post-job from the *same* restore key (OS/R-version/needs),
# and would otherwise get overwritten with this leg's hardened
# TreeSearch install -- silently handing `ubuntu` a build it never
# asked for, and next time round handing this leg a stale cached
# library that skips reinstalling under the flag.
cache-version: 3

- name: Build source tarball
shell: bash
run: R CMD build --no-build-vignettes --no-manual --no-resave-data .

- name: Install with libstdc++ hardened assertions
# MUST be PKG_CPPFLAGS, not PKG_CXXFLAGS: a user Makevars can zero the
# latter (it does on the maintainer's own dev machine), and the flag
# would then silently not reach the compiler.
#
# `shell: bash` (not the stepless default) is load-bearing here: only
# the explicit form runs with `-o pipefail`, so a failing `R CMD
# INSTALL` still fails the step even though its exit code is piped
# through `tee`.
env:
PKG_CPPFLAGS: -D_GLIBCXX_ASSERTIONS
shell: bash
run: |
R CMD INSTALL TreeSearch_*.tar.gz 2>&1 | tee /tmp/install.log
flag_count=$(grep -c -- '-D_GLIBCXX_ASSERTIONS' /tmp/install.log || echo 0)
echo "Compiler invocations carrying the flag: $flag_count"
if [ "${flag_count:-0}" -eq 0 ]; then
echo "::error::-D_GLIBCXX_ASSERTIONS never reached a compiler invocation -- this leg would silently provide no coverage"
exit 1
fi

- name: Run test suite under hardened libstdc++
shell: bash
run: |
Rscript -e "
library(testthat)
library(TreeSearch)
test_dir('tests/testthat', package = 'TreeSearch', load_package = 'installed',
reporter = 'summary', stop_on_failure = TRUE)
"

windows:
needs: ubuntu
runs-on: windows-latest
Expand All @@ -115,23 +194,23 @@ jobs:
uses: r-lib/actions/setup-r-dependencies@v2
with:
needs: check
# MaxMin url:: -- the Windows counterpart of the arm64 leg's line, and
# the reason this leg used to fail before compiling anything. MaxMin is
# Coreset url:: -- the Windows counterpart of the arm64 leg's line, and
# the reason this leg used to fail before compiling anything. Coreset is
# not on CRAN, and pak does NOT read `Additional_repositories` from
# DESCRIPTION (confirmed empirically 2026-08-03, recorded in
# ms609/packages' tools/publish-maxmin.R), so the indexed drat layout
# alone leaves it unresolvable and the solve dies with "Can't find
# package called MaxMin". Naming the flat, unversioned alias directly
# package called Coreset". Naming the flat, unversioned alias directly
# is the mechanism that publish script exists to provide; it always
# points at the current build, so it needs no edit when MaxMin moves.
# points at the current build, so it needs no edit when Coreset moves.
extra-packages: |
url::https://ms609.github.io/packages/bin/windows/MaxMin_latest.zip
url::https://ms609.github.io/packages/bin/windows/Coreset_latest.zip
# install-pandoc MUST stay explicit here, and the url:: above is not
# sufficient without it. Left unset, setup-r-dependencies auto-detects
# by running `pak::pkg_deps(".", dependencies = list(direct = "all"))`
# -- a SECOND, fresh solve that sees neither the lockfile nor
# extra-packages, so it looks MaxMin up by name and dies with
# "* local::.: Can't install dependency MaxMin" even though MaxMin has
# extra-packages, so it looks Coreset up by name and dies with
# "* local::.: Can't install dependency Coreset" even though Coreset has
# just been installed successfully. That branch only runs when pandoc
# is absent from PATH, which is exactly why the Linux legs never hit it
# (their runners ship pandoc) and this one did. `true` rather than
Expand Down
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Suggests:
future,
highs,
knitr,
MaxMin,
Coreset,
phangorn (>= 2.2.1),
PlotTools,
promises,
Expand Down
Loading
Loading