feat(projects): a directory the daemon knows about, and step 3 of the resolution order (T39) - #10
Merged
Merged
Conversation
The shim bench decides this, and it passed: p50 3.95 ms, p90 5.09 ms against a 15 ms budget, measured over /mnt/c in WSL. The narrow private struct is gone; core::manifest is the one reader.
The walk lives in projects::pinning rather than in resolve, and it is a different question from projects::find: a project silent about a language does not shadow the project above it, which is the behaviour this step has always had and the manifest walk's own rule.
…ce crosses it (T39)
…hs reach it (T39)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap task T39, the projects half. Sites move to T39a.
A directory becomes a project the daemon knows about, and step 3 of the resolution order —
"which PHP does this directory use?" — starts answering for the first time: it has had a
branch for a registered project since the beginning and never a row to hit.
Spec:
docs/superpowers/specs/2026-08-22-t39-project-model-design.mdPlan:
docs/superpowers/plans/2026-08-22-t39-project-model.mdWhat lands
core::manifest— one reader and one writer formixengine.toml. The writer edits atoml_editdocument, so an export keeps the comments, the key order and the[site]sectionit does not own.
core::projects— the table, the name rules, and the walk that used to live insideresolve.project.create/list/show/update/delete/export, andmix projectover them.importis a second name forcreate, at the CLI only.runtime.uninstallrefuses to remove a version a project pins, names the projects and theirconstraints, and
--forcecrosses it.mix project showsays which of thetwo decided each version.
Three places the plan was wrong, and the tests that said so
updatecompared the row's holder by name, so every rename refused itself: by then the namein hand was the new one and the row still held the old.
holder()returns the rowid andupdatecompares that.
through a project that pins nothing about the language asked for. Rewiring as written would have
let a registered sub-package shadow the PHP of the repository around it.
projects::find(nearest) and
projects::pinning(nearest that pins this language) are now two questions over onewalk.
fakeservice, which refuses--nodaemonizeand crash-loops tofailed— a state an uninstall isentitled to remove. The row is recorded as running through
declare::running, which is what therefusal actually reads.
One product bug CI found
mix project create /tmp/blogon macOS registered a directory thatcd /tmp/blog && mix project showcould not then find:/tmpis a symlink to/private/tmpandgetcwdanswers with thesecond.
paths::in_fullnow resolves symlinks off Windows, over the longest prefix that exists,with the rest put back as it came — the same rule the Windows branch already followed, so a
spelling still does not change the first time the directory appears.
canonicalizeis right onthat side for the reason it is wrong on this one: the
\?\prefix is a Windows problem.Verification
lint,testandbenchgreen on all three runners. The shim budget the spec made D9 conditionalon was measured before the manifest reader was kept on the hot path: p50 3.95 ms, p90 5.09 ms
against 15 ms.