Skip to content

feat: codex profile homes, herdr marker titles, wake settled threads on sync - #3

Open
matthias-scale wants to merge 18 commits into
mainfrom
feat/sync-wakes-settled
Open

matthias-scale wants to merge 18 commits into
mainfrom
feat/sync-wakes-settled

Conversation

@matthias-scale

@matthias-scale matthias-scale commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

Summary

The fork build currently live on ub2 as 0.0.43-fork.2. It stacks on #1 (titles and interval sync) and #2 (settle after hours), and adds:

  • Codex multi-profile scan: a codexAdditionalSessionHomes setting scans extra CODEX_HOMEs, deduplicated by realpath and session id. Bindings record the home so resume uses the right profile.
  • Herdr marker titles: manual titles prefixed ● Herdr <host:pane> keep the prefix and take the provider title. Legacy placeholders (# AGENTS.md instructions, <environment_context>, …) are replaced.
  • Wake on synced activity: a thread.history.append newer than settledAt emits a neutral thread.unsettled (reason activity), so it does not pin the thread active.
  • Version bumps for fork builds (the launcher checks that the built-in version matches the runtime folder).

Acceptance criteria

  • Codex sessions from codexAdditionalSessionHomes are imported, deduplicated by realpath and session id, and resume uses the recorded home.
  • Manual titles with a ● Herdr <host:pane> prefix keep the prefix and take the provider title; legacy placeholder titles are replaced.
  • A synced thread.history.append newer than settledAt unsettles a settled thread with reason activity, without pinning it active.
  • Importing history does not settle threads.
  • Auto-settle uses sidebarAutoSettleAfterHours (default 12, null = never), and legacy day values migrate to hours.
  • Imported sessions re-sync on an interval, with titles and appended messages updated.

Evidence

  • pnpm server tests: 54 files, 858/858 passed. tsgo is clean for contracts, server and web.
  • Live on ub2: the service launcher runs protocol 3 on 0.0.43-fork.2. The sync imported 294 threads with no errors; recently active threads are unsettled.

https://claude.ai/code/session_01SHuGjA6vRucev3H2TiY2bu

debugrror and others added 12 commits September 16, 2026 01:23
Use Codex session index titles when available, fall back past injected context, and repair legacy placeholder titles during a repeated import.

Closes pingdotgg#10513
Bound session-index reads, preserve concurrent manual renames, recover fallback titles from imported history, and isolate repair failures.
Replace sidebarAutoSettleAfterDays with sidebarAutoSettleAfterHours
(1-2160, default 12, null = never). Stored day values decode to hours.
History imports no longer settle a thread on arrival; threads with only
imported history count idle time from their latest imported message.

Claude-Session: https://claude.ai/code/session_01SHuGjA6vRucev3H2TiY2bu
@matthias-scale

Copy link
Copy Markdown
Owner Author

Review verdict: BLOCK

Fixed point: 479788a363e9501e50d243248362f181c8d85b82
Base and merge base: dd9528a974ba534faa8d1588f3f137fa2a281860
Frozen diff SHA-256: c36f45aa7857c46df27744380cf518f686dec3b77a749183a9f89984593260bd

Sources: PR body acceptance criteria, upstream issue #10513, repository instructions, review standards, and the review impact rubric.

Axis Result
Spec PASS
Standards BLOCK
Architecture Stopped after the verified P1, as requested
Blast radius Unproven

In-scope findings

P1 · REV-P1-001 · Mixed-version auto-settle writes are silently discarded

Current web and mobile clients admit a server when it advertises the existing threadAutoSettlement capability, then write only sidebarAutoSettleAfterHours. The base server advertises that capability but its patch schema accepts only sidebarAutoSettleAfterDays. It strips the new key, so the UI appears to save an inactivity duration while the server keeps the old value. The failure persists until the server is upgraded.

Evidence:

  • Admission still uses the old capability at SettingsPanels.tsx:2136 and sharedSettings.ts:103.
  • The web control writes the new key at SettingsPanels.tsx:2293.
  • Base 0.0.42 advertises threadAutoSettlement: true, while its ServerSettingsPatch contains only sidebarAutoSettleAfterDays.
  • Focused schema proof: the base-shaped decoder returned hours => {} and days => {"sidebarAutoSettleAfterDays":3}.

Required before merge: add a versioned capability for the hours contract or translate writes for older servers. Cover current-client to old-server web, mobile, and shared-settings writes.

Verification

  • Current-head focused suite: 8 files, 305 tests passed.
  • Additional multi-home scanner proof: 1 passed, 96 skipped.
  • Supplied full-head proof: server 54 files, 858/858 passed; contracts, server, and web tsgo clean; live 0.0.43-fork.2 imported 294 threads without errors.
  • No P0 findings. One P1 finding. No P2 or P3 findings.

Blast-radius hand-back

The needed safety fact was false: not every server admitted by threadAutoSettlement accepts the hours patch. The mixed-version web, mobile, and multi-environment paths lack coverage, so this remains unproven at confidence step 3.

@matthias-scale

Copy link
Copy Markdown
Owner Author

Review verdict: BLOCK

Fixed point: e7352e9602702245495c31e8ec42e9fd4cb24924
Base and merge base: dd9528a974ba534faa8d1588f3f137fa2a281860
Frozen diff SHA-256: 15bafe5f0e5694fc3ffdb977b2a5c7131bfdc45ad7f45385f0158d098aa403c2

Sources: PR body acceptance criteria, upstream issue #10513, repository instructions, review standards, and the review impact rubric.

Axis Result
Spec BLOCK
Standards Stopped after the verified P1 findings, as requested
Architecture P2 and P3 findings
Blast radius Unproven; stopped after the verified P1 findings

In-scope findings

P1 · REV-P1-002 · Resync leaves a stale additional Codex home pinned

When the active Codex home becomes the newest copy of a session that previously came from an additional home, the scanner correctly represents the active home with no explicit sessionHomePath. repinImportedCodexHome returns immediately for that value. It never removes the old homePath from the stored resume cursor, so resume keeps using the wrong Codex home.

Focused real-code proof expected one binding upsert with { threadId: "codex-session" } and no homePath; it observed zero upserts.

Required before merge: treat the active home as a valid repin target that clears a stale explicit homePath, and cover the additional-home-to-active-home winner transition.

P1 · REV-P1-003 · A second title sync drops the Herdr marker

The first provider-title sync preserves the marker, then thread.title.import.sync changes the title source from manual to generated. On the next interval sync, syncImportedTitle no longer runs the manual-title policy, so it replaces ● Herdr ub2:t3:2 First provider title with Second provider title.

Focused real-code proof expected ● Herdr ub2:t3:2 Second provider title; the dispatched command contained only Second provider title.

Required before merge: retain marker ownership across repeated import title syncs and cover two consecutive provider-title changes.

P2 · REV-P2-001 · Interval sync scans provider history before checking whether imports exist

AgentSessionSync.ts:104 starts the configured provider scan before the imported-session check at lines 116-117. A server with no imported sessions still pays the five-minute filesystem scan. Query imported bindings first, return when none exist, then limit discovery to their projects and homes.

P3 · REV-P3-001 · Migration 053 includes an unmeasured full-table backfill

053_ProjectionThreadsLatestImportedMessage.ts:11 adds the nullable column and updates every thread row through a correlated message lookup. The affected row count is unmeasured. Move the backfill into a separately measured migration or release step.

Prior finding

REV-P1-001 is fixed on this head. Shared client-runtime, web scoped settings, web project overrides, and mobile now translate hour writes to legacy day patches while current servers receive hours. The focused suite passed 56/56 tests.

Verification

  • Two real-code P1 repros failed exactly at the expected boundaries: stale home produced no binding upsert; repeated Herdr title sync dropped the marker.
  • Architecture pass: 15 focused server tests passed.
  • Broader focused run: 480 tests passed. One unrelated scanner fixture could not create a path under /home/ubuntu2/Documents inside this sandbox. The supplied outside-sandbox proof passed that suite and all six package typechecks.
  • Supplied full-head proof: contracts 446, shared 848, client-runtime 1,526, mobile 1,621, web 5,144, server 4,940 passed with 10 skipped. Build 0.0.43-fork.2 imported 294 threads without errors.
  • No P0 findings. Two P1, one P2, and one P3 finding.

Blast-radius hand-back

The repair delta fixed REV-P1-001, but the review stopped after the two new P1 repros. Current-head blast-radius coverage remains unproven.

@matthias-scale matthias-scale added the review-risk Requires expanded review coverage label Sep 17, 2026
@matthias-scale

Copy link
Copy Markdown
Owner Author

Review verdict: BLOCK

Fixed point: 974eff727a5ad3fd4e351870c50deb5beac29d3e
Base and merge base: dd9528a974ba534faa8d1588f3f137fa2a281860
Frozen diff SHA-256: 25d7194755c09935fd41cc5eea825b7cf8877f81da6a8dacb6d035d48ae46663

Sources: PR body acceptance criteria, repository instructions, review standards, review impact rubric, and prior PR review dispositions.

Axis Result
Spec PASS with one P2
Standards BLOCK
Review-risk variation Stopped after the verified P1
Architecture Stopped after the verified P1
Blast radius Unproven; stopped after the verified P1

In-scope findings

P1 · REV-P1-004 · Previous clients read 12 hours as 3 days

The new server encoder sends sidebarAutoSettleAfterHours but does not synthesize sidebarAutoSettleAfterDays. The immediately preceding 0.0.42 client schema knows only the days field and defaults it to 3. An old client connected to this server therefore shows 3 days instead of 12 hours. If it saves that value, the new server migrates it to 72 hours. This breaks the previous shipped client during a mixed-version rollout.

Evidence:

  • The current encoder passes settings straight to the wire decoder without adding the legacy field at settings.ts:1273-1308.
  • The current focused test explicitly expects hours with no days at settings.test.ts:702-705.
  • Base 0.0.42 accepts only sidebarAutoSettleAfterDays and defaults it to 3 at settings.ts:1131.
  • Focused current-head proof passed 1/1. A legacy-shape decode of { sidebarAutoSettleAfterHours: 12 } produced { sidebarAutoSettleAfterDays: 3 }.

Required before merge: include the legacy days value in server-to-client settings encoding while retaining hours for current clients. Cover current-server to 0.0.42 client decoding for 12 hours, null, and a non-day-aligned hour value.

P2 · REV-P2-002 · Title-only renames stop syncing after 30 days

The scanner filters old transcript mtimes before it reaches the completed-import path. A Codex title rename updates session_index.jsonl without changing the rollout transcript mtime, so an imported session older than 30 days keeps its stale title until transcript activity resumes.

Evidence: the age filter runs at AgentSessionScanner.ts:1570-1577, before the completed-source title handoff at AgentSessionScanner.ts:1621-1629.

Prior dispositions

  • REV-P1-001, REV-P1-002, and REV-P1-003 are fixed on this head.
  • REV-P2-001 and REV-P3-001 remain accepted as out of scope and were not re-raised.

Verification

  • Importer repair: 20/20 passed.
  • Repeated Herdr title repair: 12/12 passed.
  • Mixed-version encoder proof: 1/1 passed and confirms the missing legacy field.
  • Supplied outside-sandbox proof: server 4,940 passed and 10 skipped; the unrelated GitVcsDriverCore flake passes alone at 82/82. Contracts, server, and web typechecks are clean. The live 0.0.43-fork.2 build imported 294 threads without errors.
  • No P0 findings. One P1 and one P2 finding.

Blast-radius hand-back

The repair delta fixes the two prior P1s, but the review stopped on the server-to-old-client settings failure. Current-head blast-radius coverage remains unproven.

Send sidebarAutoSettleAfterDays beside the hour value for server settings and project overrides so 0.0.42 clients do not fall back to three days. Round partial days up because an older client may lengthen the delay, but must not shorten it and settle threads earlier than configured.
@matthias-scale

Copy link
Copy Markdown
Owner Author

Review verdict: BLOCK

Fixed point: 144d171998c6a2b8baa296bc415f22bf5c74e3f3
Base and merge base: dd9528a974ba534faa8d1588f3f137fa2a281860
Frozen diff SHA-256: 089e6a1d1043c2abca0b9a8d00a38a9b22a25b4310ea436e62d80213732e456b

Sources: PR body acceptance criteria, repository instructions, review standards, review impact rubric, and prior PR review dispositions.

Axis Result
Spec PASS
Standards PASS with one P2
Review-risk variation BLOCK
Architecture PASS
Blast radius Unproven; stopped after the verified P1

In-scope findings

P1 · REV-P1-005 · Clearing another project override erases auto-settle on legacy servers

Both project-override clear planners return the whole remaining entry without adapting it to the target server's capabilities. A current client reading a legacy sidebarAutoSettleAfterDays override represents it as sidebarAutoSettleAfterHours. If the user clears another override, the current client sends that hours key back to the legacy server. The legacy schema drops the unknown key, and entry-replacement semantics remove the saved day override. The project silently falls back to its environment rule.

Evidence:

  • planScopedSettingsClear returns projectOverrideWrites directly. The adapted write path above it is bypassed.
  • planProjectOverridesClear has the same gap.
  • The server deliberately replaces each project override entry instead of deep-merging it at serverSettings.ts:312-316.
  • Focused real-code probe for both planners produced {"projectSettingsOverrides":{"project":{"sidebarAutoSettleAfterHours":72}}}. A 0.0.42-shaped decode produced {"projectSettingsOverrides":{"project":{}}}.

Required before merge: capability-adapt both clear planners, and cover current-client clears against a 0.0.42 server while preserving the unrelated auto-settle override.

P2 · REV-P2-003 · User docs still promise a three-day default

docs/user/thread-sidebar.md:89 says inactive threads settle after three days. This PR changes the default to 12 hours, so the shipped guidance is wrong by 60 hours.

Prior dispositions

  • REV-P1-001, REV-P1-002, REV-P1-003, and REV-P1-004 are fixed on this head.
  • REV-P2-001, REV-P2-002, and REV-P3-001 remain accepted as out of scope and were not re-raised.

Cleared review candidate

The risk pass also questioned whether old imported history can auto-settle on the next minute sweep. That is intended. The PR summary says threads with only imported history count idle time from their latest imported message. Import itself leaves the thread active; the normal inactivity rule may settle it later.

Verification

  • Current-head contracts settings suite: 145/145 passed.
  • Spec pass: 236/237 passed across seven files; the only failure is the known sandbox fixture that expects /home/ubuntu2/Documents/Codex.
  • Standards focused suite: 69/69 passed. Architecture focused suite: 54/54 passed.
  • Review-risk focused suites: 166 tests passed. The two-planner real-code probe reproduced REV-P1-005.
  • Supplied outside-sandbox proof: server 4,940 passed and 10 skipped; the unrelated GitVcsDriverCore flake passes alone at 82/82. Contracts, shared, client-runtime, and server typechecks are clean. The live 0.0.43-fork.2 build imported 294 threads without errors.
  • No P0 findings. One P1 and one P2 finding.

Blast-radius hand-back

The latest repair sends legacy day values beside current hour values, but the pass stopped on the verified mixed-version clear failure. Current-head blast-radius coverage remains unproven.

This branch has not been deployed

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

Labels

review-risk Requires expanded review coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants