feat(using-projects-meta): v1.1.0 — mandatory Step 0 freshness gate

Cross-machine workflows broke silently when the agent reasoned on a stale
MCP cache, or hit sha-based optimistic-lock 422s on shared-wiki writes
because another host had pushed minutes earlier. Codify the missing
pre-flight as Step 0:

  1. Always probe mcp__projects-meta__meta_status first.
  2. If cache_age_minutes > 10 OR errors_count > 0 → run
     `node ~/.local/projects-meta-mcp/dist/sync.js` before any read.
  3. For shared-wiki WRITES (knowledge_ingest, knowledge_promote) →
     unconditional `git -C ~/projects/projects-wiki pull --ff-only`
     (sha-lock will reject the commit otherwise; failure is opaque).
  4. Tasks-mutations: sync via dist/sync.js is enough (no local clone
     of target tasks repo).
  5. Sync 401/403 → STOP, send user to ~/.config/projects-mcp/auth.toml
     to rotate gitea_token. No silent retry.

10-minute cache window chosen as the read threshold — balances
multi-machine drift detection against unnecessary Gitea round-trips.

Common mistakes + Red flags expanded to call out the new failure modes.
README mirrors the rule for human readers. Wiki concept page
projects-meta-skills.md gets a "Freshness gate (v1.1.0)" subsection.

Closes [using-projects-meta-freshness-gate].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-30 00:33:05 +03:00
parent e744dad46b
commit 6c83a35d6d
7 changed files with 133 additions and 5 deletions

View File

@@ -49,6 +49,32 @@ wiki content. See the table below.
| "Has the **shared** wiki got X?" | `mcp__projects-meta__knowledge_search` |
| "Sync state across machines?" | `mcp__projects-meta__meta_status` |
## Step 0 — Freshness gate (v1.1.0, mandatory pre-flight)
`projects-meta` is a bus between machines — another host may have pushed
minutes ago. Without this gate, reads return stale data and writes hit
sha-based optimistic-lock 422s with no explanation.
Before **any** `tasks_*` or `knowledge_*` call:
1. `mcp__projects-meta__meta_status` — probe cache age + errors.
2. If `cache_age_minutes` > 10 OR `errors_count` > 0 →
`node ~/.local/projects-meta-mcp/dist/sync.js`.
3. For shared-wiki **writes** (`knowledge_ingest`, `knowledge_promote`) →
**also** `git -C ~/projects/projects-wiki pull --ff-only`. Unconditional.
The MCP server uses sha-based optimistic locking on the wiki repo;
without an up-to-date local SHA the commit is rejected with a 422.
4. For tasks-mutations (`tasks_create`/`update`/`close`) → sync via
`dist/sync.js` is enough; there's no local clone of the target tasks repo.
5. If sync returns **401 / 403** → STOP. Token is dead. Send the user to
`~/.config/projects-mcp/auth.toml` to rotate `gitea_token`. Don't
pretend success, don't retry silently.
**Don't sync unconditionally** on every call — overhead + 401-risk for
casual reads. The 10-minute window is the chosen threshold.
**Don't apply Step 0 to `meta_status` itself** — it's the probe.
## Two operation classes
### Read (no confirmation)