Integrate pb-mirror into os-sdlc: .pbm.yml, gitignore, after_commit tickle #510

Closed
opened 2026-08-25 18:22:46 +00:00 by jared · 5 comments
Owner

Context

ADR-0150 decides a read-only PocketBase mirror of .sdlc/pipeline.db via the standalone pb-mirror gem (~/dev/ruby-gems/pb-mirror, binary pbm). The gem is built separately; this ticket is the os-sdlc side of the integration. Design settled in the 2026-08-25 grilling session.

Slice

A pipeline gate settlement on a repo with pbm installed appears as fresh rows in the PocketBase admin UI within ~2s, via a fire-and-forget after_commit tickle.

Tasks

[ ] Add committed .pbm.yml at repo root: db_path .sdlc/pipeline.db, table list with watermark columns (default updated_at), port, PocketBase version pin.
[ ] Gitignore .pbm/ (pb_data, credentials, pidfile, lockfile).
[ ] Add a Sequel after_commit tickle in the runner that spawns pbm sync fire-and-forget (never blocks a write path; pbm handles lockfile-skip and self-healing up/full-sync).
[ ] Verify worktree behavior: tickles from worktree sessions resolve through the ADR-0143 symlink to the owning pipeline.db; one mirror instance total.
[ ] History row in the os-sdlc implementation-status leaf.

Acceptance criteria

[ ] A pipeline run with pbm installed shows fresh rows in the PocketBase admin UI within ~2s of gate settlement, with no runner slowdown or new runner test failures.
[ ] With pbm absent or PocketBase down and unbootable, the runner behaves exactly as today (tickle failure is silent-to-the-pipeline, logged only).

Non-goals

• The pb-mirror gem itself (own repo).
• Any monitoring front-end pages.

Notes for implementer

.pbm.yml already exists at repo root and is now staged for commit; the stray .gitignore entry ignoring it was removed on 2026-08-27 during triage — task 1's remaining work is verifying content and committing. The .pbm/ gitignore entry already exists. The runner integration point is plugins/os-sdlc/lib/os_sdlc/runner/db.rb per ADR-0150. Real gem commands: pbm init <db> writes config, pbm install downloads the pinned PocketBase binary.

Origin

• Trigger: 2026-08-25 grilling session on swapping sqlite for PocketBase in os-sdlc.
• Improvised this session: none
• Chain: no live view of pipeline data ← pipeline.db only readable via sqlite CLI ← DESIGN (ADR-0089 SQLite+Sequel persistence; resolved additively by ADR-0150)
• Root candidate: this ticket (with the pb-mirror gem as its dependency)

## Context ADR-0150 decides a read-only PocketBase mirror of .sdlc/pipeline.db via the standalone pb-mirror gem (~/dev/ruby-gems/pb-mirror, binary pbm). The gem is built separately; this ticket is the os-sdlc side of the integration. Design settled in the 2026-08-25 grilling session. ## Slice A pipeline gate settlement on a repo with pbm installed appears as fresh rows in the PocketBase admin UI within ~2s, via a fire-and-forget after_commit tickle. ## Tasks [ ] Add committed .pbm.yml at repo root: db_path .sdlc/pipeline.db, table list with watermark columns (default updated_at), port, PocketBase version pin. [ ] Gitignore .pbm/ (pb_data, credentials, pidfile, lockfile). [ ] Add a Sequel after_commit tickle in the runner that spawns pbm sync fire-and-forget (never blocks a write path; pbm handles lockfile-skip and self-healing up/full-sync). [ ] Verify worktree behavior: tickles from worktree sessions resolve through the ADR-0143 symlink to the owning pipeline.db; one mirror instance total. [ ] History row in the os-sdlc implementation-status leaf. ## Acceptance criteria [ ] A pipeline run with pbm installed shows fresh rows in the PocketBase admin UI within ~2s of gate settlement, with no runner slowdown or new runner test failures. [ ] With pbm absent or PocketBase down and unbootable, the runner behaves exactly as today (tickle failure is silent-to-the-pipeline, logged only). ## Non-goals • The pb-mirror gem itself (own repo). • Any monitoring front-end pages. ## Notes for implementer .pbm.yml already exists at repo root and is now staged for commit; the stray .gitignore entry ignoring it was removed on 2026-08-27 during triage — task 1's remaining work is verifying content and committing. The .pbm/ gitignore entry already exists. The runner integration point is plugins/os-sdlc/lib/os_sdlc/runner/db.rb per ADR-0150. Real gem commands: `pbm init <db>` writes config, `pbm install` downloads the pinned PocketBase binary. ## Origin • Trigger: 2026-08-25 grilling session on swapping sqlite for PocketBase in os-sdlc. • Improvised this session: none • Chain: no live view of pipeline data ← pipeline.db only readable via sqlite CLI ← DESIGN (ADR-0089 SQLite+Sequel persistence; resolved additively by ADR-0150) • Root candidate: this ticket (with the pb-mirror gem as its dependency)
Author
Owner

