Skip to content

feat(discovery): discover OMP session transcripts in the pi adapter - #151

Open
MrGTV-love wants to merge 10 commits into
kunchenguid:mainfrom
MrGTV-love:fm/backpass-omp-adapter-20-clean-pr
Open

MrGTV-love wants to merge 10 commits into
kunchenguid:mainfrom
MrGTV-love:fm/backpass-omp-adapter-20-clean-pr

Conversation

@MrGTV-love

Copy link
Copy Markdown

Intent

Discover OMP session transcripts in the Pi adapter and preserve parent and subagent identity through analysis, folding, and remote discovery. Parent and subagent files remain separately discoverable and analyzable but share the root parent corroboration identity; selected legacy gap-ledger observations migrate to that identity, and cached child relationships refresh when an ancestor session appears or changes. Discover second-level nested OMP subagents and resolve their full ancestry to the root. Preserve fold admission by overlaying only parentSessionId, corroborationIdentity, corroborationNativeId, and corroborationStartedAt; legacy evidence without its stored interaction stamp remains excluded. Migrate legacy ledger IDs only when their identity is unambiguous. Remove synthetic chain re-queue behavior only with a real nested-discovery regression test proving root identity and old per-file ledger observations converge. Keep shared parent/subagent domain voting order-independent, with project evidence taking precedence as normalization already requires. Document ~/.omp/agent/sessions/ and root-parent sharing in README and AGENTS.md. Keep OMP subagents non-interactive when parentSessionId exists. Link nested OMP parent identity by nested file path regardless of child header cwd. Publish only a clean-history branch that preserves the reviewed code and documentation fixes but contains no graft/ artifacts, no .ignore change, and only the tracked .gitignore rule graft/.cache/, never /graft/. Preserve the original 070dced branch and PR 150 unchanged.

What Changed

  • The Pi adapter (src/discovery/adapters/pi.js) now also scans ~/.omp/agent/sessions/. It reads the session header whether it is on line 1 (Pi) or line 2 after OMP's {type:"title"} record. It also reads OMP's model field. It finds subagent transcripts up to two levels deep. It links each subagent to its root session by the nested file path, whatever cwd the child header shows. Discovery and the remote probe now pass one shared scan context. The scan cache now stores a per-adapter cacheVersion and a cacheDependency fingerprint of each ancestor session. So a cached subagent is classified again when an ancestor session appears or changes.
  • Each discovered transcript now carries parentSessionId and a corroboration identity, native id, and start date taken from its root session. A new helper, corroborationIdentityOf, gives this shared identity. Analysis stores these fields on evidence. Fold lays only these four fields from current discovery over admitted evidence, so the admission checks do not change. Harm and non-compliance session counts, gap-ledger sightings, and evidence source labels now use the root identity. Parent and subagent files are still sampled and analyzed as separate files. An OMP subagent is always non-interactive.
  • A new function, normalizeGapLedgerSessions, moves old per-file gap-ledger keys for selected sessions to the root identity. It moves a legacy transcript.id key only when the fold proves that id belongs to exactly one evidence identity. When sightings merge, the domain vote does not depend on order: any project sighting wins over orchestration. The README and AGENTS.md now document the OMP path and how subagents share the root identity. .gitignore now ignores graft/.cache/. New tests and an OMP fixture cover the adapter, nested discovery, ledger migration, fold, interaction, analysis reuse, and remote discovery.

Risk Assessment

⚠️ Medium: The change rewrites durable identity keys in persisted state (evidence metadata, scan cache, gap ledger migration) across discovery, analysis, and fold; traced paths (nested ancestry, cache refresh, legacy-id gating, order-independent domain vote, remote identity) behave correctly and are tested, but the persisted-state migration surface warrants follow-up attention rather than blocking.

Testing

