Skip to content

Releases: Shaan-alpha/Skill-Issue

v1.0.0

28 May 22:11
a349574

Choose a tag to compare

First stable release. Caps the v0.9.x beta-hardening line with launch polish.

Added

  • Rich link previews for the homepage. Sharing the site now renders a branded Open Graph / Twitter card (image, title, description).
  • The search box is focused on arrival (desktop), so you can type a username immediately.
  • Analyze another profile without leaving a report — a search box now lives on the report page.

Changed

  • Removed unused starter assets.

Fixed

  • Mentor-mode advice no longer shows raw field names (e.g. engineering_maturity) — it reads in plain English.
  • Tighter spacing at the top of the mobile landing page.
  • The creator scorecard no longer overflows horizontally on mobile.

v0.9.8

28 May 19:40
daf0345

Choose a tag to compare

Added

  • Launch landing sections. Beneath the hero: a "see it in action" row of example profiles linking to live reports, a "how it works" methodology section, and a "Star on GitHub" call-to-action.

v0.9.7

28 May 15:37
7063278

Choose a tag to compare

Added

  • Privacy Policy and Terms of Service. Plain-language legal pages at /privacy and /terms, linked from a new site-wide footer.

v0.9.6

28 May 14:10
a9c6207

Choose a tag to compare

Added

  • Load-test harness (backend/loadtest/) — a reusable open-loop load tester for the backend warm /analyze path, reporting latency percentiles, error rate, and achieved throughput against pass/fail thresholds. Includes a runbook for a local 100 RPS warm-cache run and for pointing at a deployed target.

v0.9.5

28 May 13:12
1e594e6

Choose a tag to compare

Security

  • Full pre-launch security review — no high or critical findings. Authorization (ownership checks on every mutation), session encryption, OAuth CSRF protection, SQL-injection safety, output escaping, and SSRF protection on user-supplied input were all verified sound.

Changed

  • Tightened the GitHub sign-in permission to read-only. Sign-in previously requested a scope that technically allowed writing to your public repositories; it now requests read-only access only, since Skill Issue exclusively reads public data. (Existing sessions are unaffected; the narrower permission applies on next sign-in.)
  • Added HTTP security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy) plus a report-only Content-Security-Policy as a baseline for hardening before public launch.

v0.9.4

28 May 08:12
67c28e7

Choose a tag to compare

Changed

  • Database connection pool size is now configurable via the DB_POOL_SIZE and DB_MAX_OVERFLOW environment variables (defaults unchanged at 5 each), so it can be tuned in production without a redeploy. Telemetry showed no connection-pool pressure at current scale, so this ships the capability without changing the running defaults.

Fixed

  • Search button no longer sticks on a spinner after pressing browser Back. Returning to the landing page from a report could leave the analyze button spinning and its input disabled. The v0.9.3 attempt fixed the wrong mechanism; this is the real fix.

v0.9.3

27 May 20:32

Choose a tag to compare

Added

  • Delete saved analyses. Each card on your history page (/me) now has a ✕ to remove an analysis, with a brief Undo in case you change your mind.
  • Creator flair. The project's creator account gets a distinguished golden scorecard (gold ring, chips, and badges) and a "CREATOR · SKILL ISSUE" tag — on the report page and the shareable card, so the person who built Skill Issue is recognizable on their own report.

Fixed

  • Stuck search spinner. After analyzing a profile and pressing the browser Back button, the landing-page search button could stay stuck spinning (and the input disabled). It now resets correctly when the page is restored.

v0.9.2

27 May 12:19

Choose a tag to compare

Added

  • Rate limiting on analysis and narrative requests. Anonymous visitors are limited per IP; signed-in users get a higher per-account limit (they analyze with their own GitHub token). Exceeding a limit returns a clear, on-voice "slow down" page with a retry hint instead of a generic error. Defaults: 20 analyses / 30 narratives per hour for anonymous visitors, 60 / 90 for signed-in users — all tunable via env vars without a redeploy.