This was generated by AI during triage.

Refined to ticket tier: added Slice, renamed Out of scope to Non-goals, added Notes for implementer. Gitignore contradiction resolved (.pbm.yml unignored and staged, .pbm/ stays ignored). Redundancy check found the after_commit tickle unimplemented. No undecided choices, so no decision children.

> *This was generated by AI during triage.* Refined to ticket tier: added Slice, renamed Out of scope to Non-goals, added Notes for implementer. Gitignore contradiction resolved (.pbm.yml unignored and staged, .pbm/ stays ignored). Redundancy check found the after_commit tickle unimplemented. No undecided choices, so no decision children.
Author
Owner

Work started via os-sdlc pipeline. Branch: ticket-510.

Work started via os-sdlc pipeline. Branch: ticket-510.
Author
Owner

os-sdlc pipeline run failed at node code-probe (implementation_id 2, reason verdict:fail). Gate details: code-probe found no after_commit/pbm/sync/tickle code under plugins/os-sdlc/lib (all four PHANTOM), so it returned verdict fail because the ticket's core behavior is unimplemented. Evidence it did collect: write-path entry points Db.connect/Db.file_db at plugins/os-sdlc/lib/os_sdlc/runner/db.rb:15,36; .pbm.yml exists at repo root (port 8090, version pin) but with an absolute db_path; .gitignore already has .pbm/; worktree pipeline.db symlink matches ADR-0143. Branch ticket-510 kept. No resume path — recovery starts with a new implementation-open.

os-sdlc pipeline run failed at node code-probe (implementation_id 2, reason verdict:fail). Gate details: code-probe found no after_commit/pbm/sync/tickle code under plugins/os-sdlc/lib (all four PHANTOM), so it returned verdict fail because the ticket's core behavior is unimplemented. Evidence it did collect: write-path entry points Db.connect/Db.file_db at plugins/os-sdlc/lib/os_sdlc/runner/db.rb:15,36; .pbm.yml exists at repo root (port 8090, version pin) but with an absolute db_path; .gitignore already has .pbm/; worktree pipeline.db symlink matches ADR-0143. Branch ticket-510 kept. No resume path — recovery starts with a new implementation-open.
Author
Owner

os-sdlc run 3 (implementation_id 3) terminated: bound_exhausted:test-writer/fail at dispatch 22. Cause is the known unexpected-pass routing gap, not missing work: behavior-verifier required a failure-path test, that test (test_a_failing_tickler_stays_silent_and_commit_succeeds in plugins/os-sdlc/tests/runner/db_pbm_tickle_test.rb) exists and pins the correction exactly, but it is green on arrival because MirrorTickle's rescue already shipped in the programmer round — the test-writer node demands red, has no unexpected-pass verdict, and looped until the bound tripped. Work state: after_commit tickle implemented (db.rb + mirror_tickle.rb), 3 behavior tests, suite green, lint green, contract-auditor pass with zero corrections. Awaiting human decision on manual acceptance (precedent: #491 override).

