ccg-annotate — Annotation Workflow
Add structured business metadata to source comments so graph search and generated documentation can retrieve intent and operational contracts.
Retrieval-Aware Tag Selection
Annotations are retrieval features, but they must stay truthful. Use the
specific tag that matches the code's role instead of stuffing keywords into
@intent.
| When you see this | Add this |
|---|---|
| File/package/module should be found as one unit | @index |
| Public function, handler, CLI command, service method, or UI workflow has a clear purpose | @intent |
| Policy, constraint, operational rule, or false-positive/false-negative criterion matters | @domainRule |
| DB/file/network/cache/log/process side effect exists | @sideEffect |
| Receiver or argument object changes in memory | @mutates |
| Caller-facing input/output contract matters | @requires, @ensures |
| Related implementation must be followed, especially across namespaces | @see |
Good retrieval annotations include the words a developer or LLM would naturally
use to ask for the code, while matching the implementation. For example, if a
graph component focuses a resolved ccg:// node, say graph viewer, ccg ref,
and node focus in the appropriate @index/@intent. Do not add unrelated
terms just to raise score; broad terms make the wrong files rank higher.
Read references/annotation-reference.md
before using less-common tags, aliases, multiline values, typed JSDoc/YARD
forms, cross-namespace refs, or language-specific comment syntax.
Annotation Workflow
This is an agent skill workflow, not a ccg CLI subcommand. The agent reads and
edits code directly.
Step 1: Pick targets
- File path → that file only
- Directory → all source files
- Skip: vendor, dependencies, and generated code
- Skip tests by default; include a test only when it is itself important domain-contract evidence
Step 2: Analyze each target
Read the code and determine:
- What it does → first summary line
- File/package discoverability →
@indexwhen the file itself is a useful search target - Why it exists →
@intentfor meaningful public/workflow entry points - Business or operational rules →
@domainRule(must be specific) - Real side effects →
@sideEffect - State changes →
@mutates - Caller-facing contracts →
@requires,@ensureswhen they matter
For cross-namespace behavior, explain the reason in the semantic tag and put the target in @see:
// @sideEffect records token validation audit in auth-svc.
// @see ccg://auth-svc/internal/audit/token_audit.go#RecordTokenAudit
Step 3: Write
- Add comments directly above the declaration using the language's documentation-comment syntax
- Preserve accurate human-authored context; update or remove stale, false, or duplicate tags when refinement is requested
- Do not erase non-obvious rationale unless the code contradicts it; report such changes explicitly
- Skip trivial functions (getters/setters, obvious one-line wrappers)
- Do not add tags that do not match real behavior
- Do not repeat the same keyword across tags unless each tag adds distinct evidence
- Match the language of existing comments (Korean for Korean codebases, English for English)
Step 4: Report reindex requirement
Annotations enter the search index only at graph build time. An annotation
written but not rebuilt is invisible to search — the most common way to
conclude, wrongly, that "annotations don't work". Do not invoke ccg-build
automatically. Report that reindexing is required and that the user must
explicitly name ccg-build in a new request before graph refresh.
After an explicitly authorized refresh, representative changed symbols can be
checked with get_annotation. Until then, report graph-backed verification as
pending. The parser returns unknown-tag warnings to direct callers, but the
current ingestion discards that warning list and ccg lint does not surface it.
Treat the reference tag list as an allowlist; a green lint result alone does not
prove an unknown tag was indexed.
Quality Example
❌ Bad annotation:
// @intent creates a user
func CreateUser(...) {}
WHAT only. Function name already tells you that.
✅ Good annotation:
// @intent register a normalized account for the onboarding flow
// @domainRule email must be unique across all tenants
// @sideEffect inserts the user and audit record, then sends a verification email
// @mutates input.NormalizedEmail
func CreateUser(input *SignupRequest) error { ... }
WHY + business rules + side effects. Code and documentation search become powerful.
Annotation Priority
Don't annotate everything. Prioritize:
- Tier 1: domain core (auth, payment, billing — business logic)
- Tier 2: frequently searched (entry points, public APIs)
- Tier 3: complex functions (high cognitive load)
- Skip: getters/setters, simple wrappers, generated code
Use ccg lint unannotated category and pick top-priority functions from there.
Retrieval Quality Checks
After adding annotations for a feature area, run a few natural-language retrieve/search probes that match how an LLM or engineer would ask:
ccg search "graph viewer ccg ref node focus"
For MCP/Web UI retrieval, use search + get_doc_content or Wiki search. If the
expected file is missing, prefer improving the precise @index, @intent,
@domainRule, or @see evidence on that file over changing global scoring.
Closing the Question Loop
When this skill was entered from the ccg skill's search failure path — a
plain-language question that came back empty because no recorded reason
answered it — the work is not done until that question succeeds:
- Annotate the area the question was about (Steps 1–3), writing the
@intent/@domainRulein words that answer the question actually asked. - Rebuild (Step 4). Without this the re-ask is guaranteed to fail again.
- Re-ask the original question, verbatim, through
search, and confirm the answer now carries reason-matched hits (reasonandmatched_terms) pointing at the annotated area.
If the re-ask still comes back empty, the recorded reason and the question do not share vocabulary — revise the annotation's wording, not the search.
Completion
List annotated files and meaningful tags added or deliberately revised, report
any existing rationale changed, confirm the rebuild ran, verify representative
nodes with get_annotation, run retrieval probes for affected concepts, and
report lint plus any unknown-tag risk or unrelated finding without claiming it
was fixed. When the work started from a failed question, state the original
question and what its re-ask returned.