Anti-Manipulation is a Flask prototype of the demo system.
This repository is meant to be easy to hand off. It already has:
- a working Flask backend,
- a dataset-aware frontend,
- bundled demo datasets,
- stable API contracts between UI and backend,
- sample algorithm hooks that can be replaced by a real implementation.
The paper frames Anti-Manipulation as a mediator for querying data sources that may have incentives to manipulate rankings.
Core ideas from the paper that this prototype mirrors:
- A user has an intent: the ranking they actually want.
- The data source may return a biased interpretation of that intent.
- Anti-Manipulation helps the user:
- inspect the returned top-k result,
- flag untrustworthy tuples,
- generate a query reformulation,
- improve that reformulation,
- compare the updated result against the original one.
The paper’s demonstration section uses three dataset families:
- Amazon
- Manipulation scenario: a shopping site may promote low-rated, slow-selling, or otherwise preferred products.
- Example attributes:
rating,sales in the last month,price.
- PriceRunner
- Manipulation scenario: a comparison platform may favor certain sellers.
- Example attributes:
seller,product model,product category.
- Flights
- Manipulation scenario: a booking platform may favor certain airlines or price patterns.
- Example attributes:
airline,days until departure,price.
The paper’s running demo scenario over Amazon uses:
category = headphonesprice < 20- ranking by
rating - top-16 style inspection
- trust analysis that can flag tuples like JBL / Haoyuyan
- a CASE-based reformulation that promotes
Skullcandyand demotesJBL
This repository keeps that headphone example intact in the bundled sample data.
This codebase is designed to help a developer do the next implementation step quickly.
That means:
- the data loading path is simple and centralized,
- the UI behavior is already aligned with the paper demo,
- the request/response contracts are stable,
- the places where the real backend should plug in are clearly marked,
- the demo can already be run by a tester without extra setup beyond Python dependencies.
- Flask app and REST API routes
- Dataset catalog dropdown
- Schema detection and normalization for the three paper dataset families
- Dynamic query builder that changes by dataset
- Multi-select categorical filters
- Numeric sliders
- Ranking builder with
FeaturedandCustom - Multi-attribute custom ranking
- Top-k control
- Saved result summaries with persistent browser storage
- Styled result table and row highlighting
check_influential_equilibriumdetect_untrustworthy_tuplesfind_influential_queryimprove_user_utilityFeaturedranking mode- source-side bias modeling heuristics
All placeholder logic lives behind stable helper functions in algorithms.py or the small demo ranking helpers in app.py.
- app.py
- Flask app
- dataset normalization
- ranking flow
- API routes
- algorithms.py
- sample algorithm hooks that mimic the paper workflow
- templates/index.html
- main page layout
- static/app.js
- dynamic UI rendering
- query submission
- saved result persistence
- static/styles.css
- app styling
- sample_data/amazon_headphones.csv
- running-example demo dataset
- sample_data/amazon_products_with_categories.csv
- larger Amazon-style dataset
- sample_data/pricerunner_aggregate.csv
- PriceRunner-style dataset
- sample_data/flights_bucketized.csv
- flights dataset
- docs/HANDOFF.md
- developer handoff notes
- docs/TESTING.md
- tester checklist
When the user selects a data source, the frontend calls /api/load-dataset.
The backend then:
- reads just the header,
- detects whether the dataset is Amazon, PriceRunner, or Flights,
- maps raw columns to canonical names,
- computes filter metadata,
- returns UI metadata to the frontend.
This lets the frontend stay generic.
When the user clicks Run Query, the frontend sends:
- selected filters,
- ranking mode,
- primary ranking attribute and direction,
- secondary ranking attribute and direction,
- top-k.
The backend then:
- applies filters,
- computes the clean intent ranking,
- computes a visible ranking using either:
- the demo biased source behavior, or
- the placeholder
featuredranking,
- returns the visible top-k rows.
Analyze Trustworthiness- backend flags suspicious tuples
- frontend highlights those rows
Find Influential- backend returns a first reformulation
- frontend shows the generated query card
Improve Query- backend returns a refined reformulation
- frontend updates the generated query card
Submit Query- backend applies the last reformulation
- frontend refreshes the result table
The right panel stores complete result summaries, not individual tuples.
Each saved entry records:
- dataset label,
- selected filters,
- ranking mode,
- primary and secondary ranking,
- top-k,
- summary text,
- generated constraint when relevant,
- tuple ids shown,
- timestamp.
These saved summaries are stored in browser local storage.
The dropdown currently exposes four demo sources:
Amazon Headphones DemoAmazon ProductsPriceRunner AggregateFlights Bucketized
The backend loader currently supports:
.csv.json.jsonl.parquet
Amazon-style:
modelbrandcategoryratingpricebest_sellersales_last_month
PriceRunner-style:
offer_titleproduct_modelsellerproduct_categoryproduct_idcluster_id
Flights-style:
airlinesourcedestinationtravel_classstopsdays_until_departuredurationprice
The loader also accepts common alias names and normalizes them.
From Anti-Manipulation:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python app.pyOpen http://127.0.0.1:5000.
Use Amazon Headphones Demo.
Suggested demo steps aligned with the paper:
- Keep
category = headphones. - Set
Max Priceto20. - Set
Min Ratingto4. - Rank by
rating desc. - Keep
Top-K = 16. - Click
Run Query. - Click
Analyze Trustworthiness. - Click
Find Influential. - Click
Submit Query. - Click
Improve Query. - Click
Submit Queryagain. - Save the result summary on the right for comparison.
Returns the curated dropdown catalog.
Input:
{ "path": "/absolute/path/to/file.csv" }Returns dataset-aware UI metadata.
Runs the original query.
Flags suspicious tuples in the current visible result.
Generates the first reformulation.
Generates the improved reformulation.
Applies the last generated reformulation.
The main replacement points are:
- algorithms.py
- replace sample algorithm functions with real logic
- app.py
- replace
_bias_score,_rank_by_biased_source, and_rank_featured - keep request/response contracts stable if possible
- replace
The UI already expects:
- flagged row ids from trust analysis,
- a
relativeConstraint, - a
reformulation.queryText, - a reformulation that can be submitted later.
- This is a prototype, not a production service.
- The backend keeps one active dataset/query session in memory.
- Saved result summaries are stored in browser local storage, not in a database.
- The research algorithms are not yet implemented.
- The current bias behavior is heuristic and demo-only.
- Developer notes: docs/HANDOFF.md
- Tester checklist: docs/TESTING.md
