Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/skills/audit-user-stories/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,12 @@ Execute the operator's chosen scope in this wave order. Each wave can run in par
If the operator's chosen scope creates any new sub-issues (e.g., a shared-types consolidation story, a verification-conversion that splits one story into two), run the cap check before any writes — the same pre-flight `draft-user-stories` runs. Hitting the cap mid-repair leaves the work tree half-fixed and forces an out-of-band consolidation rollup before you can resume.

- `needed` = number of new sub-issues the repair will create. If the repair only rewrites + cancels existing issues (the common case), `needed = 0` and you can skip — `save_issue(id=...)` updates don't consume cap.
- For `needed > 0`, run `uv run python scripts/check_linear_cap.py --needed <needed> --json` (one JSON line: `active`, `cap`, `buffer`, `needed`, `margin`, `required`, `ok`; 2-issue safety margin applied internally; exit code mirrors `ok`: `0` clear, `1` cap risk, `2` error).
- For `needed > 0`, run `uv run python scripts/linear/check_linear_cap.py --needed <needed> --json` (one JSON line: `active`, `cap`, `buffer`, `needed`, `margin`, `required`, `ok`; 2-issue safety margin applied internally; exit code mirrors `ok`: `0` clear, `1` cap risk, `2` error).

Decision:

- **`ok == true`** — proceed to Wave 1.
- **`ok == false`** — surface to the operator *before any writes*. Report the numbers from the JSON. Recommend `/linear-consolidate` (per the `project_linear_consolidation` memory) or `scripts/linear_consolidation_candidates.py` to free slots. Ask whether to (a) pause for rollup, (b) proceed accepting cap-risk and inline the un-created stories in the hand-off, or (c) trim repair scope to drop the new creations.
- **`ok == false`** — surface to the operator *before any writes*. Report the numbers from the JSON. Recommend `/linear-consolidate` (per the `project_linear_consolidation` memory) or `scripts/linear/linear_consolidation_candidates.py` to free slots. Ask whether to (a) pause for rollup, (b) proceed accepting cap-risk and inline the un-created stories in the hand-off, or (c) trim repair scope to drop the new creations.
- **exit 2** — script failure (missing `LINEAR_API_KEY` in `.env`, network/API error). Surface and resolve before proceeding; don't fall back to manual MCP counting.

#### Wave 1 — Duplicate cleanup
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/comb-collector-logs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ After identifying a candidate bug in today's log, grep older rotated logs for th

A traceback shows *what raised*, not *what should have caught it*. Always read the relevant file:

- For retry-related errors: read `src/alphamind/data_sources/_common.py` `_is_retryable` to confirm the exception type is covered. If `_is_retryable` returns False, the retry wrapper silently gave up — that's the bug, not the vendor error.
- For retry-related errors: read `_is_retryable` in `src/alphamind/data_sources/_common/retry.py` to confirm the exception type is covered. If `_is_retryable` returns False, the retry wrapper silently gave up — that's the bug, not the vendor error.
- For per-ticker collectors: check whether the loop has try/except per ticker. No isolation means one ticker's exhausted retries kills the cycle.
- For wrapped exceptions: check `__context__` and `__cause__` — fredapi wraps `urllib.HTTPError` as `ValueError(None)`, the message is lost but the context isn't.

Expand Down Expand Up @@ -94,7 +94,7 @@ For each event group:
1. **Read the surrounding traceback** in `collector.log`. Note: full exception type, the immediate raising frame, and `__context__` if present.
2. **Cross-check operator memory** at `collector-service-ops.md` for known-transient patterns. If listed there with "should retry":
- Verify retries actually engaged by checking elapsed time between cycle start (`collector=X start`) and error. Sub-second to a few seconds = retry didn't fire; tens of seconds = retry fired but exhausted.
- If retry didn't fire, the bug is in `_is_retryable` not classifying that exception as retryable. Read `src/alphamind/data_sources/_common.py:276-296` to confirm.
- If retry didn't fire, the bug is in `_is_retryable` not classifying that exception as retryable. Read `_is_retryable` in `src/alphamind/data_sources/_common/retry.py` to confirm.
3. **Read the source file from the traceback.** Confirm root cause — don't trust the traceback alone (Rule 4).
4. **Check rotated logs for recurrence** — grep the same error signature across `collector.log.YYYY-MM-DD` files. Record cadence (one-off, daily, multi-day pattern).
5. **Check git log for recent fixes** — `git log --oneline -5 -- <path-from-traceback>`. A commit in the last day that matches the symptom means it was already fixed.
Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/draft-user-stories/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Don't worry about ordering or naming conventions yet — those happen in Phase 5

