Community-maintained open-source project for reporting and reviewing suspected ghost job postings.
Public site | Report a suspected ghost job | Community roadmap
Ghost Sweep helps job seekers submit good-faith reports about suspected ghost job postings. Community reports are unverified allegations until moderation is complete. The project protects personal information and does not present allegations as established facts.
Status: Active development public MVP. Not production-complete. Volunteer-maintained; no paid contributor roles.
| Link | URL |
|---|---|
| Public site | https://codethor0.github.io/ghost-sweep/ |
| Report form | https://forms.gle/PsjaYrbrCjAgZXjW8 |
| Repository | https://github.com/codethor0/ghost-sweep |
- Provides a public landing page and Google Form for suspected ghost job reports
- Requires human moderation before reports are treated as credible
- Maintains open-source code for future integrity scoring, moderation UI, and local Docker development
- Documents privacy boundaries between public code and private submission data
- Does not publicly host the full backend API today
- Does not automatically verify or publish allegations
- Does not expose raw Form or Sheet submission data in the repository
- Does not run production Sheet import or
--apply - Does not promise paid roles or production readiness
See docs/reporting-and-moderation-policy.md.
flowchart LR
A[Job seeker] --> B[GitHub Pages public site]
B --> C[Google Form]
C --> D[Private Google Sheet]
D --> E[Manual moderation]
E --> F[Future reviewed workflow]
flowchart LR
A[Contributor selects issue] --> B[Creates branch or fork]
B --> C[Opens draft pull request]
C --> D[CI checks]
D --> E[Maintainer review]
E --> F[Protected merge to main]
Maintainers: @codethor0 (owner), @bgreg (community review lead).
- Read CONTRIBUTING.md, GOVERNANCE.md, and docs/contributor-onboarding.md
- Start with Issue #15: Community contribution roadmap
- Comment on an issue before substantial work
- Open a draft pull request early
- Follow CODE_OF_CONDUCT.md and SECURITY.md
Safe lanes: documentation, tests, job URL validation, accessibility, public MVP usability. Approval required for auth, schema, deploy, CI permissions, Sheet import, and --apply.
Job seekers often invest time in postings that remain open without hiring intent, receive no recruiter follow-up, or are reposted repeatedly without closure. Hiring transparency is uneven, and public information is fragmented across boards, employer sites, and anecdotal reports.
ghost-sweep collects structured, evidence-backed reports about job postings and companies, calculates documented integrity scores, and gives employers a path to verify active roles, respond to reports, and dispute incorrect information.
The platform uses risk-signal language. It does not make unsupported legal accusations.
flowchart TB
subgraph public [Public today]
P[GitHub Pages]
F[Google Form]
end
subgraph private [Private today]
S[Google Sheet moderation]
end
subgraph local [Local Docker only]
B[FastAPI backend]
DB[(PostgreSQL)]
R[(Redis)]
end
P --> F
F --> S
B --- DB
B --- R
S -.->|import blocked| B
| Layer | Hosting | Status |
|---|---|---|
| Public landing + report CTA | GitHub Pages | Live |
| Report intake | Google Form | Live |
| Moderation queue | Google Sheet | Private; manual |
| Full app | Local Docker | Not publicly hosted |
| Production import | Not enabled | --apply blocked; Live Gates 11/12 BLOCKED-LIVE |
ghost-sweep/
backend/ FastAPI API, scoring engine, auth, moderation services
frontend/ Next.js web application (local Docker; server-mode)
public-mvp/ Canonical static MVP source (mirrored to repo root for GitHub Pages)
extension/ Manifest V3 browser extension for job board overlays
docs/ Architecture, API, scoring, moderation, legal guidance
.github/ CI workflows and community templates
Data stores:
- PostgreSQL 15 for primary records
- Redis 7 for auth rate limiting and refresh token storage
Backend: Python 3.11, FastAPI, SQLAlchemy 2.0 async, Alembic, Pydantic v2, PostgreSQL 15, Redis 7
Frontend: Next.js 16.2.9, React, TypeScript strict mode, Tailwind CSS
Extension: Chrome and Firefox Manifest V3
cp .env.example .env
docker compose up -d postgres postgres_test redis
docker compose up --build backend frontendOptional local demo data (development only):
cd backend
python3.11 scripts/seed_demo_data.pyThis creates a demo company and job posting when ENVIRONMENT=development. It is idempotent and refuses to run in staging or production.
For employer/moderation live validation without the seed script, see SQL bootstrap examples in docs/local-docker-validation.md. SQL bootstrap is for local validation only, not product UX.
Validation artifacts must redact tokens. See docs/validation-artifacts.md.
API: http://localhost:8000
Frontend: http://localhost:3000
The free public launch path uses a standalone static site. Source files live in public-mvp/; root index.html, styles.css, and .nojekyll mirror that folder for GitHub Pages (branch deploy supports / or /docs only).
After editing public-mvp/, sync the root mirror:
python3.11 scripts/sync_public_mvp.py
python3.11 scripts/validate_public_mvp.py| Layer | Hosting | Status |
|---|---|---|
| Public landing + report CTA | GitHub Pages (root mirror of public-mvp/) |
Live at https://codethor0.github.io/ghost-sweep/ |
| Report intake | Google Form -> Google Sheet | Live; manual review per moderation-sop.md |
| Full app (FastAPI/Postgres/Redis) | Local Docker only | Not publicly hosted |
| Live scoring database | Not hosted | Deferred |
GitHub Pages serves static HTML/CSS/JS only. It cannot run FastAPI, PostgreSQL, or Redis. The Batch 6C Next.js frontend is server-mode and is not GitHub Pages-ready without separate changes.
Preview the static MVP locally:
python3 -m http.server 8080 --directory public-mvpValidate before deploy:
python3.11 scripts/validate_public_mvp.pySee docs/google-form-intake-spec.md, docs/public-launch-checklist.md, docs/post-launch-roadmap.md, and docs/sheet-import-design.md.
The Google Form URL is https://forms.gle/PsjaYrbrCjAgZXjW8. Raw applicant emails must not be published.
Current main includes public launch (Batches 8A--10E), Sheet import dry-run (Batch 12A), apply-mode design (Batch 12B), offline verification (Batch 12F-P), Section 18 MVP amendment (Batch 12S), and moderation planning docs (Batches 13E--14E). The public static MVP and Google Form intake are live; the full application remains local Docker only.
Live public surfaces:
- Repository: public — https://github.com/codethor0/ghost-sweep
- GitHub Pages MVP: https://codethor0.github.io/ghost-sweep/
- Google Form intake: https://forms.gle/PsjaYrbrCjAgZXjW8
- Google Sheet moderation: manual review per moderation-sop.md
Privacy and moderation:
- Form and Sheet submission data remain private and are not published in the repository
- Reports require moderation before being treated as credible
- See docs/reporting-and-moderation-policy.md
Sheet import pipeline:
- Batch 12A (shipped): dry-run CLI —
scripts/sheet_import_dry_run.py,scripts/verify_sheet_columns.py; no database writes - Batch 12B (shipped): apply-mode design — sheet-import-apply-design.md
- Batch 12F-P / 12S (shipped): offline post-upload artifact verification ACCEPTED-MVP
- Live Sheet export proof: BLOCKED-LIVE
--applyimplementation: not implemented; blocked- Production import automation: not enabled
Current limitations:
- No publicly hosted backend or live scoring database
- No public moderation UI (planning docs exist; implementation deferred)
- No production Sheet import automation
- Extension has no backend API integration yet
- Volunteer project; no guaranteed staffing or paid roles
CI:
- GitHub Actions CI passes on latest
main(backend, frontend, extension smoke, public-mvp validator). - Local verification remains required before every push and pull request.
Implemented backend (through Batch 6B):
- Auth: register, login,
/me, refresh, logout - Auth rate limiting
- Company read APIs
- Job posting read APIs
- Report create/read/list
- Votes
- Employer claims (submit, admin approve/reject, migration 002 constraints)
- Moderation queue
- Report verify/dismiss
- Employer responses (auto-dispute from
pendingorverified) - Scoring recalculation and score snapshots
- Audit logging (reports, votes, claims, moderation, employer responses)
Job URL validation (Batch 6D foundation, offline only):
- Pure Python helper module:
backend/app/services/job_url_validation.py - Normalizes http/https URLs and detects likely ATS or career-page providers
- Unit tests only; not wired to backend API routes; no network calls
Contributor readiness:
- GitHub issue templates, PR template, CODEOWNERS, and label taxonomy documented in docs/labels.md
- Community governance: GOVERNANCE.md, CODE_OF_CONDUCT.md, SECURITY.md
- Maintainer review lead: @bgreg (Admin)
- Project owner: @codethor0
Implemented frontend (Batch 6C):
- API client for existing backend read and write endpoints
- Register and login forms
- In-memory access token session (React state only; lost on page refresh)
- Dashboard (
GET /api/v1/auth/me) - Companies list and detail with integrity scores
- Job posting detail with risk scores
- Report submission form (
POST /api/v1/reports) - Home health probe and extension
posting_urlhandoff display
Scaffold (not backend-wired):
- Browser extension: MV3 popup reads active tab URL and opens frontend with
?posting_url=; no backend API calls
Deferred (not publicly hosted):
- Public backend hosting and live scoring database
- Sheet import
--applymode (design complete; implementation blocked; live export proof required before production automation) - Google Sheet to backend import automation (dry-run only; offline gate ACCEPTED-MVP; production import deferred)
- Public moderation UI and evidence file upload
- Extension backend API integration
- Wiring job URL validation into public API or intake flows
- Frontend moderation, employer, and admin UI
- Frontend refresh-token handling
- Remaining dependency advisories (see docs/dependency-audit.md; Issue #4)
GitHub repository: https://github.com/codethor0/ghost-sweep (public)
Live Docker validation notes: docs/local-docker-validation.md
Backend:
cd backend
python3.11 -m pip install -e ".[dev]"
pytest tests/test_scoring.py
uvicorn app.main:app --reloadFrontend:
cd frontend
npm install
npm run devBackend verification:
cd backend && python3.11 -m py_compile $(find app tests alembic -name "*.py")
cd backend && black --check --quiet app tests alembic
cd backend && flake8 app tests alembic
cd backend && mypy --strict .
cd backend && TEST_DATABASE_URL="postgresql+asyncpg://ghost_sweep:ghost_sweep@localhost:5433/ghost_sweep_test" TEST_REDIS_URL="redis://localhost:6379/1" pytest -v --cov=app --cov-report=term-missing --cov-fail-under=80
cd backend && bandit -r app
cd backend && pip-auditFrontend verification:
cd frontend && npm run lint
cd frontend && npm run typecheck
cd frontend && npm test
cd frontend && npm audit --audit-level=highExtension verification:
node extension/tests/smoke.test.mjsDocker verification:
docker compose config
docker compose build
docker compose up -d
docker compose psRead CONTRIBUTING.md, GOVERNANCE.md, AGENTS.md, and CODE_OF_CONDUCT.md before opening a pull request.
- Community roadmap (Issue #15)
- Support and community help
- Security policy
- Reporting and moderation policy
- Contributor onboarding
- Changelog
MIT. See LICENSE.