From 11f8f821f99dc69288b0885cc8b135fdf6c7aac1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 13 Apr 2026 22:52:29 +0000
Subject: [PATCH 1/4] Add MemPalace as a shared agentic workflow MCP server
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ec374765-400d-4135-889f-9bd4a6254c43
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/shared/mcp/mempalace.md | 131 ++++++++++++++++++++++
1 file changed, 131 insertions(+)
create mode 100644 .github/workflows/shared/mcp/mempalace.md
diff --git a/.github/workflows/shared/mcp/mempalace.md b/.github/workflows/shared/mcp/mempalace.md
new file mode 100644
index 00000000000..65d8aa7edd9
--- /dev/null
+++ b/.github/workflows/shared/mcp/mempalace.md
@@ -0,0 +1,131 @@
+---
+# MemPalace MCP Server
+# Semantic memory system for AI agents — store, search, and retrieve
+# verbatim content across workflow runs using ChromaDB.
+#
+# Palace data is persisted using cache-memory across workflow runs.
+# On first use the palace directory is created automatically.
+#
+# Documentation: https://github.com/MemPalace/mempalace
+#
+# Usage:
+# imports:
+# - shared/mcp/mempalace.md
+
+tools:
+ cache-memory: true
+
+mcp-servers:
+ mempalace:
+ command: "python"
+ args:
+ - "-m"
+ - "mempalace.mcp_server"
+ - "--palace"
+ - "/tmp/gh-aw/cache-memory/palace"
+ allowed:
+ - "mempalace_status"
+ - "mempalace_list_wings"
+ - "mempalace_list_rooms"
+ - "mempalace_get_taxonomy"
+ - "mempalace_search"
+ - "mempalace_check_duplicate"
+ - "mempalace_get_aaak_spec"
+ - "mempalace_add_drawer"
+ - "mempalace_delete_drawer"
+ - "mempalace_kg_query"
+ - "mempalace_kg_add"
+ - "mempalace_kg_invalidate"
+ - "mempalace_kg_timeline"
+ - "mempalace_kg_stats"
+ - "mempalace_traverse"
+ - "mempalace_find_tunnels"
+ - "mempalace_graph_stats"
+ - "mempalace_diary_write"
+ - "mempalace_diary_read"
+
+steps:
+ - name: Install MemPalace
+ run: pip install "mempalace==3.2.0"
+---
+
From dda28f7108519ec4cec4700c3277c02e755a62cb Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 13 Apr 2026 22:53:13 +0000
Subject: [PATCH 2/4] Add explicit type: stdio to mempalace MCP server config
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/ec374765-400d-4135-889f-9bd4a6254c43
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/shared/mcp/mempalace.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/shared/mcp/mempalace.md b/.github/workflows/shared/mcp/mempalace.md
index 65d8aa7edd9..1fab8ed136e 100644
--- a/.github/workflows/shared/mcp/mempalace.md
+++ b/.github/workflows/shared/mcp/mempalace.md
@@ -17,6 +17,7 @@ tools:
mcp-servers:
mempalace:
+ type: stdio
command: "python"
args:
- "-m"
From 801d202e3a3dd4ea036dbe4e1eea505f4d636634 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 13 Apr 2026 23:15:23 +0000
Subject: [PATCH 3/4] Use mempalace in daily-fact workflow for variety
enforcement
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b5ef527a-4579-4126-81cb-3c04ba3d16b7
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/daily-fact.lock.yml | 185 ++++++++++++++++++++++++--
.github/workflows/daily-fact.md | 21 +++
2 files changed, 192 insertions(+), 14 deletions(-)
diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml
index a47a7c4df13..7ba99ed7431 100644
--- a/.github/workflows/daily-fact.lock.yml
+++ b/.github/workflows/daily-fact.lock.yml
@@ -1,5 +1,5 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"f30e2e8af65bbdca1d696a63d2d0fd8c58c5af55f900c07ebf15ad33abd07a2a","strict":true,"agent_id":"codex","agent_model":"gpt-5.1-codex-mini"}
-# gh-aw-manifest: {"version":1,"secrets":["CODEX_API_KEY","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/setup-node","sha":"53b83947a5a98c8d113130e565377fae1a50d02f","version":"v6.3.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20","digest":"sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20","digest":"sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20","digest":"sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19","digest":"sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0","digest":"sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28","pinned_image":"ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b08ee72b7ae7225e4dd2702f9125605eff9489e4dd1c789d6604d9db4e726569","strict":true,"agent_id":"codex","agent_model":"gpt-5.1-codex-mini"}
+# gh-aw-manifest: {"version":1,"secrets":["CODEX_API_KEY","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/setup-node","sha":"53b83947a5a98c8d113130e565377fae1a50d02f","version":"v6.3.0"},{"repo":"actions/setup-python","sha":"a309ff8b426b58ec0e2a45f0f869d46889d02405","version":"v6.2.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20","digest":"sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20","digest":"sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20","digest":"sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19","digest":"sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0","digest":"sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28","pinned_image":"ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -26,6 +26,7 @@
#
# Resolved workflow manifest:
# Imports:
+# - shared/mcp/mempalace.md
# - shared/observability-otlp.md
#
# inlined-imports: true
@@ -40,10 +41,13 @@
# - OPENAI_API_KEY
#
# Custom actions used:
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
# - actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
+# - actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
#
# Container images used:
@@ -178,14 +182,15 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_337b05bbd721387f_EOF'
+ cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
- GH_AW_PROMPT_337b05bbd721387f_EOF
+ GH_AW_PROMPT_583d5a63d6d337f1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
+ cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_337b05bbd721387f_EOF'
+ cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
Tools: add_comment, missing_tool, missing_data, noop
@@ -217,17 +222,26 @@ jobs:
{{/if}}
- GH_AW_PROMPT_337b05bbd721387f_EOF
+ GH_AW_PROMPT_583d5a63d6d337f1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_337b05bbd721387f_EOF'
+ cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
+
{{#runtime-import? .github/shared-instructions.md}}
# Daily Fact About gh-aw
Your task is to post a poetic, whimsical fact about the __GH_AW_GITHUB_REPOSITORY__ project to discussion #4750.
+ ## Step 0: Load Memory
+
+ Before gathering repository activity, check what has already been celebrated in the palace to avoid repetition.
+
+ 1. Call `mempalace_status` to confirm the palace is ready.
+ 2. Call `mempalace_search` with `query: "gh-aw daily fact"` to retrieve the most recent facts that have been posted (wing: `daily-facts`, if already indexed).
+ 3. Note any PR numbers, issue numbers, release tags, or contributor handles that appear in the results — **do not repeat those topics today**.
+
## Data Sources
Mine recent activity from the repository to find interesting facts. Focus on:
@@ -250,6 +264,7 @@ jobs:
## Guidelines
+ - **Check memory first**: Skip any PR, issue, or release that already appears in the palace results from Step 0
- **Favor recent updates** but include variety - pick something interesting, not just the most recent
- **Be specific**: Include PR numbers, issue references, or release tags when relevant
- **Keep it short**: One or two poetic sentences for the main fact, optionally with a brief context
@@ -282,6 +297,17 @@ jobs:
- "There were some changes." (not specific, uninspired)
- Long paragraphs (keep it brief and lyrical)
+ ## Step 3: Save to Memory
+
+ After posting the comment, store the fact in the palace so it will be excluded from future runs:
+
+ Call `mempalace_add_drawer` with:
+ - `wing`: `"daily-facts"`
+ - `room`: the type of fact (e.g., `"pr"`, `"release"`, `"issue"`, `"contributor"`)
+ - `content`: a short record containing the PR/issue/release identifier and a one-line summary of the fact posted today
+
+ This ensures tomorrow's verse celebrates something new.
+
Now, analyze the recent activity and compose one poetic fact to share in discussion #4750.
**Important**: If no action is needed after completing your analysis, you **MUST** call the `noop` safe-output tool with a brief explanation. Failing to call any safe-output tool is the most common cause of safe-output workflow failures.
@@ -290,7 +316,7 @@ jobs:
{"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}}
```
- GH_AW_PROMPT_337b05bbd721387f_EOF
+ GH_AW_PROMPT_583d5a63d6d337f1_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -307,6 +333,9 @@ jobs:
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
+ GH_AW_ALLOWED_EXTENSIONS: ''
+ GH_AW_CACHE_DESCRIPTION: ''
+ GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/'
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
@@ -326,6 +355,9 @@ jobs:
return await substitutePlaceholders({
file: process.env.GH_AW_PROMPT,
substitutions: {
+ GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS,
+ GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION,
+ GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR,
GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
@@ -418,12 +450,34 @@ jobs:
with:
node-version: '24'
package-manager-cache: false
+ - name: Setup Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.12'
- name: Create gh-aw temp directory
run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
- name: Configure gh CLI for GitHub Enterprise
run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
env:
GH_TOKEN: ${{ github.token }}
+ - name: Install MemPalace
+ run: pip install "mempalace==3.2.0"
+
+ # Cache memory file share configuration from frontmatter processed below
+ - name: Create cache-memory directory
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/create_cache_memory_dir.sh"
+ - name: Restore cache-memory file share data
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }}
+ path: /tmp/gh-aw/cache-memory
+ restore-keys: |
+ memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-
+ - name: Setup cache-memory git repository
+ env:
+ GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory
+ GH_AW_MIN_INTEGRITY: none
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/setup_cache_memory_git.sh"
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }}
@@ -477,9 +531,9 @@ jobs:
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_74c27d721041c8e1_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_2a05655400b7b95a_EOF'
{"add_comment":{"max":1,"target":"4750"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_74c27d721041c8e1_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_2a05655400b7b95a_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -658,7 +712,7 @@ jobs:
export GH_AW_ENGINE="codex"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19'
- cat > /tmp/gh-aw/mcp-config/config.toml << GH_AW_MCP_CONFIG_4364ac61d8efeb74_EOF
+ cat > /tmp/gh-aw/mcp-config/config.toml << GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
[history]
persistence = "none"
@@ -674,6 +728,8 @@ jobs:
env = { "GITHUB_HOST" = "$GITHUB_SERVER_URL", "GITHUB_PERSONAL_ACCESS_TOKEN" = "$GH_AW_GITHUB_TOKEN", "GITHUB_READ_ONLY" = "1", "GITHUB_TOOLSETS" = "context,repos,issues,pull_requests,discussions" }
env_vars = ["GITHUB_HOST", "GITHUB_PERSONAL_ACCESS_TOKEN", "GITHUB_READ_ONLY", "GITHUB_TOOLSETS"]
+ [mcp_servers.mempalace]
+
[mcp_servers.safeoutputs]
type = "http"
url = "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT"
@@ -685,10 +741,10 @@ jobs:
[mcp_servers.safeoutputs."guard-policies".write-sink]
accept = ["*"]
- GH_AW_MCP_CONFIG_4364ac61d8efeb74_EOF
+ GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
# Generate JSON config for MCP gateway
- cat << GH_AW_MCP_CONFIG_4364ac61d8efeb74_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
+ cat << GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
{
"mcpServers": {
"github": {
@@ -706,6 +762,44 @@ jobs:
}
}
},
+ "mempalace": {
+ "type": "stdio",
+ "command": "python",
+ "args": [
+ "-m",
+ "mempalace.mcp_server",
+ "--palace",
+ "/tmp/gh-aw/cache-memory/palace"
+ ],
+ "tools": [
+ "mempalace_status",
+ "mempalace_list_wings",
+ "mempalace_list_rooms",
+ "mempalace_get_taxonomy",
+ "mempalace_search",
+ "mempalace_check_duplicate",
+ "mempalace_get_aaak_spec",
+ "mempalace_add_drawer",
+ "mempalace_delete_drawer",
+ "mempalace_kg_query",
+ "mempalace_kg_add",
+ "mempalace_kg_invalidate",
+ "mempalace_kg_timeline",
+ "mempalace_kg_stats",
+ "mempalace_traverse",
+ "mempalace_find_tunnels",
+ "mempalace_graph_stats",
+ "mempalace_diary_write",
+ "mempalace_diary_read"
+ ],
+ "guard-policies": {
+ "write-sink": {
+ "accept": [
+ "*"
+ ]
+ }
+ }
+ },
"safeoutputs": {
"type": "http",
"url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
@@ -734,7 +828,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_4364ac61d8efeb74_EOF
+ GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
@@ -894,6 +988,17 @@ jobs:
if [ ! -f /tmp/gh-aw/agent_output.json ]; then
echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
fi
+ - name: Commit cache-memory changes
+ if: always()
+ env:
+ GH_AW_CACHE_DIR: /tmp/gh-aw/cache-memory
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/commit_cache_memory_git.sh"
+ - name: Upload cache-memory data as artifact
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ if: always()
+ with:
+ name: cache-memory
+ path: /tmp/gh-aw/cache-memory
- name: Upload agent artifacts
if: always()
continue-on-error: true
@@ -924,6 +1029,7 @@ jobs:
- agent
- detection
- safe_outputs
+ - update_cache_memory
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true')
@@ -1324,3 +1430,54 @@ jobs:
/tmp/gh-aw/temporary-id-map.json
if-no-files-found: ignore
+ update_cache_memory:
+ needs:
+ - activation
+ - agent
+ - detection
+ if: >
+ always() && (needs.detection.result == 'success' || needs.detection.result == 'skipped') &&
+ needs.agent.result == 'success'
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ env:
+ GH_AW_WORKFLOW_ID_SANITIZED: dailyfact
+ steps:
+ - name: Checkout actions folder
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ repository: github/gh-aw
+ sparse-checkout: |
+ actions
+ persist-credentials: false
+ - name: Setup Scripts
+ id: setup
+ uses: ./actions/setup
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ trace-id: ${{ needs.activation.outputs.setup-trace-id }}
+ - name: Download cache-memory artifact (default)
+ id: download_cache_default
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+ continue-on-error: true
+ with:
+ name: cache-memory
+ path: /tmp/gh-aw/cache-memory
+ - name: Check if cache-memory folder has content (default)
+ id: check_cache_default
+ shell: bash
+ run: |
+ if [ -d "/tmp/gh-aw/cache-memory" ] && [ "$(ls -A /tmp/gh-aw/cache-memory 2>/dev/null)" ]; then
+ echo "has_content=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "has_content=false" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Save cache-memory to cache (default)
+ if: steps.check_cache_default.outputs.has_content == 'true'
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: memory-none-nopolicy-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }}
+ path: /tmp/gh-aw/cache-memory
+
diff --git a/.github/workflows/daily-fact.md b/.github/workflows/daily-fact.md
index 284e56daf73..1acd84e18eb 100644
--- a/.github/workflows/daily-fact.md
+++ b/.github/workflows/daily-fact.md
@@ -37,6 +37,7 @@ safe-outputs:
run-failure: "🌧️ Alas! [{workflow_name}]({run_url}) {status}, its quill fallen mid-verse. The poem remains unfinished..."
imports:
- shared/observability-otlp.md
+ - shared/mcp/mempalace.md
---
{{#runtime-import? .github/shared-instructions.md}}
@@ -45,6 +46,14 @@ imports:
Your task is to post a poetic, whimsical fact about the ${{ github.repository }} project to discussion #4750.
+## Step 0: Load Memory
+
+Before gathering repository activity, check what has already been celebrated in the palace to avoid repetition.
+
+1. Call `mempalace_status` to confirm the palace is ready.
+2. Call `mempalace_search` with `query: "gh-aw daily fact"` to retrieve the most recent facts that have been posted (wing: `daily-facts`, if already indexed).
+3. Note any PR numbers, issue numbers, release tags, or contributor handles that appear in the results — **do not repeat those topics today**.
+
## Data Sources
Mine recent activity from the repository to find interesting facts. Focus on:
@@ -67,6 +76,7 @@ Mine recent activity from the repository to find interesting facts. Focus on:
## Guidelines
+- **Check memory first**: Skip any PR, issue, or release that already appears in the palace results from Step 0
- **Favor recent updates** but include variety - pick something interesting, not just the most recent
- **Be specific**: Include PR numbers, issue references, or release tags when relevant
- **Keep it short**: One or two poetic sentences for the main fact, optionally with a brief context
@@ -99,6 +109,17 @@ Bad facts:
- "There were some changes." (not specific, uninspired)
- Long paragraphs (keep it brief and lyrical)
+## Step 3: Save to Memory
+
+After posting the comment, store the fact in the palace so it will be excluded from future runs:
+
+Call `mempalace_add_drawer` with:
+- `wing`: `"daily-facts"`
+- `room`: the type of fact (e.g., `"pr"`, `"release"`, `"issue"`, `"contributor"`)
+- `content`: a short record containing the PR/issue/release identifier and a one-line summary of the fact posted today
+
+This ensures tomorrow's verse celebrates something new.
+
Now, analyze the recent activity and compose one poetic fact to share in discussion #4750.
**Important**: If no action is needed after completing your analysis, you **MUST** call the `noop` safe-output tool with a brief explanation. Failing to call any safe-output tool is the most common cause of safe-output workflow failures.
From 5f450f9703df6fecf4edb303bd5685ff163839b0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 13 Apr 2026 23:19:17 +0000
Subject: [PATCH 4/4] Clarify mempalace wing/room usage in daily-fact prompt
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/b5ef527a-4579-4126-81cb-3c04ba3d16b7
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/workflows/daily-fact.lock.yml | 35 +++++++++++++++------------
.github/workflows/daily-fact.md | 9 +++++--
2 files changed, 27 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml
index 7ba99ed7431..ef731a4f460 100644
--- a/.github/workflows/daily-fact.lock.yml
+++ b/.github/workflows/daily-fact.lock.yml
@@ -1,4 +1,4 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b08ee72b7ae7225e4dd2702f9125605eff9489e4dd1c789d6604d9db4e726569","strict":true,"agent_id":"codex","agent_model":"gpt-5.1-codex-mini"}
+# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"b3670a8831ed5d250baf423d20648de5f58f3be722cdf671142cc2f4fca9c7b6","strict":true,"agent_id":"codex","agent_model":"gpt-5.1-codex-mini"}
# gh-aw-manifest: {"version":1,"secrets":["CODEX_API_KEY","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"373c709c69115d41ff229c7e5df9f8788daa9553","version":"v9"},{"repo":"actions/setup-node","sha":"53b83947a5a98c8d113130e565377fae1a50d02f","version":"v6.3.0"},{"repo":"actions/setup-python","sha":"a309ff8b426b58ec0e2a45f0f869d46889d02405","version":"v6.2.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20","digest":"sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.25.20@sha256:9161f2415a3306a344aca34dd671ee69f122317e0a512e66dc64c94b9c508682"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20","digest":"sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.20@sha256:6971639e381e82e45134bcd333181f456df3a52cd6f818a3e3d6de068ff91519"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20","digest":"sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.25.20@sha256:5411d903f73ee597e6a084971c2adef3eb0bd405910df3ed7bf5e3d6bd58a236"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.19","digest":"sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.2.19@sha256:44d4d8de7e6c37aaea484eba489940c52df6a0b54078ddcbc9327592d5b3c3dd"},{"image":"ghcr.io/github/github-mcp-server:v0.32.0","digest":"sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28","pinned_image":"ghcr.io/github/github-mcp-server:v0.32.0@sha256:2763823c63bcca718ce53850a1d7fcf2f501ec84028394f1b63ce7e9f4f9be28"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]}
# ___ _ _
# / _ \ | | (_)
@@ -182,15 +182,15 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
+ cat << 'GH_AW_PROMPT_1a67feaf245becf7_EOF'
- GH_AW_PROMPT_583d5a63d6d337f1_EOF
+ GH_AW_PROMPT_1a67feaf245becf7_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
+ cat << 'GH_AW_PROMPT_1a67feaf245becf7_EOF'
Tools: add_comment, missing_tool, missing_data, noop
@@ -222,9 +222,9 @@ jobs:
{{/if}}
- GH_AW_PROMPT_583d5a63d6d337f1_EOF
+ GH_AW_PROMPT_1a67feaf245becf7_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_583d5a63d6d337f1_EOF'
+ cat << 'GH_AW_PROMPT_1a67feaf245becf7_EOF'
@@ -239,7 +239,7 @@ jobs:
Before gathering repository activity, check what has already been celebrated in the palace to avoid repetition.
1. Call `mempalace_status` to confirm the palace is ready.
- 2. Call `mempalace_search` with `query: "gh-aw daily fact"` to retrieve the most recent facts that have been posted (wing: `daily-facts`, if already indexed).
+ 2. Call `mempalace_search` with `query: "gh-aw daily fact"` and `wing: "daily-facts"` to retrieve recently posted facts. On the very first run the palace will be empty — that is fine, proceed without results.
3. Note any PR numbers, issue numbers, release tags, or contributor handles that appear in the results — **do not repeat those topics today**.
## Data Sources
@@ -303,7 +303,12 @@ jobs:
Call `mempalace_add_drawer` with:
- `wing`: `"daily-facts"`
- - `room`: the type of fact (e.g., `"pr"`, `"release"`, `"issue"`, `"contributor"`)
+ - `room`: the category of the fact — use one of these canonical values:
+ - `"pr"` — a merged pull request
+ - `"release"` — a release or version tag
+ - `"issue"` — a closed issue
+ - `"contributor"` — a community contributor highlight
+ - `"pattern"` — a code pattern or architectural observation
- `content`: a short record containing the PR/issue/release identifier and a one-line summary of the fact posted today
This ensures tomorrow's verse celebrates something new.
@@ -316,7 +321,7 @@ jobs:
{"noop": {"message": "No action needed: [brief explanation of what was analyzed and why]"}}
```
- GH_AW_PROMPT_583d5a63d6d337f1_EOF
+ GH_AW_PROMPT_1a67feaf245becf7_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@373c709c69115d41ff229c7e5df9f8788daa9553 # v9
@@ -531,9 +536,9 @@ jobs:
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_2a05655400b7b95a_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_a0659c0401bd349c_EOF'
{"add_comment":{"max":1,"target":"4750"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_2a05655400b7b95a_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_a0659c0401bd349c_EOF
- name: Write Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -712,7 +717,7 @@ jobs:
export GH_AW_ENGINE="codex"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.2.19'
- cat > /tmp/gh-aw/mcp-config/config.toml << GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
+ cat > /tmp/gh-aw/mcp-config/config.toml << GH_AW_MCP_CONFIG_eb2e9cfae7244675_EOF
[history]
persistence = "none"
@@ -741,10 +746,10 @@ jobs:
[mcp_servers.safeoutputs."guard-policies".write-sink]
accept = ["*"]
- GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
+ GH_AW_MCP_CONFIG_eb2e9cfae7244675_EOF
# Generate JSON config for MCP gateway
- cat << GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
+ cat << GH_AW_MCP_CONFIG_eb2e9cfae7244675_EOF | bash "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh"
{
"mcpServers": {
"github": {
@@ -828,7 +833,7 @@ jobs:
}
}
}
- GH_AW_MCP_CONFIG_aa72838dac2fdc49_EOF
+ GH_AW_MCP_CONFIG_eb2e9cfae7244675_EOF
- name: Download activation artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
diff --git a/.github/workflows/daily-fact.md b/.github/workflows/daily-fact.md
index 1acd84e18eb..c887d1565c9 100644
--- a/.github/workflows/daily-fact.md
+++ b/.github/workflows/daily-fact.md
@@ -51,7 +51,7 @@ Your task is to post a poetic, whimsical fact about the ${{ github.repository }}
Before gathering repository activity, check what has already been celebrated in the palace to avoid repetition.
1. Call `mempalace_status` to confirm the palace is ready.
-2. Call `mempalace_search` with `query: "gh-aw daily fact"` to retrieve the most recent facts that have been posted (wing: `daily-facts`, if already indexed).
+2. Call `mempalace_search` with `query: "gh-aw daily fact"` and `wing: "daily-facts"` to retrieve recently posted facts. On the very first run the palace will be empty — that is fine, proceed without results.
3. Note any PR numbers, issue numbers, release tags, or contributor handles that appear in the results — **do not repeat those topics today**.
## Data Sources
@@ -115,7 +115,12 @@ After posting the comment, store the fact in the palace so it will be excluded f
Call `mempalace_add_drawer` with:
- `wing`: `"daily-facts"`
-- `room`: the type of fact (e.g., `"pr"`, `"release"`, `"issue"`, `"contributor"`)
+- `room`: the category of the fact — use one of these canonical values:
+ - `"pr"` — a merged pull request
+ - `"release"` — a release or version tag
+ - `"issue"` — a closed issue
+ - `"contributor"` — a community contributor highlight
+ - `"pattern"` — a code pattern or architectural observation
- `content`: a short record containing the PR/issue/release identifier and a one-line summary of the fact posted today
This ensures tomorrow's verse celebrates something new.