dop
Skill7 starsChanged 53 days agoApache-2.0View on GitHub
Data-Oriented Programming paradigm for data pipelines. Guides code structure around pure transformations of immutable data with explicit schemas, separation of data from logic, and pipeline composition. Use when building data pipelines, analytics code, or processing tabular data with pandas/numpy.
In this repository10 other files it gives its agents.
- bend-formalizerSkill
- bendSkill
- dodSkill
- hpcSkill
- okfSkill
- pr-reviewerSkill
- quality-testingSkill
- security-auditSkill
- simulate-user-testingSkill
- theorem-oriented-programmingSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 5 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 22
Never mix mutable state with behavior
- Distinctive: line 25
Never modify data in-place
- Very specific: line 27
Use .assign(), pd.concat() instead of mutation
- Distinctive: line 32
Document schemas as contracts
- Distinctive: line 36
No side effects (does not alter external state)
- Distinctive: line 37
No dependency on global state
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Data-Oriented Programming (DOP)
What It Is
Data-Oriented Programming is a paradigm where data is a first-class citizen. Code is organized around immutable data transformations, with clear separation between data and logic. Instead of encapsulating data in objects with methods, you work with generic data structures (dicts, lists, DataFrames) and pure functions that transform those structures.
DOP is ideal for analytics pipelines and data processing workflows.
Core Principles
1. Separate Data from Logic
- Data lives in generic structures (dict, list, DataFrame, Series)
- Logic lives in pure functions that receive and return data
- Never mix mutable state with behavior
2. Data is Immutable
- Never modify data in-place
- Each transformation returns a NEW structure
- Use
.assign(),pd.concat()instead of mutation
3. Data has Explicit Schema
- Define the expected format of data (columns, types, constraints)
- Validate at the entry of each function/pipeline
- Document schemas as contracts
4. Functions are Pure
- Same input → same output (deterministic)
- No side effects (does not alter external state)
- No dependency on global state
5. Pipeline as Composition of Transformations
- Each step is a pure function:
data_in → data_out - The pipeline is the sequential composition of these functions
- Each intermediate step is inspectable and testable
Separation of Data vs Logic (Directory Structure)
src/
├── domain/ # PURE DATA (schemas, constants, enums)
│ ├── schema.py # BRONZE_SCHEMA, SILVER_SCHEMA, GOLD_SCHEMA
│ ├── constants.py # thresholds, regex patterns, mappings
│ └── types.py # type aliases, TypedDicts
├── transformations/ # PURE LOGIC (functions without side effects)
│ ├── cleaning.py # remove_nulls(), normalize(), deduplicate()
│ ├── features.py # compute_metrics(), add_derived_columns()
│ ├── aggregation.py # daily_summary(), group_by_user()
│ └── validation.py # validate_schema(), check_invariants()
└── effects/ # EFFECTS (I/O, API calls, external state)
├── io.py # read_parquet(), save_parquet(), read_csv()
├── api.py # fetch_from_api(), post_results()
└── database.py # query_table(), upsert_records()Principle: domain/ and transformations/ never do I/O.
effects/ is the only place with side effects (read/write disk, call APIs, query databases).
Rules for the Agent
When working with data:
- Never mutate DataFrames — use
.assign(),.pipe(),.copy() - Always define schemas — document expected columns in the docstring
- Validate at entry — check columns and types before processing
- Pure functions — no side effects, no global state
- Pipeline as composition — use
.pipe()to chain transformations - Name transformations — each
.pipe(fn)should have a descriptive name - Release memory —
del df; gc.collect()after large intermediate DataFrames - Batch assign — group multiple columns in a single
.assign()call
When designing pipelines:
- Clear layers — bronze → silver → gold
- Each step testable in isolation
- Intermediate data inspectable (save parquet between steps)
- Explicit errors — fail early with clear message
- Progress bars — use tqdm for long operations
- Logging — record input/output counts at each step
- Checkpoints — for expensive operations (embeddings), save incremental progress
- Deduplication — compare with existing gold before reprocessing
When writing tests:
- Prefer property-based tests for data transformations
- Test properties, not examples — "output always has N columns" > "input X gives output Y"
- Use custom strategies to generate realistic data
- Test schemas — output always follows the contract
- Test invariants — metrics in range, counts preserved, no unexpected NaN
- Test idempotency — cleaning applied 2x = 1x
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

