Commit graph

264 commits

Author SHA1 Message Date
9d2ed1d00d docs: circuitforge-hooks design — gitleaks-based secret + PII scanning
Centralised pre-commit/pre-push hook repo design covering the token leak
root causes: unactivated hooksPath and insufficient regex coverage.
2026-03-07 12:23:54 -08:00
1b500b9f26 docs: update changelog for v0.3.0 release
- Add v0.3.0 section: feedback button, BYOK warning, LLM suggest,
  backup/restore, privacy scrub
- Retroactively document v0.2.0 (was in [Unreleased])
- Clear [Unreleased] for future work
2026-03-06 16:04:28 -08:00
d1c5c89da7 feat: merge feedback-button branch — BYOK warning, PII scrub, LLM suggest, sidebar indicator
Key changes in this branch:
- BYOK cloud backend detection (scripts/byok_guard.py) with full test coverage
- Sidebar amber badge when any cloud LLM backend is active
- Activation warning + acknowledgment required when enabling cloud backend in Settings
- Privacy policy reference doc added
- Suggest search terms, resume keywords, and LLM suggest button in Settings
- Test suite anonymized: real personal data replaced with fictional Alex Rivera
- Full PII scrub from git history (name, email, phone number)
- Digest email parser design doc
- Settings widget crash fixes, Docker service controls, backup/restore script
2026-03-06 16:01:44 -08:00
bf8eee8a62 test: anonymize real personal data — use fictional Alex Rivera throughout test suite 2026-03-06 15:35:04 -08:00
d3f86f2143 fix: remove dead byok_cloud_acknowledged scalar key — list is the authority 2026-03-06 15:17:26 -08:00
8da36f251c docs: clarify byok acknowledgment semantics and double-read intent 2026-03-06 15:14:26 -08:00
89f11b0cae feat: byok activation warning — require acknowledgment when enabling cloud LLM 2026-03-06 15:09:43 -08:00
84862b8ab8 fix: use explicit utf-8 encoding when reading llm.yaml in sidebar 2026-03-06 14:52:22 -08:00
5827386789 feat: sidebar cloud LLM indicator — amber badge when any cloud backend active 2026-03-06 14:48:20 -08:00
7ca348b97f test: add missing base_url edge case + clarify 0.0.0.0 marker intent
Document defensive behavior: openai_compat with no base_url returns True
(cloud) because unknown destination is assumed cloud. Add explanatory
comment to LOCAL_URL_MARKERS for the 0.0.0.0 bind-address case.
2026-03-06 14:43:45 -08:00
329baf013f feat: byok_guard — cloud backend detection with full test coverage 2026-03-06 14:40:06 -08:00
67634d459a docs: digest parsers implementation plan (TDD, 6 tasks) 2026-03-05 22:41:40 -08:00
5124d18770 docs: add privacy policy reference 2026-03-05 20:59:01 -08:00
92e0ea0ba1 feat: add LLM suggest button to Skills & Keywords section
Places a  Suggest button inline with the Skills & Keywords subheader.
On click, calls suggest_resume_keywords() and stores results in session
state. Suggestions render as per-category chip panels (skills, domains,
keywords); clicking a chip appends it to the YAML and removes it from
the panel. A ✕ Clear button dismisses the panel entirely.
2026-03-05 15:13:57 -08:00
0e30096a88 feat: wire enhanced suggest_search_terms into Search tab (three-angle excludes)
- Remove old inline _suggest_search_terms (no blocklist/profile awareness)
- Replace with import shim delegating to scripts/suggest_helpers.py
- Call site now loads blocklist.yaml + user.yaml and passes them through
- Update button help text to reflect blocklist, mission values, career background
2026-03-05 15:08:07 -08:00
2bae1a92ed feat: add suggest_resume_keywords for skills/domains/keywords gap analysis
Replaces NotImplementedError stub with full LLM-backed implementation.
Builds a prompt from the last 3 resume positions plus already-selected
skills/domains/keywords, calls LLMRouter, and returns de-duped suggestions
in all three categories.
2026-03-05 15:00:53 -08:00
dbcd2710ae fix: guard mission_preferences values against non-string types in suggest_search_terms 2026-03-05 13:40:53 -08:00
5f1c372c0a feat: add suggest_search_terms with three-angle exclude analysis
Replaces NotImplementedError stub with a real LLMRouter-backed implementation
that builds a structured prompt covering blocklist alias expansion, values
misalignment, and role-type filtering, then parses the JSON response into
suggested_titles and suggested_excludes lists.

