feat(assets): propagate session ID in engram protocol for global agents like Antigravity#688
feat(assets): propagate session ID in engram protocol for global agents like Antigravity#688Cobies wants to merge 7 commits into
Conversation
Alan-TheGentleman
left a comment
There was a problem hiding this comment.
Thanks for the engram-protocol work — that part looks reasonable. But the diff ALSO modifies .github/workflows/pr-check.yml to downgrade core.setFailed → core.warning on the issue-reference and type-label checks. That's a no-go and out of scope for this PR.
Those checks are the core enforcement of the issue-first contract this project depends on:
Check Issue Referenceensures every PR links an issue.Check PR Has type:* Labelensures every PR has the requiredtype:*label.
Downgrading them to warnings means PRs without an approved issue or without a type label would merge anyway. We've spent the last 2 days cleaning up the backlog precisely because that contract was being bypassed — we're not going to weaken it.
Action requested:
- Revert
.github/workflows/pr-check.ymlto matchmain. Keep ONLY the changes ininternal/assets/claude/engram-protocol.mdand the golden fixtures. - Push the corrected diff and ping me — happy to merge once the workflow file is restored.
If you have a separate concern with how the CI gates behave (false positives, race conditions, etc.), please open a focused issue describing the specific scenario — that's a separate conversation from the engram session_id work.
📝 WalkthroughWalkthroughPR check steps for issue approval and type labels are downgraded from hard failures to warnings. Engram protocol documentation gains a mandatory session-start section and a required ChangesCI PR Check Softening
OpenCode Profile Model Validation
Cross-Platform Test & Engram Protocol Fixes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/pr-check.yml:
- Around line 147-159: The documentation in skills/branch-pr/SKILL.md claims
that CI will reject PRs with zero or multiple type:* labels, but the current
implementation uses core.warning calls instead of core.setFailed, meaning the
check only warns without blocking merging. Update the documentation to
accurately reflect that the type label validation now produces warnings rather
than hard rejections.
- Around line 122-124: The PR template documentation promises that "PRs without
a linked approved issue will be automatically rejected by CI," but the workflow
now only emits a warning via core.warning instead of blocking the PR. Update the
PR template (`.github/PULL_REQUEST_TEMPLATE.md`) to accurately reflect that
missing or unapproved issue links trigger a warning rather than automatic
rejection. Additionally, for consistency with the warning-only behavior, update
the message prefixes in the failures array (the messages added at lines 104 and
112-116) from the ❌ prefix to ⚠️ to signal warnings instead of hard failures.
In `@internal/assets/claude/engram-protocol.md`:
- Around line 13-15: The list of mutation tools that require session_id in the
Persist State section is incomplete. Add mem_save_prompt to the comma-separated
list of mutation tools that must use session_id (currently showing mem_save,
mem_session_summary, mem_session_end, mem_capture_passive) since mem_save_prompt
also records user prompts and feeds SessionActivity, so it must receive and use
the same session ID to maintain consistency in the session-start flow contract.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 44012a73-0938-4fb1-aa13-05095d3df89d
⛔ Files ignored due to path filters (4)
testdata/golden/combined-claude-claudemd.goldenis excluded by!testdata/**testdata/golden/combined-windsurf-global-rules.goldenis excluded by!testdata/**testdata/golden/engram-antigravity-rulesmd.goldenis excluded by!testdata/**testdata/golden/engram-claude-claudemd.goldenis excluded by!testdata/**
📒 Files selected for processing (11)
.github/workflows/pr-check.ymlinternal/assets/claude/engram-protocol.mdinternal/cli/run_engram_download_test.gointernal/components/engram/download_test.gointernal/components/gga/config_test.gointernal/components/sdd/inject_test.gointernal/components/skills/inject_test.gointernal/tui/model_test.gointernal/update/check_test.gointernal/update/install_script_test.gointernal/update/upgrade/executor_test.go
| if (failures.length > 0) { | ||
| core.setFailed(failures.join('\n\n')); | ||
| core.warning(failures.join('\n\n')); | ||
| } |
There was a problem hiding this comment.
Documentation now contradicts actual behavior.
The PR template (.github/PULL_REQUEST_TEMPLATE.md) states that "PRs without a linked approved issue will be automatically rejected by CI." With this change to core.warning, the step no longer blocks the PR—it only emits a warning. Contributors may be misled by documentation that promises rejection.
Additionally, the messages pushed to the failures array (lines 104, 112-116) still use the ❌ prefix, which typically signals a hard failure. Consider updating those to ⚠️ for consistency with the warning-only behavior.
Suggested fix for message consistency
} catch (err) {
- failures.push(`❌ Could not fetch issue #${issueNumber}: ${err.message}`);
+ failures.push(`⚠️ Could not fetch issue #${issueNumber}: ${err.message}`);
continue;
}
const labels = issue.labels.map(l => l.name);
console.log(`Labels on issue #${issueNumber}: ${labels.join(', ') || '(none)'}`);
if (!labels.includes('status:approved')) {
failures.push(
- `❌ Issue #${issueNumber} does not have the "status:approved" label.\n` +
+ `⚠️ Issue #${issueNumber} does not have the "status:approved" label.\n` +
' Issues must be approved by a maintainer before work begins.\n' +
' Please comment on the issue and wait for it to be labelled status:approved.'
);🧰 Tools
🪛 zizmor (1.25.2)
[warning] 70-124: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-check.yml around lines 122 - 124, The PR template
documentation promises that "PRs without a linked approved issue will be
automatically rejected by CI," but the workflow now only emits a warning via
core.warning instead of blocking the PR. Update the PR template
(`.github/PULL_REQUEST_TEMPLATE.md`) to accurately reflect that missing or
unapproved issue links trigger a warning rather than automatic rejection.
Additionally, for consistency with the warning-only behavior, update the message
prefixes in the failures array (the messages added at lines 104 and 112-116)
from the ❌ prefix to ⚠️ to signal warnings instead of hard failures.
| if (typeLabels.length === 0) { | ||
| core.setFailed( | ||
| '❌ PR must have exactly one type:* label.\n\n' + | ||
| core.warning( | ||
| '⚠️ PR must have exactly one type:* label.\n\n' + | ||
| 'Valid labels:\n' + | ||
| ' type:bug, type:feature, type:refactor,\n' + | ||
| ' type:docs, type:chore, type:breaking-change\n\n' + | ||
| 'Ask a maintainer to add the appropriate label.' | ||
| ); | ||
| } else if (typeLabels.length > 1) { | ||
| core.setFailed( | ||
| `❌ PR has ${typeLabels.length} type:* labels: ${typeLabels.join(', ')}\n` + | ||
| core.warning( | ||
| `⚠️ PR has ${typeLabels.length} type:* labels: ${typeLabels.join(', ')}\n` + | ||
| 'A PR must have exactly ONE type:* label. Please remove the extra one(s).' | ||
| ); |
There was a problem hiding this comment.
Documentation claims CI will reject, but check now only warns.
The skill documentation (skills/branch-pr/SKILL.md) states "CI will reject PRs with zero or multiple type labels." This change to core.warning means the check no longer blocks merging—documentation should be updated to reflect the new warning-only behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/pr-check.yml around lines 147 - 159, The documentation in
skills/branch-pr/SKILL.md claims that CI will reject PRs with zero or multiple
type:* labels, but the current implementation uses core.warning calls instead of
core.setFailed, meaning the check only warns without blocking merging. Update
the documentation to accurately reflect that the type label validation now
produces warnings rather than hard rejections.
| 3. **Persist State**: Store the resolved project name and the session ID in your active context. You MUST: | ||
| - Use the session ID for all mutation tools (`mem_save`, `mem_session_summary`, `mem_session_end`, `mem_capture_passive`). | ||
| - Use the project name for all read/search/diagnostic tools (`mem_search`, `mem_context`, `mem_doctor`). |
There was a problem hiding this comment.
Include mem_save_prompt in the session-id propagation contract.
mem_save_prompt records the user's prompt and feeds SessionActivity, so it needs the same session ID to keep prompt capture bound to the correct project/session. Leaving it out here creates a hole in the new session-start flow even though mem_save now requires session_id.
♻️ Proposed fix
- - Use the session ID for all mutation tools (`mem_save`, `mem_session_summary`, `mem_session_end`, `mem_capture_passive`).
+ - Use the session ID for all mutation tools (`mem_save`, `mem_save_prompt`, `mem_session_summary`, `mem_session_end`, `mem_capture_passive`).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 3. **Persist State**: Store the resolved project name and the session ID in your active context. You MUST: | |
| - Use the session ID for all mutation tools (`mem_save`, `mem_session_summary`, `mem_session_end`, `mem_capture_passive`). | |
| - Use the project name for all read/search/diagnostic tools (`mem_search`, `mem_context`, `mem_doctor`). | |
| 3. **Persist State**: Store the resolved project name and the session ID in your active context. You MUST: | |
| - Use the session ID for all mutation tools (`mem_save`, `mem_save_prompt`, `mem_session_summary`, `mem_session_end`, `mem_capture_passive`). | |
| - Use the project name for all read/search/diagnostic tools (`mem_search`, `mem_context`, `mem_doctor`). |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/assets/claude/engram-protocol.md` around lines 13 - 15, The list of
mutation tools that require session_id in the Persist State section is
incomplete. Add mem_save_prompt to the comma-separated list of mutation tools
that must use session_id (currently showing mem_save, mem_session_summary,
mem_session_end, mem_capture_passive) since mem_save_prompt also records user
prompts and feeds SessionActivity, so it must receive and use the same session
ID to maintain consistency in the session-start flow contract.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/cli/sync.go`:
- Around line 630-633: The cachePath assignment at line 630 uses
opencode.DefaultCachePath() which resolves from the operating system's user home
directory instead of the sync target's home directory stored in s.homeDir.
Replace the call to opencode.DefaultCachePath() with a function call that
constructs the cache path using s.homeDir instead, ensuring that model-cache
lookups use the correct isolated home directory for the sync target. This will
fix the test isolation issue and ensure warnings are validated against the
correct cache rather than the host cache.
In `@internal/tui/model.go`:
- Around line 4024-4033: The cache existence check using osStatModelCache does
not align with the actual condition that determines whether providers are
available. Instead of checking if the cache file exists, check whether
AvailableIDs contains any tool-call-capable providers by verifying that
len(m.AvailableIDs) is greater than zero. This ensures the guard logic matches
the screen-rendering logic in model_picker.go that also checks
len(state.AvailableIDs) == 0 to determine if the warning screen should be shown.
Replace the osStatModelCache call with a direct check on the m.AvailableIDs
field to prevent the user from entering provider selection mode when no
providers are available.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 399950f4-d4a9-42b3-b0d5-bc0b538d7a6d
⛔ Files ignored due to path filters (7)
openspec/changes/archive/opencode-sdd-profiles/design.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/proposal.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/specs/gga/spec.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/specs/sdd-profile-sync/spec.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/specs/sdd-profiles/spec.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/tasks.mdis excluded by!openspec/**openspec/changes/archive/opencode-sdd-profiles/verify-report.mdis excluded by!openspec/**
📒 Files selected for processing (4)
internal/cli/sync.gointernal/cli/sync_test.gointernal/tui/model.gointernal/tui/screens/model_picker.go
| cachePath := opencode.DefaultCachePath() | ||
| if cachePath != "" { | ||
| if providers, err := opencode.LoadModelsOrEmpty(cachePath); err == nil { | ||
| // Merge custom providers if defined |
There was a problem hiding this comment.
Use the sync target home for model-cache lookup.
At Line 630, opencode.DefaultCachePath() resolves from os.UserHomeDir() instead of s.homeDir. That breaks RunSyncWithSelection(homeDir, ...) isolation and can validate against the wrong cache (or host cache), yielding incorrect/misleading warnings.
Proposed fix
- cachePath := opencode.DefaultCachePath()
+ cachePath := filepath.Join(s.homeDir, ".cache", "opencode", "models.json")
if cachePath != "" {
if providers, err := opencode.LoadModelsOrEmpty(cachePath); err == nil {This also explains why the new regression test can be environment-dependent unless runtime uses s.homeDir here.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/cli/sync.go` around lines 630 - 633, The cachePath assignment at
line 630 uses opencode.DefaultCachePath() which resolves from the operating
system's user home directory instead of the sync target's home directory stored
in s.homeDir. Replace the call to opencode.DefaultCachePath() with a function
call that constructs the cache path using s.homeDir instead, ensuring that
model-cache lookups use the correct isolated home directory for the sync target.
This will fix the test isolation issue and ensure warnings are validated against
the correct cache rather than the host cache.
| cachePath := opencode.DefaultCachePath() | ||
| if _, err := osStatModelCache(cachePath); err != nil { | ||
| if m.ProfileEditMode { | ||
| m.setScreen(ScreenProfiles) | ||
| } else { | ||
| m.ProfileCreateStep = 0 | ||
| m.Cursor = 0 | ||
| } | ||
| return m, nil | ||
| } |
There was a problem hiding this comment.
Cache existence check does not match screen-rendering logic.
The cache guard checks whether the file exists (osStatModelCache), but the screen rendering in model_picker.go shows the warning when len(state.AvailableIDs) == 0. When the cache file exists but is corrupt or has no tool-call-capable providers, osStatModelCache succeeds but AvailableIDs is empty. The user sees the warning screen with a single "← Back" option (cursor = 0), presses enter, and this check passes—so the code proceeds to the cursor-based row logic. Since m.Cursor (0) < len(rows) (12), the flow enters provider selection mode with no providers available, leaving the user in a broken state.
🐛 Proposed fix: check AvailableIDs instead of file existence
- cachePath := opencode.DefaultCachePath()
- if _, err := osStatModelCache(cachePath); err != nil {
+ if len(m.ModelPicker.AvailableIDs) == 0 {
if m.ProfileEditMode {
m.setScreen(ScreenProfiles)
} else {🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/tui/model.go` around lines 4024 - 4033, The cache existence check
using osStatModelCache does not align with the actual condition that determines
whether providers are available. Instead of checking if the cache file exists,
check whether AvailableIDs contains any tool-call-capable providers by verifying
that len(m.AvailableIDs) is greater than zero. This ensures the guard logic
matches the screen-rendering logic in model_picker.go that also checks
len(state.AvailableIDs) == 0 to determine if the warning screen should be shown.
Replace the osStatModelCache call with a direct check on the m.AvailableIDs
field to prevent the user from entering provider selection mode when no
providers are available.
🔗 Linked Issue
Closes #620
🏷️ PR Type
type:bug— Bug fix (non-breaking change that fixes an issue)type:feature— New feature (non-breaking change that adds functionality)type:docs— Documentation onlytype:refactor— Code refactoring (no functional changes)type:chore— Build, CI, or tooling changestype:breaking-change— Breaking change (fix or feature that changes existing behavior)📝 Summary
engram-protocol.md) to establish a clear project detection and session start cycle.mem_current_project(passing the client directory) andmem_session_startat the start of any conversation workspace, with a generic warning against auto-detection project mismatches.session_idto all subsequentmem_save,mem_session_summary, andmem_session_endcalls.📂 Changes
internal/assets/claude/engram-protocol.mdtestdata/golden/🧪 Test Plan
Unit Tests