Build Ghostfeed

KINDAreplaces $49/mosaves $588/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

An avatar video pipeline where consent and licensing are enforced as data rather than assumed, and the engineering is in driving a likeness from a performance convincingly enough to be watchable while marking every frame of output as synthetic.

estimated effort multi-daythe files for this build are in the project pack

ConsentA signed record per depicted person, with scope and revocationAvatarsBuilt only from footage whose subject consentedDrivingMotion and speech from a performance you own or licensedRenderingA local or self-hosted pipeline with provenance embeddedRuntimePython 3.12 with a job queue

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Orchestrates the pipeline and the job queue.

    Get it python.org or your package manager, then a virtual environment.

    Verify python3 --version prints 3.12 or higher

  2. have readyfree if you own the hardware; substantial to rent

    Why Sending someone's consented likeness to a third party service is a second disclosure they did not agree to, and renders are long enough that hosted costs add up quickly.

    Get it A machine with enough video memory for your chosen model, or a self-hosted instance you control.

    Verify A one minute render completes locally

  3. decidefree to draft; advice worth having if this is commercial

    Why Consent is enforced as data with named scopes, and inventing the scopes after people have signed means the signatures do not cover them.

    Get it Write the form, list the specific uses it permits, state the expiry and the withdrawal process. Have someone read it who is not you. open ↗

    Verify A written form exists naming specific permitted uses, an expiry and a withdrawal route

  4. have readyfree

    Why Every phase depends on there being a consented avatar, and the obvious first subject is yourself.

    Get it Record yourself, or someone who has signed the form, with the range of head movement the driving will need.

    Verify Footage exists with a matching signed consent record

  5. decidefree to read

    Why Eight states have specific statutes and there is no federal right, so the rule depends on where the depicted person is and where the work is distributed.

    Get it Identify where your subjects are and where output will be seen, then take the strictest applicable position.

    Verify A written note names the jurisdictions and the rule applied

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- people(id, name, contact, created_at)
- consents(id, person_id, scope_json, granted_at, evidence_path, expires_at, revoked_at) · scope names the uses permitted
- avatars(id, person_id, consent_id, source_footage_path, built_at, disabled_at)
- sources(id, kind, path, licence_id, rights_holder, obtained_from) · kind is performance, audio or background
- licences(id, name, allows_derivative, allows_commercial, allows_synthetic_use, source_url)
- renders(id, avatar_id, source_id, script_id, output_path, marked_synthetic, at)
- revocation_actions(consent_id, at, renders_withdrawn, avatars_disabled) · because withdrawal has to actually do something
- A render cannot exist without a live consent and a licensed source, and the foreign keys make that structural rather than procedural.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATABASE_URLsecretrequiredpostgres://localhost:5432/avatarsConsent records and provenance. The evidence you were permitted to make these.
CONSENT_REQUIREDrequiredalwaysPresent as a constant so the answer is visible. There is no other value.
SYNTHETIC_MARKINGrequiredalwaysEmbedded in the file and verified before export.
URL_INGESTIONrequireddisabledPresent as a constant. A clip from a URL arrives without a licence record.
RENDER_DIRrequired./rendersOutputs, each carrying provenance metadata in the file.
CONSENT_EVIDENCE_DIRrequired./consentsSigned forms. Retained longer than the renders they permit.

The build, in order

  1. Consent as a record with teeth

    An avatar cannot exist without a consent that can be withdrawn.

    1. A single boolean is not consent to anything specific.

      Files src/consent.py

    2. A foreign key, not a check. Structural rather than procedural.

      Files src/schema.sql

    3. Disabling the avatar and flagging renders. Consent without it is decorative.

      Files src/revoke.pytests/test_revocation.py

    done when · tick each as it passes
    watch out
    • A consent checkbox with no revocation path is not consent in any meaningful sense, and the first person who changes their mind will find there is nothing the tool can do. Build withdrawal in the same phase as consent, and make it actually disable the avatar and flag the renders rather than only setting a flag on a row.
  2. Source material you have rights to

    Every clip, voice and background carries a licence permitting synthetic use.

    1. Derivative, commercial, synthetic. A licence may allow one and not the others.

      Files src/licences.py

    2. Where the licence is silent, which is most of the time.

      Files src/licences.py

    3. Its absence is the design. A clip from a URL has no licence record.

      Files src/sources.py

    done when · tick each as it passes
    watch out
    • A licence that permits derivative works does not necessarily permit using the footage to drive a synthetic performance, and treating those as the same question is how a permitted use becomes an unpermitted one. Record synthetic use separately, and default it to not permitted where the licence is silent.
  3. Driving a likeness convincingly enough

    The avatar moves and speaks in a way that is watchable.

    1. Not from text. Estimated timing drifts within a sentence and is very visible.

      Files src/lipsync.py

    2. Where these pipelines produce their worst artefacts.

      Files src/drive.py

    3. Shipping a bad render is worse than reporting one.

      Files src/quality.py

    done when · tick each as it passes
    watch out
    • Lip movement estimated from text rather than from the audio's actual phoneme timings drifts out of sync within a sentence, and unlike a caption drifting, a mouth out of sync is immediately and viscerally noticeable. Take the timings from the speech itself.
  4. Marking every output as what it is

    No file leaves this pipeline without being identifiable as synthetic.

    1. A database column is lost the moment the file is copied.

      Files src/marking.py

    2. Read from the file. Test by stripping it deliberately.

      Files src/export.pytests/test_marking.py

    3. Metadata satisfies machine readability, not human disclosure.

      Files src/overlay.py

    done when · tick each as it passes
    watch out
    • Marking in the database and not in the file means the marking is lost the moment the file is copied anywhere, which is immediately. The mark has to travel with the bytes, and the export path has to read it back from the file rather than trusting a column.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more ai video.