

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
12345## Context67This instruction file applies to data pipeline code: Kafka producers and consumers, Apache Spark PySpark jobs, dbt SQL models, and Airflow / AWS Step Functions DAG definitions. The guiding principle is **idempotency** — every pipeline step must be safe to re-run without producing duplicate or corrupted output. All pipeline code must emit observability metrics and route unprocessable records to a Dead-Letter Queue (DLQ).89---1011## Coding Standards1213- **Idempotency first:** Every step must use UPSERT/MERGE, partition overwrite, or deduplication keys — never plain INSERT14- **Manual Kafka commit:** `enable.auto.commit=false`; commit only after successful downstream write15- **Dead-letter everything:** Unprocessable records go to DLQ with full metadata — never silently drop16- **Schema contracts:** All data crossing a system boundary has a registered, versioned Avro/JSON Schema Registry schema17- **`logging` not `print()`:** `logging.getLogger(__name__)` in every module; structured fields18- **DataFrame API only:** PySpark DataFrame API exclusively in new code — never RDD API19- **No business logic in dbt staging:** Staging models rename columns only; transformations go in intermediate layer20- **Observability metrics:** Emit `records_read`, `records_written`, `records_failed`, `duration_seconds` for every job run2122---2324## Preferred Patterns2526### Kafka Producer (idempotent, Schema Registry)2728```python29# ✅ CORRECT — idempotent producer with Avro serialisation30from confluent_kafka import Producer31from confluent_kafka.schema_registry import SchemaRegistryClient32from confluent_kafka.schema_registry.avro import AvroSerializer3334registry = SchemaRegistryClient({"url": settings.schema_registry_url})35serialiser = AvroSerializer(registry, ORDER_AVRO_SCHEMA)3637producer = Producer({38 "bootstrap.servers": settings.kafka_bootstrap_servers,39 "acks": "all",40 "enable.idempotence": True,41 "max.in.flight.requests.per.connection": 5,42})4344def publish_order_event(event: OrderPlacedEvent) -> None:45 producer.produce(46 topic="orders.placed",47 key=event.order_id,48 value=serialiser(event.to_dict(), SerializationContext("orders.placed", MessageField.VALUE)),49 on_delivery=_delivery_callback,50 )51 producer.flush()52```5354### Kafka Consumer (manual commit, DLQ)5556```python57# ✅ CORRECT — manual commit, DLQ routing58consumer = Consumer({59 "bootstrap.servers": settings.kafka_bootstrap_servers,60 "group.id": "order-processor",61 "auto.offset.reset": "earliest",62 "enable.auto.commit": False,63})6465while True:66 msg = consumer.poll(timeout=1.0)67 if msg is None:68 continue69 try:70 event = deserialise(msg.value())71 processor.handle(event)72 consumer.commit(message=msg)73 except ProcessingError as exc:74 logger.error("Processing failed; routing to DLQ", exc_info=True)75 dlq_producer.produce(topic="orders.placed.dlq", value=msg.value(), headers=_error_headers(exc))76 consumer.commit(message=msg)7778# ❌ WRONG — auto-commit loses records on failure79Consumer({"enable.auto.commit": True})80```8182### PySpark Job (DataFrame API, explicit schema)8384```python85# ✅ CORRECT — explicit schema, partition overwrite, observability86from pyspark.sql import SparkSession87from pyspark.sql.types import StructType, StructField, StringType, TimestampType8889ORDER_SCHEMA = StructType([90 StructField("order_id", StringType(), nullable=False),91 StructField("customer_id", StringType(), nullable=False),92 StructField("created_at", TimestampType(), nullable=False),93])9495spark = SparkSession.builder.appName("OrderEnrichmentJob").getOrCreate()9697raw_df = spark.read.schema(ORDER_SCHEMA).parquet(input_path)98enriched_df = raw_df.join(customer_df, on="customer_id", how="left")99enriched_df.write.mode("overwrite").partitionBy("created_date").parquet(output_path)100101logger.info("records_read=%d records_written=%d", raw_df.count(), enriched_df.count())102103# ❌ WRONG — inferred schema, RDD API, no observability104rdd = spark.sparkContext.textFile(input_path)105```106107### dbt Layered Models108109```sql110-- ✅ CORRECT: staging model — rename only, no business logic111-- models/staging/stg_orders.sql112select113 order_id,114 cust_id as customer_id,115 order_ts as placed_at,116 total_amt_gbp as total_amount_gbp117from {{ source('raw', 'orders') }}118119-- ✅ CORRECT: intermediate model — business logic here120-- models/intermediate/int_orders_with_status.sql121select122 o.order_id,123 o.customer_id,124 o.placed_at,125 o.total_amount_gbp,126 case when s.fulfilled_at is not null then 'FULFILLED' else 'PENDING' end as status127from {{ ref('stg_orders') }} o128left join {{ ref('stg_fulfilments') }} s using (order_id)129130-- ❌ WRONG: business logic in staging model131select order_id,132 case when total_amt_gbp > 1000 then 'HIGH_VALUE' else 'STANDARD' end as tier133from raw.orders134```135136---137138## Anti-Patterns — Do NOT Generate139140```python141# WRONG: auto-commit on Kafka consumer — loses messages on crash [BLOCKER]142Consumer({"enable.auto.commit": True})143144# WRONG: silently dropping failed records [BLOCKER]145try:146 process(record)147except Exception:148 pass # record silently lost149150# WRONG: RDD API in new PySpark code [MAJOR]151rdd = sc.textFile(path).map(lambda x: x.split(","))152153# WRONG: inferred schema in Spark — breaks on empty partitions [MAJOR]154df = spark.read.parquet(path) # no explicit schema155156# WRONG: plain INSERT — not idempotent [MAJOR]157cursor.execute("INSERT INTO orders VALUES (%s, %s)", (order_id, amount))158159# WRONG: print() in pipeline code [MAJOR]160print(f"Processed {count} records")161162# WRONG: business logic in dbt staging model [MINOR]163-- stg_orders.sql164select *, total_amt_gbp * 0.2 as vat_amount from raw.orders165```166167---168169## Dependencies & Versions170171| Technology | Version | Notes |172|-----------|---------|-------|173| confluent-kafka | 2.x | `acks=all`, `enable.idempotence=True` for producers |174| apache-spark (PySpark) | 3.5+ | DataFrame API only; use `SparkSession.builder` |175| dbt-core | 1.7+ | `staging → intermediate → mart` layer convention |176| great-expectations | 0.18+ | Data quality suite; `checkpoint.run()` in CI |177| apache-airflow | 2.8+ | Task-level idempotency; use `execution_date` as partition key |178| boto3 | 1.34+ | AWS Step Functions, S3 access; use `waiters` for polling |179180---181182## Test Conventions183184- Unit test pipeline functions with mocked Kafka client (`MagicMock`) and in-memory DataFrames185- Integration test Kafka consumers with `testcontainers-python` Kafka container186- Test idempotency: run the pipeline twice on the same input; verify output row count does not double187- Test DLQ routing: inject a record that will fail processing and verify it appears in the DLQ topic188- For dbt, use `dbt test` with `not_null`, `unique`, `relationships` tests on every mart model189- Verify observability metrics are emitted: assert `records_read`, `records_written` counters in test output190
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| doubts-suplab/eeik-bootstrap.clinerules/golden-rules.md · 1 | Cline rules | gitsecuritydo-not | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.clinerules/project.md · 1 | Cline rules | teststylegit | 63/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/architecture.mdc · 1 | Cursor rules | do-not | 52/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/capabilities.mdc · 1 | Cursor rules | teststylegit | 58/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/golden-rules.mdc · 1 | Cursor rules | gitsecuritydo-not | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/python.mdc · 1 | Cursor rules | lint-formatstyletypesapi+1 | 77/100 | today | |
| doubts-suplab/eeik-bootstrap.cursor/rules/security.mdc · 1 | Cursor rules | security | 39/100 | today | |
| doubts-suplab/eeik-bootstrap.github/copilot-instructions.md · 1 | Copilot instructions | lint-formatstyletesting-strategygit+2 | 54/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/a2a-protocol.instructions.md · 1 | Copilot instructions | styleagent-behaviour | 48/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/ai-governance.instructions.md · 1 | Copilot instructions | stylearchdo-notagent-behaviour | 61/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/angular.instructions.md · 1 | Copilot instructions | teststyletypestesting-strategy+4 | 69/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/architecture-governance.instructions.md · 1 | Copilot instructions | testlint-formatstylegit+4 | 65/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/autogen.instructions.md · 1 | Copilot instructions | typessecurityagent-behaviour | 50/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/aws-architecture.instructions.md · 1 | Copilot instructions | styletypessecurityperformance | 58/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/aws-data-ml-ai.instructions.md · 1 | Copilot instructions | deployment | 54/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/cdk-terraform.instructions.md · 1 | Copilot instructions | teststylearchtypes+2 | 96/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/cicd.instructions.md · 1 | Copilot instructions | stylesecuritydeploymentdo-not+1 | 65/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/containerisation.instructions.md · 1 | Copilot instructions | buildstylesecuritydo-not | 77/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/crewai.instructions.md · 1 | Copilot instructions | styleagent-behaviour | 48/100 | today | |
| doubts-suplab/eeik-bootstrap.github/instructions/deployment.instructions.md · 1 | Copilot instructions | teststylegitdeployment | 77/100 | today |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| chihebnabil/lovable-boilerplate.github/instructions/global.instructions.md · 65 | Copilot instructions | buildlint-formatstylearch+4 | 100/100 | 14 days ago | |
| louislam/uptime-kuma.github/copilot-instructions.md · 90k | Copilot instructions | setupbuildtestlint-format+9 | 100/100 | 14 days ago | |
| pytorch/pytorch.github/copilot-instructions.md · 102k | Copilot instructions | setupbuildteststyle+5 | 100/100 | 14 days ago | |
| HerringtonDarkholme/megarepo.github/copilot-instructions.md · 17 | Copilot instructions | setupbuildtestlint-format+7 | 100/100 | 14 days ago | |
| bagisto/bagisto.github/copilot-instructions.md · 28k | Copilot instructions | setupbuildteststyle+5 | 97/100 | 14 days ago | |
| hiyouga/LlamaFactory.github/copilot-instructions.md · 74k | Copilot instructions | setupbuildtestlint-format+5 | 97/100 | 13 days ago | |
| JCodesMore/ai-website-cloner-template.github/copilot-instructions.md · 32k | Copilot instructions | buildlint-formatstylearch+3 | 97/100 | 7 days ago | |
| nerolis-lab/nerolis-lab.github/copilot-instructions.md · 32 | Copilot instructions | setupbuildtestlint-format+11 | 96/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/doubts-suplab-eeik-bootstrap-github-instructions-data-engineering-instructions)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.