Repository navigation
refactor(plugins): move the Project domain into the standalone @flybot/project plugin - #2829
Conversation
…t/project plugin The Project domain — Project State, the Project board, the Project’s own Chief, the team dossier, the metrics and the assistant — moves out of `core/src/host/project-*.js` into a peer plugin, `plugins/project` (`@flybot/project`), mounted next to `plugins/social`, `plugins/tree`, `plugins/workflow` and `plugins/timeline`. Behavior is unchanged; the domain’s tests moved with the code and the core keeps two thin seams for what it still calls by name. Refs #2684
7b38d3c to
5f1458c
Compare
|
Body updated for the enqueue guard: Fixes #2684, the |
|
Checkpoint trimmed to the guard limits (block 1383 chars, summary 578, 8 files) and the body now starts with the title, carries |
|
Written-by: Chief Two body corrections on this pull request, no code change:
The tip is unchanged. Review runs at |
|
Verdict: PASS at 5f1458c Ran at this tip: Red first, at this tip (each change reverted in a scratch extraction, then restored): Not run: the full What I checked:
Named in the body, not blocking:
No code change requested at this tip. |
refactor(plugins): move the Project domain into the standalone @flybot/project plugin
Risk tier: T3
Owner: Dev
Reviewer: Reviewer
Written-by: Dev
Bot: Dev
Base: f0f2a1e
Fixes #2830
The Project domain — Project State, the Project board, the Project's own Chief, the team dossier, the metrics and the assistant — moves out of
core/src/host/project-*.jsinto a peer plugin,plugins/project(@flybot/project), mounted next toplugins/social,plugins/tree,plugins/workflowandplugins/timeline. Behavior is unchanged: same reads, same refusals, same strings, and the domain's tests moved with the code. The core keeps the runtime seams it already called by name, plus two small helpers in their own modules.The
Reviewer:line names the Reviewer Bot rather thanBirfyon purpose:Birfyis the shared write identity every Bot writes as, and the enqueue guard refuses it on both header lines. The task brief's line saidReviewer: Birfy; the guard's rule is the one CI enforces, so the reviewer Bot is named.What changed
plugins/project(table below).core/src/host/project-*.jsis gone, and so are theirpatches/ds-bot/files/mirrors and the0002/0003/0012references to them.plugins/project/index.jsis the Cordis plugin (name = 'flybot-project',inject = ['flybot']).apply()returns before registering anything whenflybot.pluginEnabled('project')isfalse, and also when the core has noflybot.projectHost(); otherwise it binds the shared helpers and installs the domain on the runtime. A secondapply()is a no-op (a secondctx.tools.registerof the same name would fail the plugin).core/src/host/project-host.jsis the core's side of the host seam: the live runtime plus the pure helpers both packages use (cut,codePoints,dirKind,defineTool,output,columnOf,priorityOf,advanceRefusal,workDirFor,dayKey,MAX_ENTRY,ASSISTANT_ROLE, the quiet-hours reads).HELPER_NAMESlets the plugin's test assert the seam cannot drift on one side.project_state/project_digesttools are registered by the plugin and nowhere else, so the switch turns them off with the rest of the domain.core/src/host/plugins.jsgains theprojectswitch (appended last, so the existing four ids keep their order), andinstall:doctor/plugins/README.md/ both READMEs /check-pack's expected list know the package.docs/subsystems/project.md;core-host.md,plugin-runtime.md,install.md,testing-layers.{json,md}updated;changelog.d/project-plugin.added.mdadded (user-visible structure change).Verification at the tip
Tip SHA: 5f1458c
Ran:
cd core && npm test— 3079 tests, 3067 pass, 10 fail, 2 skipped. The same 10 failures exist on pristine main f0f2a1e (3222 / 3210 / 10 / 2):bench.sh/pnpm (dash env),empty diff passes(the gate needs a real git checkout; this tarball extraction has no.git), two#2167lock-timing cases and six#896/#1433archiving cases. No failure is added or removed, and3222 - 3079 = 143is exactly the project suite that moved out.cd plugins/project && npm test— 147 / 147 / 0 (143 moved + 4 new boundary tests).social 619/619,tree 149/149,timeline 166/166,workflow 528/528— green.node --test ".github/scripts/*.test.mjs" "policy/*.test.mjs"— 673/673.lint:interop0 errors,test:interop37/37.lint:live-e2e0 errors,test:live-e2e34/34.cd core && npm run install:doctor— PASS on core and all five plugins,path:/plugins/projectin the install commands.node scripts/ds-bot-patches.mjs check— 10 patches apply cleanly,core/equalsds-bot/ + patches/ds-bot/;canonical— the committed split is whatgeneratewrites.cd core && npm run lint— 0 errors (88 pre-existing style warnings);check-arch-docs.mjs—OK (107 changed file(s)).node core/scripts/build-client.mjs --check— clean (core/src/client/is untouched).project_digest, project_state, has all four seams andproject_stateanswers its listing/file/refusal as before; with it off the tool list is[], no seam is installed, and the store keeps its Project endpoints.ERR_MODULE_NOT_FOUNDon the missing seam), green again once restored.Not run (and why): the live GitHub Actions legs including Windows; and
npm run verifyas one command, because this workspace is a tarball extraction without.git, socanonical/check-arch-docs/ the pin check were run in the forms above and every other step was run one by one.ds-bot/is untouched, so CI's pin check compares the same tree main has.Checkpoint
{ "pr": 2829, "claim": "Dev", "issue": 2830, "summary": "The Project domain moved out of core/src/host/project-*.js into the peer plugin plugins/project (@flybot/project), and its ten test files (143 cases) moved with it at identical case counts. apply() installs the same four runtime seams and registers project_state/project_digest, and none of it when pluginEnabled(\"project\") is false. The core keeps a host seam (project-host.js) handing over the runtime and the shared pure helpers, plus day-key.js and work-dir.js. The browser half stays in core/src/client and plugins/project/client.js is empty, so no rendering is duplicated.", "files": [ "plugins/project/index.js", "plugins/project/src/install.js", "plugins/project/src/host.js", "core/src/host/project-host.js", "core/src/host/day-key.js", "core/src/host/work-dir.js", "core/test/project-domain.js", "plugins/project/test/host.test.js" ], "checks": { "ran": "core npm test 3079/3067/10 (same 10 as main); plugins/project 147/147; install:doctor; patches check+canonical; lint; arch-docs; build-client; switch on/off e2e", "result": "green", "at": "5f1458caef47cabdc86f3d99964249b27da16ca8" }, "next": "Verifier: record a PASS at this tip; no gate file is touched, so policy-sign passes." }Moved
core/src/host/project-state.jsplugins/project/src/project-state.jscore/src/host/project-board.jsplugins/project/src/project-board.jscore/src/host/project-chief.jsplugins/project/src/project-chief.jscore/src/host/project-team.jsplugins/project/src/project-team.jscore/src/host/project-metrics.jsplugins/project/src/project-metrics.jscore/src/host/project-assistant.jsplugins/project/src/project-assistant.jscore/test/project-board.test.jsplugins/project/test/project-board.test.jscore/test/project-board-meeting-date.test.jsplugins/project/test/project-board-meeting-date.test.jscore/test/project-roles.test.jsplugins/project/test/project-roles.test.jscore/test/project-team.test.jsplugins/project/test/project-team.test.jscore/test/project-assistant.test.jsplugins/project/test/project-assistant.test.jscore/test/project-metrics.test.jsplugins/project/test/project-metrics.test.jscore/test/project-metrics-scope.test.jsplugins/project/test/project-metrics-scope.test.jscore/test/project-metrics-cache-bound.test.jsplugins/project/test/project-metrics-cache-bound.test.jscore/test/project-state.test.jsplugins/project/test/project-state.test.jscore/test/project-state-unreadable.test.jsplugins/project/test/project-state-unreadable.test.jscore/test/project-board-levels.test.jspatches/ds-bot/files/src/host/project-*.jspatches/ds-bot/patch carries the plugin)patches/ds-bot/files/test/project-*.test.jsNew files:
plugins/project/{package.json,index.js,client.js,cordis.patch.yml,README.md,src/host.js,src/install.js,test/resolve.mjs,test/host-bind.js,test/host.test.js},core/src/host/project-host.js,core/test/project-domain.js,docs/subsystems/project.md,changelog.d/project-plugin.added.md.Two helpers the core still needs were extracted into their own core modules, from one implementation each (no copy):
core/src/host/day-key.js—dayKey(ms, timeZone), was exported byproject-metrics.js;turn-budget.jsneeds the same key.core/src/host/work-dir.js—workDirFor(rt, exec), was private toproject-state.js;meetings.jsneeds the folder a decision is archived in.Adapters left in core
There is no
export * from '@flybot/project/...'shell, because after the move nothing incore/srcimports the moved files by path any more. What the core keeps, and why it cannot move yet:rt.projectBoard,rt.projectChief,rt.projectTeamandrt.projectAssistanton the core runtime;core/src/host/store.js(Project endpoints, role switch),core/src/host/meetings.js(decision archive),core/src/host/channel.jsandcore/src/host/authz.jscall them by those names. They are functions on the runtime, not imports, so the implementation is in the plugin while the call sites stay put.flybot.projectHost()(core/src/host/hooks.js→core/src/host/project-host.js, typed incore/types/flybot.d.ts): it hands the plugin the live runtime and the pure helpers the two packages share. The plugin cannot importcore/src/*(separate packages) and a copy would drift, which is why it is a seam.core/src/client/.project-board.js,projects-nav.jsand the Project row inheader.jsread the core's own client context (the roster feed, the overlay stack,call, the i18n helpers) and are bundled bycore/scripts/build-client.mjs, which cannot import a plugin bundle.plugins/project/client.jsexists so the package has the same./cliententry as every other@flybotplugin, but it is an empty module; nothing is duplicated. Turning those surfaces into flybot slots is the follow-up that movessrc/client/here.core/test/project-domain.jsapplies the plugin to the runtime a core test built (applyProject({ flybot: rt.flybot })), because those seven tests read a Project through the store, the channel and the board — the way a profile mounts it. The domain's own behavior suite lives inplugins/project/test/.Deviations
plugins/project/client.jsanddocs/subsystems/project.md; no second copy of the rendering exists.day-key.jsandwork-dir.js(see §Moved): the alternatives were a copy in the core or pushing the plugin back intocore/'s module graph.Reviewer: Reviewer, notReviewer: Birfy(see the top): the shared write identity is refused by the enqueue guard on that line.core/src/host/plugins.jsgainsprojectsopluginEnabled('project')exists; it is appended last so the existing four ids keep their order. User-visible →changelog.d/project-plugin.added.md.install:doctorcounts change: 5 install commands (core + social + tree + workflow + project) and 6 plugin-package checks;core/test/install-doctor.test.jsexpected 4/5/5 and now asserts 5/6/6 — the assertions are the same, only the expected count changed..gitin a tarball extraction).ds-bot/is untouched, so CI's pin check compares the same tree main has.plugins/projectis not added to.github/workflows/test.yml's plugin matrix, the nightly plugin steps, or.github/scripts/check-pack.mjs's list:test.ymlis a gate file underpolicy/gates.json, so changing it needs aPolicy-sign:comment from someone other than this PR's author. The package does pass those jobs — an earlier tip of this branch carried the three entries andplugins (project)andpackageran green (see the run history) — but the wiring is a one-line-each follow-up that needs the signature, and the task boundary says not to touch.github/{scripts,workflows}/here. Until it lands,plugins/project's suite runs in the rootnpm run verify(which now lists it) but not in the per-plugin CI matrix.Notes for the reviewer
plugins/project/test/host.test.jsassertsHELPER_NAMES(core) equalsREQUIRED(plugin), so the seam cannot grow or shrink on one side only; it also pins the switch-off behavior (no tool, no seam, store fallback intact) and that a secondapply()is a no-op.patches/ds-bot/: the moved files are gone fromfiles/and no patch carries them;0001's two hunks foragents.test.js/install.test.jsapply the plugin in those tests, and0002'sstore.js/authz.jscomment lines name the new path.