quill: add issue-to-draft brief and retry_decorator sample

This commit is contained in:
quill committed 2026-10-24 16:15:33 +00:00
1 parent cdf6828fe0
commit ef9f0380da
2 files changed
+91

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
# Issue-to-Draft Brief
A reusable template that converts a structured issue spec into a ready-to-run task brief for a Draft-lane agent.
## Input Contract
- **issue_id**: str
- **title**: str
- **acceptance_criteria**: list[str]
- **constraints**: list[str] (optional)
- **context**: str (optional)
## Output Contract
A single markdown file containing:
1. Goal (1 sentence)
2. Scope (bullets from acceptance criteria)
3. Constraints (bullets, or "none")
4. Artifact path (where the deliverable lives)
5. Verdict template (one-line + CHECK command)
## Rules
- No filler, no hedging.
- Plain claims over adjectives.
- If a claim is unmeasured, mark it `[CLAIMED]`.
- End with `VERDICT:` line and `CHECK:` line (exit code 0 = correct).
## Sample Filled Brief
**Input:**
- issue_id: DRAFT-7
- title: Add retry decorator to http client
- acceptance_criteria:
- decorator retries 3x on 5xx
- exponential backoff capped at 5s
- type hints present
- constraints: stdlib only, <80 LOC
- context: replaces ad-hoc retry loop in main.py
**Output:**
GOAL: Add a stdlib-only retry decorator for 5xx errors with 3 attempts and exponential backoff capped at 5 seconds.
SCOPE:
- Decorator with 3-attempt retry on 5xx
- Exponential backoff (1s, 2s, 5s cap)
- Type hints on all public callables
- Remove ad-hoc retry loop from main.py
CONSTRAINTS:
- stdlib only
- <80 LOC
ARTIFACT: /root/.hermes/wizard-outputs/quill/retry_decorator.py
VERDICT: Decorator implemented, tested, and under 80 LOC.
CHECK: python /root/.hermes/wizard-outputs/quill/verify.py
+35
View File
@@ -0,0 +1,35 @@
"""Stdlib-only retry decorator for 5xx errors.
Exponential backoff: 1s, 2s, 5s cap. 3 attempts max.
Type hints on all public callables. <80 LOC.
"""
import time
import functools
from typing import TypeVar, Callable, ParamSpec
P = ParamSpec("P")
R = TypeVar("R")
def retry_on_5xx(max_attempts: int = 3, base_delay: float = 1.0, cap: float = 5.0) -> Callable[[Callable[P, R]], Callable[P, R]]:
"""Decorator: retry wrapped callable on 5xx up to max_attempts times."""
def decorator(func: Callable[P, R]) -> Callable[P, R]:
@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
delay = base_delay
last_exc: BaseException | None = None
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except Exception as exc:
last_exc = exc
status = getattr(exc, "status", None)
if not (isinstance(status, int) and 500 <= status < 600):
raise
if attempt == max_attempts:
break
time.sleep(delay)
delay = min(delay * 2, cap)
raise last_exc # type: ignore[misc]
return wrapper
return decorator