Skip to content

Commit 207456a

Browse files
committed
fix(docs): update logging prompt for clarity and language specificity
1 parent 3fc5fe6 commit 207456a

2 files changed

Lines changed: 215 additions & 22 deletions

File tree

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
---
2+
description: Evaluate and enforce specific CLI argument parsing discipline across the codebase
3+
---
4+
5+
**Input argument:** `Language` (for example `Python` or `TypeScript`).
6+
7+
## Goal 🎯
8+
9+
Audit every CLI entrypoint and argument parser in this repository against the CLI Contract Baseline and the argument parsing standards defined below. For each entrypoint, report compliance or non-compliance per category, citing concrete evidence (function names, line numbers, code snippets). Where gaps exist, implement fixes immediately using the sensible defaults described in this prompt and the baseline.
10+
11+
## Steps 👣
12+
13+
### Step 1: Discover CLI entrypoints
14+
15+
1. Detect the `Language` (Python or TypeScript) before running any file discovery.
16+
2. Run `git ls-files '*.<ext>'` to enumerate tracked files for the detected language (for example `.py`, `.ts`, `.tsx`).
17+
3. Locate CLI entrypoints in each language and runtime, including:
18+
- Conventional entry files (for example `__main__`, `main`, `cli`, `bin/`, `scripts/`).
19+
- Package metadata that registers commands (for example `pyproject.toml`, `setup.cfg`, `setup.py`, `package.json`, `Cargo.toml`).
20+
4. Record the entrypoint function or module for each CLI.
21+
22+
### Step 2: Identify argument parsing logic
23+
24+
1. For each CLI, find the argument parsing library (for example argparse, click, typer, clap, cobra, commander, yargs).
25+
2. Flag manual parsing (`sys.argv`, `os.Args`, `process.argv`) or ad-hoc split logic that bypasses a parser.
26+
3. Record where validation and default handling occur.
27+
28+
### Step 3: Assess compliance
29+
30+
Evaluate each CLI against the CLI Contract Baseline at:
31+
32+
- `.github/instructions/includes/cli-contract-baseline.include.md`
33+
34+
Report compliance for:
35+
36+
- Exit codes
37+
- Stdout vs stderr
38+
- Documentation and testing expectations
39+
- Developer ergonomics
40+
- Wrappers and shared libraries
41+
- Cloud and serverless workloads (where relevant)
42+
- Argument parsing and flags
43+
44+
### Step 4: Remediate
45+
46+
1. Apply fixes immediately using the defaults in this prompt and the baseline.
47+
2. Keep changes small and consistent with existing patterns.
48+
3. Where behaviour changes are introduced, add tests using a strict Red → Green → Refactor flow.
49+
50+
## Implementation requirements 🛠️
51+
52+
### Anti-patterns (flag and fix immediately) 🚫
53+
54+
- Manual `argv` parsing that bypasses a dedicated parser.
55+
- Abbreviated long flags or prefix matching that can become ambiguous.
56+
- More than two positional arguments without clear documentation and validation.
57+
- Boolean values represented as positional arguments.
58+
- Unknown flags or surplus positional arguments ignored or silently dropped.
59+
- Flag names that are inconsistent across commands for the same concept.
60+
- Help output that omits defaults, environment variable sources, or usage examples.
61+
- Hidden side effects on flag parsing or validation that make flags non-idempotent.
62+
- Interactive prompts triggered by default without a non-interactive equivalent.
63+
- Diagnostics printed to `stdout` or mixed into machine-readable outputs.
64+
- Wrapper CLIs that re-implement business logic instead of delegating to shared libraries.
65+
66+
### Principles 🧭
67+
68+
- Keep parsing predictable, explicit, and stable for both humans and automation.
69+
- Prefer clarity over brevity; avoid clever parsing tricks.
70+
- Keep behaviour deterministic for the same inputs and environment.
71+
- Use clear, consistent naming: kebab-case for flags and nouns for commands.
72+
- Prefer long flags and add short aliases only when they are common and unambiguous.
73+
- Keep interfaces stable; avoid breaking changes or add deprecation periods.
74+
- Ensure flags are idempotent and avoid hidden side effects.
75+
- Accept arguments in predictable order and prefer explicit named flags over positional ambiguity.
76+
- Make configuration precedence explicit: CLI > env vars > config file > defaults.
77+
- Keep CLI entrypoints thin: parse/validate, call shared logic, and forward exit codes.
78+
79+
### Argument parsing and flag rules 🧩
80+
81+
- Use a dedicated argument parser with validation, defaults, and help output.
82+
- Use kebab-case for long flags and single-letter short flags only for common actions.
83+
- Require exact long-flag matches; do not allow abbreviations.
84+
- Support `--` to stop option parsing and treat the remainder as positional input.
85+
- Use explicit boolean switches (`--feature` and `--no-feature`) or a single clear switch.
86+
- Validate required inputs, mutual exclusions, and ranges at parse time and exit with code `2` plus a `--help` hint.
87+
- Support repeatable flags for multiple values and document ordering, de-duplication, and limits.
88+
- Reject unknown flags and surplus positional arguments with exit code `2`.
89+
- Follow standard conventions for `-h/--help`, `-v/--version`, `--verbose`, and `--quiet`. These are must-have arguments for every CLI.
90+
- Provide `--yes` or `--no-input` for non-interactive operation and make prompts opt-in.
91+
92+
### Modern parser defaults 🧱
93+
94+
- Use type hints or explicit parameter types for all options and arguments.
95+
- Prefer specialised parameter types (choice/enum, path/file, range, UUID, datetime) instead of raw strings.
96+
- Validate file and path parameters for existence and permissions at parse time.
97+
- Use explicit prompts only when configured; never prompt for required values by default.
98+
- For sensitive inputs, require confirmation prompts and avoid echoing input back to the terminal.
99+
- Use subcommands for distinct actions instead of large flag sets on a single command.
100+
- Use a shared context object to pass parsed configuration to subcommands; avoid global mutable state.
101+
- Use parser callbacks for validation and normalisation rather than manual checks after parsing.
102+
- Keep `--help` and `--version` eager so they work even when other inputs are invalid.
103+
- Provide shell completion support when the parser supports it and document how to enable it.
104+
- Use the parser's output helpers for consistent encoding and `stdout`/`stderr` handling.
105+
106+
### Help and documentation 📋
107+
108+
- Keep `--help` short, structured, grouped, and example-driven.
109+
- Make defaults sensible and document them clearly in `--help`.
110+
- Include a piping or `--json` example when machine-readable output exists.
111+
- Document exit codes and diagnostic behaviour in README and help output.
112+
- Describe mutually exclusive options, default value sources, and configuration precedence.
113+
114+
### Validation and errors 🚦
115+
116+
- Validate inputs early and return clear, actionable errors.
117+
- Use exit code `2` for parsing and validation errors.
118+
- Ensure errors are actionable and include a `--help` hint.
119+
- Do not emit diagnostics on `stdout`.
120+
- Use exit code `0` for success and `1` for operational failures when no specific code applies.
121+
- Exit with the first failure cause; do not mask distinct failures behind the same code unless documented.
122+
123+
### Stdout and stderr semantics 📤
124+
125+
- Keep `stdout` for primary result payloads and `stderr` for diagnostics.
126+
- Ensure `stdout` stays clean for piping or redirection.
127+
- Emit progress to `stderr` for long-running commands.
128+
- Provide an explicit `--json` mode when machine-readable output is supported.
129+
- Flush and close streams explicitly before exiting short-lived handlers.
130+
131+
### Developer ergonomics 🧑‍💻
132+
133+
- Provide `--help`, `--version`, and `--verbose` or `--quiet` consistently.
134+
- Offer `--dry-run` when the command mutates resources.
135+
- Keep interactive prompts opt-in and always provide a non-interactive equivalent.
136+
137+
### Logging verbosity controls 🔊
138+
139+
- `--verbose` raises verbosity one step; allow `-v`, `-vv`, `-vvv` to increment levels (for example INFO → DEBUG → TRACE).
140+
- `--quiet` lowers verbosity one step; allow `-q`, `-qq` similarly.
141+
- Document the exact mapping from flags to log levels in `--help`.
142+
- Provide `--log-level <level>` for explicit control; flags are convenience.
143+
- Support an environment variable for verbosity (for example `LOG_LEVEL` or `VERBOSITY`), with precedence: CLI flags > env vars > config file > defaults.
144+
- Keep diagnostics on `stderr` and keep outputs deterministic.
145+
146+
### Wrappers and shared libraries 📦
147+
148+
- Keep CLI entrypoints thin and delegate domain logic to shared libraries.
149+
- Align wrapper validation rules and defaults with the underlying library API.
150+
- Centralise shared parsing or logging helpers across related CLIs.
151+
- Expose a `main(args: list[str]) -> int` or equivalent entrypoint where possible.
152+
153+
### Cloud and serverless workloads ☁️
154+
155+
- Avoid reliance on background daemons or writable current directories unless explicitly provisioned.
156+
- Provide `--timeout` flags where platform limits apply and emit periodic progress to `stderr`.
157+
- Emit structured logs compatible with shared observability standards.
158+
- Avoid interactive authentication flows; support token injection or credentials for automation.
159+
160+
### Testing expectations 🧪
161+
162+
- Add integration tests for each CLI covering a success case and each reserved non-zero exit code.
163+
- Add unit tests for parsing edge cases (unknown flag, missing required input, mutual exclusions).
164+
- Keep tests deterministic and assert exact exit codes.
165+
- Test the CLI contract explicitly (help text, parsing, errors, exit codes).
166+
- Include smoke tests for wrapper CLIs to ensure deterministic exit codes and diagnostics.
167+
- Use the parser's built-in test runner where available instead of spawning subprocesses.
168+
169+
## Output requirements 📋
170+
171+
1. **Findings per file**: for each category above and each of its bullet point, state one of the following statuses with a brief explanation and the emoji shown: ✅ Fully compliant, ⚠️ Partially compliant, ❌ Not compliant.
172+
2. **Evidence links**: reference specific lines using workspace-relative Markdown links (e.g., `[src/app.py](src/app.py#L10-L40)`).
173+
3. **Immediate fixes**: apply sensible defaults inline where possible; do not defer trivial remediations.
174+
4. **Unknowns**: when information is missing, record **Unknown from code – {suggested action}** rather than guessing.
175+
5. **Summary checklist**: after processing all CLIs, confirm overall compliance with:
176+
- [ ] Principles
177+
- [ ] Argument parsing and flag rules
178+
- [ ] Modern parser defaults
179+
- [ ] Help and documentation
180+
- [ ] Validation and errors
181+
- [ ] Stdout and stderr semantics
182+
- [ ] Developer ergonomics
183+
- [ ] Logging verbosity controls
184+
- [ ] Wrappers and shared libraries
185+
- [ ] Cloud and serverless workloads
186+
- [ ] Testing expectations
187+
188+
---
189+
190+
> **Version**: 1.0.1
191+
> **Last Amended**: 2026-01-29

