Files
stack/docs/plans/2026-09-06_ng-goal-footer-dev.md
T

12 KiB

NG goal footer development plan

Issue: #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.