Skip to content

About

Ghostmaxxing because if the world stalks you become a ghost!

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Latest commit

 

History

290 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ghostmaxxing

Unit Test Coverage

CI Docs Source License

Release: 1.1.0 · 1 November 2026

Ghostmaxxing is a static, browser-side lab and an optional Docker-packaged local fuzzer for testing face-recognition camouflage. Point a webcam at your face for an interactive test, or give the fuzzer a controlled face-turn video and search many Ghostyle recipes across its clean poses. The browser tools run on the device; the fuzzer keeps its video and outputs in the local Docker data volume unless you deliberately copy or share them.

It is not a protection product and it does not promise anonymity. It makes parts of a face-recognition pipeline visible, testable, and discussable.

Who this README is for

This page is the developer entry point. Three audiences, three documents:

  • This README — clone it, run it, test it, build the docs. (You are here.)
  • Technical documentation — module map, runtime architecture, the Ghostyle plugin API, and the generated JSDoc reference. Locally: run npm run docs and open docs/.
  • The public site — the lab, the vision, the research references, and the reporting channel, written for workshop participants and curious readers rather than for developers.

Read the disclaimer first

A result in this lab is a local, conditional finding, not a general protection claim. The detectors and models are open-source; results depend on the model, camera, lighting, pose, distance, thresholds, and context. A look that defeats the local match here may not affect any other system, and a human watching camera footage can often still recognise someone wearing makeup. Local evasion is not real-world protection. Use consenting test subjects, and never present an experimental overlay as an operational safety guarantee.

Quickstart

git clone https://github.com/vecna/ghostmaxxing.git
cd ghostmaxxing
npm install          # Playwright (the local fuzzer's runtime) + dev tooling (tests, docs, validation)
npm start            # serves the repo and opens /lab.html

npm install --omit=dev installs only what npm run localfuzzer needs (the Docker image does this). npm start runs a small dependency-free static file server (scripts-dev/static-server.cjs) bound to this machine only; npm start -- --host 0.0.0.0 makes it reachable from a phone. There is no build step, and any static server works:

npm run serve        # http://localhost:8080/ (frontend only)
npm run serve:integrated # stage the client, then serve it from gstmxx-backend
npm run test:integration # isolated same-origin gallery lifecycle
python3 -m http.server 8000

Entry points once served:

  • /lab.html — the main webcam / AR lab (the app).
  • / (index.html) — public landing page.
  • /about.html — project vision and context.
  • NINA reporting guidance — confidential whistleblowing, managed by NINA’s Universal Union.
  • Ghòstati! workshops — NINA’s facilitator guide and Signal group.
  • /loader.html — internal MP4 loader for repeatable 2D/3D video tests.
  • /realtime.html — temporal face-descriptor measurements from a camera or local video.
  • /docs/guides/localfuzzer.html — run the Docker-packaged Local Fuzzer.
  • /docs/guides/localfuzzer-report.html — interpret every number and visualization in its report.
  • /projects/ — products, prototypes, and practices pursuing complementary anti-surveillance approaches.
  • /references/ — cultural and technical source archive reached through the related-projects section.
  • /docs/ — technical documentation (after npm run docs).

Common tasks

npm run check              # validator + unit tests (run before proposing changes)
npm run test:unit          # Vitest unit tests
npm run test:unit -- --coverage
npm run test:e2e           # Playwright browser tests
npm run test:e2e:realtime  # Focused realtime camera/video workflow
npm run localfuzzer        # Local service on http://127.0.0.1:11111 (Node/ffmpeg setup)
npm run docs               # generate the JSDoc site into docs/jsdoc/
npm run docs:functional    # generate the public task guides into docs/
npm run validate:ghostyles # validate every ghostyle in ghostyles/
npm run validate:ghostyle -- ghostyles/your-slug.js   # validate one
npm run update:references  # rebuild references/index.html from REFERENCES.json
npm run update:genealogy   # redraw genealogy.html from REFERENCES.json + PROJECTS.json (python3)
npm run update:projects    # rebuild projects/index.html from PROJECTS.json
npm run i18n:extract       # regenerate the .pot / summary CSV for translation
npm run docs:screenshots -- --locale en,it --loader-time 3 # regenerate screenshots for functionality docs, also with --include-brush