.github/prompts/dev.implement-logging.prompt.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
---
2-
description: Evaluate and enforce Python logging discipline across the codebase
2+
description: Evaluate and enforce specific logging discipline across the codebase
33
---
44

5+
**Input argument:** `Language` (for example `Python` or `TypeScript`).
6+
57
## Goal 🎯
68

79
Audit every Python file in this repository against the logging standards defined below. For each file, report compliance or non-compliance per category, citing concrete evidence (function names, line numbers, code snippets). Where gaps exist, implement fixes immediately using the sensible defaults described in this prompt.
810

911
## Steps 👣
1012

11-
### Step 1: Discover Python files
13+
### Step 1: Discover language-specific files
1214

13-
1. Run `git ls-files '*.py'` to enumerate all tracked Python files.
14-
2. For each file, search for **any** diagnostic output pattern:
15-
- Logging imports: `logging`, `structlog`, `loguru`, or project logger
16-
- Direct stderr: `sys.stderr.write`, `sys.stderr.flush`
17-
- Print to stderr: `print(..., file=sys.stderr)`
18-
- Print for diagnostics: `print(` used for status/error output
15+
1. Detect the `Language` (Python or TypeScript) before running any file discovery.
16+
2. Run `git ls-files '*.<ext>'` to enumerate tracked files for the detected language (for example `.py`, `.ts`, `.tsx`).
17+
3. For each file, search for **any** diagnostic output pattern:
18+
- Logging imports: language-standard logger, structured logger, or project logger
19+
- Direct stderr writes or console error output
20+
- Print/console output used for diagnostics
1921
- Logger references: `logger`, `log`, `_log`
20-
3. Flag files with diagnostic output that do **not** import the central logger.
22+
4. Flag files with diagnostic output that do **not** import the central logger.
2123

