The business file accepts a kind "library" project entry, and each consumer that assumed a project root skips it. An organization write whose projects differ from the file's is refused (M9). The bare mirror is created at the projectRepo path with no remote. library.file and library.status are human only and refuse an agent session with human-required. Candidate herb/row215-on197dde3445abona36523713, Filbert APPROVE rev 2924.
247 lines
15 KiB
Markdown
247 lines
15 KiB
Markdown
# C2-04 library business entry implementation plan
|
|
|
|
> Execution: Herb implements in this session using the executing-plans skill.
|
|
> Filbert approves this manifest before any product implementation.
|
|
|
|
**Goal:** Load a library mapping without giving an agent a checkout, protect
|
|
all project mappings from organization writes, and expose human-only bus
|
|
reads of the bare mirror's served commit and sync status.
|
|
|
|
**Architecture:** C2-01 checks mappings and reads commits. Business consumers
|
|
skip library entries. A host-only mirror module owns local mirror reads and
|
|
initialization. runtime.mjs injects that module into the broker, preserving
|
|
the broker's sandbox import closure. Sync and HTTP routes belong to later rows.
|
|
|
|
**Tech stack:** Existing Node ESM, node:test and bounded local Git helpers.
|
|
No dependencies. node_modules remains the plain canonical symlink.
|
|
|
|
**Spec:** Pinned C2-04 brief; Gosalyn's approved design 1.1, 1.3, 2.1,
|
|
M4/M9 and 7.2; BUILD.md's sage-1848/1852/1860 scope and shared-state contract.
|
|
|
|
## Constraints and review focus
|
|
|
|
- Base a2c72ac95; rebase only onto Sage's named 212 landing on a new branch.
|
|
- Existing code-project entries retain root/repo/remote behavior. Library
|
|
entries have no root or repo override and use C2-01 checkMapping.
|
|
- Preserve the broker's pinned imports. No library import in broker.mjs and
|
|
no new runner mount. Do not edit serve.mjs or add an HTTP route.
|
|
- No fetch, remote config, credential read, timer, sync writer, bus write or
|
|
live operation. All tests use made-up content and local repositories.
|
|
- All test/probe runs require Sage's grant (sage-1867), including singles.
|
|
Stop and report two failures in one gate. Do not push without authorization.
|
|
|
|
Review focus, with owning tasks below: library-first iteration must not
|
|
break a later code project (T1); serialized documents cannot bypass M9
|
|
(T2); racing initialization must not replace another mirror (T3); stale or
|
|
unsafe state must not leak content (T3); async socket replies must preserve
|
|
the result and human-only admission (T4).
|
|
|
|
## Paths and evidence from the base
|
|
|
|
| Product path | Allowed change |
|
|
| --- | --- |
|
|
| packages/business/src/business.mjs | Dispatch kind:library to checkMapping before code-root validation (:228-244) |
|
|
| packages/business/src/organization.mjs | Compare canonical projects in write before publication (:177 onward) |
|
|
| packages/business/src/cli.mjs | Skip library roots in validate, resolve --project and credential exclusion roots (:60-61, :71-79, :118) |
|
|
| packages/business/src/resolve.mjs | Skip library entries while matching a project file (:44) |
|
|
| packages/business/src/instance-settings.mjs | Skip library before projectFilePath (:142), nothing else |
|
|
| packages/seat/src/checkout.mjs | Skip library entries in ensureCheckouts (:315-327) |
|
|
| packages/cli/src/launcher.mjs | Pass only code entries to ensureCheckouts (:354) |
|
|
| packages/cli/src/config.mjs | Skip library entries in trackerFor's root loop (:61-63), per sage-1860 |
|
|
| packages/project/src/paths.mjs | Skip library entries in overlap loop (:41-44); default record use refuses library, mirrorPath internally opts into allowLibrary |
|
|
| packages/library/src/mirror.mjs | New bare init, checked state and served-commit file read module |
|
|
| packages/library/src/index.mjs | Export mirror module interface and SYNC_STATE_FILE |
|
|
| packages/bus/src/broker.mjs | New injected library adapter, human-only admission and two async verbs |
|
|
| packages/bus/src/runtime.mjs | Library adapter wiring, mirror initialization and protectedRoots skip only |
|
|
| packages/bus/src/server.mjs | Await the two library verbs only |
|
|
| packages/webui/src/cli.mjs | Two library read callbacks beside project callbacks on main and tester listener; no routes |
|
|
|
|
packages/business/src/project.mjs need not change: callers skip a library
|
|
before projectFilePath or loadProject. Do not weaken their code-root checks.
|
|
scripts/stack-copy.sh already copies packages/library/src and needs no edit.
|
|
|
|
Test paths to modify: business/tests/business.test.mjs, cli.test.mjs,
|
|
resolve.test.mjs, instance-settings.test.mjs; seat/tests/checkout.test.mjs;
|
|
cli/tests/launcher.test.mjs, trackers-boot.test.mjs; project/tests/project.test.mjs;
|
|
bus/tests/project-runtime.test.mjs. All paths are under packages/.
|
|
|
|
T5 dependency-audit addition: cli/tests/stack-release.test.mjs and its
|
|
stack-release-fixture.mjs helper copy packages/library/src alongside
|
|
business/src, whose validator now imports the mapping checker. No assertions
|
|
or timeouts change. Whole-file dependent singles require a later Sage slot.
|
|
|
|
New tests: packages/business/tests/library-projects-protected.test.mjs;
|
|
packages/library/tests/mirror.test.mjs; packages/bus/tests/library.test.mjs;
|
|
packages/webui/tests/library-cli.test.mjs. Reuse existing made-up fixtures.
|
|
If a new fixture is needed, define it within the corresponding new test file.
|
|
No unrelated test assertion or timeout changes.
|
|
|
|
Record paths: agents/herb/work/queue-215/{MANIFEST.md,BUILD.md}, later source
|
|
manifest and test receipts there; one append-only BUILD-LOG.md phase for this
|
|
row when implementation begins. Sage owns docs/SESSIONS.md.
|
|
|
|
## T1. Mapping and consumer skips
|
|
|
|
- [ ] Add failing business tests: accept a frozen library mapping without a
|
|
root, retain mixed/only-library documents, and propagate C2-01's mapping
|
|
and playground refusal codes. A role publish naming a library project
|
|
refuses at load, even with an otherwise valid fork identity and remote.
|
|
Existing code validation remains unchanged.
|
|
- [ ] Add a separate regression for each consumer: CLI validate and its
|
|
credential exclusion roots; CLI resolve --project books has no project
|
|
layer; resolveInstance finds a later real project; instance settings still
|
|
writes an unrelated setting; ensureCheckouts returns no library checkout;
|
|
launcher creates no books workspace clone; projectRepo skips a library
|
|
while still rejecting overlap with a real code root. Put books first.
|
|
- [ ] Add the real bus boot regression in cli/tests/trackers-boot.test.mjs:
|
|
tracker.baseUrl is set and books is a library entry; boot succeeds, books
|
|
produces no tracker, and a later real tracker project still works.
|
|
- [ ] projectRepo(context, {allowLibrary = false} = {}) refuses a library
|
|
entry by default with project-invalid. Only mirrorPath opts in. Test that
|
|
ordinary human and tester record initialization leave no directory at the
|
|
future mirror path; no public verb can supply allowLibrary.
|
|
- [ ] Add runtime's protectedRoots consumer regression in T4's real runtime
|
|
fixture. A valid credential outside code/data roots still loads with a
|
|
library entry, and existing credential protections still refuse unsafe files.
|
|
- [ ] Run each changed test singly, confirm the new cases fail for the
|
|
intended root assumption, then implement only the table's guards and
|
|
checkMapping dispatch. Re-run the same files singly.
|
|
|
|
CLI validate reports a library entry as library, without an absent-project
|
|
warning. CLI resolve --project books resolves without loading a project file,
|
|
as the design's skip requires. It does not fabricate project vars or a root.
|
|
|
|
## T2. M9 at the organization writer
|
|
|
|
- [ ] In the new business test file, call organizationWriter.write directly
|
|
with a changed playground prefix and, separately, a changed hybrid entry.
|
|
Both refuse organization-projects-protected. Snapshot business bytes and
|
|
changes.jsonl before each call; assert both remain identical afterward.
|
|
- [ ] Cover addition, deletion and changes to code projects too, since M9
|
|
protects all projects. Reordered object keys are allowed; array changes
|
|
are changes. An ordinary non-project write still succeeds and logs.
|
|
- [ ] Add a serialization regression so a proposed object's serialized
|
|
projects cannot differ from those checked before publication.
|
|
- [ ] Run the file singly to see the missing refusal, compare canonical
|
|
projects against old disk JSON and the document that actually lands,
|
|
before any publication/receipt, then re-run it singly.
|
|
|
|
## T3. Bare mirror, served file and read-only state
|
|
|
|
- [ ] Add failing tests for mirrorPath and ensureMirror: exact projectRepo
|
|
default, no checkout/remote, retained no-links/overlap protections,
|
|
idempotence, simultaneous creators and preservation of a pre-existing
|
|
non-mirror directory or unsafe Git metadata.
|
|
- [ ] Add failing state tests for BUILD.md's full version-1 contract: missing
|
|
state/ref, valid state, malformed JSON, unknown keys/types, branch mismatch,
|
|
invalid times/IDs/problem shape, symlink/hardlink/non-private file and
|
|
missing or mismatched served ref. Assert reads change no bytes.
|
|
- [ ] Add shared-lock tests: withLibraryLock(mirror, operation) waits at most
|
|
5000 ms, refuses library-sync-busy on timeout and releases after a throw.
|
|
A reader arriving between the publisher's served move and state write
|
|
waits, then reads the consistent pair. Cover first sync and fast-forward
|
|
in independent processes, same-process independent acquisitions and
|
|
release after owner death. A callback-scoped reader expires on release.
|
|
- [ ] Implement the lock by async spawn of flock on the parent's inherited
|
|
fd 3, as pinned in BUILD.md. Await acquisition-child exit before calling
|
|
operation. Never spawnSync during acquisition, which could freeze the bus
|
|
for 5 s. A parallel ordinary bus read remains responsive while a library
|
|
read waits. Only the publication/read lock is shared; fetch is outside it.
|
|
- [ ] Add served-read tests against local fixtures containing spaces,
|
|
capitals, a .canvas and unmapped top-level note. Seed a served ref and state
|
|
without fetching. A newer unrelated HEAD does not change the returned
|
|
file. R1/R2/R7 exclusions, traversal, a missing path, a caller commit and a
|
|
never-synced mirror refuse. Status contains no fixture body marker.
|
|
- [ ] Implement mirror.mjs and index exports using the shared contract.
|
|
Initialization stages into an owned private sibling directory and renames
|
|
atomically; a losing creator validates the winner and removes only its own
|
|
staging directory. Git uses existing bounded safe helpers, no remote.
|
|
- [ ] Run mirror.test.mjs singly, red then green. Re-run C2-01 reader.test.mjs
|
|
singly if a reader assumption changes. Do not change C2-01 reader rules.
|
|
|
|
mirror.mjs validates a bare mirror's metadata before Git reads it, including
|
|
no remote/include/indirection. It does not apply inspectGit's working-tree
|
|
.git assumption to a bare repository. Failures reuse library-git or the
|
|
approved library-state-invalid code. State reads are bounded and private.
|
|
|
|
## T4. Human-only bus reads and deferred Console callbacks
|
|
|
|
- [ ] Add broker tests for library.file and library.status using injected
|
|
adapters. Each agent session refuses human-required before adapter access,
|
|
including bad arguments and an absent adapter. A reader or tester does not
|
|
gain a human capability. Human calls validate keys, then use checked
|
|
library context. Secret checking and bounded refusal evidence remain.
|
|
- [ ] Add real startBroker/socket tests for both verbs. Seed only local
|
|
fixture mirror data. Assert result shape/content and an actual status
|
|
field, not merely successful transport or {}. Cover never-synced status
|
|
and runtime's protectedRoots skip. Keep the pinned import-closure test.
|
|
- [ ] Inject a separate library adapter via runtime, initialize only library
|
|
mirrors, add the two async request paths, and include them in server's
|
|
awaited list. Do not import library or fs into broker.
|
|
- [ ] Unsafe or pre-existing non-mirror initialization refuses bus boot,
|
|
closes opened resources and never publishes a ready socket. Add that
|
|
runtime regression in library.test.mjs.
|
|
- [ ] Wire main and tester Console callbacks beside project-file callbacks.
|
|
No HTTP route is shipped. The new CLI test captures the startServer
|
|
options with a test-only module loader and calls the supplied callbacks
|
|
against a fixture bus, checking the verb and transport identity. No
|
|
product test seam, UI page, endpoint or serve.mjs change is needed.
|
|
- [ ] Run library.test.mjs, project-runtime.test.mjs and library-cli.test.mjs
|
|
individually, red then green. Human admission may use the existing
|
|
fixture authentication seam; do not forge or bypass a live identity.
|
|
|
|
## T5. Review packet and Sage's gate
|
|
|
|
- [ ] Search packages/*/tests and scripts/test-*.sh for each changed source
|
|
path, imports and 64-hex pins. Record the resulting test-file list and run
|
|
each changed/touched test singly. Stop and report a scope error.
|
|
- [ ] Self-review the diff against this manifest and all acceptance cases.
|
|
Record results, commands, skips, source hashes and remaining limits in
|
|
BUILD.md. Request Sage's slot for the required business, seat, cli, project,
|
|
bus and webui suites and every scripts/test-*.sh. Do not run them ungranted.
|
|
- [ ] After applicable tests are green, make the source commit, build the
|
|
candidate manifest from the authorized pushed tip, and move the row with
|
|
scripts/mosaic. Sage posts token-requiring requests; Filbert reviews the
|
|
candidate. Push only when authorized. No merge or live change by Herb.
|
|
|
|
## Self-review
|
|
|
|
Every brief acceptance item is in T1-T4. Added host support paths match
|
|
sage-1848/1860. BUILD.md records the complete 14-hit root audit. State shape
|
|
and authority match sage-1852; the shared read/publication lock follows
|
|
sage-1860 and Megavolt's agreement. Fetch, timers, outer sync serialization
|
|
and HTTP stay with their later rows.
|
|
This is a plan only; no product edits or test execution precede approval.
|
|
|
|
|
|
Landing update: prepared herb/row215-on212 on fefd54e13 (includes row 212
|
|
landing ee7b2f137), without history replay or stash. Only BUILD-LOG.md and
|
|
cli/tests/stack-release.test.mjs overlap the a2c72ac95-to-landing change
|
|
set. BUILD-LOG preserves all landed entries and appends the existing Herb
|
|
entry. stack-release preserves the landing plus only the library/src copy
|
|
list addition. No test has run on this landing yet. All further execution
|
|
requires a Sage grant (supersedes the original COMMON singles rule).
|
|
|
|
|
|
Current merge preparation per sage-1983/1987: new branch
|
|
herb/row215-on-f827 on f8276c5eb3ecb0aad353ee65e3dd8f7faac5dd87.
|
|
Nine landed overlaps are recorded in current-MERGE.json and the exact
|
|
candidate deltas against the landing are in current-merge-only.patch.
|
|
Two textual conflicts were resolved manually: Broker keeps hostKeys and
|
|
adds library; business.mjs keeps CREATIVE_DEFINITIONS and adds checkMapping.
|
|
The other seven merges preserve the landing plus the original C2-04 edits.
|
|
All other product/test paths match the early215 tree byte for byte. The
|
|
landing's BUILD-LOG is preserved and the existing Herb entry is appended.
|
|
No history replay, stash, force push, branch deletion or source commit.
|
|
No test/probe/syntax check ran on the merged tree after the slot was cleared.
|
|
All16 whole singles need a new Sage grant before candidate commit/review.
|
|
The10 old-base315/0 results are early reads only, never merged gate evidence.
|
|
|
|
|
|
Candidate status: source commit e333af4dc7af3a9d3789c8c0db26a0df8bdddfee. The16 whole
|
|
singles passed451/0 under sage-2008 with zero skips/cancellations; raw
|
|
outputs and merge receipts are in this packet, indexed by EVIDENCE.json
|
|
and SOURCE.json. Sage keeps the landing gate. Filbert's implementation
|
|
review and that gate remain pending. Prior315/0 on fefd54e13 is early
|
|
read evidence only. Sage-2016 authorizes the seat-only source/packet push.
|