From 8273ad7a65071689073eb12e9f14ee9d17bbb2fa Mon Sep 17 00:00:00 2001 From: Proactive Runtime Bot Date: Sat, 18 Jul 2026 18:07:49 +0200 Subject: [PATCH 1/2] fix(relay-feature-guardian): narrow Relayfile mount intent --- .../agents/relay-feature-guardian/agent.test.ts | 15 +++++++++++++++ .../agents/relay-feature-guardian/persona.json | 8 ++++++++ CHANGELOG.md | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.agentworkforce/agents/relay-feature-guardian/agent.test.ts b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts index af09878e6..7daaae88e 100644 --- a/.agentworkforce/agents/relay-feature-guardian/agent.test.ts +++ b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts @@ -23,6 +23,10 @@ import guardian, { } from './agent.ts'; const persona = JSON.parse(readFileSync(new URL('./persona.json', import.meta.url), 'utf8')) as { + integrations: Record< + string, + { relayfileMount?: { requiredReadPaths?: unknown; writeOnlyPaths?: unknown } } + >; inputs: { SLACK_CHANNEL: { default: string } }; }; @@ -318,6 +322,17 @@ describe('relay-feature-guardian runtime paths', () => { expect(persona.inputs.SLACK_CHANNEL.default).toBe('C0AEKNLDNKW'); }); + it('mounts only the manifest directory and configured Slack output channel', () => { + expect(persona.integrations.github?.relayfileMount).toEqual({ + requiredReadPaths: ['/github/repos/AgentWorkforce/relay/.agentworkforce/features/**'], + writeOnlyPaths: [], + }); + expect(persona.integrations.slack?.relayfileMount).toEqual({ + requiredReadPaths: [], + writeOnlyPaths: ['/slack/channels/${SLACK_CHANNEL}/**'], + }); + }); + it('deduplicates an ambiguous post retry and advances after a saved receipt', async () => { const transport = new IdempotentSlackTransport(); const restore = bindPreviewTransport(transport); diff --git a/.agentworkforce/agents/relay-feature-guardian/persona.json b/.agentworkforce/agents/relay-feature-guardian/persona.json index f5c4b1e8e..ddbe37ccb 100644 --- a/.agentworkforce/agents/relay-feature-guardian/persona.json +++ b/.agentworkforce/agents/relay-feature-guardian/persona.json @@ -13,11 +13,19 @@ "github": { "scope": { "repo": "AgentWorkforce/relay" + }, + "relayfileMount": { + "requiredReadPaths": ["/github/repos/AgentWorkforce/relay/.agentworkforce/features/**"], + "writeOnlyPaths": [] } }, "slack": { "scope": { "paths": "/slack/channels/**" + }, + "relayfileMount": { + "requiredReadPaths": [], + "writeOnlyPaths": ["/slack/channels/${SLACK_CHANNEL}/**"] } } }, diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b7d2ade6..87f3fb85e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `agent-relay integration` now discovers relayfile control-plane capabilities before sending API v3 headers, fails fast with upgrade and restart guidance for incompatible daemons, and safely replaces stale daemons when a compatible binary is installed. - `AgentRelaySDK` now maps Relaycast lifecycle states onto its existing Swift presence states, so root-package consumers compile with Relaycast 6.1 and later while package-local builds remain compatible with 6.0.5. -- `relay-feature-guardian` now reads the scoped Relay clone, posts to its configured channel, and advances its exact, revision-safe cycle checkpoint only after a bounded wait returns a real Slack receipt, while safely reconciling retired manifest features. +- `relay-feature-guardian` now limits read mirrors to the feature manifest and workspace memory while keeping Slack write-only to its configured output channel, and advances its exact, revision-safe cycle checkpoint only after a bounded wait returns a real Slack receipt while safely reconciling retired manifest features. - `agent-relay-broker` and `@agent-relay/utils` now preserve mise/asdf/rtx-style CLI shims when spawning provider workers, so Codex, Claude, Gemini, and other agent CLIs installed via a version manager receive their own permission flags (e.g. `--dangerously-bypass-approvals-and-sandbox`) instead of the manager binary rejecting them. ## [10.6.3] - 2026-07-17 From 9bb3b74d6c4fd1342e5c0d70681b90e8b260f5d9 Mon Sep 17 00:00:00 2001 From: Proactive Runtime Bot Date: Sat, 18 Jul 2026 18:20:32 +0200 Subject: [PATCH 2/2] test(relay-feature-guardian): document memory mirror --- .../agents/relay-feature-guardian/agent.test.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.agentworkforce/agents/relay-feature-guardian/agent.test.ts b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts index 7daaae88e..8a93bae75 100644 --- a/.agentworkforce/agents/relay-feature-guardian/agent.test.ts +++ b/.agentworkforce/agents/relay-feature-guardian/agent.test.ts @@ -28,6 +28,7 @@ const persona = JSON.parse(readFileSync(new URL('./persona.json', import.meta.ur { relayfileMount?: { requiredReadPaths?: unknown; writeOnlyPaths?: unknown } } >; inputs: { SLACK_CHANNEL: { default: string } }; + memory: { enabled: boolean; scopes: string[]; ttlDays: number }; }; const manifestFeatures = [ @@ -322,11 +323,16 @@ describe('relay-feature-guardian runtime paths', () => { expect(persona.inputs.SLACK_CHANNEL.default).toBe('C0AEKNLDNKW'); }); - it('mounts only the manifest directory and configured Slack output channel', () => { + it('declares bounded manifest and memory reads plus configured Slack output', () => { expect(persona.integrations.github?.relayfileMount).toEqual({ requiredReadPaths: ['/github/repos/AgentWorkforce/relay/.agentworkforce/features/**'], writeOnlyPaths: [], }); + expect(persona.memory).toEqual({ + enabled: true, + scopes: ['workspace'], + ttlDays: 14, + }); expect(persona.integrations.slack?.relayfileMount).toEqual({ requiredReadPaths: [], writeOnlyPaths: ['/slack/channels/${SLACK_CHANNEL}/**'],