Vibecode Clipdrop
track this build5 phases, 15 steps, beginner friendly0%The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Clipdrop, run background removal, cleanup, relighting, and upscaling on local images. The hard boundary is specialized hosted models, api capacity, and polished mobile tools, plus frontier models, compute, and data.
You are building a lean indie version of Clipdrop. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Clipdrop · indie build A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | Python 3.12 orchestrating a local model server | the work is masks, tiling and bookkeeping rather than inference | | Models | Open inpainting and upscaling models run locally, with licences recorded | no images leave the machine, and the licence question is answered before the model is used | | Masks | Painted masks with feathering, stored alongside the job | a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust | | Tiling | Overlapping tiles with blended seams for large images | upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid | | Storage | Originals untouched, outputs plus a job record alongside | reproducibility is the property that makes the whole thing usable | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Python 3.12 or newer** · free - Why: Runs the orchestration, masking and tiling. - Get it: python.org or your package manager, then a virtual environment. - Verify: python3 --version prints 3.12 or higher - [ ] **A machine that can run image models, ideally with a GPU** · free with suitable hardware; renting GPU time is the alternative - Why: Inpainting and upscaling are slow without one, which changes whether batch processing is practical rather than whether it works. - Get it: Check what you have and time one job before committing to a folder of two hundred images. - Verify: One job completes in a time you can multiply by your batch size - [ ] **Models with licences you have read** · free to download; commercial use terms vary - Why: They are the engine and their licences differ in ways that matter for commercial work. - Get it: Download the models you intend to use and read each licence for commercial use before using it rather than after. - Verify: Each model runs and its licence is recorded with a check date - [ ] **Test images with a gradient and fine texture** · free - Why: Seams and blend errors are invisible on a busy photograph and unmistakable on a sky or a brick wall. - Get it: One photo with a large smooth sky and one with fine repeating texture. Keep both as fixtures. - Verify: Both are saved as fixtures - [ ] **A decision about what these images are for** · free - Why: It determines which model licences are acceptable and whether provenance should be embedded, and both are easier to decide before than after. - Get it: Write down whether the output is personal, commercial, or used in a context where an edit would mislead. One line, before Phase 5. - Verify: The decision is recorded and the licence check matches it ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. - specialized hosted models, API capacity, and polished mobile tools - frontier proprietary models - hosted GPU capacity - licensed training data - moderation and fast global delivery If one of those is essential to you, that is the reason to keep paying for Clipdrop, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Clipdrop The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a local image workbench for cleanup, object removal and upscaling, with reproducible jobs to replace Clipdrop. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train models. Open models exist for inpainting and upscaling and the work worth doing is the pipeline around them: masks that produce clean edges, tiling that does not leave seams, and jobs that can be re-run with the same settings and produce the same result. Be deliberate about one thing that is not technical. This produces images where content has been removed or invented, and the output is indistinguishable from a photograph. Keep a record of what was done to each image, and decide before you share anything whether that record travels with it. ### Stack (fixed, do not substitute) - Runtime: Python 3.12 orchestrating a local model server · the work is masks, tiling and bookkeeping rather than inference - Models: Open inpainting and upscaling models run locally, with licences recorded · no images leave the machine, and the licence question is answered before the model is used - Masks: Painted masks with feathering, stored alongside the job · a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust - Tiling: Overlapping tiles with blended seams for large images · upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid - Storage: Originals untouched, outputs plus a job record alongside · reproducibility is the property that makes the whole thing usable ### Data model (create this before Phase 1) - images(id, source_path, width, height, content_hash, imported_at) - jobs(id, image_id, kind, params_json, model_key, seed, mask_path, output_path, started_at, finished_at, state) · kind is inpaint, cleanup, upscale or relight - provenance(job_id, note) · what was changed, in words, for the record - models(key, name, source, licence, commercial_use, checked_on) - A job records its model, seed and every parameter. The same inputs and the same job record must produce the same output. ### Phase 1 · One masked operation, reproducibly Build: Import an image, paint a mask, run an inpainting model over the masked region, and write the result alongside the original. Record the model, the seed and every parameter. Then run it again and compare the outputs byte for byte. Trap: A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. Done when: An object is removed and the result looks plausible at full resolution. Re-running the recorded job produces a byte-identical output. The source image checksum is unchanged. The job record contains the model, seed and every parameter needed to reproduce it. Do not build yet: No feathering, tiling, upscaling or batch. ### Phase 2 · Masks with edges that do not show Build: Paint masks with an adjustable brush and feather the edge. Composite the model output back through the feathered mask rather than replacing a hard rectangle. Compare edges at full resolution against the original. Trap: Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. Done when: An edit across a smooth gradient shows no visible boundary at full resolution. Increasing the feather widens the blend rather than shifting it. Compositing happens in linear light, verified by comparing against a gamma-space composite on a gradient. The mask is stored with the job so it can be adjusted and rerun. Do not build yet: No upscaling or batch yet. ### Phase 3 · Upscaling large images without seams Build: Upscale in overlapping tiles, blending the overlaps rather than butting tiles together. Choose the tile size from available memory. Verify on an image with a smooth gradient and on one with fine repeating texture, which are the two cases that expose seams. Trap: Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. Done when: A large image upscales with no visible tile seam on a gradient at full resolution. Memory stays within budget during the upscale, verified by watching it. The output dimensions are exactly the requested multiple. Fine repeating texture shows no discontinuity at tile boundaries. Do not build yet: No batch or licensing work yet. ### Phase 4 · Batch and queue Build: Queue jobs with a concurrency limit sized to memory. Process a folder with one saved operation. Isolate failures so one bad image does not stop the run. Report progress and per-image outcomes. Trap: Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. Done when: A folder of thirty images processes unattended. A corrupt image is reported and the run continues. Concurrency stays within the configured limit and memory does not exceed budget, verified by watching a full run. Each output records its job for reproduction. Do not build yet: No licensing or provenance work yet. ### Phase 5 · Provenance, which is the honest part Build: Record a readable note per job describing what changed. Produce a provenance report for an image showing every operation applied. Decide deliberately whether that record is embedded in exported files or kept separately, and document the choice. Trap: An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. Done when: Every image has a readable provenance report listing its operations in order. The report survives export as a sidecar file. The decision about embedding provenance in image metadata is documented with its reasoning. An image with no operations reports as unmodified. Do not build yet: Licensing comes last. ### Phase 6 · Model licences and serving others Build: Record every model's licence and whether it permits commercial use. If you expose the pipeline to anyone else, add authentication, per-user limits and a queue. Then confirm the licences cover the use you are actually making. Trap: Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. Done when: Every model has its licence and commercial use status recorded with a check date. A model whose licence does not permit your use is blocked rather than warned about. An exposed endpoint requires authentication and enforces per-user limits. Exceeding concurrency queues rather than exhausting memory. Do not build yet: Nothing after this. ### Out of scope (and why) - The specialised hosted models behind the commercial product, which are trained for these exact tasks and beat general open models on the cases that matter. - API capacity and hosted processing, so an hour of work takes an hour of your machine's time. - Mobile capture with live preview, which is how most of these tools are actually used. - Any claim that an edited image is unmodified. The provenance record exists because that distinction matters. ### README must contain - That every job records its model, seed and parameters, and that reruns are byte-identical - That masks are feathered and compositing happens in linear light - That upscaling tiles with overlap and blending, and how to verify no seam - That every image carries a provenance record, and the decision about embedding it - Every model's licence and whether it permits your use ===== AGENTS.md ===== # Agent instructions · Clipdrop indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Python 3.12 orchestrating a local model server, Open inpainting and upscaling models run locally, with licences recorded, Painted masks with feathering, stored alongside the job, Overlapping tiles with blended seams for large images, Originals untouched, outputs plus a job record alongside. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ===== BUILD_PLAN.md ===== # Build plan · Clipdrop A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · One masked operation, reproducibly Removing an object works, and running the same job again produces the same image. ### Steps 1. Run a local model server Whichever you choose, running locally so images do not leave the machine. Files: `docs/setup.md` 2. Record everything a rerun needs Model, seed, parameters, mask. If a rerun needs something not recorded, the record is incomplete. Files: `src/jobs.py` 3. Verify determinism by rerunning Byte comparison. Do this before building anything else on the pipeline. Files: `tests/test_determinism.py` ### Done when - [ ] An object is removed plausibly at full resolution - [ ] A rerun produces a byte-identical output - [ ] The source checksum is unchanged - [ ] The job record is sufficient to reproduce the result ### Watch out - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. ## Phase 2 · Masks with edges that do not show The boundary between edited and original is invisible. ### Steps 1. Paint and feather masks Adjustable brush and feather radius, stored as an image alongside the job. Files: `src/mask.py` 2. Composite in linear light Convert, blend, convert back. Gamma-space blending darkens the seam. Files: `src/composite.py` 3. Inspect edges at full resolution On a gradient. This is where a hard mask or a gamma-space blend becomes obvious. ### Done when - [ ] No visible boundary on a gradient at full resolution - [ ] Feather radius widens the blend predictably - [ ] Linear light compositing is confirmed against a gamma-space comparison - [ ] The mask is stored and the job can be adjusted and rerun ### Watch out - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. ## Phase 3 · Upscaling large images without seams A large photo upscales without a visible grid across it. ### Steps 1. Tile with overlap A margin sized so blending has room. Compute tiles from the memory budget rather than a fixed number. Files: `src/tile.py` 2. Blend the overlaps A weighted blend across the margin, not a hard join. Files: `src/tile.py` 3. Test on gradient and texture Both. A gradient exposes blending errors and texture exposes alignment errors. ### Done when - [ ] No visible seam on a gradient at full resolution - [ ] Memory stays within budget during the upscale - [ ] Output dimensions are the exact requested multiple - [ ] Repeating texture shows no discontinuity at boundaries ### Watch out - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. ## Phase 4 · Batch and queue A folder of images processes unattended without exhausting the machine. ### Steps 1. Queue with a memory-derived limit From what you measured, not from a core count. Image models are memory bound. Files: `src/queue.py` 2. Isolate per-image failures Reported and skipped. One bad file must not cost an hour. Files: `src/batch.py` 3. Record a job per output So any output in a batch can be reproduced or adjusted individually. Files: `src/jobs.py` ### Done when - [ ] Thirty images process unattended - [ ] A corrupt image is reported without stopping the run - [ ] Concurrency and memory stay within budget - [ ] Every output has a reproducible job record ### Watch out - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. ## Phase 5 · Provenance, which is the honest part You can say what was done to an image, and decide whether that travels with it. ### Steps 1. Write a readable note per job What changed, in words. Parameters are for reproduction; the note is for a person. Files: `src/provenance.py` 2. Produce a per-image report Every operation in order. This is the artefact that answers the question later. Files: `src/report.py` 3. Decide about embedding In metadata or as a sidecar. Both are defensible; not deciding is not. Files: `docs/provenance.md` ### Done when - [ ] Every image has an ordered provenance report - [ ] The report survives export as a sidecar - [ ] The embedding decision is documented - [ ] An unmodified image reports as unmodified ### Watch out - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ## Not in this build - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. ## After v1, if you want it - A history view showing an image's versions with the job that produced each - Mask suggestion from a segmentation model, proposed rather than applied - A comparison view that flips between original and result at full resolution ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Your local model server. Nothing leaves the machine. MODEL_ENDPOINT=http://localhost:8188 # Required. Input directory. Never written to. SOURCE_DIR=./images/source # Required. Outputs, masks and job records. OUTPUT_DIR=./images/out # Required. Overlap between tiles when upscaling. Too small and blending has no room. TILE_OVERLAP_PX=64 # Required. Used to derive tile size and batch concurrency. Measured rather than guessed. MEMORY_BUDGET_GB=8 # Required. What outputs are for. Checked against model licences, and a mismatch blocks the job. DECLARED_USE=personal
You are building a lean indie version of Clipdrop. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Clipdrop · indie build A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | Python 3.12 orchestrating a local model server | the work is masks, tiling and bookkeeping rather than inference | | Models | Open inpainting and upscaling models run locally, with licences recorded | no images leave the machine, and the licence question is answered before the model is used | | Masks | Painted masks with feathering, stored alongside the job | a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust | | Tiling | Overlapping tiles with blended seams for large images | upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid | | Storage | Originals untouched, outputs plus a job record alongside | reproducibility is the property that makes the whole thing usable | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Python 3.12 or newer** · free - Why: Runs the orchestration, masking and tiling. - Get it: python.org or your package manager, then a virtual environment. - Verify: python3 --version prints 3.12 or higher - [ ] **A machine that can run image models, ideally with a GPU** · free with suitable hardware; renting GPU time is the alternative - Why: Inpainting and upscaling are slow without one, which changes whether batch processing is practical rather than whether it works. - Get it: Check what you have and time one job before committing to a folder of two hundred images. - Verify: One job completes in a time you can multiply by your batch size - [ ] **Models with licences you have read** · free to download; commercial use terms vary - Why: They are the engine and their licences differ in ways that matter for commercial work. - Get it: Download the models you intend to use and read each licence for commercial use before using it rather than after. - Verify: Each model runs and its licence is recorded with a check date - [ ] **Test images with a gradient and fine texture** · free - Why: Seams and blend errors are invisible on a busy photograph and unmistakable on a sky or a brick wall. - Get it: One photo with a large smooth sky and one with fine repeating texture. Keep both as fixtures. - Verify: Both are saved as fixtures - [ ] **A decision about what these images are for** · free - Why: It determines which model licences are acceptable and whether provenance should be embedded, and both are easier to decide before than after. - Get it: Write down whether the output is personal, commercial, or used in a context where an edit would mislead. One line, before Phase 5. - Verify: The decision is recorded and the licence check matches it ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. - specialized hosted models, API capacity, and polished mobile tools - frontier proprietary models - hosted GPU capacity - licensed training data - moderation and fast global delivery If one of those is essential to you, that is the reason to keep paying for Clipdrop, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Clipdrop The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a local image workbench for cleanup, object removal and upscaling, with reproducible jobs to replace Clipdrop. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train models. Open models exist for inpainting and upscaling and the work worth doing is the pipeline around them: masks that produce clean edges, tiling that does not leave seams, and jobs that can be re-run with the same settings and produce the same result. Be deliberate about one thing that is not technical. This produces images where content has been removed or invented, and the output is indistinguishable from a photograph. Keep a record of what was done to each image, and decide before you share anything whether that record travels with it. ### Stack (fixed, do not substitute) - Runtime: Python 3.12 orchestrating a local model server · the work is masks, tiling and bookkeeping rather than inference - Models: Open inpainting and upscaling models run locally, with licences recorded · no images leave the machine, and the licence question is answered before the model is used - Masks: Painted masks with feathering, stored alongside the job · a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust - Tiling: Overlapping tiles with blended seams for large images · upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid - Storage: Originals untouched, outputs plus a job record alongside · reproducibility is the property that makes the whole thing usable ### Data model (create this before Phase 1) - images(id, source_path, width, height, content_hash, imported_at) - jobs(id, image_id, kind, params_json, model_key, seed, mask_path, output_path, started_at, finished_at, state) · kind is inpaint, cleanup, upscale or relight - provenance(job_id, note) · what was changed, in words, for the record - models(key, name, source, licence, commercial_use, checked_on) - A job records its model, seed and every parameter. The same inputs and the same job record must produce the same output. ### Phase 1 · One masked operation, reproducibly Build: Import an image, paint a mask, run an inpainting model over the masked region, and write the result alongside the original. Record the model, the seed and every parameter. Then run it again and compare the outputs byte for byte. Trap: A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. Done when: An object is removed and the result looks plausible at full resolution. Re-running the recorded job produces a byte-identical output. The source image checksum is unchanged. The job record contains the model, seed and every parameter needed to reproduce it. Do not build yet: No feathering, tiling, upscaling or batch. ### Phase 2 · Masks with edges that do not show Build: Paint masks with an adjustable brush and feather the edge. Composite the model output back through the feathered mask rather than replacing a hard rectangle. Compare edges at full resolution against the original. Trap: Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. Done when: An edit across a smooth gradient shows no visible boundary at full resolution. Increasing the feather widens the blend rather than shifting it. Compositing happens in linear light, verified by comparing against a gamma-space composite on a gradient. The mask is stored with the job so it can be adjusted and rerun. Do not build yet: No upscaling or batch yet. ### Phase 3 · Upscaling large images without seams Build: Upscale in overlapping tiles, blending the overlaps rather than butting tiles together. Choose the tile size from available memory. Verify on an image with a smooth gradient and on one with fine repeating texture, which are the two cases that expose seams. Trap: Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. Done when: A large image upscales with no visible tile seam on a gradient at full resolution. Memory stays within budget during the upscale, verified by watching it. The output dimensions are exactly the requested multiple. Fine repeating texture shows no discontinuity at tile boundaries. Do not build yet: No batch or licensing work yet. ### Phase 4 · Batch and queue Build: Queue jobs with a concurrency limit sized to memory. Process a folder with one saved operation. Isolate failures so one bad image does not stop the run. Report progress and per-image outcomes. Trap: Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. Done when: A folder of thirty images processes unattended. A corrupt image is reported and the run continues. Concurrency stays within the configured limit and memory does not exceed budget, verified by watching a full run. Each output records its job for reproduction. Do not build yet: No licensing or provenance work yet. ### Phase 5 · Provenance, which is the honest part Build: Record a readable note per job describing what changed. Produce a provenance report for an image showing every operation applied. Decide deliberately whether that record is embedded in exported files or kept separately, and document the choice. Trap: An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. Done when: Every image has a readable provenance report listing its operations in order. The report survives export as a sidecar file. The decision about embedding provenance in image metadata is documented with its reasoning. An image with no operations reports as unmodified. Do not build yet: Licensing comes last. ### Phase 6 · Model licences and serving others Build: Record every model's licence and whether it permits commercial use. If you expose the pipeline to anyone else, add authentication, per-user limits and a queue. Then confirm the licences cover the use you are actually making. Trap: Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. Done when: Every model has its licence and commercial use status recorded with a check date. A model whose licence does not permit your use is blocked rather than warned about. An exposed endpoint requires authentication and enforces per-user limits. Exceeding concurrency queues rather than exhausting memory. Do not build yet: Nothing after this. ### Out of scope (and why) - The specialised hosted models behind the commercial product, which are trained for these exact tasks and beat general open models on the cases that matter. - API capacity and hosted processing, so an hour of work takes an hour of your machine's time. - Mobile capture with live preview, which is how most of these tools are actually used. - Any claim that an edited image is unmodified. The provenance record exists because that distinction matters. ### README must contain - That every job records its model, seed and parameters, and that reruns are byte-identical - That masks are feathered and compositing happens in linear light - That upscaling tiles with overlap and blending, and how to verify no seam - That every image carries a provenance record, and the decision about embedding it - Every model's licence and whether it permits your use ===== AGENTS.md ===== # Agent instructions · Clipdrop indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Python 3.12 orchestrating a local model server, Open inpainting and upscaling models run locally, with licences recorded, Painted masks with feathering, stored alongside the job, Overlapping tiles with blended seams for large images, Originals untouched, outputs plus a job record alongside. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ===== BUILD_PLAN.md ===== # Build plan · Clipdrop A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · One masked operation, reproducibly Removing an object works, and running the same job again produces the same image. ### Steps 1. Run a local model server Whichever you choose, running locally so images do not leave the machine. Files: `docs/setup.md` 2. Record everything a rerun needs Model, seed, parameters, mask. If a rerun needs something not recorded, the record is incomplete. Files: `src/jobs.py` 3. Verify determinism by rerunning Byte comparison. Do this before building anything else on the pipeline. Files: `tests/test_determinism.py` ### Done when - [ ] An object is removed plausibly at full resolution - [ ] A rerun produces a byte-identical output - [ ] The source checksum is unchanged - [ ] The job record is sufficient to reproduce the result ### Watch out - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. ## Phase 2 · Masks with edges that do not show The boundary between edited and original is invisible. ### Steps 1. Paint and feather masks Adjustable brush and feather radius, stored as an image alongside the job. Files: `src/mask.py` 2. Composite in linear light Convert, blend, convert back. Gamma-space blending darkens the seam. Files: `src/composite.py` 3. Inspect edges at full resolution On a gradient. This is where a hard mask or a gamma-space blend becomes obvious. ### Done when - [ ] No visible boundary on a gradient at full resolution - [ ] Feather radius widens the blend predictably - [ ] Linear light compositing is confirmed against a gamma-space comparison - [ ] The mask is stored and the job can be adjusted and rerun ### Watch out - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. ## Phase 3 · Upscaling large images without seams A large photo upscales without a visible grid across it. ### Steps 1. Tile with overlap A margin sized so blending has room. Compute tiles from the memory budget rather than a fixed number. Files: `src/tile.py` 2. Blend the overlaps A weighted blend across the margin, not a hard join. Files: `src/tile.py` 3. Test on gradient and texture Both. A gradient exposes blending errors and texture exposes alignment errors. ### Done when - [ ] No visible seam on a gradient at full resolution - [ ] Memory stays within budget during the upscale - [ ] Output dimensions are the exact requested multiple - [ ] Repeating texture shows no discontinuity at boundaries ### Watch out - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. ## Phase 4 · Batch and queue A folder of images processes unattended without exhausting the machine. ### Steps 1. Queue with a memory-derived limit From what you measured, not from a core count. Image models are memory bound. Files: `src/queue.py` 2. Isolate per-image failures Reported and skipped. One bad file must not cost an hour. Files: `src/batch.py` 3. Record a job per output So any output in a batch can be reproduced or adjusted individually. Files: `src/jobs.py` ### Done when - [ ] Thirty images process unattended - [ ] A corrupt image is reported without stopping the run - [ ] Concurrency and memory stay within budget - [ ] Every output has a reproducible job record ### Watch out - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. ## Phase 5 · Provenance, which is the honest part You can say what was done to an image, and decide whether that travels with it. ### Steps 1. Write a readable note per job What changed, in words. Parameters are for reproduction; the note is for a person. Files: `src/provenance.py` 2. Produce a per-image report Every operation in order. This is the artefact that answers the question later. Files: `src/report.py` 3. Decide about embedding In metadata or as a sidecar. Both are defensible; not deciding is not. Files: `docs/provenance.md` ### Done when - [ ] Every image has an ordered provenance report - [ ] The report survives export as a sidecar - [ ] The embedding decision is documented - [ ] An unmodified image reports as unmodified ### Watch out - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ## Not in this build - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. ## After v1, if you want it - A history view showing an image's versions with the job that produced each - Mask suggestion from a segmentation model, proposed rather than applied - A comparison view that flips between original and result at full resolution ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Your local model server. Nothing leaves the machine. MODEL_ENDPOINT=http://localhost:8188 # Required. Input directory. Never written to. SOURCE_DIR=./images/source # Required. Outputs, masks and job records. OUTPUT_DIR=./images/out # Required. Overlap between tiles when upscaling. Too small and blending has no room. TILE_OVERLAP_PX=64 # Required. Used to derive tile size and batch concurrency. Measured rather than guessed. MEMORY_BUDGET_GB=8 # Required. What outputs are for. Checked against model licences, and a mismatch blocks the job. DECLARED_USE=personal
You are building a production product version of Clipdrop. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # Clipdrop · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Clipdrop, run background removal, cleanup, relighting, and upscaling on local images. The hard boundary is specialized hosted models, api capacity, and polished mobile tools, plus frontier models, compute, and data. ## Product outcome An image workbench that reproduces any result from its job record, leaves no visible edges or seams, never touches an original, and keeps an honest record of what was changed. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - GPU-capable machine or user-supplied generation API - ComfyUI - model files with appropriate licenses - local storage ## Explicit non-goals for v1 - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. - specialized hosted models, API capacity, and polished mobile tools - frontier proprietary models - hosted GPU capacity - licensed training data - moderation and fast global delivery ## Success criteria - Reruns are confirmed byte-identical - No visible edge on the gradient fixture after a masked edit - No visible seam on the gradient fixture after upscaling - Every model licence is recorded and matches the declared use - Every image has a provenance report ===== BRIEF.md ===== # Build brief · Clipdrop The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a local image workbench for cleanup, object removal and upscaling, with reproducible jobs to replace Clipdrop. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train models. Open models exist for inpainting and upscaling and the work worth doing is the pipeline around them: masks that produce clean edges, tiling that does not leave seams, and jobs that can be re-run with the same settings and produce the same result. Be deliberate about one thing that is not technical. This produces images where content has been removed or invented, and the output is indistinguishable from a photograph. Keep a record of what was done to each image, and decide before you share anything whether that record travels with it. ### Stack (fixed, do not substitute) - Runtime: Python 3.12 orchestrating a local model server · the work is masks, tiling and bookkeeping rather than inference - Models: Open inpainting and upscaling models run locally, with licences recorded · no images leave the machine, and the licence question is answered before the model is used - Masks: Painted masks with feathering, stored alongside the job · a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust - Tiling: Overlapping tiles with blended seams for large images · upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid - Storage: Originals untouched, outputs plus a job record alongside · reproducibility is the property that makes the whole thing usable ### Data model (create this before Phase 1) - images(id, source_path, width, height, content_hash, imported_at) - jobs(id, image_id, kind, params_json, model_key, seed, mask_path, output_path, started_at, finished_at, state) · kind is inpaint, cleanup, upscale or relight - provenance(job_id, note) · what was changed, in words, for the record - models(key, name, source, licence, commercial_use, checked_on) - A job records its model, seed and every parameter. The same inputs and the same job record must produce the same output. ### Phase 1 · One masked operation, reproducibly Build: Import an image, paint a mask, run an inpainting model over the masked region, and write the result alongside the original. Record the model, the seed and every parameter. Then run it again and compare the outputs byte for byte. Trap: A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. Done when: An object is removed and the result looks plausible at full resolution. Re-running the recorded job produces a byte-identical output. The source image checksum is unchanged. The job record contains the model, seed and every parameter needed to reproduce it. Do not build yet: No feathering, tiling, upscaling or batch. ### Phase 2 · Masks with edges that do not show Build: Paint masks with an adjustable brush and feather the edge. Composite the model output back through the feathered mask rather than replacing a hard rectangle. Compare edges at full resolution against the original. Trap: Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. Done when: An edit across a smooth gradient shows no visible boundary at full resolution. Increasing the feather widens the blend rather than shifting it. Compositing happens in linear light, verified by comparing against a gamma-space composite on a gradient. The mask is stored with the job so it can be adjusted and rerun. Do not build yet: No upscaling or batch yet. ### Phase 3 · Upscaling large images without seams Build: Upscale in overlapping tiles, blending the overlaps rather than butting tiles together. Choose the tile size from available memory. Verify on an image with a smooth gradient and on one with fine repeating texture, which are the two cases that expose seams. Trap: Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. Done when: A large image upscales with no visible tile seam on a gradient at full resolution. Memory stays within budget during the upscale, verified by watching it. The output dimensions are exactly the requested multiple. Fine repeating texture shows no discontinuity at tile boundaries. Do not build yet: No batch or licensing work yet. ### Phase 4 · Batch and queue Build: Queue jobs with a concurrency limit sized to memory. Process a folder with one saved operation. Isolate failures so one bad image does not stop the run. Report progress and per-image outcomes. Trap: Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. Done when: A folder of thirty images processes unattended. A corrupt image is reported and the run continues. Concurrency stays within the configured limit and memory does not exceed budget, verified by watching a full run. Each output records its job for reproduction. Do not build yet: No licensing or provenance work yet. ### Phase 5 · Provenance, which is the honest part Build: Record a readable note per job describing what changed. Produce a provenance report for an image showing every operation applied. Decide deliberately whether that record is embedded in exported files or kept separately, and document the choice. Trap: An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. Done when: Every image has a readable provenance report listing its operations in order. The report survives export as a sidecar file. The decision about embedding provenance in image metadata is documented with its reasoning. An image with no operations reports as unmodified. Do not build yet: Licensing comes last. ### Phase 6 · Model licences and serving others Build: Record every model's licence and whether it permits commercial use. If you expose the pipeline to anyone else, add authentication, per-user limits and a queue. Then confirm the licences cover the use you are actually making. Trap: Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. Done when: Every model has its licence and commercial use status recorded with a check date. A model whose licence does not permit your use is blocked rather than warned about. An exposed endpoint requires authentication and enforces per-user limits. Exceeding concurrency queues rather than exhausting memory. Do not build yet: Nothing after this. ### Out of scope (and why) - The specialised hosted models behind the commercial product, which are trained for these exact tasks and beat general open models on the cases that matter. - API capacity and hosted processing, so an hour of work takes an hour of your machine's time. - Mobile capture with live preview, which is how most of these tools are actually used. - Any claim that an edited image is unmodified. The provenance record exists because that distinction matters. ### README must contain - That every job records its model, seed and parameters, and that reruns are byte-identical - That masks are feathered and compositing happens in linear light - That upscaling tiles with overlap and blending, and how to verify no seam - That every image carries a provenance record, and the decision about embedding it - Every model's licence and whether it permits your use ===== ARCHITECTURE.md ===== # Architecture · Clipdrop ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | Python 3.12 orchestrating a local model server | the work is masks, tiling and bookkeeping rather than inference | | Models | Open inpainting and upscaling models run locally, with licences recorded | no images leave the machine, and the licence question is answered before the model is used | | Masks | Painted masks with feathering, stored alongside the job | a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust | | Tiling | Overlapping tiles with blended seams for large images | upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid | | Storage | Originals untouched, outputs plus a job record alongside | reproducibility is the property that makes the whole thing usable | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Jobs | Parameters, seeds and reproducibility. | The record is the product. If a rerun needs something not in it, the record is incomplete. | | Masks | Selection and feathering. | Any painting implementation. Linear light compositing is a correctness property. | | Tiling | Large image handling. | Any tiling strategy with overlap and blending. Butted tiles are the failure mode. | | Queue | Batch concurrency within memory. | Sizing from measured memory rather than core count is what keeps long runs alive. | | Provenance | What was done to each image. | Never remove this. It is the part that makes the output honest. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `MODEL_ENDPOINT` · required · Your local model server. Nothing leaves the machine. - `SOURCE_DIR` · required · Input directory. Never written to. - `OUTPUT_DIR` · required · Outputs, masks and job records. - `TILE_OVERLAP_PX` · required · Overlap between tiles when upscaling. Too small and blending has no room. - `MEMORY_BUDGET_GB` · required · Used to derive tile size and batch concurrency. Measured rather than guessed. - `DECLARED_USE` · required · What outputs are for. Checked against model licences, and a mismatch blocks the job. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it. ===== AGENTS.md ===== # Agent instructions · Clipdrop product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Python 3.12 orchestrating a local model server, Open inpainting and upscaling models run locally, with licences recorded, Painted masks with feathering, stored alongside the job, Overlapping tiles with blended seams for large images, Originals untouched, outputs plus a job record alongside. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. - Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. ===== MILESTONES.md ===== # Delivery milestones · Clipdrop Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · One masked operation, reproducibly Removing an object works, and running the same job again produces the same image. ### Steps 1. Run a local model server Whichever you choose, running locally so images do not leave the machine. Files: `docs/setup.md` 2. Record everything a rerun needs Model, seed, parameters, mask. If a rerun needs something not recorded, the record is incomplete. Files: `src/jobs.py` 3. Verify determinism by rerunning Byte comparison. Do this before building anything else on the pipeline. Files: `tests/test_determinism.py` ### Done when - [ ] An object is removed plausibly at full resolution - [ ] A rerun produces a byte-identical output - [ ] The source checksum is unchanged - [ ] The job record is sufficient to reproduce the result ### Watch out - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. ## M2 · Masks with edges that do not show The boundary between edited and original is invisible. ### Steps 1. Paint and feather masks Adjustable brush and feather radius, stored as an image alongside the job. Files: `src/mask.py` 2. Composite in linear light Convert, blend, convert back. Gamma-space blending darkens the seam. Files: `src/composite.py` 3. Inspect edges at full resolution On a gradient. This is where a hard mask or a gamma-space blend becomes obvious. ### Done when - [ ] No visible boundary on a gradient at full resolution - [ ] Feather radius widens the blend predictably - [ ] Linear light compositing is confirmed against a gamma-space comparison - [ ] The mask is stored and the job can be adjusted and rerun ### Watch out - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. ## M3 · Upscaling large images without seams A large photo upscales without a visible grid across it. ### Steps 1. Tile with overlap A margin sized so blending has room. Compute tiles from the memory budget rather than a fixed number. Files: `src/tile.py` 2. Blend the overlaps A weighted blend across the margin, not a hard join. Files: `src/tile.py` 3. Test on gradient and texture Both. A gradient exposes blending errors and texture exposes alignment errors. ### Done when - [ ] No visible seam on a gradient at full resolution - [ ] Memory stays within budget during the upscale - [ ] Output dimensions are the exact requested multiple - [ ] Repeating texture shows no discontinuity at boundaries ### Watch out - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. ## M4 · Batch and queue A folder of images processes unattended without exhausting the machine. ### Steps 1. Queue with a memory-derived limit From what you measured, not from a core count. Image models are memory bound. Files: `src/queue.py` 2. Isolate per-image failures Reported and skipped. One bad file must not cost an hour. Files: `src/batch.py` 3. Record a job per output So any output in a batch can be reproduced or adjusted individually. Files: `src/jobs.py` ### Done when - [ ] Thirty images process unattended - [ ] A corrupt image is reported without stopping the run - [ ] Concurrency and memory stay within budget - [ ] Every output has a reproducible job record ### Watch out - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. ## M5 · Provenance, which is the honest part You can say what was done to an image, and decide whether that travels with it. ### Steps 1. Write a readable note per job What changed, in words. Parameters are for reproduction; the note is for a person. Files: `src/provenance.py` 2. Produce a per-image report Every operation in order. This is the artefact that answers the question later. Files: `src/report.py` 3. Decide about embedding In metadata or as a sidecar. Both are defensible; not deciding is not. Files: `docs/provenance.md` ### Done when - [ ] Every image has an ordered provenance report - [ ] The report survives export as a sidecar - [ ] The embedding decision is documented - [ ] An unmodified image reports as unmodified ### Watch out - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ## M6 · Model licences and serving others (production only) Everything you use is something you are allowed to use for what you are doing. ### Steps 1. Record every model licence Source, licence, commercial use, check date. One table, checked rather than assumed. Files: `docs/models.md` 2. Block rather than warn If a model's licence does not cover your declared use, the pipeline refuses it. Files: `src/models.py` 3. Authenticate and limit if exposed Per-user job limits and a queue sized to memory. Files: `src/server.py` ### Done when - [ ] Every model licence is recorded with a check date - [ ] A licence mismatch blocks rather than warns - [ ] An exposed endpoint requires authentication - [ ] Exceeding the limit queues rather than exhausting memory ### Watch out - Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. ===== OPERATIONS.md ===== # Operations · Clipdrop ## Backup Source images are irreplaceable and belong in a backup. Outputs regenerate from sources plus job records, which is the practical payoff of determinism, so the job database matters more than the output files. ## Restore Restore sources and the job database, then re-run a job and compare against a stored output. Byte equality is what proves the restore. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Memory during batch runs and per-job duration. A duration creeping up usually means tiles got smaller because memory pressure rose, which is worth knowing before a long run. ## Incident checklist A batch processed with wrong settings is fully recoverable because sources are untouched and jobs are reproducible. That is the reason for both rules and it justifies itself the first time a mask needs adjusting across thirty images. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Reruns are confirmed byte-identical - [ ] No visible edge on the gradient fixture after a masked edit - [ ] No visible seam on the gradient fixture after upscaling - [ ] Every model licence is recorded and matches the declared use - [ ] Every image has a provenance report ## Launch constraint Do not market omitted Clipdrop capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered. ===== .env.example ===== # Copy to .env and fill in. Never commit .env; this file documents it. # Required. Your local model server. Nothing leaves the machine. MODEL_ENDPOINT=http://localhost:8188 # Required. Input directory. Never written to. SOURCE_DIR=./images/source # Required. Outputs, masks and job records. OUTPUT_DIR=./images/out # Required. Overlap between tiles when upscaling. Too small and blending has no room. TILE_OVERLAP_PX=64 # Required. Used to derive tile size and batch concurrency. Measured rather than guessed. MEMORY_BUDGET_GB=8 # Required. What outputs are for. Checked against model licences, and a mismatch blocks the job. DECLARED_USE=personal
# Clipdrop · indie build A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Estimated effort: **weekend**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | Python 3.12 orchestrating a local model server | the work is masks, tiling and bookkeeping rather than inference | | Models | Open inpainting and upscaling models run locally, with licences recorded | no images leave the machine, and the licence question is answered before the model is used | | Masks | Painted masks with feathering, stored alongside the job | a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust | | Tiling | Overlapping tiles with blended seams for large images | upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid | | Storage | Originals untouched, outputs plus a job record alongside | reproducibility is the property that makes the whole thing usable | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **Python 3.12 or newer** · free - Why: Runs the orchestration, masking and tiling. - Get it: python.org or your package manager, then a virtual environment. - Verify: python3 --version prints 3.12 or higher - [ ] **A machine that can run image models, ideally with a GPU** · free with suitable hardware; renting GPU time is the alternative - Why: Inpainting and upscaling are slow without one, which changes whether batch processing is practical rather than whether it works. - Get it: Check what you have and time one job before committing to a folder of two hundred images. - Verify: One job completes in a time you can multiply by your batch size - [ ] **Models with licences you have read** · free to download; commercial use terms vary - Why: They are the engine and their licences differ in ways that matter for commercial work. - Get it: Download the models you intend to use and read each licence for commercial use before using it rather than after. - Verify: Each model runs and its licence is recorded with a check date - [ ] **Test images with a gradient and fine texture** · free - Why: Seams and blend errors are invisible on a busy photograph and unmistakable on a sky or a brick wall. - Get it: One photo with a large smooth sky and one with fine repeating texture. Keep both as fixtures. - Verify: Both are saved as fixtures - [ ] **A decision about what these images are for** · free - Why: It determines which model licences are acceptable and whether provenance should be embedded, and both are easier to decide before than after. - Get it: Write down whether the output is personal, commercial, or used in a context where an edit would mislead. One line, before Phase 5. - Verify: The decision is recorded and the licence check matches it ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. - specialized hosted models, API capacity, and polished mobile tools - frontier proprietary models - hosted GPU capacity - licensed training data - moderation and fast global delivery If one of those is essential to you, that is the reason to keep paying for Clipdrop, and the README should say so rather than pretend.
# Build brief · Clipdrop The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a local image workbench for cleanup, object removal and upscaling, with reproducible jobs to replace Clipdrop. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train models. Open models exist for inpainting and upscaling and the work worth doing is the pipeline around them: masks that produce clean edges, tiling that does not leave seams, and jobs that can be re-run with the same settings and produce the same result. Be deliberate about one thing that is not technical. This produces images where content has been removed or invented, and the output is indistinguishable from a photograph. Keep a record of what was done to each image, and decide before you share anything whether that record travels with it. ### Stack (fixed, do not substitute) - Runtime: Python 3.12 orchestrating a local model server · the work is masks, tiling and bookkeeping rather than inference - Models: Open inpainting and upscaling models run locally, with licences recorded · no images leave the machine, and the licence question is answered before the model is used - Masks: Painted masks with feathering, stored alongside the job · a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust - Tiling: Overlapping tiles with blended seams for large images · upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid - Storage: Originals untouched, outputs plus a job record alongside · reproducibility is the property that makes the whole thing usable ### Data model (create this before Phase 1) - images(id, source_path, width, height, content_hash, imported_at) - jobs(id, image_id, kind, params_json, model_key, seed, mask_path, output_path, started_at, finished_at, state) · kind is inpaint, cleanup, upscale or relight - provenance(job_id, note) · what was changed, in words, for the record - models(key, name, source, licence, commercial_use, checked_on) - A job records its model, seed and every parameter. The same inputs and the same job record must produce the same output. ### Phase 1 · One masked operation, reproducibly Build: Import an image, paint a mask, run an inpainting model over the masked region, and write the result alongside the original. Record the model, the seed and every parameter. Then run it again and compare the outputs byte for byte. Trap: A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. Done when: An object is removed and the result looks plausible at full resolution. Re-running the recorded job produces a byte-identical output. The source image checksum is unchanged. The job record contains the model, seed and every parameter needed to reproduce it. Do not build yet: No feathering, tiling, upscaling or batch. ### Phase 2 · Masks with edges that do not show Build: Paint masks with an adjustable brush and feather the edge. Composite the model output back through the feathered mask rather than replacing a hard rectangle. Compare edges at full resolution against the original. Trap: Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. Done when: An edit across a smooth gradient shows no visible boundary at full resolution. Increasing the feather widens the blend rather than shifting it. Compositing happens in linear light, verified by comparing against a gamma-space composite on a gradient. The mask is stored with the job so it can be adjusted and rerun. Do not build yet: No upscaling or batch yet. ### Phase 3 · Upscaling large images without seams Build: Upscale in overlapping tiles, blending the overlaps rather than butting tiles together. Choose the tile size from available memory. Verify on an image with a smooth gradient and on one with fine repeating texture, which are the two cases that expose seams. Trap: Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. Done when: A large image upscales with no visible tile seam on a gradient at full resolution. Memory stays within budget during the upscale, verified by watching it. The output dimensions are exactly the requested multiple. Fine repeating texture shows no discontinuity at tile boundaries. Do not build yet: No batch or licensing work yet. ### Phase 4 · Batch and queue Build: Queue jobs with a concurrency limit sized to memory. Process a folder with one saved operation. Isolate failures so one bad image does not stop the run. Report progress and per-image outcomes. Trap: Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. Done when: A folder of thirty images processes unattended. A corrupt image is reported and the run continues. Concurrency stays within the configured limit and memory does not exceed budget, verified by watching a full run. Each output records its job for reproduction. Do not build yet: No licensing or provenance work yet. ### Phase 5 · Provenance, which is the honest part Build: Record a readable note per job describing what changed. Produce a provenance report for an image showing every operation applied. Decide deliberately whether that record is embedded in exported files or kept separately, and document the choice. Trap: An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. Done when: Every image has a readable provenance report listing its operations in order. The report survives export as a sidecar file. The decision about embedding provenance in image metadata is documented with its reasoning. An image with no operations reports as unmodified. Do not build yet: Licensing comes last. ### Phase 6 · Model licences and serving others Build: Record every model's licence and whether it permits commercial use. If you expose the pipeline to anyone else, add authentication, per-user limits and a queue. Then confirm the licences cover the use you are actually making. Trap: Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. Done when: Every model has its licence and commercial use status recorded with a check date. A model whose licence does not permit your use is blocked rather than warned about. An exposed endpoint requires authentication and enforces per-user limits. Exceeding concurrency queues rather than exhausting memory. Do not build yet: Nothing after this. ### Out of scope (and why) - The specialised hosted models behind the commercial product, which are trained for these exact tasks and beat general open models on the cases that matter. - API capacity and hosted processing, so an hour of work takes an hour of your machine's time. - Mobile capture with live preview, which is how most of these tools are actually used. - Any claim that an edited image is unmodified. The provenance record exists because that distinction matters. ### README must contain - That every job records its model, seed and parameters, and that reruns are byte-identical - That masks are feathered and compositing happens in linear light - That upscaling tiles with overlap and blending, and how to verify no seam - That every image carries a provenance record, and the decision about embedding it - Every model's licence and whether it permits your use
# Agent instructions · Clipdrop indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Python 3.12 orchestrating a local model server, Open inpainting and upscaling models run locally, with licences recorded, Painted masks with feathering, stored alongside the job, Overlapping tiles with blended seams for large images, Originals untouched, outputs plus a job record alongside. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ## Known traps - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later.
# Build plan · Clipdrop A local workbench that takes an image, applies a masked operation such as removing an object or cleaning a blemish, upscales without visible tile seams, records every job with its settings so a result can be reproduced, and keeps the original untouched with a provenance record of what was changed. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · One masked operation, reproducibly Removing an object works, and running the same job again produces the same image. ### Steps 1. Run a local model server Whichever you choose, running locally so images do not leave the machine. Files: `docs/setup.md` 2. Record everything a rerun needs Model, seed, parameters, mask. If a rerun needs something not recorded, the record is incomplete. Files: `src/jobs.py` 3. Verify determinism by rerunning Byte comparison. Do this before building anything else on the pipeline. Files: `tests/test_determinism.py` ### Done when - [ ] An object is removed plausibly at full resolution - [ ] A rerun produces a byte-identical output - [ ] The source checksum is unchanged - [ ] The job record is sufficient to reproduce the result ### Watch out - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. ## Phase 2 · Masks with edges that do not show The boundary between edited and original is invisible. ### Steps 1. Paint and feather masks Adjustable brush and feather radius, stored as an image alongside the job. Files: `src/mask.py` 2. Composite in linear light Convert, blend, convert back. Gamma-space blending darkens the seam. Files: `src/composite.py` 3. Inspect edges at full resolution On a gradient. This is where a hard mask or a gamma-space blend becomes obvious. ### Done when - [ ] No visible boundary on a gradient at full resolution - [ ] Feather radius widens the blend predictably - [ ] Linear light compositing is confirmed against a gamma-space comparison - [ ] The mask is stored and the job can be adjusted and rerun ### Watch out - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. ## Phase 3 · Upscaling large images without seams A large photo upscales without a visible grid across it. ### Steps 1. Tile with overlap A margin sized so blending has room. Compute tiles from the memory budget rather than a fixed number. Files: `src/tile.py` 2. Blend the overlaps A weighted blend across the margin, not a hard join. Files: `src/tile.py` 3. Test on gradient and texture Both. A gradient exposes blending errors and texture exposes alignment errors. ### Done when - [ ] No visible seam on a gradient at full resolution - [ ] Memory stays within budget during the upscale - [ ] Output dimensions are the exact requested multiple - [ ] Repeating texture shows no discontinuity at boundaries ### Watch out - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. ## Phase 4 · Batch and queue A folder of images processes unattended without exhausting the machine. ### Steps 1. Queue with a memory-derived limit From what you measured, not from a core count. Image models are memory bound. Files: `src/queue.py` 2. Isolate per-image failures Reported and skipped. One bad file must not cost an hour. Files: `src/batch.py` 3. Record a job per output So any output in a batch can be reproduced or adjusted individually. Files: `src/jobs.py` ### Done when - [ ] Thirty images process unattended - [ ] A corrupt image is reported without stopping the run - [ ] Concurrency and memory stay within budget - [ ] Every output has a reproducible job record ### Watch out - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. ## Phase 5 · Provenance, which is the honest part You can say what was done to an image, and decide whether that travels with it. ### Steps 1. Write a readable note per job What changed, in words. Parameters are for reproduction; the note is for a person. Files: `src/provenance.py` 2. Produce a per-image report Every operation in order. This is the artefact that answers the question later. Files: `src/report.py` 3. Decide about embedding In metadata or as a sidecar. Both are defensible; not deciding is not. Files: `docs/provenance.md` ### Done when - [ ] Every image has an ordered provenance report - [ ] The report survives export as a sidecar - [ ] The embedding decision is documented - [ ] An unmodified image reports as unmodified ### Watch out - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ## Not in this build - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. ## After v1, if you want it - A history view showing an image's versions with the job that produced each - Mask suggestion from a segmentation model, proposed rather than applied - A comparison view that flips between original and result at full resolution
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Your local model server. Nothing leaves the machine. MODEL_ENDPOINT=http://localhost:8188 # Required. Input directory. Never written to. SOURCE_DIR=./images/source # Required. Outputs, masks and job records. OUTPUT_DIR=./images/out # Required. Overlap between tiles when upscaling. Too small and blending has no room. TILE_OVERLAP_PX=64 # Required. Used to derive tile size and batch concurrency. Measured rather than guessed. MEMORY_BUDGET_GB=8 # Required. What outputs are for. Checked against model licences, and a mismatch blocks the job. DECLARED_USE=personal
# Clipdrop · product brief ## Problem The core loop is buildable, but a dependable replacement becomes a real weekend or multi-day project. For Clipdrop, run background removal, cleanup, relighting, and upscaling on local images. The hard boundary is specialized hosted models, api capacity, and polished mobile tools, plus frontier models, compute, and data. ## Product outcome An image workbench that reproduces any result from its job record, leaves no visible edges or seams, never touches an original, and keeps an honest record of what was changed. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - GPU-capable machine or user-supplied generation API - ComfyUI - model files with appropriate licenses - local storage ## Explicit non-goals for v1 - Specialised hosted models trained for these tasks. - Hosted processing and API capacity. - Mobile capture with live preview. - Any claim that an edited image is unmodified. - specialized hosted models, API capacity, and polished mobile tools - frontier proprietary models - hosted GPU capacity - licensed training data - moderation and fast global delivery ## Success criteria - Reruns are confirmed byte-identical - No visible edge on the gradient fixture after a masked edit - No visible seam on the gradient fixture after upscaling - Every model licence is recorded and matches the declared use - Every image has a provenance report
# Build brief · Clipdrop The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a local image workbench for cleanup, object removal and upscaling, with reproducible jobs to replace Clipdrop. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Rule zero Do not train models. Open models exist for inpainting and upscaling and the work worth doing is the pipeline around them: masks that produce clean edges, tiling that does not leave seams, and jobs that can be re-run with the same settings and produce the same result. Be deliberate about one thing that is not technical. This produces images where content has been removed or invented, and the output is indistinguishable from a photograph. Keep a record of what was done to each image, and decide before you share anything whether that record travels with it. ### Stack (fixed, do not substitute) - Runtime: Python 3.12 orchestrating a local model server · the work is masks, tiling and bookkeeping rather than inference - Models: Open inpainting and upscaling models run locally, with licences recorded · no images leave the machine, and the licence question is answered before the model is used - Masks: Painted masks with feathering, stored alongside the job · a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust - Tiling: Overlapping tiles with blended seams for large images · upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid - Storage: Originals untouched, outputs plus a job record alongside · reproducibility is the property that makes the whole thing usable ### Data model (create this before Phase 1) - images(id, source_path, width, height, content_hash, imported_at) - jobs(id, image_id, kind, params_json, model_key, seed, mask_path, output_path, started_at, finished_at, state) · kind is inpaint, cleanup, upscale or relight - provenance(job_id, note) · what was changed, in words, for the record - models(key, name, source, licence, commercial_use, checked_on) - A job records its model, seed and every parameter. The same inputs and the same job record must produce the same output. ### Phase 1 · One masked operation, reproducibly Build: Import an image, paint a mask, run an inpainting model over the masked region, and write the result alongside the original. Record the model, the seed and every parameter. Then run it again and compare the outputs byte for byte. Trap: A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. Done when: An object is removed and the result looks plausible at full resolution. Re-running the recorded job produces a byte-identical output. The source image checksum is unchanged. The job record contains the model, seed and every parameter needed to reproduce it. Do not build yet: No feathering, tiling, upscaling or batch. ### Phase 2 · Masks with edges that do not show Build: Paint masks with an adjustable brush and feather the edge. Composite the model output back through the feathered mask rather than replacing a hard rectangle. Compare edges at full resolution against the original. Trap: Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. Done when: An edit across a smooth gradient shows no visible boundary at full resolution. Increasing the feather widens the blend rather than shifting it. Compositing happens in linear light, verified by comparing against a gamma-space composite on a gradient. The mask is stored with the job so it can be adjusted and rerun. Do not build yet: No upscaling or batch yet. ### Phase 3 · Upscaling large images without seams Build: Upscale in overlapping tiles, blending the overlaps rather than butting tiles together. Choose the tile size from available memory. Verify on an image with a smooth gradient and on one with fine repeating texture, which are the two cases that expose seams. Trap: Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. Done when: A large image upscales with no visible tile seam on a gradient at full resolution. Memory stays within budget during the upscale, verified by watching it. The output dimensions are exactly the requested multiple. Fine repeating texture shows no discontinuity at tile boundaries. Do not build yet: No batch or licensing work yet. ### Phase 4 · Batch and queue Build: Queue jobs with a concurrency limit sized to memory. Process a folder with one saved operation. Isolate failures so one bad image does not stop the run. Report progress and per-image outcomes. Trap: Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. Done when: A folder of thirty images processes unattended. A corrupt image is reported and the run continues. Concurrency stays within the configured limit and memory does not exceed budget, verified by watching a full run. Each output records its job for reproduction. Do not build yet: No licensing or provenance work yet. ### Phase 5 · Provenance, which is the honest part Build: Record a readable note per job describing what changed. Produce a provenance report for an image showing every operation applied. Decide deliberately whether that record is embedded in exported files or kept separately, and document the choice. Trap: An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. Done when: Every image has a readable provenance report listing its operations in order. The report survives export as a sidecar file. The decision about embedding provenance in image metadata is documented with its reasoning. An image with no operations reports as unmodified. Do not build yet: Licensing comes last. ### Phase 6 · Model licences and serving others Build: Record every model's licence and whether it permits commercial use. If you expose the pipeline to anyone else, add authentication, per-user limits and a queue. Then confirm the licences cover the use you are actually making. Trap: Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use. Done when: Every model has its licence and commercial use status recorded with a check date. A model whose licence does not permit your use is blocked rather than warned about. An exposed endpoint requires authentication and enforces per-user limits. Exceeding concurrency queues rather than exhausting memory. Do not build yet: Nothing after this. ### Out of scope (and why) - The specialised hosted models behind the commercial product, which are trained for these exact tasks and beat general open models on the cases that matter. - API capacity and hosted processing, so an hour of work takes an hour of your machine's time. - Mobile capture with live preview, which is how most of these tools are actually used. - Any claim that an edited image is unmodified. The provenance record exists because that distinction matters. ### README must contain - That every job records its model, seed and parameters, and that reruns are byte-identical - That masks are feathered and compositing happens in linear light - That upscaling tiles with overlap and blending, and how to verify no seam - That every image carries a provenance record, and the decision about embedding it - Every model's licence and whether it permits your use
# Architecture · Clipdrop ## Stack | Part | Choice | Why | | --- | --- | --- | | Runtime | Python 3.12 orchestrating a local model server | the work is masks, tiling and bookkeeping rather than inference | | Models | Open inpainting and upscaling models run locally, with licences recorded | no images leave the machine, and the licence question is answered before the model is used | | Masks | Painted masks with feathering, stored alongside the job | a hard-edged mask produces a visible boundary, and the mask is what you will want to adjust | | Tiling | Overlapping tiles with blended seams for large images | upscaling a large photo in one pass exhausts memory, and naive tiling leaves a grid | | Storage | Originals untouched, outputs plus a job record alongside | reproducibility is the property that makes the whole thing usable | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Jobs | Parameters, seeds and reproducibility. | The record is the product. If a rerun needs something not in it, the record is incomplete. | | Masks | Selection and feathering. | Any painting implementation. Linear light compositing is a correctness property. | | Tiling | Large image handling. | Any tiling strategy with overlap and blending. Butted tiles are the failure mode. | | Queue | Batch concurrency within memory. | Sizing from measured memory rather than core count is what keeps long runs alive. | | Provenance | What was done to each image. | Never remove this. It is the part that makes the output honest. | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - `MODEL_ENDPOINT` · required · Your local model server. Nothing leaves the machine. - `SOURCE_DIR` · required · Input directory. Never written to. - `OUTPUT_DIR` · required · Outputs, masks and job records. - `TILE_OVERLAP_PX` · required · Overlap between tiles when upscaling. Too small and blending has no room. - `MEMORY_BUDGET_GB` · required · Used to derive tile size and batch concurrency. Measured rather than guessed. - `DECLARED_USE` · required · What outputs are for. Checked against model licences, and a mismatch blocks the job. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
# Agent instructions · Clipdrop product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Python 3.12 orchestrating a local model server, Open inpainting and upscaling models run locally, with licences recorded, Painted masks with feathering, stored alongside the job, Overlapping tiles with blended seams for large images, Originals untouched, outputs plus a job record alongside. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ## Known traps - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. - Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use.
# Delivery milestones · Clipdrop Estimated effort: **weekend** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · One masked operation, reproducibly Removing an object works, and running the same job again produces the same image. ### Steps 1. Run a local model server Whichever you choose, running locally so images do not leave the machine. Files: `docs/setup.md` 2. Record everything a rerun needs Model, seed, parameters, mask. If a rerun needs something not recorded, the record is incomplete. Files: `src/jobs.py` 3. Verify determinism by rerunning Byte comparison. Do this before building anything else on the pipeline. Files: `tests/test_determinism.py` ### Done when - [ ] An object is removed plausibly at full resolution - [ ] A rerun produces a byte-identical output - [ ] The source checksum is unchanged - [ ] The job record is sufficient to reproduce the result ### Watch out - A pipeline with an unpinned seed or a nondeterministic sampler cannot reproduce a result, so a good output you want to adjust slightly has to be rediscovered by trial. Pin the seed, record it, and verify by running twice before building anything on top. ## M2 · Masks with edges that do not show The boundary between edited and original is invisible. ### Steps 1. Paint and feather masks Adjustable brush and feather radius, stored as an image alongside the job. Files: `src/mask.py` 2. Composite in linear light Convert, blend, convert back. Gamma-space blending darkens the seam. Files: `src/composite.py` 3. Inspect edges at full resolution On a gradient. This is where a hard mask or a gamma-space blend becomes obvious. ### Done when - [ ] No visible boundary on a gradient at full resolution - [ ] Feather radius widens the blend predictably - [ ] Linear light compositing is confirmed against a gamma-space comparison - [ ] The mask is stored and the job can be adjusted and rerun ### Watch out - Compositing through a hard-edged mask leaves a visible boundary, especially across a gradient like sky, and it is exactly the thing that makes an edit obvious. Feather the mask, and composite in linear light so the blend does not darken at the seam. ## M3 · Upscaling large images without seams A large photo upscales without a visible grid across it. ### Steps 1. Tile with overlap A margin sized so blending has room. Compute tiles from the memory budget rather than a fixed number. Files: `src/tile.py` 2. Blend the overlaps A weighted blend across the margin, not a hard join. Files: `src/tile.py` 3. Test on gradient and texture Both. A gradient exposes blending errors and texture exposes alignment errors. ### Done when - [ ] No visible seam on a gradient at full resolution - [ ] Memory stays within budget during the upscale - [ ] Output dimensions are the exact requested multiple - [ ] Repeating texture shows no discontinuity at boundaries ### Watch out - Tiling without overlap produces a visible grid, and overlapping without blending produces a doubled edge. Overlap by a meaningful margin and blend across it, then check on a sky gradient where any seam is unmistakable. ## M4 · Batch and queue A folder of images processes unattended without exhausting the machine. ### Steps 1. Queue with a memory-derived limit From what you measured, not from a core count. Image models are memory bound. Files: `src/queue.py` 2. Isolate per-image failures Reported and skipped. One bad file must not cost an hour. Files: `src/batch.py` 3. Record a job per output So any output in a batch can be reproduced or adjusted individually. Files: `src/jobs.py` ### Done when - [ ] Thirty images process unattended - [ ] A corrupt image is reported without stopping the run - [ ] Concurrency and memory stay within budget - [ ] Every output has a reproducible job record ### Watch out - Running several image jobs concurrently on a machine sized for one exhausts memory and takes the whole run down partway through, usually after an hour. Size the concurrency from actual memory use measured in Phase 3, and queue rather than parallelise beyond it. ## M5 · Provenance, which is the honest part You can say what was done to an image, and decide whether that travels with it. ### Steps 1. Write a readable note per job What changed, in words. Parameters are for reproduction; the note is for a person. Files: `src/provenance.py` 2. Produce a per-image report Every operation in order. This is the artefact that answers the question later. Files: `src/report.py` 3. Decide about embedding In metadata or as a sidecar. Both are defensible; not deciding is not. Files: `docs/provenance.md` ### Done when - [ ] Every image has an ordered provenance report - [ ] The report survives export as a sidecar - [ ] The embedding decision is documented - [ ] An unmodified image reports as unmodified ### Watch out - An edited image is indistinguishable from a photograph, and in some contexts, including journalism, evidence and marketplace listings, presenting one as the other is a real problem rather than a stylistic question. Keep the record whatever you decide about embedding it, because you cannot reconstruct it later. ## M6 · Model licences and serving others (production only) Everything you use is something you are allowed to use for what you are doing. ### Steps 1. Record every model licence Source, licence, commercial use, check date. One table, checked rather than assumed. Files: `docs/models.md` 2. Block rather than warn If a model's licence does not cover your declared use, the pipeline refuses it. Files: `src/models.py` 3. Authenticate and limit if exposed Per-user job limits and a queue sized to memory. Files: `src/server.py` ### Done when - [ ] Every model licence is recorded with a check date - [ ] A licence mismatch blocks rather than warns - [ ] An exposed endpoint requires authentication - [ ] Exceeding the limit queues rather than exhausting memory ### Watch out - Model licences in this area vary considerably and several permit research use only, which is not the same as producing images for a client or a product listing. Check each one specifically against what you are doing rather than assuming that open weights mean unrestricted use.
# Operations · Clipdrop ## Backup Source images are irreplaceable and belong in a backup. Outputs regenerate from sources plus job records, which is the practical payoff of determinism, so the job database matters more than the output files. ## Restore Restore sources and the job database, then re-run a job and compare against a stored output. Byte equality is what proves the restore. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Memory during batch runs and per-job duration. A duration creeping up usually means tiles got smaller because memory pressure rose, which is worth knowing before a long run. ## Incident checklist A batch processed with wrong settings is fully recoverable because sources are untouched and jobs are reproducible. That is the reason for both rules and it justifies itself the first time a mask needs adjusting across thirty images. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Reruns are confirmed byte-identical - [ ] No visible edge on the gradient fixture after a masked edit - [ ] No visible seam on the gradient fixture after upscaling - [ ] Every model licence is recorded and matches the declared use - [ ] Every image has a provenance report ## Launch constraint Do not market omitted Clipdrop capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# Copy to .env and fill in. Never commit .env; this file documents it. # Required. Your local model server. Nothing leaves the machine. MODEL_ENDPOINT=http://localhost:8188 # Required. Input directory. Never written to. SOURCE_DIR=./images/source # Required. Outputs, masks and job records. OUTPUT_DIR=./images/out # Required. Overlap between tiles when upscaling. Too small and blending has no room. TILE_OVERLAP_PX=64 # Required. Used to derive tile size and batch concurrency. Measured rather than guessed. MEMORY_BUDGET_GB=8 # Required. What outputs are for. Checked against model licences, and a mismatch blocks the job. DECLARED_USE=personal
$ choose a build depth, inspect the files, then open the complete pack in your agent
People still pay for Clipdrop because the product value is the model and compute fleet, not the prompt box around it. The recurring cost buys GPU procurement, model licensing, safety filters, queueing, storage, and rapid model replacement, not just the visible interface.
xspecialized hosted models, API capacity, and polished mobile tools
xfrontier proprietary models
xhosted GPU capacity
xlicensed training data
xmoderation and fast global delivery
Don't feel like building it? These folks already made it free.
no votes, no pay-to-list · just what's real
Vibecode Clipdrop
Kinda. The core of Clipdrop is buildable in a weekend with the prompt on this page, but there are real gaps: specialized hosted models, API capacity, and polished mobile tools, frontier proprietary models. Read the honest list above before committing.
How much does Clipdrop cost?
Clipdrop costs about $15/month (Pro, checked 2026-07-31), which is $180 per year.
What do I lose by replacing Clipdrop?
Honestly: specialized hosted models, API capacity, and polished mobile tools; frontier proprietary models; hosted GPU capacity; licensed training data; moderation and fast global delivery. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to Clipdrop?
Yes: NodeTool (Mask, remove backgrounds, retouch, relight, upscale and composite locally; the buttons exist, the cloud polish does not.) The prompt is for when you want it exactly your way.