@@ -0,0 +1,94 @@
|
||||
# Replacement repository source layout
|
||||
|
||||
Tracking issue: [#55](https://git.mosaicstack.dev/mosaicstack/stack-v2/issues/55)
|
||||
|
||||
## Authority and scope
|
||||
|
||||
Jason requested canonical codebase storage for extensions, skills, and other components, with phased replacement of mosaicstack/stack. Source organization does not authorize deployment, credential migration, commit, push, or changes to the live fleet. The accepted goal extension is the first migration candidate. This record is an investigation and recommendation, not an implemented move.
|
||||
|
||||
## Measured legacy structure
|
||||
|
||||
Read through the Gitea contents API on 2026-09-06 at 06:14 UTC. Requests returned HTTP 200.
|
||||
|
||||
- `apps/` contains appservice, gateway, and web.
|
||||
- `packages/` contains shared domains including agent, auth, brain, comms, config, coord, db, forge, log, memory, queue, storage, and types.
|
||||
- `plugins/` contains discord, macp, mosaic-framework, and telegram. These names alone do not establish that these plugins are Pi extensions.
|
||||
- Root also has `skills/`, `tools/`, `scripts/`, `profiles/`, `infra/`, `docker/`, and documentation.
|
||||
- Root package manifest is private, declares pnpm 10.6.2, and delegates build, lint, typecheck, and tests to Turbo.
|
||||
- Workspace membership is explicit: apps/*, packages/*, plugins/*, and tools/matrix-presence-harness. Skills are not declared as JavaScript workspace packages.
|
||||
- Turbo builds dependency packages before dependents and records dist/** as build output. Tests and typechecking depend on dependency builds.
|
||||
|
||||
Inspected manifest blobs:
|
||||
|
||||
- package.json: `5910f98225226274141a6da4c81098fa122f3f46`
|
||||
- pnpm-workspace.yaml: `abb7a60e203c6d44dcf8dc9bf7c99cb3cb72cbd8`
|
||||
- turbo.json: `cf8ef998ee52391cc581c16c865f6d0c0066b24f`
|
||||
|
||||
The recursive `main` tree response identified commit/tree `7102ccb93e007d98faab3994ea552d03f522ad2c` but was truncated at 1,000 entries. Follow-up contents reads supplied complete targeted directories. This is a targeted structural and packaging inspection, not a complete legacy inventory.
|
||||
|
||||
## Recommendation for stack-v2
|
||||
|
||||
Adopt the monorepo principle now, not the entire legacy directory tree or build system.
|
||||
|
||||
- `extensions/goal/` becomes canonical goal source and tests.
|
||||
- `extensions/mosaic-core/lib/` initially holds its existing supporting dependencies. This does not activate Mosaic Core as a separate extension.
|
||||
- Existing `skills/`, `contracts/`, `adapters/`, `roles/`, `scripts/`, and `docs/` retain their distinct responsibilities.
|
||||
- `.pi/extensions/` becomes a generated native-test installation. Never edit it as canonical source. Populate it by deterministic ordinary-file copying, not symlinks.
|
||||
- `.pi/state/` remains ignored runtime state and must never enter an extension artifact.
|
||||
- Introduce apps/ or packages/ when an actual service or shared package requires them. Do not create empty placeholder packages or rename existing components merely to resemble the old repository.
|
||||
- Package explicit source inventories and dependency versions. Record artifact hashes and fail rather than overwrite unknown local edits in the development installation.
|
||||
|
||||
The current private npm manifest and pinned Pi dependency do not need to become pnpm/Turbo merely to store one extension. Decide workspace tooling when independently built JavaScript packages justify it. Native Pi 0.85.1 testing versus the container's 0.84.4 pin is an unresolved compatibility gate before managed-runtime promotion.
|
||||
|
||||
## Measured legacy packaging and installation
|
||||
|
||||
Targeted Gitea reads returned HTTP 200 for the installer, release verifier, publish pipeline, publishing helper, and representative manifests.
|
||||
|
||||
- Shared packages such as `@mosaicstack/agent` build TypeScript into `dist/`, publish only `dist`, and use explicit workspace dependencies.
|
||||
- The `@mosaicstack/mosaic` package publishes both `dist` and `framework`. This is the legacy bundle for CLI plus framework resources.
|
||||
- `plugins/mosaic-framework` declares an OpenClaw extension in its own package manifest. It is not a Pi extension package.
|
||||
- The main installer separates framework files under `~/.config/mosaic` from the globally installed npm CLI. Its development mode builds the monorepo, packs local tarballs, and installs those tarballs without registry writes.
|
||||
- The publish pipeline installs from a frozen lockfile, verifies that CI's commit equals checkout HEAD, runs one terminal release verifier, builds, and only then publishes. Registry, authentication, network, and unknown publication failures fail the job. The `next` lane snapshots and restores modified manifests.
|
||||
- A separate npmjs helper mutates manifests temporarily and restores them. It tolerates publish failures broadly, so it is not a model for stack-v2's fail-closed publication path.
|
||||
|
||||
The useful pattern is source, build output, installation, and publication as separate states tied to explicit manifests and immutable identity. The volume and complexity of the old framework package should not be copied into the first stack-v2 extension increment.
|
||||
|
||||
## Phases
|
||||
|
||||
1. Source ownership: move accepted goal source, dependencies, and tests into canonical directories; preserve source provenance and user acceptance evidence.
|
||||
2. Native development packaging: deterministic install into .pi, drift checks, source/package tests, explicit runtime version compatibility, and repeat native acceptance if behavior changes.
|
||||
3. Managed runtime integration: approved extension allowlist, image packaging, policy compatibility, isolation, and rollback checks. Docker remains deferred until authorized.
|
||||
4. Component-by-component legacy replacement: inventory dependencies, contracts, state ownership, acceptance criteria, and rollback for each component before migration. No wholesale adoption of operational state.
|
||||
|
||||
## Implemented first increment
|
||||
|
||||
The accepted goal extension now follows the recommended ownership boundary.
|
||||
|
||||
- Canonical source and tests are under `extensions/goal/`.
|
||||
- Imported support modules are under `extensions/mosaic-core/lib/`; no second entrypoint exists.
|
||||
- `scripts/sync-dev-extensions.sh` stages and verifies ordinary-file copies in `.pi/extensions/`. It records the installed manifest, rejects source symlinks or extra entrypoints, detects installation drift, and refuses to overwrite it.
|
||||
- `scripts/goal-dev.sh` synchronizes before launching isolated native Pi. `.pi/goal-dev.sh` remains a compatibility wrapper for the accepted test command.
|
||||
- `scripts/test-extension-package.sh` runs 18 controls. It covers initial installation, full-tree equality, extra destination entries, source and destination symlinks, local drift, canonical updates, nested entrypoints, active and stale locks, and interruption rollback/recovery.
|
||||
- `.pi/extensions/`, state, generated manifests, and local evidence are ignored. They are installations or runtime evidence, not canonical source.
|
||||
|
||||
Verification after the move passed: 67 goal tests, all 18 development-package controls, and native Pi PTY checks at 45 and 120 columns for Waiting, Paused, Blocked, Complete, bare `/goal`, Alt+G, and NO_COLOR. A separate read-only reviewer first requested stronger full-tree, nested-entrypoint, interruption, and lock controls. After correction, the reviewer returned APPROVE and identified each prior finding as closed. The exact canonical-source manifest is `.pi/evidence/canonical-source.sha256`, whose SHA-256 is `c2096c00fb505a53482ff6a94a0f293dbc1ca2058d7a1996961601af80c29946`.
|
||||
|
||||
No package-manager change, npm publication, Docker inclusion, live-fleet installation, commit, or push is part of this increment. Unrelated CURRENT.md work remains untouched.
|
||||
|
||||
## Replacement method
|
||||
|
||||
Use the repository as a component monorepo with explicit boundaries, not as one undifferentiated package. Keep declarative resources in their existing top-level directories. Add executable packages or apps only when they have independent build and dependency needs. Every migrated component gets canonical source, tests, a deterministic development installation, an explicit release inventory, exact runtime compatibility, independent review, and user acceptance before the old implementation can be retired.
|
||||
|
||||
For Pi resources, the Pi package format supports explicit `pi.extensions` and `pi.skills` paths. Do not publish the entire private repository by convention. When external distribution becomes necessary, create a bounded package manifest or staged artifact that names only approved resources and declares Pi APIs as peer dependencies. The current sync installation is deliberately narrower and precedes that release decision.
|
||||
|
||||
## Coordination request
|
||||
|
||||
`MS55-DW-1` asks darkwing, the current owner of CURRENT.md and issue #53 phase-2 planning, to reconcile the next foundation goal before Jason sets it. Requested return: darkwing's intended technical-mapping scope, paths this session must avoid, and a recommended division of work that incorporates #55 without overlapping writers. Destination is the default tmux session `darkwing`; follow-up owner is this assistant. `tools/tmux/agent-send.sh` returned rc=2 at 2026-09-06 06:55 UTC: it could not confirm submission after three attempts and reported that the message may be undelivered. Delivery is unknown, so this session will not resend without reconciliation. No source or shared-plan work starts from this request.
|
||||
|
||||
## Reconciliation finding
|
||||
|
||||
CURRENT.md says issue #53 phase 2 is accepted and awaits Jason's separate authorization for technical mapping. ROADMAP.md also records an earlier owner decision: the succession target uses `packages/*`, while broad restructuring waits for M20 because moving current bash entrypoints sooner would create two migrations. The #55 `extensions/` location is therefore a valid canonical source improvement now, but it cannot silently become the final post-M20 package layout. Jason's latest direction does not explicitly revoke the earlier sequencing decision.
|
||||
|
||||
The next safe step is a coordination and baseline goal, not another code move. It should reconcile the `extensions/` staging location with the `packages/*` target, assign non-overlapping writers for the current dirty tree, and define the exact committed revision that a later as-built/planned map will cite. Archify mapping requires a commit SHA and will not treat the current dirty working tree as evidence.
|
||||
|
||||
Darkwing replied directly to `MS55-DW-1` at 2026-09-06. The reply supports an evidence-backed current-versus-planned component/package map with #55 as input and no runtime implementation. Agreed ownership: darkwing owns requirement-to-code mapping and CURRENT integration; Dewey owns source, package, installation boundaries, and phased inventory in this #55 plan or a separately agreed file. Darkwing will avoid `extensions/**`, `.pi/**`, #54/#55 plans, and the four extension development scripts. Dewey will avoid CURRENT.md, the three foundation/phase-2/schema plans, and `foundation-v1-candidate/**`. Shared logs remain append-only. Both sides await Jason's explicit mapping authorization. A non-author must review the resulting candidate. The acknowledgement send returned rc=2 after three unconfirmed attempts; delivery is unknown and it was not resent.
|
||||
@@ -0,0 +1,135 @@
|
||||
# NG goal footer development plan
|
||||
|
||||
Issue: [#54](https://git.mosaicstack.dev/mosaicstack/stack-v2/issues/54)
|
||||
|
||||
## Outcome
|
||||
|
||||
Develop a repository-local copy of the Mosaic `/goal` extension for native Pi launches from this repository. Goal state appears in Pi's built-in footer as `Goal: <State>`. Bare `/goal` and a keyboard shortcut show the full stored goal text without truncation.
|
||||
|
||||
This is NG development. It does not change or reload the live extension under `~/.mosaic`, and it does not add the extension to the Docker launch path.
|
||||
|
||||
## Baseline and ownership
|
||||
|
||||
- Repository baseline at intake: `69d1bb3` with unrelated, preserved phase-2 planning changes in the working tree.
|
||||
- Source snapshot: `~/.mosaic/fleet/extensions/goal/` plus the imported `mosaic-core/lib/` modules, copied as ordinary files.
|
||||
- Initial development location: `<cwd>/.pi/extensions/`; canonical source moved to `extensions/` after acceptance.
|
||||
- Author: this native coding session, `01a07506-f3c7-76ff-a725-b3c5e2086f31`. The operator directed completion after the setup-only checkpoint. The worker declaration remains undispatched.
|
||||
- Independent reviewer: a non-authoring reviewer seat on the exact candidate.
|
||||
- Product acceptance owner: Jason.
|
||||
|
||||
The source snapshot is not evidence that the external extension is safe to change. All changes remain inside this repository; nothing writes through to the external source.
|
||||
|
||||
## Requirements
|
||||
|
||||
1. Native Pi discovers the project extension through `.pi/extensions/*/index.ts` after project trust is granted.
|
||||
2. No goal widget appears above the editor.
|
||||
3. Pi's built-in footer displays a textual state. Color reinforces the text but never carries the meaning alone.
|
||||
4. State presentation uses Pi theme roles:
|
||||
- `Active`: `accent`
|
||||
- `Waiting`: `warning`
|
||||
- `Paused`: `warning`
|
||||
- `Blocked`: `error`
|
||||
- `Complete`: `success`
|
||||
- `None`, if shown: `muted`
|
||||
5. Bare `/goal` displays the complete stored goal text. It may format or wrap the text, but it must not shorten it.
|
||||
6. A non-conflicting shortcut displays the same complete status. Tab remains Pi autocomplete because Pi's public status API does not expose focusable footer items.
|
||||
7. Waiting, blocked, and ordinary pause are distinguishable. A completed goal remains recallable without reactivating its continuation loop.
|
||||
8. Existing continuation, report, wait, abort, persistence, and incarnation-fencing behavior stays intact.
|
||||
9. Extension failures must not alter the live `~/.mosaic` files or operator goal state used by other agents.
|
||||
|
||||
## State design
|
||||
|
||||
The current source has `active`, `paused`, `blocked`, and `none` in its type, but blocked reports currently become paused with a `blocked:` reason. Satisfaction clears the state immediately. The implementation must add an explicit display projection rather than infer every label in the renderer.
|
||||
|
||||
Preserve active-loop semantics. Store a bounded terminal outcome record for recall after completion, including the full goal text and terminal state. Do not treat `Complete` as an active goal. Existing version-1 state files must load without losing their active or paused goal.
|
||||
|
||||
Bare `/goal` must use the full state text. Short text remains acceptable in transient notifications that are not the recall command.
|
||||
|
||||
## Interaction design
|
||||
|
||||
Use `ctx.ui.setStatus("goal", ...)` so the goal indicator composes with Pi's default footer. Do not replace the entire footer. Remove the project copy's `setWidget` registration and clear any stale goal widget during startup and reload.
|
||||
|
||||
Register a direct recall shortcut. `Alt+G` is the initial candidate, subject to a native terminal conflict check. The shortcut invokes the same full-status formatter as bare `/goal`; it does not insert text into the editor or start a model turn.
|
||||
|
||||
## Tasks
|
||||
|
||||
| ID | Owner | Work | Exit evidence |
|
||||
|---|---|---|---|
|
||||
| NG-GF-1 | Conductor | Copy the goal directory and imported mosaic-core library into `.pi/extensions/` with no symlinks; record source and destination hashes. Do not copy `mosaic-core/index.ts`, because Pi would auto-discover and execute that separate policy extension. | File inventory, no-symlink check, matching snapshot hashes, and one discovered goal extension. |
|
||||
| NG-GF-2 | Author worker | Implement display-state projection, terminal outcome recall, colored footer status, full `/goal` output, shortcut, and focused tests. | Clean patch plus focused test and type-check output. |
|
||||
| NG-GF-3 | Independent reviewer | Review the exact candidate for state migration, loop regressions, extension isolation, keyboard behavior, and hostile state inputs. | Written verdict tied to the candidate hash. |
|
||||
| NG-GF-4 | Conductor | Run repository suites and extension tests; verify no path resolves into `~/.mosaic`. | Green command output and path/hash checks. |
|
||||
| NG-GF-5 | Jason | Exercise native Pi at narrow and wide widths, active/waiting/paused/blocked/complete states, bare `/goal`, shortcut, and color-disabled mode. | Explicit user acceptance or findings. |
|
||||
|
||||
Worker declarations are `tasks/ng-goal-footer-implementation.json` and `tasks/ng-goal-footer-review.json`. They are not dispatched until the conductor provides an isolated exact candidate workspace. The current dirty repository is not silently adopted as a worker workspace.
|
||||
|
||||
## Verification
|
||||
|
||||
Automated checks:
|
||||
|
||||
- strict task validation;
|
||||
- extension unit and runtime tests;
|
||||
- state migration fixtures for old version-1 records;
|
||||
- footer text and theme-role assertions for every state;
|
||||
- full-text equality for `/goal` and shortcut recall;
|
||||
- no `setWidget` call for goal state;
|
||||
- no symlinks or source paths resolving into `~/.mosaic`;
|
||||
- existing repository suites;
|
||||
- `git diff --check` and prose checks.
|
||||
|
||||
Native TUI checks:
|
||||
|
||||
- normal and narrow terminal widths;
|
||||
- keyboard-only recall;
|
||||
- project reload and session replacement;
|
||||
- default theme and color-disabled output;
|
||||
- stale widget removal;
|
||||
- complete and blocked states remain textually identifiable.
|
||||
|
||||
The footer uses native terminal theme colors. Browser-specific WCAG contrast measurement is not applicable, but status meaning must remain available without color and in `NO_COLOR` mode.
|
||||
|
||||
## Security and rollback
|
||||
|
||||
Project-local extensions execute with the native Pi process's host permissions. The operator must explicitly trust this project. This test does not prove the managed execution, command recording, credential, or isolation requirements in #53.
|
||||
|
||||
Development-install rollback removes generated `.pi/extensions/` plus NG-only test state. Source rollback reverts the separately scoped canonical `extensions/` change; it never edits the external `~/.mosaic` extension.
|
||||
|
||||
## Setup checkpoint
|
||||
|
||||
NG-GF-1 completed on 2026-09-06. The copied goal tree hash is `8853f2b72dde3e87c4573648b9a931c1c75da87ccde995c3224e6d2e707a75f0`; the copied mosaic-core library hash is `d1194dce31209e5773c6cc5ce571cbca3c39b29d943a79dea06665e05d29f319`. `.pi/SOURCE-SNAPSHOT.json` records the snapshot. A no-symlink check passed, and only `.pi/extensions/goal/index.ts` is auto-discoverable.
|
||||
|
||||
An isolated native Pi RPC launch with `--approve`, a temporary `PI_CODING_AGENT_DIR`, no session, and no tools reported exactly one project-scoped `/goal` command from this repository's `.pi/extensions/goal/index.ts`. No extension error appeared.
|
||||
|
||||
The five self-contained goal suites pass 55 tests. The first broad copied-source run also exposed two repository-context tests that expect `skills-local/` files from the source brain. They remain failing in this repository and are not counted as green. Copying all of mosaic-core initially also exposed that its separate `index.ts` would be auto-discovered and that its tests require source-brain role manifests. Setup was corrected before the discovery smoke test: only the imported mosaic-core library remains. No live extension file was changed.
|
||||
|
||||
## Delivery gates
|
||||
|
||||
Implementation is not done at setup. It proceeds through author checks, independent exact-candidate review, repository checks, and Jason's native TUI acceptance. Docker promotion, release packaging, and edits to `~/.mosaic` are excluded from #54.
|
||||
|
||||
## Implementation checkpoint, 2026-09-06
|
||||
|
||||
The local implementation is available for hands-on testing. Start `bash .pi/goal-dev.sh` from this repository. It loads only the local goal extension, preserves native provider authentication, and puts goal state and conversation files under `.pi/state/`. It neither copies credentials nor loads the live fleet extension. Plain native Pi also discovers the project copy after trust, but the launcher prevents global extension collisions.
|
||||
|
||||
- NG-GF-2 implemented by the current native session. Footer status replaces widget content; stale widgets are cleared. Bare `/goal` and Alt+G share full-text recall. Complete retains full goal text and bounded evidence without an active continuation loop. Blocked has its own state and supports explicit resume. Old version-1 state remains readable.
|
||||
- NG-GF-3 has an independent read-only native reviewer APPROVE. The reviewer inspected the entrypoint, display, state, store, and launcher but did not rerun tests. The first review attempt timed out without output; a second process with a ready configured provider returned the verdict. No worker container was dispatched.
|
||||
- NG-GF-4 author checks passed: all 67 goal tests and repository suites config 24, task 90, release 14, conductor 17, auth 15. Native Pi 0.85.1 PTY checks passed at 45 and 120 columns for paused, blocked, complete, waiting, bare recall, shortcut recall, and one color-disabled case. Native discovery found exactly one local goal command. No symlinks. Live extension hashes still match the source snapshot.
|
||||
- The source-brain test failures are resolved with ordinary local contract fixtures. The executive-update fixture matches its pinned SHA-256. Tests no longer need live brain reads.
|
||||
- Static TypeScript checking was not run because no compiler is installed. Native loading and Node TypeScript execution passed, but they are not a substitute for static checking.
|
||||
- NG-GF-5 remains open for Jason. Instructions and expected results are in `.pi/README.md`. No user acceptance, commit, push, Docker integration, or release completion is claimed.
|
||||
|
||||
Evidence is in `.pi/evidence/README.md` and its logs. The reviewed candidate file manifest hashes to `10e949db54149c6bed945fab086ad7a91461683ee5661c920f9ee6bddcf04aae`. No reviewed source file changed between review and manifest recording.
|
||||
|
||||
Goal state: waiting for manual user test. Next action: Jason launches `bash .pi/goal-dev.sh`, exercises full recall and the footer, and returns acceptance or findings. Issue #54 stays open. This checkpoint does not advance or change issue #53 or CURRENT.md. No automatic wake is registered.
|
||||
|
||||
|
||||
## User acceptance, 2026-09-06 06:05 UTC
|
||||
|
||||
Jason replied "It works" to the native test handoff. NG-GF-5 is accepted for this local development test. This supersedes the manual user-test wait above; it does not establish separate measurements of every test case.
|
||||
|
||||
No further feature work is requested. Static type checking remains unperformed. Commit, push, Docker integration, and live fleet changes are not authorized by this acceptance. Issue #54 remains open for repository delivery disposition; CURRENT.md and unrelated work remain unchanged.
|
||||
|
||||
## Canonical source migration, 2026-09-06
|
||||
|
||||
At Jason's direction, the accepted implementation moved from development-only source ownership to the repository's component structure. Canonical files now live under `extensions/goal/` and `extensions/mosaic-core/lib/`. `.pi/extensions/` is generated and ignored.
|
||||
|
||||
`scripts/sync-dev-extensions.sh` performs staged ordinary-file installation with content verification and refuses local drift, symlinks, or an extra extension entrypoint. `scripts/goal-dev.sh` runs this sync before native Pi; `.pi/goal-dev.sh` remains a compatibility wrapper. The native test moved to `scripts/test-goal-native.py`. This source-only relocation does not change accepted behavior, package the extension into Docker, publish npm, or touch the live fleet.
|
||||
Reference in New Issue
Block a user