New to contributing a Ghostyle? See CONTRIBUTING.md and the Ghostyle Authoring Guide (first tutorial in the docs sidebar).

What a Ghostyle is

A Ghostyle is a small JavaScript module that draws a face-anchored overlay and can be tested live against the recognition pipeline. It exposes onDraw (2D, face-api landmarks) and/or paintUV (UV/3D, MediaPipe mesh). Start from the heavily commented ghostyles/00-template.js, then add your { id, url } line to ghostyles.json.

The plugin contract, capability detection, and header-metadata policy are documented in the technical docs and the authoring guide — kept there so they live in one place only.

Internationalization

Runtime translations for English, Italian, and Portuguese are shipped through lab-js/i18n.js (a single inline message catalog + data-i18n* attributes + t() in JS). There is no locales/ directory and no build step. Translated pages currently include index.html, lab.html, and loader.html; other static pages are English-baseline until they add data-i18n* bindings. See translations/README.md for the add-a-string / add-a-language workflow, and run npm run i18n:extract after adding user-facing strings.

Privacy, data, and limitations

  • Face descriptors and test state are stored locally in the browser (IndexedDB), not posted to a server by the default app flow.
  • Webcam access is governed by the browser permission model.
  • Local descriptors persist until you clear them; screenshots, recordings, and exports are sensitive biometric-adjacent material.
  • CDN-loaded libraries and model weights still create external network requests. For workshops or higher-risk demos, prefer self-hosting the model and library assets rather than relying on third-party CDNs.
  • Detection failure, landmark instability, and match failure are different outcomes — they must not be collapsed into "anonymity".

Field reports: public-space face recognition

If you know of a place where facial recognition is being deployed, tested, procured, or hidden in public infrastructure, the project runs a third-party GlobaLeaks node. See NINA reporting guidance for how to report safely and what happens next. Reports about suppliers, technology, data access, deployment context, limits, and abuses are project inputs, not side notes.

References dataset

projects/PROJECTS.json is the deliberately compact catalogue of related products, prototypes, and public practices. Run npm run update:projects to regenerate projects/. Its maintainer and LLM-agent ingestion contract lives in projects/CONTRIBUTING-PROJECTS.md.

references/REFERENCES.json is a curated, schema-validated dataset of artistic, research, and activism references around face obfuscation and adversarial appearance design. The curation protocol and maintenance notes live in references/NOTES.md; npm run update:references regenerates the browsable references/ page. Browse it live at ghostmaxxing.vecna.eu/references/.

Both datasets also feed genealogy.html: every reference and every project is drawn at its year, in the row its target tags select. Run npm run update:genealogy after editing either file.

CHANGELOG

1.1.0 (1 November 2026)

  • Added the Docker-packaged Local Fuzzer, its browser interface, reproducible Ghostyle search recipes, comparison workflow, and detailed HTML reports.
  • Added two measured, generated Ghostyles and expanded the fuzzer documentation with guidance for interpreting scores, pose coverage, and limitations.
  • Reworked site navigation and project attribution, clarified the boundary between Ghostmaxxing and NINA's Ghòstati! initiative, and fixed the homepage carousel.
  • Moved the supported runtime to Node.js 24, reduced dependencies, refreshed CI and Docker workflows, and expanded the generated code map.

1.0.0 (15 October 2026)

  • Published the first stable release of the browser lab, documentation, Ghostyle interface, reference archive, and local analysis tools.

Provenance

Ghostmaxxing is the international evolution of Ghòstati, a NINA.watch adversarial-makeup workshop. The original Italian-only workshop deployment remains frozen and live at sindacato.nina.watch/ghostati/; it is legacy and is not maintained as part of this repository.

License

AGPL-3.0-or-later. Ghostyles are individually copyable modules — keep the license header travelling with the file.

Hosting the lab on another domain

The browser lab may be served from a subdirectory. NINA imports it under /ghostati/. Public API and media URLs use lab-js/backend-url.js: localhost (including loopback IPs) uses http://localhost:4040, the backend default; the production hostname keeps its origin; all other hosts use https://ghostmaxxing.vecna.eu. Recognition models remain local. Private receipt links stay on the frontend that created them; their deletion requests use the backend. The backend must allow cross-origin POST/DELETE and the X-Delete-Token preflight header.

About

Ghostmaxxing because if the world stalks you become a ghost!

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages