You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pm-git-sync blocked: runtime state files land in the primary clone (.opencode/service-local.json, pm-stack/aggregator/activity-ingestion.json) #5389
pm-git-sync refuses to pull ~/git/code on the laptop because two UNTRACKED runtime files sit in the primary clone (verified 2026-11-04 04:17 CST, and present since before deploy round 5):
.opencode/service-local.json
pm-stack/aggregator/activity-ingestion.json
Journal evidence (repeats every ~30s):
pm-git-sync: FAIL /home/user/git/code working tree is dirty — not pulling. Dirty paths:
?? .opencode/service-local.json
?? pm-stack/aggregator/activity-ingestion.json
These are written by running services, not by any repo work. Per the primary-clones rule (primary clones stay on main + clean; deploys run from the primary), the dirt was named and left untouched — nobody stashes/commits/discards another writer's files to make a primary "clean". The consequence: the pm-stack aggregator still runs pre-#5376 code, and its feed still carries the frozen Jules coverage content that #5376 removed. Every future aggregator deploy is blocked the same way until the writers stop landing state in the deploy source.
Writers:
pm-stack/aggregator/activity-ingestion.json — the pm-stack aggregator itself (pm-stack/aggregator/src/config.ts + server.ts; also referenced by pm-stack/aggregator/install.sh).
.opencode/service-local.json — not identified from the repo tree; finding its writer is the first investigation step (likely a local opencode/openchamber service writing under the repo's .opencode/ directory).
Candidate fixes:
Durable (recommended): point both writers at ~/.local/state/ paths. Precedent: 2026-10-27 moved the pm-aggregator's runtime state to ~/.local/state/pm-aggregator/ for exactly this reason when its deployed copy was retired — state does not belong in the deploy source.
Quick unblock (weaker): add both paths to .gitignore so the status-based dirt check passes. Acceptable only as an interim if a deploy is waiting; the state still lives in the deploy source and the underlying smell remains.
Fixed by PR #5391 (merge 4d13062b3), deployed and verified 2026-11-04.
Writers identified (live evidence, not inference)
pm-stack/aggregator/activity-ingestion.json — the aggregator itself: server.ts builds IngestionStore from cfg.activityFile, and config.ts defaulted it to join(process.cwd(), "activity-ingestion.json") whenever PM_AGG_ACTIVITY_FILE was unset. The unit was never the problem (install.sh renders the env var to the state dir, and the live store there is current); an env-less invocation at 2026-11-03 21:41 (no pm-aggregator journal entries in that window — a test/writer/manual run) wrote the store into its cwd: the clone.
.opencode/service-local.json — the opencode CLI's service layer (developing-today/opencode), specifically pid 1326471: a source-run dev server (bun ~/git/fleet/8139-1077-mcp-timeout-cap/packages/cli/src/index.ts serve --service, channel local, up since 2026-11-03 16:00, still listening on 127.0.0.1:49375). The fork's service-config.ts persists its generated per-channel password as service-<channel>.json in the project .opencode dir; the file's password hash matches the live registration at ~/.local/state/opencode/service-local.json byte-for-byte.
config.ts: the PM_AGG_ACTIVITY_FILE default now resolves to ~/.local/state/pm-aggregator/activity-ingestion.json — the same path install.sh renders for the unit (2026-10-27 precedent). No invocation, env-less or not, can write the store into a checkout again. README env table updated. (IngestionStore already mkdir -p's the parent and writes atomically, so no migration logic was needed; the live state never moved — see deploy note.)
Tests — aggregator suite at the PR head: 1563 pass / 2 fail, the failures being exactly the known pre-existing #1282 pair; nothing new. (The one tsc error, item-history.ts: GhKind, reproduces identically on pristine main and is untouched by the diff.)
Deploy
The stale clone copy of activity-ingestion.json was archived to ~/.local/state/pm-aggregator/activity-ingestion.json.stale-clone-copy-20261104; the live state-dir store was not touched (it was newer — the clone copy's one gap record had already been superseded there).
One manual git pull --ff-only landed the merge (the chicken-and-egg step: the fix had to arrive before the sync could pull it). git status --porcelain is now empty; check-ignore confirms service-local.json is ignored via the new rule.
pm-git-sync is cycling on its own again: ok clean main, up to date, and it has since pulled two further merges by itself (via 5acabc8 to 22477f8 at last check).
Feed verified on the 04:36 collect (post-chore(jules): complete decommission follow-up wiring (code#5098) #5376 code): coverage lists exactly the four fleet repos — no Jules coverage row — and the phantom AWAITING_USER_FEEDBACK session cards are gone (the one remaining string is provenance prose describing the leftover keeper state file; the other remaining "jules" mentions are real GitHub issue titles and orchestration-section records sourced from that same leftover jules-review-state.json — data-layer residue of the decommissioned keeper, outside this issue's scope).
Follow-up filed:#5396 — install.sh's unit cp fails against the home-manager store symlink (the manual install path is broken on this machine; this deploy used pm-git-sync's restart recipe), and pm-git-sync treats a hand-moved HEAD as its baseline, so hand-unblocked pulls never enter its redeploy diff.
Activity
Merge pull request #5391 from developing-today/fix-5389-aggregator-st…
developing-today commentedon Nov 4, 2026
Fixed by PR #5391 (merge
4d13062b3), deployed and verified 2026-11-04.Writers identified (live evidence, not inference)
pm-stack/aggregator/activity-ingestion.json— the aggregator itself:server.tsbuildsIngestionStorefromcfg.activityFile, andconfig.tsdefaulted it tojoin(process.cwd(), "activity-ingestion.json")wheneverPM_AGG_ACTIVITY_FILEwas unset. The unit was never the problem (install.sh renders the env var to the state dir, and the live store there is current); an env-less invocation at 2026-11-03 21:41 (no pm-aggregator journal entries in that window — a test/writer/manual run) wrote the store into its cwd: the clone..opencode/service-local.json— the opencode CLI's service layer (developing-today/opencode), specifically pid 1326471: a source-run dev server (bun ~/git/fleet/8139-1077-mcp-timeout-cap/packages/cli/src/index.ts serve --service, channellocal, up since 2026-11-03 16:00, still listening on 127.0.0.1:49375). The fork'sservice-config.tspersists its generated per-channel password asservice-<channel>.jsonin the project.opencodedir; the file's password hash matches the live registration at~/.local/state/opencode/service-local.jsonbyte-for-byte.Fix (PR #5391)
config.ts: thePM_AGG_ACTIVITY_FILEdefault now resolves to~/.local/state/pm-aggregator/activity-ingestion.json— the same path install.sh renders for the unit (2026-10-27 precedent). No invocation, env-less or not, can write the store into a checkout again. README env table updated. (IngestionStorealready mkdir -p's the parent and writes atomically, so no migration logic was needed; the live state never moved — see deploy note.).opencode/.gitignore:service*.jsonignored, applying this repo's own established precedent (root.gitignorealready ignored.opencode/service-prod.json; the.opencode/.gitignoreheader already covers per-machine regenerated runtime state, chore(opencode): runtime state and stale backups tracked in git under .opencode/ (pid files, SQLite context.db, .bak configs, duplicate backup/ tree) #367). The writer's path logic is fork-owned and the dev server is live, so the file itself stays where its server expects it — it just can never dirty the tree again, for any channel.Tests — aggregator suite at the PR head: 1563 pass / 2 fail, the failures being exactly the known pre-existing #1282 pair; nothing new. (The one
tscerror,item-history.ts: GhKind, reproduces identically on pristine main and is untouched by the diff.)Deploy
~/.local/state/pm-aggregator/activity-ingestion.json.stale-clone-copy-20261104; the live state-dir store was not touched (it was newer — the clone copy's one gap record had already been superseded there).git pull --ff-onlylanded the merge (the chicken-and-egg step: the fix had to arrive before the sync could pull it).git status --porcelainis now empty;check-ignoreconfirmsservice-local.jsonis ignored via the new rule.ok clean main, up to date, and it has since pulled two further merges by itself (via 5acabc8 to 22477f8 at last check).supabase.muse-dev2.access-token-muse-cli(the interlock — a restart on pre-fix(pm-stack): resolve the muse-dev2 namespaced Supabase management-token name #5390 code would have latched a null Supabase client). New process up 04:34:18;/api/alerts.jsonreturns live muse-dev2 incidents through the new client, and the journal shows zero error/unavailable/null lines since the restart.coveragelists exactly the four fleet repos — no Jules coverage row — and the phantom AWAITING_USER_FEEDBACK session cards are gone (the one remaining string is provenance prose describing the leftover keeper state file; the other remaining "jules" mentions are real GitHub issue titles and orchestration-section records sourced from that same leftoverjules-review-state.json— data-layer residue of the decommissioned keeper, outside this issue's scope).Follow-up filed: #5396 — install.sh's unit
cpfails against the home-manager store symlink (the manual install path is broken on this machine; this deploy used pm-git-sync's restart recipe), and pm-git-sync treats a hand-moved HEAD as its baseline, so hand-unblocked pulls never enter its redeploy diff.