| name | facade-yard-documentation |
| description | Facade-specific YARD documentation rules for Git::Repository::* topic modules and their facade methods, overriding and extending the general yard-documentation skill. Use when writing or reviewing YARD docs for facade modules under lib/git/repository/. |
Facade YARD Documentation
Write and verify YARD documentation for facade modules and methods on
Git::Repository::*. This skill overrides and extends the general
YARD Documentation skill with facade-specific
rules.
The facade is the public API surface of the gem. Facade docs describe what
the caller passes and what they get back — never the internal command class,
parser, or execution context that implements the behavior.
Contents
Related skills
Input
Before starting, you MUST load the following skill(s) in their entirety:
Then gather:
- Facade module source —
lib/git/repository/<topic>.rb
- Underlying command class(es) —
lib/git/commands/<command>.rb for each
command the facade method calls. Use these to confirm option semantics, but
do not copy the command's @option docs verbatim — the facade only
exposes the options it documents in its public contract.
- Underlying parser/result class — when the facade returns a structured
value, read the parser or result class to confirm the documented return type.
Reference
Module-level docs
Every facade module under lib/git/repository/ requires a module-level YARD
block:
module Git
class Repository
module Topic
end
end
end
Module-level tags appear in the order required by
YARD Documentation — Modules:
@note, @deprecated, @see, @api. (Facade modules do not use module-level
@example — see the override note below.)
Required tags:
Do not add:
@see Git::Commands::* at the module level — implementation detail
@see https://git-scm.com/docs/... at the module level — git man-page
links belong on the individual facade methods, where the link maps directly
to the command being invoked. A module typically groups several facade
methods (sometimes spanning multiple git commands), so a single module-level
link is misleading; for single-command modules it is redundant with the
method-level link.
@example blocks at the module level — facade-specific override of
YARD Documentation — Modules,
which permits module-level @example when a module provides standalone
methods. Facade modules do provide standalone methods, but every facade
method already carries its own @example, so a module-level example would
be redundant. Examples belong on the methods.
Method-level docs
Every facade method requires full YARD docs. Two acceptable forms:
Form A — @overload with anonymous splat in the def (the default
for any method that forwards positional args and/or keyword options unchanged
to the underlying command). The def uses an anonymous splat — **, *, or
... — to satisfy RuboCop's Style/ArgumentsForwarding cop, and the
@overload block introduces named parameters that @param and @option bind
to:
def add(paths = '.', **)
Git::Repository::Internal.assert_valid_opts!(ADD_ALLOWED_OPTS, **)
Git::Commands::Add.new(@execution_context).call(*Array(paths), **).stdout
end
See Documenting forwarded options with
@overload for the rationale
and variations (*, ..., multiple call shapes).
Form B — direct doc comment on a fully named signature (the narrow
exception: use only when the method body must inspect or mutate the options
hash before forwarding it, or when the signature has no splat at all). When
the def has a named parameter for every documented argument, @param and
@option bind directly:
def commit(message, opts = {})
Git::Repository::Internal.assert_valid_opts!(COMMIT_ALLOWED_OPTS, **opts)
opts = opts.merge(message: message) if message
Git::Commands::Commit.new(@execution_context).call(no_edit: true, **opts).stdout
end
Form B is required here because the method body needs a named variable (opts)
to build and transform before forwarding — e.g. opts.merge(message: message)
returns a new hash that is assigned back, and opts = deprecate_commit_no_gpg_sign_option(opts)
reassigns it; an anonymous ** in the def provides no named variable to
operate on.
When a method has multiple genuinely distinct call shapes (e.g.
commit(message) vs. commit(message, opts) with materially different
return types), use one @overload block per shape — see
YARD Documentation — Overload
template.
Required elements (apply to both forms):
Documenting forwarded options with @overload
When a facade method forwards positional args and/or keyword options unchanged
to the underlying command, keep the anonymous splat (**, *, or ...) in
the def (so Style/ArgumentsForwarding stays satisfied) and document the
call shape with an @overload block that names the parameters — Form A in
Method-level docs above shows the canonical add
example.
Key constraints:
- Do not name the splat — or expand
... into *args, **kwargs, &block —
solely to make @param/@option bind. Do not suppress
Style/ArgumentsForwarding with # rubocop:disable. The @overload form is
the project-standard resolution.
- The
@overload signature owns the parameter names; @param, @option,
@yield, and @yieldparam tags inside the overload bind to those names.
- When a facade method has multiple distinct call shapes (e.g.
commit(message) vs. commit(message, **opts)), write one @overload
block per shape.
- Form B (named splat, direct doc comment) is the narrow exception — use only
when the body inspects or mutates the options hash before forwarding it.
- The anonymous block parameter (
&) is not covered by this rule.
@yield/@yieldparam/@yieldreturn describe what is yielded rather than
the block parameter itself, so anonymous & is fine. Name the block
(&block) only when documenting it as a first-class Proc value.
See the general
YARD Documentation — Documenting anonymous splats with @overload
for the underlying rule.
Decision rules for facade methods:
- Use
@overload when the method uses anonymous *, **, or ...
- Use
@overload when call shapes differ meaningfully (different params and/or
return contracts)
- Skip
@overload only when a single named signature fully describes the API
When using @overload, place tags as follows:
- Put
@param, @option, and @return in overload blocks
- Put overload-specific
@raise only in the relevant overload block
- Put shared
@raise once at top level
- Do not duplicate the same
@raise at both levels
Return type rules
The @return annotation must reflect the public contract of the facade
method, not the type of the underlying call expression.
| Facade does | @return type |
|---|
Returns the raw CommandLineResult | [Git::CommandLineResult] |
Returns result.stdout (chomped or raw) | [String] |
| Returns parsed structured data via a parser | The parser's return type (e.g. [Array<Git::BranchInfo>], [Hash]) |
| Returns a result-class instance via a factory | The result class (e.g. [Git::BranchDeleteResult]) |
| Returns a single Boolean derived from the result | [Boolean] |
Never write @return [Git::Commands::Foo::Result] — command-class result types
are internal. Surface Git::CommandLineResult only when the topic module's
documented contract is to expose raw results.
@raise rules
-
Always include @raise [Git::FailedError] for any facade method that can
cause git to exit non-zero. Use the canonical generic wording matching the
command's exit-status range:
Command's allow_exit_status | Facade @raise wording |
|---|
none / 0..0 | if git exits with a non-zero exit status |
0..1 | if git exits outside the allowed range (exit code > 1) |
-
When the facade calls assert_valid_opts!, include
@raise [ArgumentError] if unsupported options are provided.
-
When the facade itself validates arguments and raises (e.g. "you must specify
a remote if a branch is specified"), document with a specific @raise [ArgumentError] line that names the constraint.
-
Do not enumerate specific git failure causes (no "if the branch doesn't
exist", no "if the working tree is dirty"). Use the generic form.
Scope @raise tags by call-shape:
- Shared across all overloads: keep as one top-level
@raise
- Specific to one or more overloads: keep only in those overload blocks
- Never duplicate identical
@raise tags at both top level and overload level
Cross-referencing the implementation
When useful, cross-link to the underlying components with @see tags at the
end of the method's doc block:
Use sparingly — only when the cross-link helps a reader navigate to non-obvious
internals. Do not add @see for every command and parser by default; trivial
delegators do not need them.
Common issues
@return [Git::CommandLineResult] on a method that actually returns a
parsed value. Match the actual return value, not the inner call expression.
- Copying
@option blocks from the command class. The facade exposes only
the options listed in its public contract (and the <METHOD>_ALLOWED_OPTS
whitelist when present). Do not copy every option the command DSL declares.
- Documenting policy defaults as caller options. When the facade hardcodes
no_edit: true, do not list :no_edit as a caller option. The facade's contract
is "non-interactive commit"; mention the policy in prose if relevant, not as
an @option.
- Documenting the underlying command in the summary. Wrong: "Calls
Git::Commands::Add.#call". Right: "Update the index with the current
content found in the working tree."
- Leaking
Git::ExecutionContext::Repository into docs. The execution
context is injected once at construction; facade method docs do not mention
it.
- Missing
@example on a public method. Every public facade method requires
at least one @example block with a descriptive title. Examples belong on the
method, not at the module level.
- Missing
@param <name> [Hash] before @option tags. Every @option tag
requires a preceding @param for the options hash. Use the parameter name from
the @overload signature when the def uses anonymous **.
- Missing
@api public on the module. Every facade module is part of the
public API and must declare it.
- Uppercase first letter or trailing period on tag short descriptions. Same
rule as command YARD: lowercase start, no trailing punctuation on the short
description.
- Raw blank line inside a doc comment block. A line with no leading
#
silently terminates the YARD block. Use blank comment lines (#) inside
multi-paragraph descriptions.
Workflow
For each facade module file, run through these checks in order:
1. Module-level docs
2. Method-level docs (per method)
3. Formatting consistency
Output
When writing new facade YARD docs
Produce the complete YARD doc block(s) for the module and each method, then
self-verify by running every checklist item from Workflow against
your output. Fix and re-verify until all checks pass.
When reviewing existing facade YARD docs
For each file, provide:
-
issue table
-
corrected doc block snippets (only where needed)
-
Self-verify before concluding — re-run every checklist item against
your proposed snippets until all checks pass.
Branch workflow: Implement any fixes on a feature branch. Never commit or
push directly to main — open a pull request when changes are ready to merge.