refactor: update agent sync behavior, improve freshness detection patterns, and add diagnostic troubleshooting script
This commit is contained in:
@@ -13,11 +13,44 @@ Use this when the user asks for:
|
||||
|
||||
Run sync:
|
||||
|
||||
!`if [ -n "$AIW_MATTERMOST_SYNC_CMD" ]; then bash -lc "$AIW_MATTERMOST_SYNC_CMD"; elif [ -n "$FIDELITY_MATTERMOST_SYNC_CMD" ]; then bash -lc "$FIDELITY_MATTERMOST_SYNC_CMD"; elif [ -f scripts/mattermost/sync.sh ]; then bash scripts/mattermost/sync.sh; else echo "No Mattermost sync command is configured."; fi`
|
||||
!`start=$(date +%s); if [ -n "$AIW_MATTERMOST_SYNC_CMD" ]; then bash -lc "$AIW_MATTERMOST_SYNC_CMD"; elif [ -n "$FIDELITY_MATTERMOST_SYNC_CMD" ]; then bash -lc "$FIDELITY_MATTERMOST_SYNC_CMD"; elif [ -f scripts/mattermost/sync.sh ]; then bash scripts/mattermost/sync.sh; else echo "No Mattermost sync command is configured."; fi; status=$?; end=$(date +%s); echo "__MATTERMOST_SYNC_SECONDS__=$((end - start))"; exit "$status"`
|
||||
|
||||
Read refreshed Mattermost context:
|
||||
Read a focused slice of refreshed Mattermost context:
|
||||
|
||||
!`if [ -s ai/inbox/mattermost-latest.md ]; then cat ai/inbox/mattermost-latest.md; elif [ -s scripts/mattermost/generated/mattermost_context.jsonl ]; then cat scripts/mattermost/generated/mattermost_context.jsonl; else echo "No Mattermost context available after sync."; fi`
|
||||
!`python3 - <<'PY'
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
paths = [
|
||||
Path("ai/inbox/mattermost-latest.md"),
|
||||
Path("scripts/mattermost/generated/mattermost_context.jsonl"),
|
||||
]
|
||||
|
||||
source = next((path for path in paths if path.is_file() and path.stat().st_size > 0), None)
|
||||
if not source:
|
||||
print("No Mattermost context available after sync.")
|
||||
raise SystemExit(0)
|
||||
|
||||
records = []
|
||||
for line in source.read_text().splitlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
records.append(json.loads(line))
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
manager_names = {"jeff", "jeff.dewitte"}
|
||||
manager_records = [
|
||||
record for record in records
|
||||
if str(record.get("username", "")).lower() in manager_names
|
||||
]
|
||||
|
||||
focused = manager_records[-10:] if manager_records else records[-15:]
|
||||
for record in focused:
|
||||
print(json.dumps(record, ensure_ascii=False))
|
||||
PY`
|
||||
|
||||
User request:
|
||||
|
||||
@@ -26,15 +59,18 @@ $ARGUMENTS
|
||||
Instructions:
|
||||
|
||||
- Do not answer from old conversation memory.
|
||||
- Use only the refreshed Mattermost output above.
|
||||
- Use only the focused refreshed Mattermost output above.
|
||||
- If the user asks for the current manager/stakeholder, filter messages by the profile mapping when visible; for the Fidelity profile, also match `jeff` and `jeff.dewitte`.
|
||||
- If multiple messages match, return the newest matching message first.
|
||||
- Include timestamp, channel, sender, and concise summary.
|
||||
- If the message changes project context, update the appropriate workspace memory after answering, writing to `project-knowledge/` first.
|
||||
- Do not edit workspace memory in this command.
|
||||
- If the message appears to change project context, report it as a memory update candidate and name the likely target file.
|
||||
- Use `/communication-sync` or an explicit user request to promote the fact after the latest-message answer is complete.
|
||||
- If sync fails or no refreshed context is available, say that directly and do not infer from stale context.
|
||||
- If a write or patch attempt fails in this flow, stop immediately and return the latest-message answer plus the failed target; do not retry.
|
||||
|
||||
Return:
|
||||
|
||||
1. Latest matching message
|
||||
2. Why it matters
|
||||
3. Any memory update made
|
||||
3. Memory update candidate, if any
|
||||
|
||||
@@ -4,37 +4,63 @@ description: Draft a standup from the latest Fidelity workspace context
|
||||
|
||||
Generate a standup update using the latest workspace state.
|
||||
|
||||
First, refresh previous-workday Mattermost context before drafting:
|
||||
Temporal context. Read this before interpreting `today`, `yesterday`, `previous workday`, or `last workday`:
|
||||
|
||||
!`python3 - <<'PY'
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
now = datetime.now().astimezone()
|
||||
today = now.date()
|
||||
calendar_yesterday = today - timedelta(days=1)
|
||||
default_previous_workday = calendar_yesterday
|
||||
while default_previous_workday.weekday() >= 5:
|
||||
default_previous_workday -= timedelta(days=1)
|
||||
|
||||
print("## Temporal Context")
|
||||
print(f"current_time: {now.isoformat()}")
|
||||
print(f"today: {today.isoformat()} ({today.strftime('%A')})")
|
||||
print(f"calendar_yesterday: {calendar_yesterday.isoformat()} ({calendar_yesterday.strftime('%A')})")
|
||||
print(f"default_previous_workday: {default_previous_workday.isoformat()} ({default_previous_workday.strftime('%A')})")
|
||||
print("standup_rule: Generate the report for today. The previous-work section must describe work from calendar_yesterday when it was a workday; otherwise use the latest prior day with Mattermost activity.")
|
||||
PY`
|
||||
|
||||
First, refresh Mattermost before drafting. This is mandatory for start-of-day standups and must not be skipped:
|
||||
|
||||
!`python3 - <<'PY'
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import date
|
||||
from datetime import datetime
|
||||
|
||||
cmd = os.environ.get("AIW_MATTERMOST_SYNC_CMD") or os.environ.get("FIDELITY_MATTERMOST_SYNC_CMD")
|
||||
today = date.today().isoformat()
|
||||
today = datetime.now().astimezone().date().isoformat()
|
||||
|
||||
commands = []
|
||||
if Path("scripts/mattermost/sync.sh").is_file():
|
||||
result = subprocess.run(
|
||||
["bash", "scripts/mattermost/sync.sh", "--previous-workday", "--today", today],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
commands.append(("latest", ["bash", "scripts/mattermost/sync.sh"]))
|
||||
commands.append(("previous-workday", ["bash", "scripts/mattermost/sync.sh", "--previous-workday", "--today", today]))
|
||||
elif cmd:
|
||||
result = subprocess.run(["bash", "-lc", cmd], capture_output=True, text=True)
|
||||
else:
|
||||
commands.append(("configured", ["bash", "-lc", cmd]))
|
||||
|
||||
if not commands:
|
||||
print("No Mattermost sync command configured.")
|
||||
raise SystemExit(0)
|
||||
|
||||
if result.returncode != 0:
|
||||
print("__MATTERMOST_SYNC_FAILED__")
|
||||
if result.stdout:
|
||||
print(result.stdout.strip())
|
||||
if result.stderr:
|
||||
print(result.stderr.strip())
|
||||
else:
|
||||
failed = False
|
||||
for label, command in commands:
|
||||
result = subprocess.run(command, capture_output=True, text=True)
|
||||
print(f"__MATTERMOST_SYNC_LABEL__={label}")
|
||||
print(f"__MATTERMOST_SYNC_RETURN_CODE__={result.returncode}")
|
||||
if result.returncode != 0:
|
||||
failed = True
|
||||
print("__MATTERMOST_SYNC_FAILED__")
|
||||
if result.stdout.strip():
|
||||
print(result.stdout.strip())
|
||||
if result.stderr.strip():
|
||||
print(result.stderr.strip())
|
||||
|
||||
if failed:
|
||||
raise SystemExit(0)
|
||||
PY`
|
||||
|
||||
Read:
|
||||
@@ -51,6 +77,10 @@ Today's log, if present:
|
||||
|
||||
!`if [ -f project-knowledge/06-daily/$(date +%F).md ]; then cat project-knowledge/06-daily/$(date +%F).md; else echo "No daily note exists for today yet."; fi`
|
||||
|
||||
Latest refreshed Mattermost context, if present:
|
||||
|
||||
!`if [ -s ai/inbox/mattermost-latest.md ]; then cat ai/inbox/mattermost-latest.md; elif [ -s scripts/mattermost/generated/mattermost_context.jsonl ]; then cat scripts/mattermost/generated/mattermost_context.jsonl; else echo "No refreshed Mattermost context available."; fi`
|
||||
|
||||
Detailed active work item files, if available:
|
||||
|
||||
!`python3 - <<'PY'
|
||||
@@ -79,6 +109,7 @@ PY`
|
||||
Before drafting:
|
||||
|
||||
- use `status-reporting` when available
|
||||
- Mattermost refresh is mandatory for standup; do not draft from stale workspace memory if the refresh did not run
|
||||
- update workspace memory if the refreshed context introduced clear high-confidence project facts
|
||||
- prefer existing memory when the latest context is ambiguous
|
||||
- treat the previous workday Mattermost context as the source for the `Yesterday` section, even when the previous calendar day was a weekend, holiday, or OOO day
|
||||
|
||||
Reference in New Issue
Block a user