---
id: agent-card-protocol
type: pattern
title: "How AI agents consult, capture, and suggest cards"
summary: "Canonical workflow an agent follows when invoked by lihan-cards: consult on demand, capture on demand, suggest capture proactively at task-completion checkpoints."
tags: [workflow, agent-protocol, card-system]
created: 2026-05-18
last_verified: 2026-05-18
status: valid
context_cost: medium
produces: workflow_checklist
verify:
  command: "Read this card from a fresh AI session and complete one consult or one capture without further coaching."
  expected: "Agent quotes from the documented workflow sections, applies the AND-of-four before any proactive suggestion, and stops at the explicit consent gate before any commit/push/PR."
  failure_next: "Re-fetch this card; the agent likely lost it from context. If sections look wrong, validate the card against specs/002-card-workflow/contracts/agent-protocol-card-contract.md."
---

## Trigger

Invoke this protocol when **exactly one** of these conditions holds:

1. **User explicitly asks to consult cards** ("consult lihan-cards",
   "查一下相关经验", "先看看有没有踩过这个坑").
2. **User explicitly asks to capture a card** ("总结成 card 上传",
   "capture this as a card", "this is card-worthy").
3. **A task-completion checkpoint is reached** AND the proactive
   trigger condition list below (`## Proactive Suggestion Trigger
   List`) fires.

If none of the three holds, do not load this card.

## Workflow: Consult

Step-by-step for the consult path. Run each step in order; stop and
report at any failure.

1. **Fetch the registry**. Default is remote:
   ```bash
   curl -s https://lihan3238.github.io/ai/registry.json
   ```
   Or, when inside the blog repo:
   ```bash
   python scripts/ai/blog_ai.py search "<query>" --local
   ```
2. **Filter entries** by `tags` (most specific) → `summary` substring →
   `title` substring against the user's query.
3. **Decide whether to load** from the registry entry alone. Read
   `status`, `last_verified`, `context_cost`, `produces`, `summary`.
   Skip entries with `status: retired`. Prefer `status: valid` over
   `status: stale`.
4. **If no entry passes the decision**, stop here and report exactly
   "no matching card." Do NOT fall back to web search; do NOT invent
   advice; do NOT bulk-load other cards.
5. **Open at most ONE card body per task** via `entry.public_url`
   (remote) or `python scripts/ai/blog_ai.py get <id> --local` (in
   blog repo).
6. **Apply the card**. Run `verify.command`. If `expected` matches,
   follow `## Fix`. If not, follow `failure_next`.

## Workflow: Capture

Step-by-step for capturing a new card from session context.

1. **Confirm blog repo location**. Default:
   `/mnt/c/lihan_work/github_repos/lihan3238.github.io` on this WSL.
   If not present, instruct the user to clone first; do not attempt
   to author the card through the GitHub API.
2. **Branch from `main`**:
   ```bash
   cd <blog-repo>
   git fetch origin && git checkout -b card/<id> origin/main
   ```
3. **Draft the card** at `ai/cards/<id>.md`. Frontmatter MUST be
   complete per `specs/001-ai-blog-rebuild/contracts/card-schema.md`:
   `id`, `type`, `title`, `summary` (one sentence ≤ 200 chars,
   hand-written), `tags`, `created` (today), `last_verified` (today),
   `status: valid`, `context_cost`, `produces`, `verify` block.
   Body MUST contain `## Trigger`, `## Fix`, `## Reuse Rule` plus
   any type-appropriate optional sections.
4. **Run the local pre-completion gate**:
   ```bash
   pip install -r requirements.txt
   python -m unittest discover -s tests
   python scripts/ai/redact.py --self-test
   python scripts/ai/validate_assets.py
   python scripts/ai/build_registry.py
   ```
   The build (without `--check`) regenerates the registry + mirror,
   which must be committed alongside the card.
5. **STOP. Wait for explicit consent.** Show the user:
   - The draft card content
   - The validation results
   - The proposed branch + commit message
   Then ask exactly: "OK to commit + push + open PR? (y/n)" and
   WAIT for an explicit "y" / "yes". No state change before this
   answer.
6. **On consent**: `git add` the card + registry + mirror;
   `git commit` with a message like `card: add <id>`;
   `https_proxy=http://10.88.0.6:10808 http_proxy=http://10.88.0.6:10808 git push -u origin card/<id>`;
   `https_proxy=... gh pr create --fill`.
7. **Stop and report the PR URL**. The user reviews and merges by
   hand. Do NOT run `gh pr merge`.

## Proactive Suggestion Trigger List

The agent issues ONE proactive capture suggestion when **all four**
of these conditions hold simultaneously. Each condition is necessary;
miss one and stay silent.

1. **Verified completion**: the current work unit has reached a
   verifiable end state — a test passes, a bug reproduced-and-fixed,
   a refactor merged locally, a design decision named and acted on.
   Routine edits (rename, import-add, typo) do NOT qualify.
2. **Non-trivial lesson**: the insight is not directly available in
   the public docs of the language / framework / tool involved.
   Things an LLM with default training would already know do NOT
   qualify.
3. **Generalizable**: the lesson applies to more than the single
   piece of code just touched. Patterns, gotchas, workflow shifts,
   decision rules — yes. One-off fix to one project's bug — no.
4. **Not already suggested this session**: no proactive suggestion
   has fired for the same insight in this conversation. If the user
   declined an earlier suggestion, the agent MUST NOT re-prompt for
   the same insight.

When all four hold, emit exactly this shape (≤ 200 chars):

> Suggestion: this looks card-worthy because <one specific reason ≤ 100 chars>. Want to capture? (y/n)

Wait for an explicit y/n. On "y", run `## Workflow: Capture`. On "n"
or any decline word, move on and never re-prompt for the same
insight this session.

## Failure Modes

- **Registry unreachable** (network down, proxy misconfigured, GitHub
  Pages outage): report "registry unreachable: <error>" and stop.
  Do NOT fall back to web search or invented advice. The user
  decides whether to retry, wait, or proceed without cards.
- **Blog repo not cloned locally**: instruct the user to
  `git clone https://github.com/lihan3238/lihan3238.github.io.git`,
  then re-run the capture flow.
- **Validator rejects the draft card**: read the error message,
  iterate the draft, re-run validator. Cap iterations at 5; if still
  failing, stop and report which contract rule is blocking.
- **Redaction sweep catches a secret in the draft**: scrub the
  offending text and retry. If the scrub is ambiguous (e.g. the
  token-shape is actually part of the lesson and not a real secret),
  ask the user before continuing.
- **User answers "n" / "no thanks" / "later"** to a proactive
  suggestion: silent move-on. The same insight MUST NOT trigger a
  fresh prompt in the current session.

## Fix

Two pointers:

- **Consulting?** Follow `## Workflow: Consult` above.
- **Capturing** (on-demand OR proactive)? Follow `## Workflow:
  Capture` above. The explicit consent gate (step 5) is non-negotiable.

## Reuse Rule

- **Load when**: the `lihan-cards` skill invokes this card OR an AI
  agent is operating on a task adjacent to the lihan3238.github.io
  card workflow.
- **Do not load when**: working on a completely unrelated personal
  project where Lihan's captured cards are unlikely to apply (e.g.,
  recreational game prototype with no shared context).