I made a sandbox git repo with an OMP store (root, subagent, nested subagent). I ran the real backpass CLI against it: scan (text and --json), a 4-step cache refresh test, a real analyze with the claude agent, and the fold/gap-ledger part of a real propose. All results matched the intent. I stopped the propose run during its synthesis model step, after it had written the fold summary and gap ledger. Synthesis is not part of this change. Five scenarios are marked untested because they were not driven live: legacy-ledger migration, legacy fold admission, domain vote order, remote SSH discovery, and the README/AGENTS.md docs check. For the first four, I ran the 23 focused unit tests added by this change, and all passed. I checked branch hygiene with git log, git diff against 070dced, git check-ignore, and gh pr view. There is no UI surface, so there are no screenshots. The evidence is CLI transcripts and saved state files.

  • Live validation: ✅ go - 7 of 12 scenarios driven live against the product
Scenario Result Live Evidence
User runs backpass scan with sessions under ~/.omp/agent/sessions/ and sees the OMP root, subagent, and nested subagent associated with the repo ✅ pass live scan-human.txt, scan-json-summary.json: 3 transcripts tier1, each with its own identity
Subagent and nested subagent share the root's corroborationIdentity/NativeId while the root keeps its own; subagents are non-interactive and the root is interactive ✅ pass live scan-json-summary.json: child and grandchild corroborationIdentity ab61e5aa915f == root identity; interaction non-interactive vs interactive
Nested subagent whose header cwd differs (repo/src) still links to the root by nested file path ✅ pass live scan-json-summary.json: omp-grandchild cwd <repo>/src, parentSessionId omp-root
Adversarial cache: child files are cached with no parent, then the root file appears or its header id changes, and the cached child relations refresh without touching the child files ✅ pass live scan-cache-ancestor-refresh.txt: step 2 cached 2; step 3 children relinked to omp-root; step 4 all relinked to omp-root-v2
Real backpass analyze persists parentSessionId and the corroboration fields on each OMP evidence file ✅ pass live analyze-live.txt, analyze-evidence-stamps.jsonl: child/grandchild corroborationIdentity f697e406e413 = root identity
Adversarial fold: one mistake seen in the root, subagent, and nested subagent counts as ONE session, so it cannot clear minGapEvidence=2 by itself ✅ pass live gap-ledger-live.jsonl (1 entry, 1 session = root, 3 merged phrasings); fold-summary-live.json (analyzedSessions 3, 1 source, gapClusters 0, droppedGapSingletons 1)
Old per-file gap-ledger sightings of the child and grandchild move to the root identity; ambiguous legacy ids never move ⏸️ untested no The prior payload did not establish a live result. Driving this live needs a gap ledger written by a pre-change backpass version, and the sandbox had none. Only unit tests covered it (targeted-tests.t…
Fold admission: legacy evidence with no stored interaction stamp stays excluded; only the 4 overlay fields are added ⏸️ untested no The prior payload did not establish a live result. Driving this live needs pre-change legacy evidence records, and the sandbox made only current-format evidence. Only unit tests covered it (targeted-t…
Shared parent/subagent domain vote gives the same result in any order, with project taking precedence ⏸️ untested no The prior payload did not establish a live result. A real model decides the domain labels, so a live run cannot force opposing orchestration and project votes on purpose. Only a unit test covered it (…
Remote --host discovery keeps the subagent's link to the parent's corroboration identity ⏸️ untested no The prior payload did not establish a live result. No SSH host was reachable: ssh localhost gave 'Connection refused' because macOS Remote Login is off and no host is set up. Only a fake-ssh unit te…
README and AGENTS.md document ~/.omp/agent/sessions/ and root-parent sharing ⏸️ untested no The prior payload did not establish a live result. This is documentation with no runtime surface to drive; it was only checked by reading README.md:231-240 and AGENTS.md:221-225.
Branch is clean: no graft/ or .ignore in history, only the graft/.cache/ ignore rule, code same as reviewed 070dced, PR 150 unchanged ✅ pass live branch-hygiene.txt: git log shows none; git diff 070dced HEAD only removes the /graft/ rule and .ignore; git check-ignore ignores only graft/.cache/; gh pr view 150 head = 070dced
Evidence: OMP store layout used for live scan
<sandbox>~/agent/sessions/--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid.jsonl
<sandbox>~/agent/sessions/--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid/Worker.jsonl
<sandbox>~/agent/sessions/--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid/Worker/Worker.Grandchild.jsonl
Evidence: backpass scan human output (3 OMP files, 1 interactive, 2 non-interactive)
node:1: command not found: _nvm_lazy_load
demo · 1 worktree(s) · since 30d

HOST   HARNESS  SCANNED  MATCHED  SELF  CACHED  NOTE
local  pi       3        3        0     0

3 transcript(s) associated with this repo · tier1 3 (exact) · tier1.5 0 (sibling clone) · tier2 0 (remote) · tier3 0 (best-effort) · interactive 1 · non-interactive 2

HOST   HARNESS  SESSION       KIND             WHEN   SIZE  TIER  HOW
local  pi       omp-grandchi  non-interactive  today  1KB   t1    cwd is inside worktree /private<sandbox>/demo
local  pi       omp-child     non-interactive  today  1KB   t1    cwd is worktree /private<sandbox>/demo
local  pi       omp-root      interactive      today  1KB   t1    cwd is worktree /private<sandbox>/demo
Evidence: backpass scan --json: per-file identity vs shared root corroborationIdentity
{
  "mix": {
    "interactive": 1,
    "nonInteractive": 2,
    "total": 3
  },
  "transcripts": [
    {
      "nativeId": "omp-grandchild",
      "path": "--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid/Worker/Worker.Grandchild.jsonl",
      "cwd": "<repo>/src",
      "tier": 1,
      "interaction": "non-interactive",
      "parentSessionId": "omp-root",
      "identity": "10cddf4ace95",
      "corroborationIdentity": "ab61e5aa915f",
      "corroborationNativeId": "omp-root",
      "model": null
    },
    {
      "nativeId": "omp-child",
      "path": "--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid/Worker.jsonl",
      "cwd": "<repo>",
      "tier": 1,
      "interaction": "non-interactive",
      "parentSessionId": "omp-root",
      "identity": "ae957ac814c5",
      "corroborationIdentity": "ab61e5aa915f",
      "corroborationNativeId": "omp-root",
      "model": null
    },
    {
      "nativeId": "omp-root",
      "path": "--private-var-folders-x9-930nls3n16d5c1jn070_kyq00000gn-T-tmp.Vp7V81abAD-demo--/root-uuid.jsonl",
      "cwd": "<repo>",
      "tier": 1,
      "interaction": "interactive",
      "parentSessionId": null,
      "identity": "ab61e5aa915f",
      "corroborationIdentity": "ab61e5aa915f",
      "corroborationNativeId": "omp-root",
      "model": null
    }
  ]
}
Evidence: Scan-cache refresh when root appears / changes
== step 1: root session file absent (cache cold) ==
node:1: command not found: _nvm_lazy_load
perHarness.pi: {"scanned":2,"matched":2,"cached":0,"skipped":0,"self":0,"error":null}
  omp-grandchild  non-interactive  parent=omp-child corrNative=omp-child corrId=ae957ac814c5
  omp-child       interactive      parent=- corrNative=omp-child corrId=ae957ac814c5
== step 2: rescan, nothing changed (cache should hit) ==
node:1: command not found: _nvm_lazy_load
perHarness.pi: {"scanned":2,"matched":2,"cached":2,"skipped":0,"self":0,"error":null}
  omp-grandchild  non-interactive  parent=omp-child corrNative=omp-child corrId=ae957ac814c5
  omp-child       interactive      parent=- corrNative=omp-child corrId=ae957ac814c5
== step 3: root session file appears; children files untouched ==
node:1: command not found: _nvm_lazy_load
perHarness.pi: {"scanned":3,"matched":3,"cached":1,"skipped":0,"self":0,"error":null}
  omp-grandchild  non-interactive  parent=omp-root corrNative=omp-root corrId=ab61e5aa915f
  omp-child       non-interactive  parent=omp-root corrNative=omp-root corrId=ab61e5aa915f
  omp-root        interactive      parent=- corrNative=omp-root corrId=ab61e5aa915f
== step 4: root header id changes (omp-root -> omp-root-v2); children untouched ==
node:1: command not found: _nvm_lazy_load
perHarness.pi: {"scanned":3,"matched":3,"cached":0,"skipped":0,"self":0,"error":null}
  omp-root-v2     interactive      parent=- corrNative=omp-root-v2 corrId=079be5b65364
  omp-grandchild  non-interactive  parent=omp-root-v2 corrNative=omp-root-v2 corrId=079be5b65364
  omp-child       non-interactive  parent=omp-root-v2 corrNative=omp-root-v2 corrId=079be5b65364
Evidence: Live analyze run (claude)
· analyzing 3 transcript(s) with claude effort=medium at jobs=3
  3/3 analyzed

analyzed against AGENTS.md (1 instructions, 8 tok)
  3 newly analyzed · 0 cached · 0 skipped (too short) · 0 failed

  tier-1 tokens: input=6 output=1,431 cache_read=0 cache_write=72,047 total=73,484
Evidence: Persisted evidence stamps (parentSessionId / corroboration fields)
node:1: command not found: _nvm_lazy_load
{"file":"24e6690cf93ed70cc6025305ed8c7dbf820221808914338a56e866570f0849f4.json","nativeId":"pi-omp-live-grand","parentSessionId":"omp-live-root","identity":"24e6690cf93e","corroborationIdentity":"f697e406e413","corroborationNativeId":"omp-live-root","corroborationStartedAt":1790283989000,"interaction":"non-interactive","gaps":[null]}
{"file":"4e3b4a507642f772f8dc89bb9cfdf9cc328d2189f7e7b5bd6ae13dbf0e73b4ae.json","nativeId":"pi-omp-live-child","parentSessionId":"omp-live-root","identity":"4e3b4a507642","corroborationIdentity":"f697e406e413","corroborationNativeId":"omp-live-root","corroborationStartedAt":1790283989000,"interaction":"non-interactive","gaps":[null]}
{"file":"f697e406e413d43a60e6da6ee88140f3cdc25c8b27b2830d6c19f84be74b835a.json","nativeId":"pi-omp-live-root","parentSessionId":null,"identity":"f697e406e413","corroborationIdentity":"f697e406e413","corroborationNativeId":"omp-live-root","corroborationStartedAt":1790283989000,"interaction":"interactive","gaps":[null]}
Evidence: Live gap ledger: one sighting keyed by root identity
node:1: command not found: _nvm_lazy_load
{"gap":"b3ae8acbc6adca4a","sessions":["pi-omp-live-root(f697e406e413)"],"sightings":1}
Evidence: Live fold summary: 3 analyzed files, 1 source, gap dropped as singleton
{
 "analyzedSessions": 3,
 "sources": [
  "pi · omp-live-root · 2026-09-24"
 ],
 "gaps": [],
 "totals": {
  "positive": 0,
  "negative": 0,
  "gapSightings": 1,
  "gapClusters": 0,
  "reportOnlyGapClusters": 0,
  "reportOnlyByReason": {
   "majorityOrchestration": 0,
   "belowFloorMixed": 0,
   "tooFewProjects": 0
  },
  "droppedGapSingletons": 1,
  "orchestrationGapSightings": 0,
  "instructionsWithNegatives": 0,
  "usedRawTranscript": 0,
  "crossSurfaceDuplicates": 0
 }
}
Evidence: Focused OMP unit tests (23 pass)
✔ pi adapter classifies omp sessions past the title record and reads model (4.236375ms)
✔ pi adapter links an OMP subagent to its sibling parent session (6.3765ms)
✔ pi adapter links a second-level OMP subagent to the root session (5.266125ms)
✔ pi adapter links OMP subagents by nested path even when their cwd differs (9.4885ms)
✔ hermes adapter recovers v26 cli cwd from sessions.cwd when system_prompt is null, and still skips cron (67.841583ms)
✔ OMP analysis persists parent observer identity and fold restores it for legacy evidence (1627.308959ms)
✔ the rendered evidence block carries counts, relevance, quotes, effects and classes into the prompt (15.669208ms)
✔ OMP subagents share corroboration while relevance remains per file (1.001625ms)
✔ failed-trigger citations count per skill and reach the synthesis prompt with the cluster (0.71925ms)
✔ an oversized high-non-compliance paragraph attributes per sentence and invites a restructure, not a bold label (3.942375ms)
✔ OMP parent and subagent persist one ledger sighting and keep it in the child sample (70.369542ms)
✔ a selected OMP child collapses legacy parent and child ledger sightings (84.697417ms)
✔ an OMP parent and subagent sharing a root vote project in one run whatever the order (0.362834ms)
✔ an ambiguous legacy session id never migrates onto a selected session (30.635875ms)
✔ a selected session recording a gap never inherits an ambiguous legacy id's sighting (36.9775ms)
✔ fold keeps legacy evidence excluded when current discovery stamps an interaction (41.289541ms)
✔ OMP subagents share their parent identity and refresh cached relations (255.467084ms)
✔ Pi child cache is invalidated when its parent session appears (136.013417ms)
✔ nested OMP subagents share the root identity once the root session appears (146.89125ms)
✔ OMP subagents running in another repo cwd still share the root identity (158.643708ms)
✔ remote OMP subagents keep their parent's corroboration identity (2065.546291ms)
ℹ tests 21
ℹ suites 0
ℹ pass 21
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 2279.931416
✔ pi adapter accepts only line one or line two after a title header (8.621709ms)
✔ pi discovery checks a missing parent path once per scan (2.304084ms)
✔ test/interaction.test.js (356.769667ms)
ℹ pass 3
ℹ fail 0
Evidence: Branch hygiene: diff vs 070dced, graft/.ignore absence, check-ignore, PR 150 head
== diff reviewed 070dced6 -> clean HEAD ==
diff --git a/.gitignore b/.gitignore
index c6c94ba..f22397f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,3 @@ node_modules/
 *.log
 package-lock.json
 graft/.cache/
-
-# graft's local graph cache — regenerable, not committed (run `graft build`).
-/graft/
diff --git a/.ignore b/.ignore
deleted file mode 100644
index 615e581..0000000
--- a/.ignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# graft's cards are gitignored but should stay greppable: ripgrep reads
-# .ignore before .gitignore, so this re-admits the tree to search only.
-!graft/
-graft/.cache/
-graft/.graph/
== graft/ or .ignore paths touched in de6a9aa..HEAD ==
(none)
== git check-ignore on graft paths ==
fatal: /graft: '/graft' is outside repository at '~/.no-mistakes/worktrees/a60a6ba1198a/01M3AKEBACVCPE7VNYFMWBJ7CN'
== PR 150 head ==
{"headRefName":"fm/backpass-omp-adapter-20-followup-sanitized","headRefOid":"070dced6cee23a40b03a6bca74e4f2629ba44fb8","state":"OPEN"}
== git check-ignore (real git consumer of .gitignore) ==
graft/.cache/x -> .gitignore:7:graft/.cache/	graft/.cache/x
graft/other.txt -> NOT ignored
graft/.graph/g -> NOT ignored

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

⚠️ **Review** - 1 warning
  • ⚠️ src/discovery/index.js:341 - Simplification: the change adds a generic adapter cacheVersion mechanism (export const cacheVersion = 4 in src/discovery/adapters/pi.js:35, checked at src/discovery/index.js:341 and stamped at :352, plus new doc text in the discovery header). No intent requirement needs it: the required cache refresh is already delivered by cacheDependency. Every pre-change pi scan-cache entry lacks a cacheDependency field, while pi.cacheDependency() always returns a JSON string (e.g. "[null,null]"), so cached.cacheDependency === cacheDependency already fails and forces reclassification for all old entries (including OMP files previously cached as null under PI_CODING_AGENT_DIR). The version field only adds a second invalidation path and a new adapter contract. Recommended remedy: remove cacheVersion from pi.js and the two checks/stamp in discoverFiles, relying on cacheDependency; or confirm it is a deliberate future-proofing contract.
✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 7 of 12 scenarios driven live against the product
Scenario Result Live Evidence
User runs backpass scan with sessions under ~/.omp/agent/sessions/ and sees the OMP root, subagent, and nested subagent associated with the repo ✅ pass live scan-human.txt, scan-json-summary.json: 3 transcripts tier1, each with its own identity
Subagent and nested subagent share the root's corroborationIdentity/NativeId while the root keeps its own; subagents are non-interactive and the root is interactive ✅ pass live scan-json-summary.json: child and grandchild corroborationIdentity ab61e5aa915f == root identity; interaction non-interactive vs interactive
Nested subagent whose header cwd differs (repo/src) still links to the root by nested file path ✅ pass live scan-json-summary.json: omp-grandchild cwd <repo>/src, parentSessionId omp-root
Adversarial cache: child files are cached with no parent, then the root file appears or its header id changes, and the cached child relations refresh without touching the child files ✅ pass live scan-cache-ancestor-refresh.txt: step 2 cached 2; step 3 children relinked to omp-root; step 4 all relinked to omp-root-v2
Real backpass analyze persists parentSessionId and the corroboration fields on each OMP evidence file ✅ pass live analyze-live.txt, analyze-evidence-stamps.jsonl: child/grandchild corroborationIdentity f697e406e413 = root identity
Adversarial fold: one mistake seen in the root, subagent, and nested subagent counts as ONE session, so it cannot clear minGapEvidence=2 by itself ✅ pass live gap-ledger-live.jsonl (1 entry, 1 session = root, 3 merged phrasings); fold-summary-live.json (analyzedSessions 3, 1 source, gapClusters 0, droppedGapSingletons 1)
Old per-file gap-ledger sightings of the child and grandchild move to the root identity; ambiguous legacy ids never move ⏸️ untested no The prior payload did not establish a live result. Driving this live needs a gap ledger written by a pre-change backpass version, and the sandbox had none. Only unit tests covered it (targeted-tests.t…
Fold admission: legacy evidence with no stored interaction stamp stays excluded; only the 4 overlay fields are added ⏸️ untested no The prior payload did not establish a live result. Driving this live needs pre-change legacy evidence records, and the sandbox made only current-format evidence. Only unit tests covered it (targeted-t…
Shared parent/subagent domain vote gives the same result in any order, with project taking precedence ⏸️ untested no The prior payload did not establish a live result. A real model decides the domain labels, so a live run cannot force opposing orchestration and project votes on purpose. Only a unit test covered it (…
Remote --host discovery keeps the subagent's link to the parent's corroboration identity ⏸️ untested no The prior payload did not establish a live result. No SSH host was reachable: ssh localhost gave 'Connection refused' because macOS Remote Login is off and no host is set up. Only a fake-ssh unit te…
README and AGENTS.md document ~/.omp/agent/sessions/ and root-parent sharing ⏸️ untested no The prior payload did not establish a live result. This is documentation with no runtime surface to drive; it was only checked by reading README.md:231-240 and AGENTS.md:221-225.
Branch is clean: no graft/ or .ignore in history, only the graft/.cache/ ignore rule, code same as reviewed 070dced, PR 150 unchanged ✅ pass live branch-hygiene.txt: git log shows none; git diff 070dced HEAD only removes the /graft/ rule and .ignore; git check-ignore ignores only graft/.cache/; gh pr view 150 head = 070dced
  • HOME=&lt;sandbox&gt;/home node bin/backpass.js scan --harness pi --since 30d (text + --json) over ~/.omp/agent/sessions with root, Worker subagent, and Worker/Worker.Grandchild nested subagent
  • Scan-cache refresh: 4 real backpass scan --json runs (root missing, cache hit, root appears, root header id changes)
  • PI_CODING_AGENT_DIR=&lt;sandbox&gt;/omp-agent node bin/backpass.js analyze --harness pi --analysis-agent claude (real claude model) then inspected .backpass/evidence/*.json stamps
  • node bin/backpass.js propose --harness pi --analysis-agent claude --synthesis-agent claude --no-open up to fold; inspected .backpass/gap-ledger.json and .backpass/evidence-summary.json; stopped during synthesis
  • node --test --test-name-pattern='omp|OMP|Pi child|legacy session id|ambiguous legacy|legacy evidence excluded' test/adapters.test.js test/analyze-reuse.test.js test/fold.test.js test/gap-ledger.test.js test/interaction.test.js test/remote-discovery.test.js
  • node --test --test-name-pattern='accepts only line one|missing parent path once' test/adapters.test.js test/interaction.test.js
  • git log --name-only de6a9aa..HEAD | grep graft/|.ignore, git diff 070dced6 HEAD, git check-ignore -v --no-index graft/.cache/x graft/other.txt graft/.graph/g, gh pr view 150 --json headRefOid
  • ssh -o BatchMode=yes localhost true (to see if a live remote host was available: refused)
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium risk] Adds OMP session discovery to the Pi adapter.

The PR is not ready to merge because ordinary Pi scans still skip the OMP store by default.

Reviews (3) · Last reviewed commit: "feat(discovery): make OMP session collec..."

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate.

Reviewed head 09b9e1651acdfc2e10e872811cd31f4bbd518c47 (diff + fixture + live evidence in body) against VISION.md on main. This is the live help path over sibling #150 (same author/feature; #151 is the clean-history successor without .ignore / /graft/ artifacts; author asked to leave #150 unchanged).

Diff (high level): Pi adapter default scan adds ~/.omp/agent/sessions/; title-line session header; nested subagent depth-2; path-based root parent linking; shared corroborationIdentity / native id / start through analyze→fold→gap-ledger (including normalizeGapLedgerSessions); OMP subagents forced non-interactive; scan-cache version + ancestor dependency; README/AGENTS docs. Medium risk surface is durable identity/ledger key migration — tested and gated, but always-on.

VISION per-rule

  • Evidence is the only currency — aligns (real OMP JSONL; parent+subagent share one corroboration session so one tree cannot clear the two-session bar alone).
  • The human owns the weights — aligns (discovery/fold identity only; no write-path / review-gate change).
  • Nothing the model says is taken on faith — aligns (pinned omp-session.jsonl + adapter/ledger/fold/remote tests; not README-only).
  • The budget is the constraint — n/a (discovery/identity).
  • It reads what you already have and owns nothing — aligns (local OMP store; fail-soft; more harnesses welcome; path-based parent link prefers accuracy over loose cwd).
  • Failure is loud and named — aligns (non-session heads still null; ambiguous legacy ledger ids do not migrate).
  • Scope — aligns (adapter + corroboration identity; not a writer/provider).

contract-class: new-default — unconfigured scan gains a new always-on store root, and unconfigured fold/ledger behavior changes how related files count toward the two-session bar / durable keys. Same decision class as landing default OMP discovery (overlap with open #129). Not restore just because it fixes "couldn't see OMP"; not opt-in (no config flag).

Security: clean. Local read-only discovery; fs.writeFileSync / process.env only in tests; no secrets, egress, or workflow-file changes.

CI: fork workflows approved. Required checks green on this HEAD — CI ubuntu+macos 36060341084, Guard 36060341386, no-mistakes 36060341142 (attestation matches 09b9e165). Greptile pass — not a gate. Mergeable CLEAN on current tip; branch is 1 behind main (7bd9150 / #153 redact) — not rebasing (not auto-merge-eligible).

Hold: waiting on captain, not on the author. Auto-merge is blocked solely by the new-default decision. Flagging for Firstmate/captain merge-or-not. Overlap: #129 (mdc2122, narrower adapter-only) stays open until captain lands one; #150 stamped superseded by this PR.

Comment on lines +65 to +67
if (config?.discovery?.includeOmp === true) {
specs.push({ path: home(".omp", "agent", "sessions"), direct: false, nested: true });
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 OMP sessions skipped by default

An ordinary Pi scan does not visit ~/.omp/agent/sessions/ because discovery.includeOmp defaults to false. Users with OMP transcripts must discover and enable that setting before their sessions appear. This conflicts with the stated intent to discover the OMP store through the Pi adapter.

Context Used: If there is a VISION.md file at the root of the repo, the PR must not conflict / diverge / drift from it. If the PR description has an "Intent" section, respect that as the accepted user intent. - Do make comments if anything in the implementation ... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread AGENTS.md
- **backpass must never analyze itself**: keep `SELF_SESSION_SENTINEL` (`src/prompts.js`) at the start of every
model-facing prompt (`src/discovery/self.js` drops those sessions).
- **Gap evidence**: one ledger sighting per (gap, transcript) (`src/gap-ledger.js`); record before pruning;
never surface uncorroborated singletons; gap identity is judged by the consolidation call, with bigram

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 OMP guidance removed

The replacement guidance omits both ~/.omp/agent/sessions/ and the fact that parent and nested subagent files share the root corroboration identity. The stated intent requires both to be documented in AGENTS.md as well as README.md. Maintainers relying on this file lose that discovery and evidence-counting guidance, so this repository requirement must be met before merging.

Context Used: If there is a VISION.md file at the root of the repo, the PR must not conflict / diverge / drift from it. If the PR description has an "Intent" section, respect that as the accepted user intent. - Do make comments if anything in the implementation ... (source)

mdc2122 and others added 10 commits October 1, 2026 21:44
omp (Oh My Pi) writes the same version:3 JSONL session format as pi under
~/.omp/agent/sessions/, but prepends a fixed-width {type:"title"} record so
the {type:"session", cwd} entry is line 2, and nests subagent transcripts
one level deeper at <escaped-cwd>/<session-id>/<Name>.jsonl.

- Add ~/.omp/agent/sessions as a default nested store root (omp honors
  PI_CODING_AGENT_DIR, so an env redirect still dedupes against it).
- classify() scans the first head lines for the session entry instead of
  requiring it on line 1.
- enumerate() descends one extra level inside nested roots.
- read() accepts model_change.model as a fallback for modelId.
@kunchenguid
kunchenguid force-pushed the fm/backpass-omp-adapter-20-clean-pr branch from 5287c0d to 8afb786 Compare October 2, 2026 04:44
@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate.

Re-triaged head 8afb78628143fb4db1b44ef72364cfe40cff4e85 after newer activity (rebase onto main + discovery.includeOmp opt-in). Prior stamp was waiting-on-captain / new-default at 09b9e165.

Diff (high level, vs main 0268201c): Pi adapter can scan ~/.omp/agent/sessions/ only when discovery.includeOmp === true (default false); title-line session header; nested subagent depth-2 + path-based root parent linking; shared corroborationIdentity / native id / start through analyze→fold→gap-ledger (incl. normalizeGapLedgerSessions); OMP subagents forced non-interactive; scan-cache version + ancestor dependency; README + config docs. Unconfigured runs without nested parented files keep corroborationIdentity ≡ identity.

VISION per-rule

  • Evidence is the only currency — aligns (real OMP JSONL fixture; parent+subagent share one corroboration session so one tree cannot clear the two-session bar alone).
  • The human owns the weights — aligns (discovery/fold identity only; no write-path / review-gate change).
  • Nothing the model says is taken on faith — aligns (pinned omp-session.jsonl + adapter/ledger/fold/remote/config tests; not README-only).
  • The budget is the constraint — n/a (discovery/identity).
  • It reads what you already have and owns nothing — aligns (local OMP store fail-soft; more harnesses welcome; OMP default store gated; path-based parent link prefers accuracy).
  • Failure is loud and named — aligns (non-boolean includeOmp refused; non-session heads null; ambiguous legacy ledger ids do not migrate).
  • Scope — aligns (adapter + corroboration identity; not a writer/provider).

contract-class: opt-in — discovery.includeOmp defaults false; unconfigured scan does not open ~/.omp. Supporting corroboration/ledger plumbing is inert for non-parented sessions (falls back to existing identity). Not restore (OMP was never a specified default path). Prior new-default hold is lifted by the opt-in commit.

Security: clean. Local read-only discovery; no secrets/egress/workflow edits in the three-dot delta.

CI help done this pass

Author blocker (blocking): no-mistakes attestation still binds to 09b9e165; current head is 8afb78628143fb4db1b44ef72364cfe40cff4e85. Re-run git push no-mistakes so the PR body attestation matches this head (https://github.com/kunchenguid/backpass/actions/runs/36965877704). Cannot merge or re-flag captain while no-mistakes is red.

Notes: Sibling #150 remains the dirty-history twin — leave it; #151 stays the live path. #129 closed-stale earlier. Intent mentioned AGENTS.md OMP docs; tip documents the opt-in in README only (AGENTS.md unchanged vs main after the always-loaded trim) — not a merge blocker once attestation is current.

@MrGTV-love please re-attest on 8afb78628143fb4db1b44ef72364cfe40cff4e85. After no-mistakes is green we will re-stamp (opt-in is not auto-merged by cron; captain merge word still needed then).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants