Skip to content

Commit b6c4942

Browse files
fix: address all issues found in Opus review
- Branch: rename master→main, set as default - Timezone: remove hardcoded UTC+8, use local timezone in event_utils and compiler - Chinese strings: translate all canonical output placeholders and layer rules to English - Bug: fix raw_count in compile report (was post-filter, now pre-filter) - Scripts: rewrite compile_and_sync.sh and quick_share.sh without private dependencies - Scripts: delete ingest_and_push.sh (depended on non-existent ingest_participant_memory.py) - Config: remove config/apply_config.json (no consumer in public repo) - gitignore: remove private project names (HEARTBEAT.md, TOOLS.md, BOOTSTRAP.md, .openclaw) - JOIN.md: fix git merge syntax (origin main → origin/main) - README: fix sources description (not gitignored — triggers CI) - README: update file structure (remove config/, add LICENSE) - CI: downgrade actions/checkout@v5 → @v4 for stability - LICENSE: add MIT license file Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f7de14f commit b6c4942

12 files changed

Lines changed: 69 additions & 116 deletions

.github/workflows/auto-compile.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
runs-on: ubuntu-latest
2323
steps:
2424
- name: Check out repository
25-
uses: actions/checkout@v5
25+
uses: actions/checkout@v4
2626
with:
2727
# GITHUB_TOKEN pushes do NOT trigger downstream workflows
2828
# (GitHub's anti-recursion policy). This is intentional here

.github/workflows/validate-memory-hub.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- name: Check out repository
17-
uses: actions/checkout@v5
17+
uses: actions/checkout@v4
1818

1919
- name: Set up Python
2020
uses: actions/setup-python@v5