Moves LLMRouter import to module level so tests can patch it at
scripts.suggest_helpers.LLMRouter.
2026-03-05 13:15:25 -08:00
efe71150e3 docs: digest email parser design — LinkedIn/Adzuna/Ladders registry + Avocet bucket 2026-03-05 12:56:53 -08:00
8166204c05 fix: Settings widget crash, stale setup banners, Docker service controls
- Settings → Search: add-title (+) and Import buttons crashed with
  StreamlitAPIException when writing to _sp_titles_multi after it was
  already instantiated. Fix: pending-key pattern (_sp_titles_pending /
  _sp_locs_pending) applied before widget renders on next pass.

- Home setup banners: fired for email/notion/keywords even when those
  features were already configured. Add 'done' condition callables
  (_email_configured, _notion_configured, _keywords_configured) to
  suppress banners automatically when config files are present.

- Services tab start/stop buttons: docker CLI was unavailable inside
  the container so _docker_available was False and buttons never showed.
  Bind-mount host /usr/bin/docker (ro) + /var/run/docker.sock into the
  app container so it can control sibling containers via DooD pattern.
2026-03-04 12:11:23 -08:00
11997f8a13 fix: DEFAULT_DB respects STAGING_DB env var — was ignoring Docker-set path 2026-03-04 11:47:59 -08:00
e5d606ab4b feat: backup/restore script with multi-instance and legacy support
- create_backup() / restore_backup() / list_backup_contents() public API
- --base-dir PATH flag: targets any instance root (default: this repo)
  --base-dir /devl/job-seeker backs up the legacy Conda install