Anchor the Scope sections of subsequent stories to the brief's concrete names — a story's "produces `PositionRecord` with these fields" is far more useful to a dispatched subagent than "introduces a position record". When the brief surfaces a hardest-to-reverse decision the design doc hasn't settled, add it to your Phase 6 open-decisions list. Skill invocation runs in your thread (no Agent dispatch), compatible with the no-delegation rule. Skip design mode when the feature is small, purely additive to an existing module, or already fully specified at the type level by its design doc.

**Operational runbook story.** Assess whether the feature changes production operational behavior — a service, the schedule, a port, an env var, a migration / bootstrap step, a CLI flag, a monitoring surface, or a new failure mode / gotcha. If so, add a final story that updates `scripts/RUNBOOK_production.md` (its Living-document rule keeps the runbook moving with the behavior), `blockedBy` every story whose operational change it documents so it lands last. Omit it for features with no operator-visible prod-runtime effect (pure internal logic, analysis / decision-layer changes, test-only work).
**Operational runbook story.** Assess whether the feature changes production operational behavior — a service, the schedule, a port, an env var, a migration / bootstrap step, a CLI flag, a monitoring surface, or a new failure mode / gotcha. If so, add a final story that updates the affected runbook under `docs/runbooks/` (the README's Living-document rule keeps the runbooks moving with the behavior), `blockedBy` every story whose operational change it documents so it lands last. Omit it for features with no operator-visible prod-runtime effect (pure internal logic, analysis / decision-layer changes, test-only work).

### Phase 5 — Order by dependency, name with parallelism convention

Expand Down Expand Up @@ -180,15 +180,15 @@ Compute how many issues you're about to create:
Run the cap-check script with that count:

```
uv run python scripts/check_linear_cap.py --needed <needed> --json
uv run python scripts/linear/check_linear_cap.py --needed <needed> --json
```

The script queries the Linear GraphQL API directly (key from the repo-root `.env`), paginates the whole workspace, and prints one JSON line — e.g. `{"active": 243, "cap": 250, "buffer": 7, "needed": 12, "margin": 2, "required": 14, "ok": false}`. It applies a 2-issue safety margin internally (`required = needed + margin`), so you pass only the raw `needed` count. Exit code mirrors `ok`: `0` = clear, `1` = cap risk, `2` = error.

Decision:

- **`ok == true` (exit 0)** — cap risk is low. Note `active` in your working memory and proceed to 7a.
- **`ok == false` (exit 1)** — surface to the operator *before any writes*. Report `active`, `buffer`, `needed`, and `required` from the JSON. Recommend running the consolidation rollup per the `project_linear_consolidation` memory and the `/linear-consolidate` skill — `uv run python scripts/linear_consolidation_candidates.py` ranks which shipped feature would free the most slots, and `scripts/check_linear_cap.py --breakdown` shows where the active issues sit. Ask whether to (a) pause for rollup, (b) proceed accepting that the cap may fire mid-drafting (you will catch the error gracefully and surface the remaining drafts inline as a hand-off), or (c) trim story count if you can identify a fold.
- **`ok == false` (exit 1)** — surface to the operator *before any writes*. Report `active`, `buffer`, `needed`, and `required` from the JSON. Recommend running the consolidation rollup per the `project_linear_consolidation` memory and the `/linear-consolidate` skill — `uv run python scripts/linear/linear_consolidation_candidates.py` ranks which shipped feature would free the most slots, and `scripts/linear/check_linear_cap.py --breakdown` shows where the active issues sit. Ask whether to (a) pause for rollup, (b) proceed accepting that the cap may fire mid-drafting (you will catch the error gracefully and surface the remaining drafts inline as a hand-off), or (c) trim story count if you can identify a fold.
- **exit 2** — the script failed (missing `LINEAR_API_KEY` in `.env`, or a network/API error; the stderr message says which). Surface it to the operator and resolve the cause before proceeding — don't fall back to a manual MCP count.

The cap is occasionally enforced at counts above 250 — Linear's exact threshold depends on workspace age and account state. Treat the check as early-warning, not exact predictor. If a create fails despite a pre-flight `ok == true`, surface the blocker and inline the remaining drafts in the operator hand-off.
Expand Down
Loading
Loading