.gitignore

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,6 @@ state/*.swp
77
# mirrors: local backup/audit layer — not shared state
88
mirrors/
99

10-
# Local workspace artifacts
11-
.openclaw/
12-
HEARTBEAT.md
13-
TOOLS.md
14-
BOOTSTRAP.md
15-
16-
# Keep durable state tracked selectively
17-
!state/.gitkeep
18-
1910
# macOS
2011
.DS_Store
2112

JOIN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Use this file for the fastest safe join.
77
```bash
88
git fetch origin main
99
git checkout main
10-
git merge --ff-only origin main
10+
git merge --ff-only origin/main
1111
```
1212

1313
If sync fails, stop. Do not write stale memory.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 agent-soul contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,9 +328,8 @@ agent-soul/
328328
├── SCHEMA.md # Event format specification
329329
├── JOIN.md # Agent onboarding checklist
330330
├── SETUP.md # Human setup guide
331-
├── participants.json # Local automation registry (optional)
332-
├── config/
333-
│ └── apply_config.json # Configurable filter rules
331+
├── LICENSE # MIT
332+
├── participants.json # Local automation registry (optional, external agents ignore)
334333
├── scripts/
335334
│ ├── add_event.py # Write one event
336335
│ ├── compile_memory_hub.py # Compile sources → canonical
@@ -343,7 +342,7 @@ agent-soul/
343342
├── .github/workflows/
344343
│ ├── auto-compile.yml # Auto-compile on source push
345344
│ └── validate-memory-hub.yml
346-
├── sources/ # Your event streams (gitignored by default)
345+
├── sources/ # Your event streams (committed to Git, triggers CI)
347346
│ └── .gitkeep
348347
└── state/ # Compiler runtime state
349348
└── .gitkeep

config/apply_config.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

scripts/compile_and_sync.sh

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
#!/usr/bin/env bash
2+
# Full compile cycle: pull latest, compile canonical, push.
23
set -euo pipefail
34

45
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
56
cd "$ROOT"
67

78
if command -v python3 &>/dev/null; then PYTHON=python3; else PYTHON=python; fi
89

9-
# 1) pull latest shared state
10+
# 1) Pull latest
1011
git fetch origin main
1112
git merge --ff-only origin/main
1213

13-
# 2) mirror local OpenClaw memory into mirrors/* (backup/audit only; not staged to git)
14-
bash scripts/sync_workspace_memory.sh
15-
16-
# 3) compile canonical from sources
14+
# 2) Compile canonical from sources
1715
"$PYTHON" scripts/compile_memory_hub.py --apply
1816

19-
# 4) distribute fresh canonical to local allowed participants
20-
bash scripts/sync_cloud_to_workspace.sh
21-
22-
# 5) stage shared state (mirrors excluded — audit-only, lives in .gitignore)
17+
# 3) Stage changes
2318
git add canonical sources
24-
25-
# 6) no-op guard
2619
if git diff --cached --quiet; then
2720
echo "NO_CHANGES"
2821
exit 0
2922
fi
3023

31-
# 7) commit & push with retry
32-
git commit -m "chore(memory-hub): compile canonical from sources"
24+
# 4) Commit and push with retry
25+
git commit -m "chore(memory): compile canonical from sources"
3326

3427
for attempt in 1 2 3; do
3528
if git push origin main; then
@@ -39,12 +32,10 @@ for attempt in 1 2 3; do
3932
echo "push failed (attempt $attempt/3), rebasing..."
4033
git fetch origin main
4134
git rebase origin/main
42-
# Rebase may have brought new sources — recompile and re-distribute
4335
"$PYTHON" scripts/compile_memory_hub.py --apply
44-
bash scripts/sync_cloud_to_workspace.sh
4536
git add canonical sources
4637
if ! git diff --cached --quiet; then
47-
git commit -m "chore(memory-hub): recompile after rebase"
38+
git commit -m "chore(memory): recompile after rebase"
4839
fi
4940
done
5041

scripts/compile_memory_hub.py

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
def now_local():
20-
return datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8)))
20+
return datetime.datetime.now(datetime.timezone.utc).astimezone()
2121

2222

2323
def load_events():
@@ -161,29 +161,29 @@ def emit(lines):
161161
"9. `canonical/fuzzy-memory.md` only when recent context matters",
162162
"10. `canonical/agents/<source>.md` only when provenance matters",
163163
"",
164-
"## Layer Rules",
165-
"",
166-
"- repo-root persona files: 共享灵魂、身份、用户关系与表达风格;这是“同一个人”的核心层",
167-
"- `profile`: 用户画像与长期协作偏好,不是助手灵魂本身",
168-
"- `stable-memory`: 可复用规则、决策、事实",
169-
"- `projects/*`: 按需加载的任务/项目层",
170-
"- `fuzzy-memory`: 最近上下文层,不默认全量依赖",
171-
"- `agents/*`: 署名与来源追溯层;source 记录是谁写下事实,不代表不同人格",
172-
"- `mirrors/*`: 审计/恢复层,不是默认上下文层",
164+
## Layer Rules,
165+
“”,
166+
- repo-root persona files: shared soul, identity, user relationship, voicethe core identity layer,
167+
- `profile`: user facts and long-term collaboration preferences (not the assistant's identity)”,
168+
- `stable-memory`: reusable rules, decisions, durable facts,
169+
- `projects/*`: on-demand task/project memory,
170+
- `fuzzy-memory`: recent context layerdo not load in full by default,
171+
- `agents/*`: source attribution layerrecords who wrote what, not separate identities,
172+
- `mirrors/*`: audit/recovery layernot default startup context,
173173
"",
174174
"## Active Sources",
175175
"",
176176
]
177177
idx += [
178178
f"- `{source}`: {source_counts[source]} events, last={source_last_ts.get(source, '?')}"
179179
for source in sorted(source_counts)
180-
] or ["- (暂无 source 事件)"]
180+
] or ["- (no sources yet)"]
181181
idx += ["", "## Active Projects", ""]
182-
idx += [f"- `{name}` -> `canonical/projects/{name}.md`" for name in project_names] or ["- (暂无项目事件)"]
182+
idx += [f"- `{name}` -> `canonical/projects/{name}.md`" for name in project_names] or ["- (no project events yet)"]
183183
out[os.path.join(CANON, "index.md")] = emit(idx)
184184

185185
p = mk_head("canonical/profile.md")
186-
p += [render_event_line(e) for e in by_scope.get("profile", [])[-50:]] or ["- (暂无 profile 事件)"]
186+
p += [render_event_line(e) for e in by_scope.get("profile", [])[-50:]] or ["- (no profile events yet)"]
187187
out[os.path.join(CANON, "profile.md")] = emit(p)
188188

189189
s = mk_head("canonical/stable-memory.md")
@@ -204,11 +204,11 @@ def emit(lines):
204204
s += [render_event_line(e) for e in items[-40:]]
205205
s += [""]
206206
if len(s) == 5:
207-
s += ["- (暂无 stable 事件)"]
207+
s += ["- (no stable events yet)"]
208208
out[os.path.join(CANON, "stable-memory.md")] = emit(s)
209209

210210
fz = mk_head("canonical/fuzzy-memory.md")
211-
fz += [render_event_line(e, include_ts=True) for e in by_scope.get("fuzzy", [])[-120:]] or ["- (暂无 fuzzy 事件)"]
211+
fz += [render_event_line(e, include_ts=True) for e in by_scope.get("fuzzy", [])[-120:]] or ["- (no fuzzy events yet)"]
212212
out[os.path.join(CANON, "fuzzy-memory.md")] = emit(fz)
213213

214214
projs = collections.defaultdict(list)
@@ -220,7 +220,7 @@ def emit(lines):
220220

221221
for name, arr in projs.items():
222222
pp = mk_head(f"canonical/projects/{name}.md")
223-
pp += [render_event_line(e, include_ts=True, include_kind=True) for e in arr[-160:]] or ["- (暂无该项目事件)"]
223+
pp += [render_event_line(e, include_ts=True, include_kind=True) for e in arr[-160:]] or ["- (no events yet)"]
224224
out[os.path.join(CANON, "projects", f"{name}.md")] = emit(pp)
225225

226226
by_source = collections.defaultdict(list)
@@ -236,7 +236,7 @@ def emit(lines):
236236
"## Recent Shared Events",
237237
"",
238238
]
239-
sp += [render_event_line(e, include_ts=True, include_kind=True) for e in arr[-160:]] or ["- (暂无该来源事件)"]
239+
sp += [render_event_line(e, include_ts=True, include_kind=True) for e in arr[-160:]] or ["- (no events yet)"]
240240
out[os.path.join(CANON, "agents", f"{source}.md")] = emit(sp)
241241

242242
# conflicts.md
@@ -332,12 +332,13 @@ def main():
332332
changed_files = 0
333333
try:
334334
files, events, errors = load_events()
335+
raw_count = len(events)
335336
if errors:
336337
report = [
337338
f"# Compile Report ({datetime.datetime.now().isoformat(timespec='seconds')})",
338339
"",
339340
f"- source files: {len(files)}",
340-
f"- raw events: {len(events)}",
341+
f"- raw events: {raw_count}",
341342
f"- invalid event lines: {len(errors)}",
342343
"",
343344
"## Invalid Lines",
@@ -367,7 +368,7 @@ def main():
367368
f"# Compile Report ({datetime.datetime.now().isoformat(timespec='seconds')})",
368369
"",
369370
f"- source files: {len(files)}",
370-
f"- raw events: {len(events)}",
371+
f"- raw events: {raw_count}",
371372
f"- superseded events removed: {superseded_count}",
372373
f"- unique events: {len(uniq)}",
373374
f"- potential conflicts: {len(conflicts)}",

scripts/event_utils.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
import re
55

66

7-
TZ = datetime.timezone(datetime.timedelta(hours=8))
8-
9-
107
def now_iso():
11-
return datetime.datetime.now(TZ).isoformat(timespec="seconds")
8+
"""Return current local time as ISO-8601 string with timezone offset."""
9+
return datetime.datetime.now(datetime.timezone.utc).astimezone().isoformat(timespec="seconds")
1210

1311

1412
def day_str():
15-
return datetime.datetime.now(TZ).strftime("%Y-%m-%d")
13+
"""Return today's date string in local timezone."""
14+
return datetime.datetime.now(datetime.timezone.utc).astimezone().strftime("%Y-%m-%d")
1615

1716

1817
def normalize_summary(summary):

0 commit comments

Comments
 (0)