Files
jason.woltjeandClaude Opus 5.5 1e3575be66 agents: Rocko row 138 packets r1, r3-before-152 and r3 (#1632)
Round 3 candidate on 26a0b0fab, manifest digest 75e07b65...47d1, 42
paths, with the runtime.mjs project adapter Sage approved in sage-0488.
Rocko's run: 747 package tests passed, 54/54 mutants killed. Packet
scanned for secrets and binaries, none found.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 20:12:17 -05:00

8.2 KiB

Row 138 revised design — file-backed spec (proposal)

Recorded 2026-10-15 23:07:15 UTC against the section in docs/plans/2026-10-15_q167-rows-r3.md, per sage-0414. Design only. Implementation waits for Filbert to approve row 147. The superseded worktree and PAUSED.md stay preserved; no old specs/confirmation tables carry forward. Row 143 belongs to Researcher and is no longer on Rocko's list.

Layout and Git reads

Use row 147's declared business/project resolution and separate repository. The only spec path is spec/north-star.md. Proposed meaning of current commit: the most recent reachable commit that changes that file, rather than HEAD. A docs/requirements/decisions commit therefore does not invalidate citations. Read returns bounded UTF-8 content at a validated full commit ID, its file commit, and a bounded log for that path. Reject revisions outside the local repository's reachable history and paths outside this fixed path. Reads invoke no shell, network, filters, hooks or caller-supplied Git options. They use the same sanitized Git and repository checks as row 147.

A human-authored file commit is confirmation. Check the author against the business's human and the local identity convention used by init; this records local provenance, not a cryptographic identity claim. An agent-authored latest spec change must not silently fall back to an older human version. Refuse a citation until the spec has a valid human confirmation. Reads may expose committed history for diagnosis without granting a write. Dirty working bytes are never returned as confirmed content.

This needs a shared read helper in packages/project, beside its writer, to avoid copying repository/Git validation into the broker. That path is not explicitly in row 138's Files owned list: ask Sage for the small scope addition before code. Coordinate this helper with row 148's human read/save API.

Bus and tools

Add nullable spec_path and spec_commit to decisions, preserving old uncited raises. A cited raise requires project, the exact fixed path, and the current human-confirmed file commit. Require both citation fields together. Resolve and validate before any decision/event insert. Store exactly that path and full commit. Existing classification, routing, resolution and authorization stay as they are; row 139 changes routing later. A later spec commit never changes old rows or resolution events.

Any authenticated role instance may read the spec for a project declared in its own business, at current or requested historical commit, with its path log. The record-write action is separate: add its vocabulary entry and only the brief-approved role grants. Bind author definition/instance from the broker's session, never request fields. Pass the validated record to row 147 writeRecord. No spec-write verb, propose/confirm action, shell tool or alternate writer is added. The harness strict schemas expose spec read, record write, and optional paired citation fields on raise_decision. Agent writes to spec must refuse in the package, broker and harness paths.

Migration and evidence

The 3e to 3f step adds only the two nullable decision columns. No spec tables. Use the existing ordered migration mechanism, a schema-3e fixture built from the repository, and preservation assertions covering every existing table and row. Keep the future-version chaining test. MIGRATION.md gives Mos the exact backup, offline migration, validation, re-pin and rollback procedure; no seat reads or migrates the live store.

Acceptance checks each get a mutant: current citation stored; stale/nonhuman/ missing confirmation refused; no-spec raise unchanged; settled decision survives a spec edit; docs-only commit leaves current spec commit unchanged; read content and path log at current/historical commits; business/project/path isolation; bound author on record commit; each exposed spec-write path refused; migration preservation and chaining. The revised brief requires bus, business, harness, cli and all scripts/test-*.sh; include project suite if the helper is approved. Ask for the shared slot before suites or mutants. No schema/live step until 147 is done, review is approved, and Mos runs the separate window.

Shared reader API — sage-0419

Scope addition approved by Sage in sage-0419, at Rocko's request: reader and fixture tests in packages/project share row 147 repository validation. Record that approval in BUILD.md when the build begins. The API below is the proposed exported contract for Researcher's row 148; no implementation has started.

Exports from packages/project/src/index.mjs (both async):

readProjectFile({ business, project, dataRoot, path, commit })
readSpec({ business, project, dataRoot, commit })

Context is exactly row 147's context. path accepts only spec/north-star.md or docs/<name>.md, with the same canonical single-file Markdown name grammar as writeRecord; no traversal, absolute paths or extra keys. commit is optional. Omission selects a snapshot of HEAD. A supplied commit is a full lowercase 40-character Git SHA-1 naming a commit reachable from that HEAD, never an arbitrary revision expression. Capture HEAD once and use that snapshot for every subsequent Git read in the call.

readProjectFile returns:

{
  repo,             // resolved absolute path
  path,             // validated repository-relative path
  head,             // captured HEAD commit
  revision,         // requested commit, or head
  commit,           // last commit changing path at revision
  content,          // exact bounded UTF-8 blob bytes decoded, trailing LF kept
  author,           // { name, email } from that file commit
  log,              // newest first, at most 100 path-changing commits
  truncated         // true if more than 100 entries exist
}
// Each log entry: { commit, author: { name, email }, at, subject }
// at is the author timestamp rendered as canonical UTC ISO text.

The log is for this path through revision, following its fixed name (no rename following), not all repository commits. Messages/identities are data, never Git arguments. Content is at revision, and commit names its last change. The file must be a regular Git blob, not a symlink/submodule, with at most 1 MiB, valid UTF-8 and no NUL. No trimming of content. Repository identity in committed project.json must match the requested business/project. Reject unsafe local metadata/remotes using row 147's checks. Reads do not require a clean working tree: they ignore uncommitted bytes, allowing the editor to load the last committed version without silently treating pending edits as confirmation.

readSpec fixes path to spec/north-star.md and returns all fields above plus confirmed: boolean, true exactly when author.name equals business.human. It returns history even when false, so diagnosis is possible. The broker must refuse a cited raise with false; it must compare the citation against a fresh current readSpec call, not trust a caller's historical read. A direct read of an older confirmed commit does not make it current. Existing settled decisions keep their recorded commit and are never rewritten.

Failures throw ProjectError with a stable .code; messages are explanatory only:

Code Meaning
project-id Invalid context ID.
project-path Invalid repository root, overlap, or linked ancestor.
project-not-declared Project absent from this business.
project-repository Unsafe/missing Git metadata.
project-remote Repository has a remote.
project-invalid Committed project identity/layout metadata invalid.
project-read-path Missing/invalid path or unsupported argument keys.
project-read-commit Malformed, missing, non-commit or unreachable revision.
project-read-missing Path absent at the selected revision.
project-read-content Nonregular blob, oversized, invalid UTF-8 or NUL.
project-git Bounded local Git invocation otherwise failed.

Missing-spec or nonhuman confirmation refusal for decision.raise is a broker policy error, separate from the reader's diagnostic result. Neither helper writes a file, lock, index, config or commit. Row 148's save writer must still check its stale base under its write lock; a successful earlier read cannot substitute for that check. Row 138 adds no human or agent spec writer.