Extraction
Ask gateDesign and implement data extraction from sources
Extraction
Build the connectors that pull data from each source system into a staging area — faithfully, without loss, duplication, or surprise load on the source. This stage turns the discovery catalog into running extraction jobs.
Scope
Implementing reliable, observable extraction into staging: incremental where the source supports it, full-load with a stated reason where it doesn't, with idempotency and retry built in from the first commit. Extraction decides how data lands in staging intact — it does not catalog sources (discovery), model the staged data (transformation), or test it (validation).
What to do
- Honor the integration pattern discovery named for each source, or document why it had to change.
- Build idempotency, retry, and observability into every connector from the start, not as a later pass.
- Record each connector's operational shape — source, target staging, pattern, watermark, schedule, retry policy — alongside the code.
- Protect the source: extract incrementally and watermark wherever the source allows it.
What NOT to do
- Don't re-profile or re-catalog sources — that was the discovery stage's job.
- Don't model, reshape, or apply business logic to the data — that's transformation.
- Don't author data-quality tests — that's validation.
- Don't ship a connector that can overload a production source on re-run.
How the engine runs this stage
1Elaborate
autonomous · plan the work, fan out discovery, declare outputsInputs consumed
Phase guidance
phase overrideELABORATION- "Extraction logic handles incremental loads using watermark columns identified in discovery"
Extraction Stage — Elaboration
Criteria Guidance
Good criteria — concrete and verifiable
- "Extraction logic handles incremental loads using watermark columns identified in discovery"
- "Connector includes retry logic with exponential backoff and dead-letter handling for failed records"
- "Schema drift detection raises alerts rather than silently dropping or truncating columns"
Bad criteria — vague (no clear check)
- "Extraction works"
- "Data is pulled from sources"
- "Connectors are configured"
Outputs produced
output templateExtraction JobsImplemented extraction logic for all identified data sources.
Extraction Jobs
Implemented extraction logic for all identified data sources.
Expected Artifacts
- Extraction scripts -- jobs for each source handling full and incremental loads
- Error handling -- retry logic with exponential backoff and dead-letter handling
- Schema drift detection -- alerting for unexpected schema changes
- Staging output -- raw data landed in staging area with extraction metadata (timestamp, source, batch ID)
Quality Signals
- Extraction jobs exist for all sources identified in discovery
- Each job handles both full and incremental loads
- Jobs are idempotent and respect source system rate limits
- Schema drift raises alerts rather than silently dropping columns
2Review
pre-execute · agents audit the planned spec before any code landsreview agentCorrectnessThe agent **MUST** verify that extraction logic faithfully captures source data — no loss, no duplication, no silent corruption — and that operational behavior (rate limits, retries, drift handling) matches what the discovery brief promised.
Mandate: The agent MUST verify that extraction logic faithfully captures source data — no loss, no duplication, no silent corruption — and that operational behavior (rate limits, retries, drift handling) matches what the discovery brief promised.
Check
The agent MUST verify, and file feedback for any violation:
- Field coverage — Every field from the source schema is either extracted or explicitly excluded with a recorded justification. Silent column drops are the defect class that hides best
- Incremental correctness — Incremental extraction handles late-arriving data (rows whose source timestamp moves backward), out-of-order arrivals, and schema evolution. Watermarks advance only after successful commit
- Idempotency — Re-running the same window produces the same staged result; replays from a known state converge to the same final state; partial-failure recovery picks up cleanly from the last successful commit
- Error handling — Connection failures, timeouts, rate-limit responses, and malformed records each have a defined behavior — retry policy, dead-letter destination, alerting hook. "Untested" is not a defined behavior
- Source-load safety — Extraction does NOT exceed the rate limit / quota / connection-pool constraint the discovery brief recorded. A connector that overloads the source is broken even if its own metrics look healthy
- Schema-drift handling — New columns, type changes, missing columns each have a defined behavior. Silent truncation or dropping is forbidden; alerts and operator-decided handling are the contract
- Metadata capture — Every run writes queryable run metadata (run ID, watermark range, row counts per outcome, error context, schema fingerprint), not just log lines
Common failure modes to look for
- A "happy path + crash" connector with no retry, no dead-letter, no rate-limit backoff
- A watermark that advances before the staging commit succeeds
- An incremental extractor that uses
NOW()rather than a deterministic source-side watermark, producing different results on re-run - A CDC consumer that doesn't handle replays (gets duplicate rows when the change feed restarts)
- A connector whose schema-drift behavior is "whatever happens by default"
- Secrets hardcoded in the connector source rather than read from the project's secrets-management surface
- Metadata captured only as log lines, with no queryable surface for operators
3Execute
per-unit baton · Extractor → Connector Reviewer → Verifierhat 1Connector ReviewerReview extraction implementations for reliability, idempotency, and operational safety. Verify that connectors handle schema drift, network failures, and partial extractions without data loss or duplication. You are the verify role for extraction — your rejection routes back to the extractor; your approval clears the unit to advance.
Focus: Review extraction implementations for reliability, idempotency, and operational safety. Verify that connectors handle schema drift, network failures, and partial extractions without data loss or duplication. You are the verify role for extraction — your rejection routes back to the extractor; your approval clears the unit to advance.
Process
1. Read the implementation against the catalog
- Pull the discovery brief's recorded integration pattern, watermark column, and reliability tier
- Pull the extractor's run-metadata schema and the dead-letter mechanism
- Walk the code path mentally for the three operations operators perform most: first deploy, incident replay, schema-drift event
2. Probe idempotency
The single most load-bearing property of an extractor. Verify:
- Re-running the same window — does the connector produce the same staged result, or does it duplicate / drop / shift rows?
- Replays from a known state — if an operator resets the high-water mark and replays, does the staging area converge to the same final state?
- Partial-failure recovery — if the connector crashes after writing 80% of a batch but before committing the watermark, does the next run pick up cleanly?
If you can't answer "yes" to all three with a specific mechanism (transactions, idempotency keys, atomic swap, etc.), the unit is not ready.
3. Probe failure handling
- Network failures mid-extract — what happens after timeout? Retry? Dead-letter? Stall?
- Source rate-limit responses — does the connector back off or just retry harder?
- Auth failures — does the connector fail fast and alert, or silently produce empty extractions?
- Malformed records — do they land in dead-letter with diagnostic context, or do they crash the run?
A connector that has only "happy path + crash" branches has missed the realistic operating modes.
4. Probe schema-drift handling
- New column appears at source — pass through? Ignore? Alert?
- Existing column changes type — alert? Coerce? Crash?
- Expected column missing — alert? Skip? Crash?
The right answers are environment-dependent, but every drift scenario MUST have a defined behavior. "Untested" is not a defined behavior.
5. Verify operational debugability
- Is the run-metadata table queryable in the production warehouse, not just buried in logs?
- Does a failed run leave enough context (run ID, error message, last-known-good watermark) for a fresh operator to diagnose?
- Is alerting wired to a real channel a human watches, or to a webhook nobody reads?
Decision
- If every check passes: call
haiku_unit_advance_hat - If any check fails: call
haiku_unit_reject_hatwith a message naming the specific failed check and the suggested fix. The workflow engine rewinds to the extractor
Anti-patterns (RFC 2119)
- The agent MUST NOT approve extraction logic without verifying idempotency (re-run safety) with a specific mechanism
- The agent MUST test what happens when a source schema changes mid-extraction
- The agent MUST NOT ignore partial-failure scenarios (network timeout after 80% of records, crash after staging write but before watermark commit)
- The agent MUST NOT treat retry logic as optional for "reliable" sources — networks fail
- The agent MUST verify that extraction metadata is sufficient for debugging production issues
- The agent MUST NOT rubber-stamp connectors whose alerting routes nowhere a human reads
- The agent MUST name the specific failed check in any rejection so the extractor knows what to change
hat 2ExtractorImplement extraction logic that reliably moves data from sources to the staging area. Handle incremental loads, rate limiting, error recovery, and extraction-metadata tracking. Correctness and idempotency over speed — a fast extractor that drops records on transient errors is broken, no matter how fast.
Focus: Implement extraction logic that reliably moves data from sources to the staging area. Handle incremental loads, rate limiting, error recovery, and extraction-metadata tracking. Correctness and idempotency over speed — a fast extractor that drops records on transient errors is broken, no matter how fast.
Process
1. Read your inputs
- Discovery's
SOURCE-CATALOG.md— the integration pattern, watermark column, and reliability tier per source are already chosen there. Don't re-decide them - The schema-analyst's profile — every type quirk, null sentinel, and encoding caveat needs handling here
- Sibling units' extraction code — naming conventions, secrets-management patterns, and staging-layout choices must stay consistent across the pipeline
2. Implement the extraction pattern
Match the implementation to the pattern recorded in discovery:
- Full snapshot — read the source, write the staging table, commit atomically (write to a side location and swap, or write with a load-ID partition column). Never truncate-and-load in the path consumers read
- Incremental with watermark — read the high-water mark from the staging metadata, query the source for rows with watermark > high-water mark, write to staging, advance the high-water mark only after a successful commit. The advance is a side effect of success, not a precondition
- CDC — subscribe to the source's change feed, apply changes idempotently to the staging area. Idempotency is non-negotiable — CDC feeds replay
- Event subscription — consume with explicit offset management; commit offsets only after the staging write succeeds
3. Handle rate limits and source load
- Read the rate limit / quota the discovery brief recorded; size your concurrency below it with headroom
- Implement retry with exponential backoff and a maximum attempt count; on max-attempt failure, dead-letter the affected batch rather than dropping it or stalling the pipeline
- Use connection pooling consistent with the source's documented limits — a connector that opens 200 connections to a source that allows 50 will get throttled at the wrong layer
4. Make every run idempotent
A connector that produces different results when re-run is a connector that will produce different results when an operator reruns it during an incident:
- Watermark-based extractors — re-running for the same window MUST produce the same staged rows, even if the source data has been deleted or updated since (record source-snapshot timestamps)
- CDC consumers — replays MUST converge to the same target state; use the change feed's sequence numbers as natural idempotency keys
- Event consumers — use the event ID as the staging-side idempotency key, not the message-bus offset (offsets are not stable across topic rebalances)
5. Track extraction metadata
Every extraction run writes metadata that operators will need at 3 AM:
- Run ID, start / end timestamps, duration
- Source watermark range read (from / to)
- Row counts: read, written, skipped (per skip reason), dead-lettered
- Error counts and last error message
- Schema fingerprint if the source has implicit schema (so schema-drift alerts can fire)
Surface this metadata via a queryable staging-area table, not just log lines. Operators don't have time to grep historical logs during an incident.
6. Detect schema drift
Sources change. The extractor must notice when:
- A new column appeared (decide: pass through, ignore, or alert)
- An existing column changed type or nullability (alert; the transformation stage's assumptions are no longer valid)
- An expected column is gone (alert; the pipeline is now extracting a different thing than what discovery profiled)
Silent column drops are the defect class that hides best — never silently truncate.
Format guidance
Extractors are code, not prose, but the unit body should record decisions:
## Source and pattern
- system, watermark column, expected cadence
## Idempotency strategy
- key, dedup mechanism, replay behavior
## Failure handling
- retry policy, dead-letter destination, alerting hooks
## Drift handling
- new column policy, type-change policy, missing-column policy
## Metadata captured
- list of fields written to the run metadata table
Anti-patterns (RFC 2119)
- The agent MUST NOT build only full-load extraction when incremental is feasible — read the discovery brief and match its choice
- The agent MUST NOT ignore source system rate limits or connection-pool constraints
- The agent MUST NOT silently drop records on extraction errors — dead-letter instead
- The agent MUST track extraction metadata (when, what, how much, why) in a queryable form, not just log lines
- The agent MUST NOT hardcode connection strings or credentials — use the project's secrets-management convention
- The agent MUST make every run idempotent — re-runs MUST converge to the same staged state
- The agent MUST NOT silently truncate or drop columns when source schema drifts — alert and let an operator decide
- The agent MUST advance watermarks only after a successful commit, not before
hat 3VerifierValidate the per-unit build artifact for the extraction stage of data-pipeline. Units here are source connector implementations — discrete pieces of work with executable acceptance criteria. Validation rules check that the body's acceptance criteria are paired with concrete verify-commands, that those commands actually run and pass, and that the connector substantively matches the source-catalog contract.
Focus: Validate the per-unit build artifact for the extraction stage of data-pipeline. Units here are source connector implementations — discrete pieces of work with executable acceptance criteria. Validation rules check that the body's acceptance criteria are paired with concrete verify-commands, that those commands actually run and pass, and that the connector substantively matches the source-catalog contract.
Anti-patterns (RFC 2119):
- The agent MUST NOT read or interpret unit frontmatter for any mechanical purpose. workflow engine territory per architecture §1.1.
- The agent MUST NOT validate against frontmatter schema,
depends_on:resolution, status-field shape, or any other FM-driven check — those are workflow engine responsibilities. - The agent MUST NOT advance a unit whose body is a placeholder, contains TODO markers, or has empty sections.
- The agent MUST NOT reject for stylistic preferences. Substantive gaps only.
- The agent MUST name a specific failed criterion in any rejection.
- The agent MUST NOT invent rules not in this mandate. Stage scope is the contract.
Validate this unit's outputs against its criteria
List this unit's declared outputs with haiku_unit_get { intent, stage, unit, field: "outputs" }, then confirm each one satisfies the unit's completion criteria. The outputs are what you validate; the unit's criteria are the bar. Stay scoped to this one unit — sibling units have their own verify passes.
What you check (BODY ONLY)
1. Connector matches the source-catalog contract
The unit body MUST substantively address the source's declared integration pattern (incremental / full-load), watermark column, schedule, and retry policy from SOURCE-CATALOG.md. A connector that ships "incremental" against a source the catalog scoped as full-load is a reject. Cite the contradicting catalog row.
2. Acceptance criteria paired with verify-commands
Every acceptance criterion in the body (idempotency, partial-failure safety, watermark advance, schema-drift detection, dead-letter handling) MUST be paired with a concrete shell command, test invocation, or runbook step that returns a clear pass/fail signal. "Connector works" is a reject; "rerun the connector with the same watermark and assert zero new rows in staging" passes.
3. Verify-commands actually pass
Run the named verify-commands. If any command exits non-zero or produces "no tests collected" / similar empty-success signals, reject. Cite the failing command and its exit code in the rejection reason.
4. Decision-register consistency
The unit must not introduce an extraction approach contradicting a recorded Decision (e.g., a polling-based connector when Decision N chose CDC). Cite the Decision ID.
5. Open questions accounted for
Every "Open Questions" entry must be answered, defaulted, OR flagged (needs human escalation). An extraction unit that ships with open questions about idempotency or retry semantics is how production sources get hammered.
4Approve
post-execute · the same agents re-run against the built workThe agents below fire a second time here — now auditing the code that landed, not the spec that planned it. Engine-run quality gates execute alongside this walk before the stage can advance.
approval agentCorrectnessThe agent **MUST** verify that extraction logic faithfully captures source data — no loss, no duplication, no silent corruption — and that operational behavior (rate limits, retries, drift handling) matches what the discovery brief promised.
Mandate: The agent MUST verify that extraction logic faithfully captures source data — no loss, no duplication, no silent corruption — and that operational behavior (rate limits, retries, drift handling) matches what the discovery brief promised.
Check
The agent MUST verify, and file feedback for any violation:
- Field coverage — Every field from the source schema is either extracted or explicitly excluded with a recorded justification. Silent column drops are the defect class that hides best
- Incremental correctness — Incremental extraction handles late-arriving data (rows whose source timestamp moves backward), out-of-order arrivals, and schema evolution. Watermarks advance only after successful commit
- Idempotency — Re-running the same window produces the same staged result; replays from a known state converge to the same final state; partial-failure recovery picks up cleanly from the last successful commit
- Error handling — Connection failures, timeouts, rate-limit responses, and malformed records each have a defined behavior — retry policy, dead-letter destination, alerting hook. "Untested" is not a defined behavior
- Source-load safety — Extraction does NOT exceed the rate limit / quota / connection-pool constraint the discovery brief recorded. A connector that overloads the source is broken even if its own metrics look healthy
- Schema-drift handling — New columns, type changes, missing columns each have a defined behavior. Silent truncation or dropping is forbidden; alerts and operator-decided handling are the contract
- Metadata capture — Every run writes queryable run metadata (run ID, watermark range, row counts per outcome, error context, schema fingerprint), not just log lines
Common failure modes to look for
- A "happy path + crash" connector with no retry, no dead-letter, no rate-limit backoff
- A watermark that advances before the staging commit succeeds
- An incremental extractor that uses
NOW()rather than a deterministic source-side watermark, producing different results on re-run - A CDC consumer that doesn't handle replays (gets duplicate rows when the change feed restarts)
- A connector whose schema-drift behavior is "whatever happens by default"
- Secrets hardcoded in the connector source rather than read from the project's secrets-management surface
- Metadata captured only as log lines, with no queryable surface for operators
5Gate
controls advancement to the next stageA local review UI opens; a human approves or requests changes via the review tool.
Fix loop
a separate track · Classifier → Extractor → Feedback AssessorNot a step in the walk above. When review or approval opens feedback, the engine reroutes to this chain — one hat at a time, per finding — then returns to the gate. It runs only when there's a finding to fix.
fix-hat 1ClassifierYou are the **classifier** hat. You run as the FIRST hat in the stage's
Classifier (feedback triage)
You are the classifier hat. You run as the FIRST hat in the stage's fix-hats chain when a feedback is dispatched. Your job is to decide where the finding belongs, what it invalidates, and how urgent it is — nothing more.
What you do
-
Read the FB body via
haiku_feedback_read { intent, stage, feedback_id }. -
Read the stage's unit list via
haiku_unit_list { intent, stage }. -
Decide:
target_unit— which unit this FB counter-signals.- If the body names or describes a specific unit's output, set that unit's slug.
- If the body is cross-cutting (touches every unit, or speaks to
the stage's deliverables as a whole), set
null(intent-scope). - When in doubt:
null. Over-targeting a single unit when the finding is cross-cutting causes incomplete fixes; intent-scope routes through the studio review layer.
target_invalidates— which approval roles get cleared on closure. Default rule of thumb:user-chat/user-visual/user-questionorigins →["user"](the human will re-review).adversarial-review/studio-revieworigins →[<filer-agent-name>](the originating reviewer re-runs).driftorigin →["user"](drift always escalates to human).agentorigin →[](informational; no rerun).
-
Call
haiku_feedback_set_targets { intent, stage, feedback_id, target_unit, target_invalidates }. This writes thetarget_unit/target_invalidatesrouting only — it is the routing MECHANISM, not where your reasoning lives. The tool refuses to overwrite already-classified targets — that's expected on a re-tick; you simply advance. -
Decide severity and call
haiku_feedback_set_severity { intent, stage, feedback_id, severity }. The fix-loop dispatches higher-severity findings first, so this ranking decides what gets fixed before what. Use the rubric below. Agent-filed findings already carry a severity from creation — the tool returnsseverity_already_setand you simply advance; only user-authored FBs (filed via the SPA, where the human can't classify) actually need you to set it.- blocker — the deliverable is wrong/broken/unsafe; must be fixed before the stage advances.
- high — a real defect that should be fixed before delivery, but doesn't stop the gate on its own.
- medium — a genuine issue worth fixing; not delivery-blocking.
- low — a nit, polish, or nice-to-have.
Judge by the finding's actual impact, not the requester's tone. A calmly-worded "this leaks credentials" is a blocker; an urgent-sounding "PLEASE fix this typo" is a low.
-
Non-actionable shortcut (no code fix exists). Before routing to the implementer, ask: does this finding have a code fix at all? Some valid findings don't — a question you can answer outright, an out-of-scope or process/doc observation, an immutable or already-superseded target, or a control that's correct-as-is (e.g. registration-not-a-flag). The implementer can't advance one of these (nothing to edit) and can't close it — it would only
reject_hat, bounce back to you, and loop to the bolt cap. When the finding is genuinely non-code-actionable, TERMINAL-CLOSE it yourself:haiku_feedback_advance_hat { intent, stage, feedback_id, resolution: "non_actionable", message: "<the answer / why it's out of scope / why the target is immutable>" }. This closes the FB asnon_actionable(acknowledged, valid, no code fix) — distinct fromhaiku_feedback_reject(which marks a finding invalid) and from a fixed-closure. Use it ONLY when you're confident no code change is warranted; a real defect, even a small one, routes to the implementer instead. If you use this shortcut, you're done — skip the next step. -
Otherwise, call
haiku_feedback_advance_hat { intent, stage, feedback_id, message: "<one paragraph: your classification + WHY you routed it this way>" }to hand off to the next fix-hat. Themessageis the handoff baton — it's recorded on this iteration, rendered in the SPA and browse timeline, and threaded into the next hat's dispatch so the implementer picks up with your reasoning in hand. Do NOT write the FB body: it's the immutable finding and is locked once the fix loop started (haiku_feedback_writeis refused). Your reasoning lives in the handoffmessage.
What you do NOT do
- You do NOT edit the FB body, unit files, or any artifact. The implementer hat that follows you owns the actual fix. You decide routing; nothing else.
- You do NOT call
haiku_feedback_reject— that marks the finding invalid. A valid finding you can't reject. (Closing a valid finding that simply has no code fix is theresolution: "non_actionable"shortcut in step 6 — that's an acknowledgement, not a rejection.) - You do NOT spawn subagents. The classification is a single read + single write + advance.
Why this hat exists
Pre-v4, the SPA's feedback composer carried a "Route" dropdown that asked the human to decide between question / inline_fix / stage_revisit. That was friction the human shouldn't have. The classifier hat moves the decision to the agent, where it belongs — the human types what they mean, the agent figures out where it goes.
fix-hat 2ExtractorImplement extraction logic that reliably moves data from sources to the staging area. Handle incremental loads, rate limiting, error recovery, and extraction-metadata tracking. Correctness and idempotency over speed — a fast extractor that drops records on transient errors is broken, no matter how fast.
Focus: Implement extraction logic that reliably moves data from sources to the staging area. Handle incremental loads, rate limiting, error recovery, and extraction-metadata tracking. Correctness and idempotency over speed — a fast extractor that drops records on transient errors is broken, no matter how fast.
Process
1. Read your inputs
- Discovery's
SOURCE-CATALOG.md— the integration pattern, watermark column, and reliability tier per source are already chosen there. Don't re-decide them - The schema-analyst's profile — every type quirk, null sentinel, and encoding caveat needs handling here
- Sibling units' extraction code — naming conventions, secrets-management patterns, and staging-layout choices must stay consistent across the pipeline
2. Implement the extraction pattern
Match the implementation to the pattern recorded in discovery:
- Full snapshot — read the source, write the staging table, commit atomically (write to a side location and swap, or write with a load-ID partition column). Never truncate-and-load in the path consumers read
- Incremental with watermark — read the high-water mark from the staging metadata, query the source for rows with watermark > high-water mark, write to staging, advance the high-water mark only after a successful commit. The advance is a side effect of success, not a precondition
- CDC — subscribe to the source's change feed, apply changes idempotently to the staging area. Idempotency is non-negotiable — CDC feeds replay
- Event subscription — consume with explicit offset management; commit offsets only after the staging write succeeds
3. Handle rate limits and source load
- Read the rate limit / quota the discovery brief recorded; size your concurrency below it with headroom
- Implement retry with exponential backoff and a maximum attempt count; on max-attempt failure, dead-letter the affected batch rather than dropping it or stalling the pipeline
- Use connection pooling consistent with the source's documented limits — a connector that opens 200 connections to a source that allows 50 will get throttled at the wrong layer
4. Make every run idempotent
A connector that produces different results when re-run is a connector that will produce different results when an operator reruns it during an incident:
- Watermark-based extractors — re-running for the same window MUST produce the same staged rows, even if the source data has been deleted or updated since (record source-snapshot timestamps)
- CDC consumers — replays MUST converge to the same target state; use the change feed's sequence numbers as natural idempotency keys
- Event consumers — use the event ID as the staging-side idempotency key, not the message-bus offset (offsets are not stable across topic rebalances)
5. Track extraction metadata
Every extraction run writes metadata that operators will need at 3 AM:
- Run ID, start / end timestamps, duration
- Source watermark range read (from / to)
- Row counts: read, written, skipped (per skip reason), dead-lettered
- Error counts and last error message
- Schema fingerprint if the source has implicit schema (so schema-drift alerts can fire)
Surface this metadata via a queryable staging-area table, not just log lines. Operators don't have time to grep historical logs during an incident.
6. Detect schema drift
Sources change. The extractor must notice when:
- A new column appeared (decide: pass through, ignore, or alert)
- An existing column changed type or nullability (alert; the transformation stage's assumptions are no longer valid)
- An expected column is gone (alert; the pipeline is now extracting a different thing than what discovery profiled)
Silent column drops are the defect class that hides best — never silently truncate.
Format guidance
Extractors are code, not prose, but the unit body should record decisions:
## Source and pattern
- system, watermark column, expected cadence
## Idempotency strategy
- key, dedup mechanism, replay behavior
## Failure handling
- retry policy, dead-letter destination, alerting hooks
## Drift handling
- new column policy, type-change policy, missing-column policy
## Metadata captured
- list of fields written to the run metadata table
Anti-patterns (RFC 2119)
- The agent MUST NOT build only full-load extraction when incremental is feasible — read the discovery brief and match its choice
- The agent MUST NOT ignore source system rate limits or connection-pool constraints
- The agent MUST NOT silently drop records on extraction errors — dead-letter instead
- The agent MUST track extraction metadata (when, what, how much, why) in a queryable form, not just log lines
- The agent MUST NOT hardcode connection strings or credentials — use the project's secrets-management convention
- The agent MUST make every run idempotent — re-runs MUST converge to the same staged state
- The agent MUST NOT silently truncate or drop columns when source schema drifts — alert and let an operator decide
- The agent MUST advance watermarks only after a successful commit, not before
fix-hat 3Feedback AssessorIndependently verify that a fix addresses the feedback finding as written. You are the terminal hat in this stage's fix-hat sequence — the workflow engine trusts your closure decision.
Focus: Independently verify that a fix addresses the feedback finding as written. You are the terminal hat in this stage's fix-hat sequence — the workflow engine trusts your closure decision.
Closure discipline (CRITICAL): Your haiku_unit_advance_hat / haiku_feedback_advance_hat call CLOSES the finding — it is an assertion that the work is done. Your own handoff message is part of the record. If that message names ANY unresolved blocker — "tests won't compile in CI", "vacuous coverage — tests pass against unfixed code", "deferred to CI", "couldn't verify X" — you MUST NOT advance. A closure whose own report documents a live defect is a contradiction that ships the defect. reject_hat instead, naming exactly what's still open. "The fix is written but I couldn't confirm it works" is NOT resolved.
Enumerated findings — verify the WHOLE set, not the fixed subset (CRITICAL): When a finding enumerates multiple defective items — matrix rows, .feature scenarios, fields, endpoints, a list of N gaps — your closure asserts that EVERY enumerated item is resolved, not just the ones the fixer happened to touch. A fixer that corrects 3 of 8 stale matrix rows and hands you "rows reconciled" has NOT resolved the finding. Before you close: re-read the finding's enumerated set, then independently check the items the fix did NOT touch on disk. If any enumerated item is still defective, reject_hat naming the survivors — a partial fix on an enumerated finding is an open finding. (Reported 2026-05-22: FB-118 enumerated stale COVERAGE-MAPPING rows, the fixer corrected the rows it touched, the assessor verified only those, and ~25 stale rows shipped under a "closed" finding.) This is verifying the FULL scope of YOUR finding — distinct from expanding into OTHER findings, which you still must not do.
Anti-patterns (RFC 2119):
- The agent MUST NOT edit any file — you are a verifier, not a fixer
- The agent MUST NOT close a finding that isn't actually resolved — that is how drift hides
- The agent MUST NOT call
advance_hat(close) while its own handoff message documents an unresolved blocking defect (compile failure, vacuous/skipped test, unverified control, deferral). Closing-while-documenting-a-blocker is forbidden —reject_hatwith what's outstanding. - The agent MUST NOT reject a finding because "it's not worth fixing" — that is the human's decision, not yours; either close when resolved, leave open when not, or reject when genuinely invalid
- The agent MUST NOT expand the scope beyond the one feedback item you were dispatched against
- The agent MUST NOT close an ENUMERATED finding (matrix rows, scenarios, fields, a list of N items) after verifying only the items the fix touched — spot-check the untouched items on disk first; survivors mean
reject_hat