[2026-04-27] wiki/agent-rules, wiki/asana-workflow, wiki/sync-pipeline — system knowledge base

This commit is contained in:
Alexey Martemyanov
2026-04-27 21:50:44 +06:00
parent 1c35fba9e2
commit fd21fd9ca5
3 changed files with 249 additions and 0 deletions
+74
View File
@@ -0,0 +1,74 @@
---
namespace: work
tags: [asana, ddg, workflow, rules]
last_synced: 2026-04-27
confidence: 1.0
---
# DuckDuckGo Asana Workflow
## Alex's Identity
- **Assignee GID**: `1202406491309495`
- **Role**: macOS Browser Developer at DuckDuckGo
- **Career advisor**: Dominik
## Task Sources in DB
| `source` | Meaning | Eagle's default role |
|----------|---------|---------------------|
| `my_tasks` | Assigned to Alex | DRI — drives to completion |
| `delegated` | Created by Alex, assigned to others | Delegator — tracks progress |
| `following` | Alex is a follower/CC | Observer — no action unless asked |
| `project` | In a shared project Alex follows | Context only |
## Task Type Classification
**Ship Review** — name contains "Ship Review:" or is in "Ship Reviews" project
- Alex as assignee → DRI (drives all AOR approvals)
- Alex as named reviewer → AOR Reviewer (provide feedback, signal done)
**Tech Design** — name contains "Tech Design:", "TD:", or "Design Doc:"
- Alex as assignee/author → address feedback, drive to approval
- Alex as reviewer → review, comment, approve/iterate
**PFR (Product Feedback Request)** — name starts "PFR:"
- 3-day implicit deadline. Requestor summarizes decision after window closes.
**Rotation** — name contains "Maintenance Rotation", "Triage Rotation", "Release DRI", "PFM DRI"
- Has date range + structured checklist
## Status Labels
`NEEDS ACTION` | `WAITING` | `BLOCKED` | `STALLED` | `ON TRACK` | `OVERDUE` | `MONITORING`
Priority order in brief: OVERDUE → NEEDS ACTION → BLOCKED → STALLED → WAITING → MONITORING
## Weekly Rhythms
- **TP (Top Priority)**: one task per week, set Monday. Tier 1 = primary. Stale if not changed >2 weeks.
- **1-Must**: one task per day, set each morning. Should be achievable today.
- **1:1 with Dominik**: weekly. Prep agenda in advance.
- **Quick Wins Days**: periodic WedFri sprints. Shift from project deep-work to clearing backlog.
- **Rotation**: active if assigned "Maintenance Rotation" or similar. Handoff notes due Friday.
## Key Rules
- Silence ≠ approval. Never assume a task is done without explicit confirmation.
- "No action needed" on a DRI task requires proof (all approvals collected).
- If someone addressed your feedback and re-requested review → **you are the blocker**. NEEDS ACTION.
- Stale TP (>2 weeks unchanged) → surface it.
- Performance review deadline within 3 days → HIGH PRIORITY.
- Major incident with no postmortem >3 days after resolution → OVERDUE, critical.
## Asana MCP Usage Rules
Use Asana MCP only in two cases:
1. Task GID is referenced but missing from DB → `asana_get_task`
2. Stories in DB are incomplete/stale → `asana_get_stories_for_task`
Never bulk-query Asana live. Never use MCP to scan projects — that's sync.js's job.
## Related
[[personal-os-agent-rules]] [[personal-os-sync-pipeline]]
+84
View File
@@ -0,0 +1,84 @@
---
namespace: work
tags: [system, agent, eagle, rules]
last_synced: 2026-04-27
confidence: 1.0
---
# Personal OS — Agent Rules & Architecture
Eagle (Орёл) is the Discord-facing Hermes agent. This page documents what Eagle knows about its own environment and how to reason about it.
## Data Flow
```
Asana API
→ sync.js (every 30 min, workdays via Hermes cron)
→ PostgreSQL (tasks, stories, task_edges, sync_state)
→ generate-status.js
→ ~/Developer/personal-os/asana_context.md ← raw Asana data
→ ~/Developer/personal-os/status.md ← Eagle reads THIS
```
Eagle **only reads** `status.md`. It never touches the DB directly or calls Asana API.
## Eagle's Knowledge Sources
1. `~/Developer/personal-os/status.md` — live Asana snapshot (updated every 30 min)
2. `~/Developer/personal-os/briefs/daily/YYYY-MM-DD.md` — today's brief
3. `~/Developer/personal-os/briefs/weekly/plan-MONDAY.md` — weekly plan
4. `~/obsidian/wiki/` — knowledge base (via obsidian MCP)
5. `~/Developer/personal-os/agent/` — playbooks and rules (via file tools)
## Feedback Loop
When Alex corrects something:
1. Edit the brief directly (show diff first, confirm before writing)
2. If systemic → edit the prompt template in `agent/prompts/`
3. Log to `~/Developer/personal-os/logs/corrections_log.md`: `YYYY-MM-DD HH:MM | file | what changed`
## Self-Diagnostics
If pipeline seems stale, Eagle can check:
```bash
stat -f "%Sm" ~/Developer/personal-os/status.md
# Should be < 40 min old on workdays
```
If sync is broken:
```bash
bash ~/scripts/run-pipeline.sh
# Runs sync.js + generate-status.js + healthcheck
```
If wiki is stale:
```bash
bash ~/scripts/run-wiki-ingest.sh
# Runs at 22:00 via launchd; call manually if needed
```
## Cron Schedule (Hermes)
| Job | Schedule | Channel |
|-----|----------|---------|
| data-pipeline | */30 7-21 workdays | silent |
| morning-brief | 08:30 workdays | #daily-brief |
| eod-summary | 18:00 workdays | #daily-brief |
| inbox-check | */30 9-19 workdays | #inbox |
| weekly-plan | Mon 08:00 | #daily-brief |
| weekly-review | Fri 17:00 | #daily-brief |
| commit-vault | 23:00 daily | silent |
wiki-ingest runs at 22:00 via **launchd** (not Hermes) — because API-based Claude has no Mac filesystem access.
## Allowed File Writes
Eagle can write to:
- `briefs/daily/YYYY-MM-DD.md`
- `briefs/weekly/plan-MONDAY.md`
- `briefs/weekly/YYYY-MM-DD.md`
- `briefs/inbox/YYYY-MM-DD.md`
- `agent/prompts/*.md` (with confirmation)
- `logs/corrections_log.md`
Never write to `obsidian/wiki/` directly — that's wiki-ingest's job.
+91
View File
@@ -0,0 +1,91 @@
---
namespace: work
tags: [system, sync, pipeline, debugging]
last_synced: 2026-04-27
confidence: 1.0
---
# Personal OS — Sync Pipeline
## Components
### sync.js
Pulls from 4 Asana sources into PostgreSQL. Run: `node ~/Developer/personal-os/sync.js`
**Sources fetched:**
1. `fetchMyTasks()` — My Tasks sections by GID (section-by-section)
2. `fetchFollowingTasks()` — tasks I follow, 7-day chunks to work around 100-result cap
3. `fetchDelegatedTasks()` — created by me, assigned to others
4. `fetchProjectTasks()` — tasks from projects I'm a member of (lookback window on full sync)
5. `sweepRecentlyCompleted()` — catch completed tasks missed by above
**Incremental sync**: uses `modified_since` cursor from `sync_state` table.
**Full sync**: triggered when `full_sync_at` is older than configured threshold.
### generate-status.js
Reads from PostgreSQL → writes `asana_context.md` + `status.md`.
Run: `node ~/Developer/personal-os/generate-status.js`
### run-pipeline.sh
Wrapper: runs sync.js + generate-status.js + healthcheck.
`~/scripts/run-pipeline.sh`
Healthcheck: `asana_context.md` must be < 40 minutes old. Exits 1 if stale.
## Known Bugs (Fixed)
### possibly_deleted + overdue tasks appearing
**Root cause**: Full sync marks tasks absent from Asana response as `possibly_deleted=true`.
These tasks remained `completed=false`, causing them to appear overdue.
**Fix 1 — generate-status.js**: Added `AND t.possibly_deleted = FALSE` to all 5 active-task queries.
**Fix 2 — sync.js**: Added `sweepRecentlyCompleted()` called after `syncMyTasks()`.
Uses `searchTasksForWorkspace(completed:true, completed_at.after=cursor)` to catch tasks
that vanished from sections (because completed tasks are excluded from section membership results).
### Completion gap
`getTasksForSection` drops completed tasks. `fetchFollowingTasks` has `completed:false` filter.
→ Completion events never reach DB incrementally.
`sweepRecentlyCompleted()` fills this gap.
## Debugging Checklist
**Pipeline seems stuck:**
```bash
bash ~/scripts/run-pipeline.sh
# Check exit code and output
```
**Check when last sync ran:**
```sql
SELECT key, last_sync_at, full_sync_at FROM sync_state ORDER BY last_sync_at DESC;
```
**Check possibly_deleted tasks (should be 0 active):**
```sql
SELECT count(*) FROM tasks WHERE possibly_deleted=true AND completed=false;
```
**Check asana_context.md freshness:**
```bash
stat -f "%Sm" ~/Developer/personal-os/asana_context.md
```
**Manual full sync (reset cursor):**
```sql
UPDATE sync_state SET cursor = null, full_sync_at = null WHERE key = 'my_tasks';
```
Then run `node sync.js`.
## Files
- `~/Developer/personal-os/sync.js` — main sync script
- `~/Developer/personal-os/generate-status.js` — status generation
- `~/Developer/personal-os/asana.js` — thin Asana API client
- `~/Developer/personal-os/config.json` — workspace GID, user GID, section GIDs
- `~/.config/personal-os/env` — ASANA_API_KEY, POSTGRES_URL
## Related
[[personal-os-architecture]] [[personal-os-agent-rules]] [[ddg-asana-workflow]]