- _DB_CANDIDATES fallback: data/staging.db (Peregrine) or staging.db root (legacy)
- Manifest records source label (dir name), source_path, created_at, files, includes_db
- Added config/resume_keywords.yaml and config/server.yaml to backup lists
- 21 tests covering create, list, restore, legacy DB path, overwrite, roundtrip
2026-03-04 10:52:51 -08:00
db3dff268a fix: save form data to non-widget state on Next, fix disabled timing, pass page title 2026-03-03 15:17:45 -08:00
e9b389feb6 fix: llm_backend reads fallback_order, logs tee'd to data/.streamlit.log in Docker 2026-03-03 15:04:18 -08:00
483ca00f1a feat: paste/drag-drop image component, remove server-side Playwright capture button 2026-03-03 14:40:47 -08:00
ecad32cd6f fix: remove st.rerun() from dialog nav buttons — caused dialog to close on Next/Back 2026-03-03 13:28:26 -08:00
d05cb91401 fix: pass FORGEJO env vars into app container 2026-03-03 13:17:37 -08:00
3d17122334 fix: lazy-import playwright in screenshot_page, fix SQLite connection leak in collect_listings 2026-03-03 12:45:39 -08:00
2ab396bad0 feat: wire feedback button into app.py sidebar 2026-03-03 12:38:53 -08:00
199daebb87 feat: floating feedback button + two-step dialog (Streamlit shell) 2026-03-03 12:20:27 -08:00
f7f438df70 feat: feedback_api — screenshot_page with Playwright (graceful fallback) 2026-03-03 12:14:33 -08:00
e1f65d8fe9 feat: feedback_api — Forgejo label management + issue filing + attachment upload 2026-03-03 12:09:11 -08:00
20f9933e99 feat: feedback_api — build_issue_body 2026-03-03 12:00:01 -08:00
60dab647f2 feat: feedback_api — collect_logs + collect_listings 2026-03-03 11:56:35 -08:00
cad7b9ba35 chore: remove unused imports from feedback_api (will be re-added in later tasks) 2026-03-03 11:45:14 -08:00
5f466fa107 feat: feedback_api — mask_pii + collect_context 2026-03-03 11:43:35 -08:00
c3dc05fe34 chore: add playwright dep and Forgejo env config for feedback button 2026-03-03 11:38:14 -08:00
1efb033b6f docs: feedback button implementation plan (8 tasks, TDD) 2026-03-03 11:31:19 -08:00
2d9b8d10f9 docs: feedback button design (floating button, Forgejo integration, PII masking, screenshot support) 2026-03-03 11:22:20 -08:00
791e11d5d5 ci: add GitHub Actions pytest workflow 2026-03-02 20:44:33 -08:00
86613d0218 docs: add canonical-source banner and CI badge to README 2026-03-02 20:44:23 -08:00
5254212cb4 feat: issue templates, PR template, security redirect 2026-03-02 19:35:06 -08:00
435f2e71fd docs: add CONTRIBUTING.md with BSL policy and CLA note 2026-03-02 19:26:25 -08:00
0d6aa5975e docs: add SECURITY.md — responsible disclosure policy 2026-03-02 19:26:23 -08:00
476ede4267 feat: setup.sh activates .githooks on clone 2026-03-02 19:17:05 -08:00
a2f4102d78 feat: commit-msg hook enforces conventional commit format 2026-03-02 19:14:31 -08:00
0306b3716d feat: pre-commit hook blocks sensitive files and key patterns 2026-03-02 19:12:14 -08:00
adc3526470 docs: public mirror strategy design (GitHub + Codeberg + git hooks) 2026-03-02 18:49:03 -08:00
75499bc250 docs: update tier-system reference with BYOK policy + demo user.yaml
docs/reference/tier-system.md:
  - Rewritten tier table: free tier now described as "AI unlocks with BYOK"
  - New BYOK section explaining the policy and rationale
  - Feature gate table gains BYOK-unlocks? column
  - API reference updated: can_use, tier_label, has_configured_llm with examples
  - "Adding a new feature gate" guide updated to cover BYOK_UNLOCKABLE

demo/config/user.yaml:
  - Reformatted by YAML linter; added dismissed_banners for demo UX
2026-03-02 13:22:10 -08:00
1e5d354209 feat: BYOK unlocks LLM features regardless of tier
BYOK policy: if a user supplies any LLM backend (local ollama/vllm or
their own API key), they get full access to AI generation features.
Charging for the UI around a service they already pay for is bad UX.

app/wizard/tiers.py:
  - BYOK_UNLOCKABLE frozenset: pure LLM-call features that unlock with
    any configured backend (llm_career_summary, company_research,
    interview_prep, survey_assistant, voice guidelines, etc.)
  - has_configured_llm(): checks llm.yaml for any enabled non-vision
    backend; local + external API keys both count
  - can_use(tier, feature, has_byok=False): BYOK_UNLOCKABLE features
    return True when has_byok=True regardless of tier
  - tier_label(feature, has_byok=False): suppresses lock icon for
    BYOK_UNLOCKABLE features when BYOK is active

Still gated (require CF infrastructure, not just an LLM call):
  llm_keywords_blocklist, email_classifier, model_fine_tuning,
  shared_cover_writer_model, multi_user, all integrations

app/pages/2_Settings.py:
  - Compute _byok = has_configured_llm() once at page load
  - Pass has_byok=_byok to can_use() for _gen_panel_active
  - Update caption to mention BYOK as an alternative to paid tier

app/pages/0_Setup.py:
  - Wizard generation widget passes has_byok=has_configured_llm()
    to can_use() and tier_label()

tests/test_wizard_tiers.py:
  - 6 new BYOK-specific tests covering unlock, non-unlock, and
    label suppression cases
2026-03-02 11:34:36 -08:00