2224
### Step 2: Assess logging practices
2325

@@ -28,7 +30,7 @@ For every file that uses logging (or should but does not), evaluate compliance a
2830
### Anti-patterns (flag and fix immediately) 🚫
2931

3032
- **Bypassing central logger**: `sys.stderr.write()`, `print(file=sys.stderr)`, or raw `print()` for diagnostic output — route through central logger instead.
31-
- **Direct logging import**: `import logging` / `logging.getLogger()` instead of project factory — use the central logger factory.
33+
- **Direct logging import**: language-standard logger import instead of project factory — use the central logger factory.
3234
- **Inline helper functions**: local `_log_*()` wrappers that write directly to stderr rather than delegating to the central service.
3335
- **Silent failures**: bare `except:` or `except Exception:` without logging.
3436
- **Mixed output channels**: some modules using central logger while others bypass it.
@@ -51,7 +53,7 @@ For every file that uses logging (or should but does not), evaluate compliance a
5153

5254
### Class-level logging 🧩
5355

54-
- **Bound logger pattern (mandatory)**: use the factory function `get_logger(component="ClassName")` which returns a `BoundLogger` pre-bound to the component name. Call log methods directly on the bound logger (`self._logger.debug(...)`) rather than defining per-class wrapper methods (`_log_debug`, `_log_info`, etc.). This eliminates boilerplate and ensures a single point of change.
56+
- **Bound logger pattern (mandatory)**: use the factory function `get_logger(component="ClassName")` which returns a bound logger pre-bound to the component name. Call log methods directly on the bound logger (`self._logger.debug(...)`) rather than defining per-class wrapper methods (`_log_debug`, `_log_info`, etc.). This eliminates boilerplate and ensures a single point of change.
5557
- **One logger per class/module**: instantiate a logger with the class or module name so context is always present.
5658
- **Constructor logging**: log significant configuration or injected dependencies once at INFO when the object is created.
5759
- **Lifecycle events**: log state transitions (started, stopped, reloaded) at INFO or WARN as appropriate.
@@ -103,21 +105,21 @@ Flag any misuse (e.g., logging an error condition at INFO).
103105