Changed

  • The internal rate-limit counter is now keyed by a generic subject (user:<id> or ip:<addr>), shared across the force-refresh, analyze, and narrative limits.

Notes

  • New env var INTERNAL_PROXY_SECRET (set the same value on the frontend and backend) lets the site attribute analysis requests to the real visitor IP rather than the server's. Until it's set, anonymous analysis is not IP-limited — so real visitors are never throttled by mistake — while narrative and signed-in limits stay active.
  • All cache layers remain fail-open: if Redis is unavailable, requests are allowed rather than blocked.

v0.9.1

27 May 05:38
f975ee6

Choose a tag to compare

Fixed

  • /me/analyses N+1 query. The list endpoint was issuing one SELECT AnalysisRun per row inside the serializer loop (21 round-trips per 20-row page). list_user_analyses already JOINed AnalysisRun via latest_run_id but was discarding the join result; it now returns tuple[list[tuple[Analysis, AnalysisRun | None]], int] so the route consumes the joined row directly. Net: 1 query per page instead of 1+N. No JSON contract change.

Added

  • REPORT_SCHEMA_VERSION constant in app/cache/keys.py. Layer A Report cache keys now carry a per-namespace version prefix: composed key shape is si:v1:report:v1:<lowercased-username>. Bumping REPORT_SCHEMA_VERSION on future Report-shape changes invalidates only the report namespace — no more silent ~6h of cross-namespace Pydantic validation warnings on every schema bump, and no need to bump global KEY_PREFIX (which would nuke GH/narrative/lock/budget caches too).

Notes

  • Existing si:v1:report:<username> keys orphan in Upstash until their 6h TTL expires. No manual cache purge needed; the new keys win on first request, and old keys GC at TTL with bounded memory cost.
  • The Analysis model is unchanged. The N+1 fix is purely at the persistence/router layer; no new relationship, no new query path.

v0.9.0

26 May 09:54
2a68228

Choose a tag to compare

Added

  • Bounded GitHub fan-out in ingest_profile. A new per-call asyncio.Semaphore(settings.gh_ingest_concurrency) (default 8) wraps both asyncio.gather blocks — the up-to-20 root-contents enrichment and the up-to-10 commit-history fetch. A single analysis can no longer burst past GitHub's secondary rate-limit threshold, and anonymous-token sharing scales to more analyses/hr before the 5000/hr ceiling bites. Sequential list_languages loop is intentionally untouched (already bounded by construction; parallelizing it would increase peak concurrent for the same cost). Opens the v0.9.x Beta hardening family.
  • GH_INGEST_CONCURRENCY env var (optional, default 8). Tune in prod without redeploy: raise if Layer A cache hit-rate is high and you want lower analysis latency; lower if you're hitting 403s. Backend env only.

Tests

  • 2 new in tests/test_ingestion.py against a FakeGitHubClient that records max in-flight calls across a 50-repo synthetic profile. Default-cap test asserts max_in_flight ≤ 8; override-cap test (Settings(gh_ingest_concurrency=2) via monkeypatch) asserts max_in_flight ≤ 2. Suite: 261 → 263 non-DB-fixture pass.

Notes

  • This is the first slice of the v0.9.x Beta hardening family. Decomposed 2026-05-26 into: bounded fan-out (this) → /me/analyses N+1 + Layer A cache schema version → DB pool tune → rate limiting + abuse heuristics → security review + load test → legal docs. Each slice is shippable in isolation.
  • Tail latency on heavy profiles increases by ~500ms on a cold cache (3 batches of 8 instead of 1 batch of 20). Layer A's 6h Report cache absorbs this cost — first hit per user pays it once, subsequent hits are sub-200ms. RUM via PostHog (v0.8.0) will surface real-user impact post-deploy.
  • _gated uses Python 3.12 PEP 695 generic syntax (async def _gated[T](sem, coro)) instead of legacy TypeVar — eliminates one import + satisfies ruff UP047.