feat(compaction): make post-compaction context sections configurable#34556
Conversation
Greptile SummaryThis PR makes the post-compaction context injection configurable via a new
Confidence Score: 3/5
Last reviewed commit: a3b0269 |
Additional Comments (1)
The injected post-compaction message on line 89 always tells the agent to "Execute your Session Startup sequence now", regardless of what Similarly, the label Consider deriving the startup section name from the configured list, or making the message more generic: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3b0269969
ℹ️ 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".
| const configuredSections = cfg?.agents?.defaults?.compaction?.postCompactionSections; | ||
| const sectionNames = Array.isArray(configuredSections) | ||
| ? configuredSections | ||
| : DEFAULT_POST_COMPACTION_SECTIONS; |
There was a problem hiding this comment.
Make startup reminder align with configured section names
This change allows arbitrary postCompactionSections, but the injected post-compaction message still hardcodes “Execute your Session Startup sequence now.” If a deployment configures only non-Session Startup sections (for example ['Boot Sequence'] or just safety sections), the runtime now sends contradictory guidance: it extracts custom sections yet still instructs the agent to run a section name that may not exist. In those configs this can reintroduce the same false “missing startup section/file” behavior the change is trying to eliminate.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 9b470853f (same session, pushed before this review fired).
The prose now branches explicitly on whether the active section set matches the default ["Session Startup", "Red Lines"] pair:
const prose = isDefaultSections
? "...Execute your Session Startup sequence now..."
: `Re-read the sections injected below (${sectionNames.join(", ")}) and follow your configured startup procedure...`;Deployments using custom sections (e.g. ["Boot Sequence"]) receive prose that names their actual sections — no reference to "Session Startup" is injected. Default deployments are fully backward compatible.
Two regression tests verify both branches:
does NOT reference "Session Startup" in prose when custom sections are configureduses default "Session Startup" prose when default sections are active
22/22 tests passing.
There was a problem hiding this comment.
Fixed in 9b47085 — the injected prose now adapts to the configured section names instead of hardcoding 'Session Startup'. When custom sections are configured, the message references those section names directly.
|
Greptile finding is valid and addressed in The injected prose now branches on whether the active section set matches the default
Two regression tests cover both branches. 22/22 passing. |
f1530f3 to
ef5def0
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ef5def06f8
ℹ️ 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 was just compacted. The conversation summary above is a hint, NOT a substitute for your startup sequence. " + | ||
| "Execute your Session Startup sequence now — read the required files before responding to the user." | ||
| : `Session was just compacted. The conversation summary above is a hint, NOT a substitute for your full startup sequence. ` + | ||
| `Re-read the sections injected below (${sectionNames.join(", ")}) and follow your configured startup procedure before responding to the user.`; |
There was a problem hiding this comment.
Describe only sections that were actually injected
In readPostCompactionContext, custom-mode prose is built from sectionNames.join(", ") (the configured list), not from the sections that extractSections actually found. If config requests multiple headings and only some exist in AGENTS.md, the function still returns context but claims all configured sections were injected, which can send the agent looking for non-existent headings and recreate misleading “missing section” behavior in partially migrated setups.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 678cd65 — prose now references only section names that were actually found in the extracted content (matched by heading regex), so partially migrated setups won't reference non-existent headings. 22/22 tests passing.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 678cd651c3
ℹ️ 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".
| const rawCombined = sections.join("\n\n"); | ||
| const foundSectionNames = sectionNames.filter((name) => | ||
| new RegExp(`^#{2,3}\\s+${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`, "mi").test( | ||
| rawCombined, |
There was a problem hiding this comment.
Derive injected section names from extraction results
The new foundSectionNames detection can report sections that were not actually injected because it regex-scans sections.join("\n\n") for heading text instead of using extraction metadata. In particular, extractSections intentionally ignores headings inside fenced code blocks, but those lines are still present in extracted section content, so a code block containing ## <configured-name> will make displayNames include that missing section. This reintroduces misleading post-compaction prose in repos whose AGENTS sections include markdown examples.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 2c31a12 — replaced regex-based heading detection with an extractSections output parameter (foundNames). Now extractSections pushes the section name only when it actually matches a heading outside code blocks, so code block examples containing ## SectionName won't false-match.
678cd65 to
2c31a12
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2c31a1256b
ℹ️ 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".
| const sections = extractSections(content, sectionNames, foundSectionNames); | ||
|
|
||
| if (sections.length === 0) { | ||
| return null; |
There was a problem hiding this comment.
Preserve legacy section fallback when defaults are absent
With postCompactionSections unset, this path now extracts only Session Startup/Red Lines and immediately returns null when those headings are missing, which drops the previous fallback to legacy Every Session/Safety sections. Any workspace still using older AGENTS templates will therefore lose post-compaction context injection after this commit, even though other compaction code paths still treat those legacy names as supported; please keep a fallback (or alias mapping) so existing deployments don’t silently regress.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 444d6c4 — when using defaults (no explicit postCompactionSections), the code now falls back to legacy section names (Every Session / Safety) if the current headings aren't found. Explicitly configured sections skip the fallback. 22/22 tests passing.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: eab55e2dec
ℹ️ 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".
| // Fall back to legacy section names ("Every Session" / "Safety") when using | ||
| // defaults and the current headings aren't found — preserves compatibility | ||
| // with older AGENTS.md templates. | ||
| if (sections.length === 0 && !Array.isArray(configuredSections)) { |
There was a problem hiding this comment.
Apply legacy fallback for explicit default section config
When agents.defaults.compaction.postCompactionSections is explicitly set to ['Session Startup', 'Red Lines'], this condition skips the legacy fallback path and returns null on older AGENTS.md files that only have Every Session/Safety. In contrast, leaving the field unset still falls back successfully, so explicitly pinning the documented defaults changes behavior and can silently disable post-compaction context injection in partially migrated deployments.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 5e8f31d — the legacy fallback condition now also triggers when postCompactionSections is explicitly set to the default pair (["Session Startup", "Red Lines"]). Explicitly pinning the documented defaults now behaves identically to leaving the field unset. Added a dedicated test case for this scenario. 23/23 tests passing.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e8f31d6d6
ℹ️ 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".
| configuredSections.length === DEFAULT_POST_COMPACTION_SECTIONS.length && | ||
| configuredSections.every( | ||
| (s, i) => s.toLowerCase() === DEFAULT_POST_COMPACTION_SECTIONS[i].toLowerCase(), |
There was a problem hiding this comment.
Treat default section pair as order-insensitive
isExplicitDefaults uses index-by-index comparison, so postCompactionSections: ["Red Lines", "Session Startup"] is treated as a custom config instead of the default pair. In that case legacy fallback (Every Session/Safety) is skipped, and older AGENTS.md templates return null, silently disabling post-compaction context injection even though the same two default section names were configured.
Useful? React with 👍 / 👎.
5e8f31d to
722f7b0
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 722f7b0fcc
ℹ️ 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".
| configuredSections.every( | ||
| (s, i) => s.toLowerCase() === DEFAULT_POST_COMPACTION_SECTIONS[i].toLowerCase(), |
There was a problem hiding this comment.
Compare explicit default sections without order dependence
The explicit-default check uses index-by-index comparison, so postCompactionSections: ["Red Lines", "Session Startup"] is treated as a custom set instead of the documented defaults. In workspaces that still use legacy AGENTS.md headings (Every Session/Safety), this causes the legacy fallback path to be skipped and readPostCompactionContext returns null, silently disabling post-compaction reinjection just because the two default names were listed in a different order.
Useful? React with 👍 / 👎.
722f7b0 to
eddf528
Compare
eddf528 to
138116d
Compare
1189d1b to
67c504f
Compare
67c504f to
1bfcf88
Compare
1bfcf88 to
17d8031
Compare
17d8031 to
fa4d5b4
Compare
Rebased on upstream main. Squashed all commits. - Add agents.defaults.compaction.postCompactionSections config field - Adapt injected prose to reference configured section names - Only reference sections actually found via extractSections foundNames - Default: ['Session Startup', 'Red Lines'] preserves existing behavior - 22/22 tests passing
When using default sections and 'Session Startup'/'Red Lines' headings aren't found, fall back to legacy 'Every Session'/'Safety' names. Only applies when postCompactionSections is not explicitly configured.
When postCompactionSections is explicitly set to ['Session Startup', 'Red Lines'] (the documented defaults), the legacy fallback to 'Every Session'/'Safety' was skipped — silently disabling post-compaction context on older AGENTS.md templates. Now explicitly pinning the defaults behaves identically to leaving the field unset. 23/23 tests passing.
fa4d5b4 to
491bb28
Compare
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman (cherry picked from commit 03b9aba)
…penclaw#34556) Merged via squash. Prepared head SHA: 491bb28 Co-authored-by: efe-arv <[email protected]> Co-authored-by: jalehman <[email protected]> Reviewed-by: @jalehman (cherry picked from commit 03b9aba)
Abstract
This patch introduces a configuration primitive,
agents.defaults.compaction.postCompactionSections, that decouples the post-compaction context injection mechanism from its previously hardcoded section-name constants. The change resolves the inability of non-default deployments to specify which sections ofAGENTS.mdshould be re-injected into the agent context following a compaction event, without requiring source-level modification.Background
When a session compaction occurs, OpenClaw re-injects a subset of the workspace
AGENTS.mdfile into the agent context to preserve operational continuity. Prior to this change, the set of extracted sections was statically defined withinpost-compaction-context.tsas["Session Startup", "Red Lines"]. This design assumption precluded any deployment that organises itsAGENTS.mdunder alternative heading names from receiving meaningful post-compaction context, and produced spuriousWORKFLOW_AUTO.mdresolution warnings as a downstream effect.Specification
The new field is defined on
AgentCompactionConfigas:The runtime resolver applies the following precedence rule:
postCompactionSectionsis an explicit empty array ([]), injection is suppressed entirely and the function returnsnull.postCompactionSectionsis a non-empty array, the specified names are used in place of the defaults.undefined), the legacy default["Session Startup", "Red Lines"]is applied — preserving full backward compatibility.Section name matching remains case-insensitive and supports both H2 and H3 Markdown headings, consistent with the existing
extractSectionscontract.Changes
src/config/types.agent-defaults.tspostCompactionSections?: string[]field onAgentCompactionConfigsrc/config/zod-schema.agent-defaults.tsz.array(z.string()).optional()src/config/schema.labels.tssrc/auto-reply/reply/post-compaction-context.tssrc/auto-reply/reply/post-compaction-context.test.tsVerification
All pre-existing tests pass without modification, confirming backward compatibility.
Closes #33792