104106
## Output requirements 📋
105107

106-
1. **Findings per file**: for each category above and each of its bullet point, state "Compliant" or "Issue" with a brief explanation.
108+
1. **Findings per file**: for each category above and each of its bullet point, state one of the following statuses with a brief explanation and the emoji shown: ✅ Fully compliant, ⚠️ Partially compliant, ❌ Not compliant.
107109
2. **Evidence links**: reference specific lines using workspace-relative Markdown links (e.g., `[src/app.py](src/app.py#L10-L40)`).
108110
3. **Immediate fixes**: apply sensible defaults inline where possible; do not defer trivial remediations.
109111
4. **Unknowns**: when information is missing, record **Unknown from code – {suggested action}** rather than guessing.
110112
5. **Summary checklist**: after processing all files, confirm overall compliance with:
111-
- Principles
112-
- Project-level logger configuration
113-
- Class-level logging
114-
- Method-level logging
115-
- Log levels
116-
- Content
117-
- Console visualisation
118-
- Performance
113+
- [ ] Principles
114+
- [ ] Project-level logger configuration
115+
- [ ] Class-level logging
116+
- [ ] Method-level logging
117+
- [ ] Log levels
118+
- [ ] Content
119+
- [ ] Console visualisation
120+
- [ ] Performance
119121

120122
---
121123

122-
> **Version**: 1.1.1
123-
> **Last Amended**: 2026-01-28
124+
> **Version**: 1.1.3
125+
> **Last Amended**: 2026-01-29

0 commit comments

Comments
 (0)