os-sdlc run 3 (implementation_id 3) terminated: bound_exhausted:test-writer/fail at dispatch 22. Cause is the known unexpected-pass routing gap, not missing work: behavior-verifier required a failure-path test, that test (test_a_failing_tickler_stays_silent_and_commit_succeeds in plugins/os-sdlc/tests/runner/db_pbm_tickle_test.rb) exists and pins the correction exactly, but it is green on arrival because MirrorTickle's rescue already shipped in the programmer round — the test-writer node demands red, has no unexpected-pass verdict, and looped until the bound tripped. Work state: after_commit tickle implemented (db.rb + mirror_tickle.rb), 3 behavior tests, suite green, lint green, contract-auditor pass with zero corrections. Awaiting human decision on manual acceptance (precedent: #491 override).
Author
Owner

Resolution

Done: os-sdlc integration of pb-mirror complete: MirrorTickle module spawns pbm sync fire-and-forget via an after_commit hook installed at Db.connect (CommitHook wraps Database#transaction); failures swallowed and logged to stderr; committed .pbm.yml now has relative db_path .sdlc/pipeline.db, port 8090, PocketBase 0.40.1 pin; .pbm/ already gitignored; worktree tickles resolve through the ADR-0143 symlink (relative db_path + symlinked .sdlc/pipeline.db); history row added to docs/implementation-status/os-sdlc.md

Evidence: Merged to main: a18e16a (tickle + 3 behavior tests: commit fires once, rollback never fires, failing tickler stays silent with commit intact), 125cfcf (history row), a486944 (relative db_path). Suite 1226 runs 0 failures; lint clean; contract-auditor pass with zero corrections. Pipeline run itself ended bound_exhausted:test-writer/fail (unexpected-pass gap) and was accepted by explicit user override, precedent #491.

Follow-ups: #522 already filed this session (code-probe greenfield misroute, skeptic VERDICT: CREATE). Unexpected-pass verdict gap in the test-writer gate: investigated this session (local per-edge bound exhaustion routes via error: to terminal by ADR-0133 design; ADR-0152 cap-as-escalation covers only the global dispatch cap); previously left unticketed by explicit user choice after #475; findings surfaced to the user, ticketing decision is the user's. No other follow-ups.

## Resolution **Done:** os-sdlc integration of pb-mirror complete: MirrorTickle module spawns pbm sync fire-and-forget via an after_commit hook installed at Db.connect (CommitHook wraps Database#transaction); failures swallowed and logged to stderr; committed .pbm.yml now has relative db_path .sdlc/pipeline.db, port 8090, PocketBase 0.40.1 pin; .pbm/ already gitignored; worktree tickles resolve through the ADR-0143 symlink (relative db_path + symlinked .sdlc/pipeline.db); history row added to docs/implementation-status/os-sdlc.md **Evidence:** Merged to main: a18e16a (tickle + 3 behavior tests: commit fires once, rollback never fires, failing tickler stays silent with commit intact), 125cfcf (history row), a486944 (relative db_path). Suite 1226 runs 0 failures; lint clean; contract-auditor pass with zero corrections. Pipeline run itself ended bound_exhausted:test-writer/fail (unexpected-pass gap) and was accepted by explicit user override, precedent #491. **Follow-ups:** #522 already filed this session (code-probe greenfield misroute, skeptic VERDICT: CREATE). Unexpected-pass verdict gap in the test-writer gate: investigated this session (local per-edge bound exhaustion routes via error: to terminal by ADR-0133 design; ADR-0152 cap-as-escalation covers only the global dispatch cap); previously left unticketed by explicit user choice after #475; findings surfaced to the user, ticketing decision is the user's. No other follow-ups.
jared closed this issue 2026-08-27 19:09:28 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#510
No description provided.