feat(agent-core-v2): keep session updatedAt stable across meta management writes - #2815
feat(agent-core-v2): keep session updatedAt stable across meta management writes#2815liruifengv wants to merge 7 commits into
Conversation
…ment writes Rename, archive/restore, and fork no longer bump a session's updatedAt, so recency-sorted session lists stop reshuffling on management actions: - setTitle/setArchived pass touchUpdatedAt: false; an explicit patch.updatedAt always wins (fork inherits the source's recency, so a fork lands next to the source instead of floating to the top) - new SessionMeta.archivedAt records the archive moment (cleared on restore) and is surfaced through the session index, the v1/v2 session routes (archived_at), and the klient contract, so the archived list keeps an accurate archive time without relying on the updatedAt bump
🦋 Changeset detectedLatest commit: 00bbd6e The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7fe71f963d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ing a cold session A cold legacy/v1 state.json read from disk can still carry an ISO-string updatedAt; passing it through as the fork's explicit patch.updatedAt would persist a string into the v2 metadata. Normalize with toEpochMs (falling back to now when absent/unparseable).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52f5a43295
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52f5a43295
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Registering each copied agent during fork is an ordinary metadata write that bumps updatedAt, which overwrote the inherited source recency and still floated normal forks (sessions with agents) to the top. Move the fork's metadata update after the agent recreation loop so the inherited updatedAt is the final write.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 84ff77647c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…session Resume creates the main agent for a cold session that has no persisted agents.main entry (e.g. an empty session), and that registration bumps updatedAt — so unarchiving an empty session still floated it to the top. Capture the index summary's updatedAt before resume and re-apply it in the restore write (archived:false, archivedAt cleared, explicit updatedAt wins over the bump).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c365f9a098
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Registering an agent is a structural write, not content activity — but it went through an ordinary metadata update that bumped updatedAt. That reordered recency-sorted listings whenever materialization created an agent: resume of a cold session without a persisted agents.main (so archive-via-resume and restore of empty sessions still floated), and runtime subagent registration mid-turn. registerAgent now passes touchUpdatedAt: false; restore goes back to the plain unarchive write and no longer needs the capture/reapply workaround.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a4b897396
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a4b897396
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
… is durable With the metadata write moved after agent recreation, cron duplication ran before it — a rejected metadata update left cloned cron records pointing at a fork whose directory the catch block just removed. Keep cron duplication after the durable metadata write.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0444fa425
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The package convention keeps comments in the top-of-file block only — move the touchUpdatedAt precedence, non-touching registration, and fork ordering notes out of statement-level positions into the respective module headers.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 00bbd6e7b7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Related Issue
No linked issue — the problem is explained below.
Problem
Recency-sorted session lists reshuffled on actions that have nothing to do with session activity, because every metadata write bumped
updatedAt:updatedAtbump as its "archived at" display, which breaks once the bump goes away.What changed
updatedAtnow tracks content activity only:ISessionMetadata.updatealready hadtouchUpdatedAt: false(used by the turn-outcome mirror); an explicitpatch.updatedAtnow always wins over both bump and keep.setTitle/setArchivedpasstouchUpdatedAt: false— rename and archive/restore no longer reorder listings.fork()passesupdatedAt: sourceMeta.updatedAt— a fork inherits the source's recency and lands next to it;createdAtstays "now".SessionMeta.archivedAtrecords the archive moment (cleared on restore) and is surfaced through the session index →sessionLegacy→ v1 route (archived_at, ISO) + v2meta.archived_at(Unix ms, null when absent) → klient contract. Clients fall back toupdatedAtfor sessions archived before this field existed, so no data migration is needed.Client-side consumers (sidebar insertion semantics, archived-list display) live in the code-app repo and reference this change.
Verification
setTitle/setArchivedkeepupdatedAt;archivedAtwritten/cleared; explicitpatch.updatedAtwins; fork inherits the sourceupdatedAt.vitest rungreen (one pre-existing stalestate-manifest.d.tsregenerated viagen:state-manifest) and fulltypecheckgreen.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.