data-lifecycle-contracts
How SA identifies gate fields and cross-component column-write contracts in the data model, and documents them in docs/architecture.md §6 so BE/FE Dev know…
Skill by evolplus
Chalk Labs
Need help deploying data-lifecycle-contracts?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/evolplus-data-lifecycle-contracts
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: frontend, data, writing, productivity
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/data-lifecycle-contracts
What's inside
- Skill name
data-lifecycle-contracts- Description
- How SA identifies gate fields and cross-component column-write contracts in the data model, and documents them in docs/architecture.md §6 so BE/FE Dev know which columns each task may write. Prevents the class of bug where the "ORM convenience" pattern (stamping a timestamp on every upsert) silently breaks downstream skip / eligibility / rate-limit gates that read the same column.
- License
- Apache-2.0
- Instructions
- 140 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Data Lifecycle Contracts
## When to use
You are the SA authoring `docs/architecture.md` (in `design` or `extract` mode). Your data model has columns that are **written by one component** and **read by another to gate behavior**. This skill prescribes how to identify those columns and document their write-ownership contract so downstream developers don't accidentally break the gate.
The motivating bug: A repository-sync service stamped `last_synced_at = CURRENT_TIMESTAMP` on every upsert during the discovery phase (a natural ORM-convenience pattern). The downstream WorkerPool's skip check read the same column to decide whether to re-process a repo: `now - last_synced_at < SYNC_MIN_INTERVAL → skip`. Result: every repo appeared "just synced" right after discovery, so every repo was always skipped. The data pipeline never ran. The discovery service wrote the column with one semantic ("we touched this row"); the worker read it with a different semantic ("last successful data collection"). No layer of the kit's discipline caught the mismatch because column-level write ownership sits between C3 (component responsibilities) and C4 (code-level columns) — neither layer documented it.
This skill exists so the SA explicitly hoists this contract up into the architecture.
## Inputs and outputs
- **Inputs:** SRS §3.1 Domain Specification + §3.3 FRs (which name the data-mutating operations); `docs/architecture.md` §3 Components (which name the components doing the mutations).
- **Outputs:** Architecture §6 Cross-Component Data Contracts table; cross-references from the relevant FRs' Data Effects sub-section; gate-field write-prohibition constraints propagated to BE Dev / FE Dev `## Project Specialization` by the Agent Generator.
## What is a gate field?
A column whose **read** controls behavior in a component different from the one(s) that write it. Common patterns:
| Pattern | Read controls | Common columns |
|---|---|---|
| Skip / rate-limit gate | "Should I re-process this row?" | `last_synced_at`, `last_run_at`, `next_eligible_at`, `cooldown_until` |
| State machine gate | "What transition is allowed?" | `state`, `status`, `phase`, `disposition` |
| Eligibility gate | "Is this row eligible for X?" | `is_active`, `is_verified`, `is_premium`, `eligible_until` |
| Idempotency / dedup gate | "Have we already done this?" | `processed_at`, `acknowledged_at`, `idempotency_key`, `dedup_hash` |
| Version gate | "Is the data new enough?" | `schema_version`, `etag`, `last_modified` |
| Ownership / audit gate | "Who owns this and when was it touched?" | `owner_id`, `updated_by`, `created_by` (when used in authorization) |
**Detection heuristic.** For each column in the data model, ask:
1. Is this column **read in a WHERE clause** by a component other than the one that writes it?
2. Is this column **read in a JOIN condition** that controls visibility?
3. Is this column **read by a worker / scheduler** to decide what to process next?
4. Is this column **read by an authorization check**?
If yes to any → it's a gate field. Document it in §6.
## Why this matters at architecture level
Without an explicit contract, BE Dev (and FE Dev for client-side caches with similar semantics) makes a judgment call when implementing the writer task. The judgment is influenced by common ORM patterns:
- "Stamp `updated_at` / `last_synced_at` / `touched_at` on every upsert" — natural ORM convenience.
- "Use the timestamp for index ordering" — natural index-design pattern (e.g., `(last_synced_at, is_active)` composite for least-recently-synced queries).
- "Stamp `state = 'discovered'` even though we haven't processed yet" — natural state-machine pattern.
Each is locally sensible. Each silently breaks the downstream gate. The bug surfaces only at integration time, when the worker / authz check / scheduler reads the column with a different semantic.
The architecture is where this contract lives because:
- The **SRS** is functional (what behavior the user gets), not data-flow.
- The **C3 Components** describe responsibilities ("upserts repositories table") but not per-column write semantics.
- The **C4 Code** is where the violation happens — too late.
- **BE Dev / FE Dev specialization** is where the constraint should be enforced, but it has to be sourced from somewhere upstream.
§6 fills the gap.
## Authoring §6
The architecture template provides a structured table — see [`.claude/agents/_templates/_artifacts/architecture-template.md`](../../agents/_templates/_artifacts/architecture-template.md) §6 for the canonical format. Schema:
| Column | Owner(s) | Write condition | Consumers (Readers) | Gate semantics | Other-writer constraint |
|---|---|---|---|---|---|
| `<schema.column>` | `<Component / Task>` | `<when this writer stamps>` | `<who reads it + how>` | `<what the read controls>` | `<what other services MUST NOT do>` |
### Authoring procedure
1. **Enumerate candidate columns** by walking the data model + applying the detection heuristic above. Aim for a small, focused list — most data-model columns are NOT gate fields. A typical project has 3–15 gate fields total.
2. **For each candidate, identify owners.** Owner = the component(s) authorized to write under the documented condition. Multiple owners is common (e.g., `last_synced_at` is written by both Branch Detection AND MR Collection, after successful per-repo data collection).
3. **State the write condition precisely.** Not "during data sync" but "AFTER successful per-repo data collection (Main Flow steps 5–8 of FR-003 complete without error)." Vague conditions don't bind BE Dev to a specific implementation point; precise conditions do.
4. **Name every consumer.** WorkerPool's skip check, scheduler's eligibility filter, authz middleware, etc. If you can't name a consumer, the column might not be a gate field — re-check the detection heuristic.
5. **Document gate semantics.** The exact condition under which the read changes behavior. E.g., `now - last_synced_at < SYNC_MIN_INTERVAL → skip` is precise enough that BE Dev knows the stamping moment matters.
6. **Spell out the other-writer constraint.** This is what prevents the bug. Examples:
- "Repository Sync Service (T-011) MUST NOT stamp `last_synced_at`. T-011 only writes structural metadata: `name`, `path_with_namespace`, `gitlab_group_id`, `is_active`."
- "Authorization middleware MUST NOT mutate `state`; state transitions are owned by Order Service."
- "Read-replica queries MUST NOT update `last_accessed_at` (which the eviction worker reads to decide cache TTL)."
Without the explicit prohibition, BE Dev sees "the writer column" as a general-purpose timestamp and stamps it whenever they touch the row.
## Worked example — the T-011 case
The bug report's case, written as §6 would document it:
```markdown
## 6. Cross-Component Data Contracts
| Column | Owner(s) | Write condition | Consumers (Readers) | Gate semantics | Other-writer constraint |
|---|---|---|---|---|---|
| `repositories.last_synced_at` | Branch Detection (T-012), MR Collection (T-013) | After successful per-repo data collection — all of FR-002 (branch detection succeeded), FR-003 (MR collection succeeded), FR-004 (commit collection succeeded), FR-005 (scoring succeeded) complete without error | WorkerPool skip check (per FR-006 Main Flow step 4) | `now - last_synced_at < SYNC_MIN_INTERVAL_MS → skip this repo for the current run` | Repository Sync Service (T-011, FR-001) MUST NOT stamp `last_synced_at` during discovery / upsert. T-011 only writes structural metadata: `name`, `path_with_namespace`, `gitlab_group_id`, `is_active`. ORM-convenience patterns (stamping `updated_at` on every upsert) MUST NOT apply to this column. |
| `repositories.is_active` | Repository Sync Service (T-011) | When project not found in GitLab discovery (set false) OR re-discovered after absence (set true) | WorkerPool eligibility filter (per FR-006 Main Flow step 3); analytics queries | `is_active = false → skip from current run` | Branch Detection (T-012), MR Collection (T-013) MUST NOT toggle `is_active`. Discovery owns active/inactive lifecycle. |
| `collection_runs.status` | Worker (T-006) | At run start (`running`), on each batch checkpoint (`running` heartbeat), at run end (`completed`, `partial`, `failed`) | Health-check API (per FR-011); admin dashboard | `status = running AND now - last_heartbeat > 5min → mark crashed` | Per-repo task workers (T-011/T-012/T-013) MUST NOT mutate `collection_runs.status`. Pool owns the run lifecycle; per-repo failures aggregate via event emission, not direct column writes. |
```
Each row encodes what was implicit in the SRS + architecture before. With §6 present, the Agent Generator extracts each row into BE Dev's `## Project Specialization` as a write-prohibition constraint:
```markdown
### Gate-field write constraints (from architecture.md §6)
For T-011 (Repository Sync Service) implementation:
- MUST NOT write to `repositories.last_synced_at`. This column is owned by T-012 and T-013, written AFTER successful per-repo data collection. T-011 only writes structural metadata: `name`, `path_with_namespace`, `gitlab_group_id`, `is_active`. The ORM-convenience pattern of stamping a timestamp on every upsert MUST be suppressed for this column.
- MAY write to `repositories.is_active` (T-011 is the owner of the active/inactive lifecycle per §6).
- MUST NOT write to `collection_runs.status` (Worker-pool-owned).
```
That's the kind of guardrail BE Dev needs at dispatch time. Without it, the bug is inevitable; with it, the implementation is constrained correctly.
## Common pitfalls
- **Treating a gate field as "just an updated_at."** ORM convenience patterns (UPDATE SET updated_at = NOW() on every mutation) silently break gates. If a column is a gate, it is NOT a general-purpose timestamp — it has a specific write semantic that the gate depends on.
- **Owner = "the service that touches the row most often."** Owner = "the service whose write semantic matches what the reader expects." Frequency is irrelevant.
- **Forgetting the precise write condition.** "During the sync flow" is too vague. "After FR-003 Main Flow steps 5–8 complete without error" is precise enough to constrain BE Dev's code placement.
- **Omitting the other-writer constraint.** Without "T-011 MUST NOT write this column" stated explicitly, BE Dev sees no prohibition and stamps it.
- **Documenting only timestamps.** State enums, eligibility flags, idempotency keys, version columns are all candidates. Don't filter to "timestamp columns."From evolplus/talos, Apache-2.0.
More from evolplus/talos
- 0.631score
design-system-author
evolplus
How to build a Figma Foundation page (design tokens + reusable components) BEFORE drawing screens, so spacing / text sizes / button styles / element alignment…
SkillAFreshness: A★ 8Claude Code +9 - 0.631score
be-framework-coding-standard
evolplus
Standardized backend implementation guidance for BE Dev using the SRS-declared Backend-Track and Backend-Framework.
SkillAFreshness: A★ 8Claude Code +9 - 0.628score
adr-author
evolplus
How to write an Architecture Decision Record under docs/decisions/.
SkillAFreshness: A★ 8Claude Code +9 - 0.628score
api-contract-author
evolplus
How to publish, freeze, and version an API contract under docs/api-contracts/.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-post-implementation
evolplus
BA Phase 5 — post-implementation completeness verification (UI tasks).
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-design-completeness
evolplus
BA Phase 3 — post-sign-off design completeness verification.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-iteration-planning
evolplus
BA Phase 4 — iteration dispatch planning.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-mode-external-source
evolplus
BA Phase 1.C ingestion mode (ingest-from-external-source).
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-mode-reverse-engineer
evolplus
BA Phase 1.E ingestion mode (reverse-engineer-from-code) — brownfield onboarding Stage 3.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
backend-logging-traceability
evolplus
Backend logging and traceability standard for BE Dev.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
codebase-inventory
evolplus
Produce the deterministic Tier-1 inventory of an existing codebase — routes/RPC/jobs, broker channels, persistent schema, external egress, deployables…
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-mode-requirements-folder
evolplus
BA Phase 1.F ingestion mode (ingest-from-requirements-folder) — greenfield with fragmented upstream.
SkillAFreshness: A★ 8Claude Code +9
Signals
- Stars
- 8
- Forks
- 0
- Open issues
- 1
- Last commit (this folder)
- Jun 17, 2026 (4 months ago)
- Last release
- Oct 12, 2026 (19 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- Apache-2.0
- Repository
- github.com/evolplus/talos
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from evolplus
- 0.631score
be-framework-coding-standard
evolplus
Standardized backend implementation guidance for BE Dev using the SRS-declared Backend-Track and Backend-Framework.
SkillAFreshness: A★ 8Claude Code +9 - 0.631score
design-system-author
evolplus
How to build a Figma Foundation page (design tokens + reusable components) BEFORE drawing screens, so spacing / text sizes / button styles / element alignment…
SkillAFreshness: A★ 8Claude Code +9 - 0.628score
adr-author
evolplus
How to write an Architecture Decision Record under docs/decisions/.
SkillAFreshness: A★ 8Claude Code +9 - 0.628score
api-contract-author
evolplus
How to publish, freeze, and version an API contract under docs/api-contracts/.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-iteration-planning
evolplus
BA Phase 4 — iteration dispatch planning.
SkillAFreshness: A★ 8Claude Code +9 - 0.626score
ba-design-completeness
evolplus
BA Phase 3 — post-sign-off design completeness verification.
SkillAFreshness: A★ 8Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get data-lifecycle-contracts running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
data-lifecycle-contracts skill. Agent Mart. https://agentmart.dev/skills/evolplus-data-lifecycle-contracts (last updated 2026-10-24)