- **AB-029 Option A sibling-Flink prototype v0.1.0** — first real placement prototype for the AB-029 runtime placement benchmark. Ships as new `src/flink-jobs/dr-predictor/` Maven module (Java, Flink 1.20.3, matches pattern-matcher's structure) plus a real `SiblingFlinkPrototype` class in `src/runtime-placement-benchmark/forge_works/dr/ab029_spike/prototypes.py` that replaces `SiblingFlinkStub`'s NOT_IMPLEMENTED measurements with actual OK measurements for D1 (replay behavior), D3 (model rollout mechanics), D4 (failure isolation), D7 (cognitive load), and explicit NOT_APPLICABLE with reasoning for D2 (backpressure — needs running cluster + load generator), D5 (cost — needs real prediction volume + infra pricing), D6 (latency — needs Kafka broker + Prometheus scrape). Java pipeline: `DrPredictorJob.java` (main entry — Kafka source `forge.events.normalized.v1` → filter deploys → keyBy service:environment slice → score → Kafka sink `forge.predictions.dynamic_reliability.v1`), `NormalizedEvent.java` (input DTO mirroring pattern-matcher's `EventEnvelope`), `PredictionEnvelope.java` (output DTO per PC §3 shape — signal_role=recommendation, type=score, estimand_id=`deploy_slo_breach_60m_association_v0` per AB-033, horizon=next_1h, slice=(service, environment); `score()` + `abstain()` factory methods), `EventDeserializer.java` + `PredictionSerializer.java` (Jackson-based Kafka schemas, transient ObjectMapper re-initialized in Flink's `open()` per house lifecycle pattern), `model/ScoringModel.java` (pluggable interface), `model/ConstantPredictor.java` (final class, placeholder that returns 0.05 as base-rate placeholder from AB-028 RFC §4.4 — real MLflow-loaded predictor comes from AB-028 spike + AB-032 MLflow readiness), `model/DeployFeatureExtractor.java` (extracts plan_diff_size / resources_touched / touched_sensitive_resource from payload — placeholder; four-family feature families from AB-028 §4.3 require stateful rolling windows and land when AB-028 executes). Includes `input_freshness` gate: if `now - event.timestamp > 300s`, emit `abstain` prediction with reason `input_stale` per PC §3.0 eligibility rules. `src/flink-jobs/spotbugs-exclude.xml` updated to add `dr.EventDeserializer` + `dr.PredictionSerializer` to the SE_TRANSIENT_FIELD_NOT_RESTORED filter (documented Flink lifecycle pattern; identical suppression to the sibling schema impls). Python-side `SiblingFlinkPrototype` measurements are derived from static inspection of the module (pom.xml existence, source file count, documented Flink semantics from Kafka OffsetsInitializer + savepoint restore + JobManager isolation model); D4 scored 5.0 as reference for full isolation (standalone job, dedicated slots, no shared state with sibling jobs beyond Kafka topics), D7 scored 5.0 as top reuse of existing platform knowledge (same conceptual footprint as pattern-matcher/event-router/insight-generator, no new tools/languages/deploy paths). 10 new tests in `tests/test_prototypes.py`: protocol conformance, option code = "A", contract implications mention topic/placeholder/estimand, D1 qualitative mentions savepoint+kafka, D3 mentions 3-step/savepoint, D4 = 5.0 value, D7 = 5.0 value + Java file count in qualitative, D2/D5/D6 all NOT_APPLICABLE with notes, unknown-dimension raises ValueError, measure_all shape (D1/D3/D4/D7 OK, D2/D5/D6 NOT_APPLICABLE). Test count: 54 (44 pre-existing + 10 new). Java build clean under strict spotbugs (`Max` effort, `Low` threshold, `failOnError=true`) after fixing three findings: EI_EXPOSE_REP on `PredictionEnvelope.getPools()` / `getSlice()` (wrapped in List.copyOf + Collections.unmodifiableMap(new HashMap(...))) and CT_CONSTRUCTOR_THROW on `ConstantPredictor` (made class final to close finalizer-attack vector). Spotless (google-java-format AOSP) clean. Ruff clean under repo-wide config. What this DOES NOT include: the real AB-028 model (spike hasn't executed), the four-family feature extraction from AB-028 §4.3 (needs stateful rolling windows), MLflow model-loading (needs AB-032 readiness assessment), integration tests via Flink MiniCluster (no sibling Flink job has tests either — house style is production-code-only in the Flink modules; the AB-029 prototype layer measures placement properties at the correct level of abstraction). Blockers acknowledged (upstream — not addressed by this PR): AB-028 spike execution still needed for a real model; AB-029 scoping-approval meeting still needed to lock the §6.2 weighted-score rubric weights + confirm 7 dimensions; the other 4 stub prototypes (B/C/D/E) remain stubs pending their own real-prototype PRs. Introduced by [PR #31](https://github.com/adamatdevops/forge-works/pull/31) at [`0a1c406`](https://github.com/adamatdevops/forge-works/commit/0a1c406).
0 commit comments