quill: add issue-to-draft brief and retry_decorator sample
This commit is contained in:
1 parent
cdf6828fe0
commit
ef9f0380da
2 files changed
+91
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
Reference in new issue
Block a user