trae-coding-engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -0
- package/bin/coding-engine.js +16 -0
- package/lib/cli.js +86 -0
- package/lib/index.js +6 -0
- package/lib/setup.js +290 -0
- package/package.json +32 -0
- package/templates/.agents/skills/coding-architecture/SKILL.md +347 -0
- package/templates/.agents/skills/coding-code-review/SKILL.md +95 -0
- package/templates/.agents/skills/coding-cve-remediation/SKILL.md +163 -0
- package/templates/.agents/skills/coding-db-schema/SKILL.md +273 -0
- package/templates/.agents/skills/coding-deploy-config/SKILL.md +129 -0
- package/templates/.agents/skills/coding-docs-audit/SKILL.md +285 -0
- package/templates/.agents/skills/coding-docs-audit-autofix/SKILL.md +33 -0
- package/templates/.agents/skills/coding-http-api/SKILL.md +269 -0
- package/templates/.agents/skills/coding-issue-autodev/SKILL.md +172 -0
- package/templates/.agents/skills/coding-merge-request/SKILL.md +199 -0
- package/templates/.agents/skills/coding-observability/SKILL.md +193 -0
- package/templates/.agents/skills/coding-refactor-insight/SKILL.md +89 -0
- package/templates/.agents/skills/coding-release-merge/SKILL.md +224 -0
- package/templates/.agents/skills/coding-runtime-adapter/SKILL.md +115 -0
- package/templates/.agents/skills/coding-testing/SKILL.md +169 -0
- package/templates/AGENTS.md +179 -0
- package/templates/MR-Template-Default.md +33 -0
- package/templates/Makefile +370 -0
- package/templates/REGISTRY.md +53 -0
- package/templates/scripts/check-adr.sh +283 -0
- package/templates/scripts/check-comment-i18n.py +209 -0
- package/templates/scripts/check-comment-i18n.sh +38 -0
- package/templates/scripts/check-doc-refs.sh +40 -0
- package/templates/scripts/check-docs.sh +103 -0
- package/templates/scripts/check-go-names.sh +59 -0
- package/templates/scripts/check-iam-actions.py +126 -0
- package/templates/scripts/check-migration-sql-immutability.sh +232 -0
- package/templates/scripts/check-mr-desc.sh +165 -0
- package/templates/scripts/check-mr-size.sh +128 -0
- package/templates/scripts/check-mr-title.sh +123 -0
- package/templates/scripts/check-openapi.py +221 -0
- package/templates/scripts/check-rdb-structured-queries.sh +98 -0
- package/templates/scripts/check-repository-transactions.sh +100 -0
- package/templates/scripts/check-runbooks.sh +229 -0
- package/templates/scripts/check-skill-router-sync.py +331 -0
- package/templates/scripts/check-skills.sh +243 -0
- package/templates/scripts/docs-audit-to-issues.py +373 -0
- package/templates/scripts/docs-verification-reminder.sh +63 -0
- package/templates/scripts/find-ci-failures.sh +133 -0
- package/templates/scripts/find-stale-mrs.sh +72 -0
- package/templates/scripts/gen-adr-index.sh +122 -0
- package/templates/scripts/open-mr.sh +536 -0
- package/templates/scripts/regen-agent-md.sh +149 -0
- package/templates/scripts/run-mr-hygiene.sh +140 -0
- package/templates/scripts/runbook.sh +91 -0
- package/templates/scripts/self-maintenance-digest.py +125 -0
- package/templates/scripts/send-self-maintenance-lark-card.py +116 -0
- package/templates/scripts/skill-graph.sh +114 -0
- package/templates/scripts/skill-impact.sh +134 -0
- package/templates/scripts/skill-propose.sh +302 -0
- package/templates/scripts/skill-router-hook.sh +152 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-db-schema
|
|
3
|
+
description: Use when adding, modifying, or removing a database schema element in coding_engine — new column, dropped column, renamed column, new table, new index, type change, or new GORM model under `internal/adapters/outbound/persistence/rdb/` or `mem-svc/internal/adapters/outbound/persistence/rdb/`. Encodes explicit migration SQL ownership for the coding-engine main DB, GORM PO / SQL alignment, mem-svc AutoMigrate ownership, RDB repository behavior checks, soft-delete vs physical-delete rules, forward-only safety rules, and the breaking-change ADR trigger.
|
|
4
|
+
version: 1.3.3
|
|
5
|
+
last_updated: 2026-06-24
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# coding-db-schema: Schema Ownership
|
|
9
|
+
|
|
10
|
+
> coding-engine main DB schema is owned by explicit SQL migrations under top-level `migration/`, executed by the Helm migrate Job / `coding-engine migrate` CLI. GORM PO structs remain the application mapping source and must stay in parity with migration SQL.
|
|
11
|
+
|
|
12
|
+
## Trigger — does this skill apply?
|
|
13
|
+
|
|
14
|
+
YES if your change touches any of:
|
|
15
|
+
|
|
16
|
+
- A field on a struct under `internal/adapters/outbound/persistence/rdb/po/` (the GORM models)
|
|
17
|
+
- A repository under `internal/adapters/outbound/persistence/rdb/repository/`
|
|
18
|
+
- Adding/removing/renaming a column, table, index, or constraint
|
|
19
|
+
- Changing a column type
|
|
20
|
+
- Adding a new aggregate that needs persistence
|
|
21
|
+
|
|
22
|
+
NO if you're only changing application-layer code (services, handlers, DTOs).
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## The Schema Track
|
|
26
|
+
|
|
27
|
+
| Track | Mechanism | Trigger | Idempotent? | Can drop? |
|
|
28
|
+
|---|---|---|---|---|
|
|
29
|
+
| **coding-engine main DB** | Top-level `migration/{mysql,postgres,dm}/{up,down}/vX.Y.Z/NNN.sql`; dialect directory names are lowercase; release entrypoint is `coding-engine migrate apply` via Helm migrate Job | Any main DB table/column/index/constraint/type change under `internal/adapters/outbound/persistence/rdb/**` | SQL must be idempotent or scoped to one irreversible DDL per file with a matching operational rollback plan | Yes, only through explicit `down/` SQL and compatibility review |
|
|
30
|
+
|
|
31
|
+
**Decision rule:**
|
|
32
|
+
- For coding-engine main DB, every PO shape change that affects schema must update both the GORM PO tag and `migration/mysql` + `migration/postgres` + `migration/dm` SQL in the same MR.
|
|
33
|
+
- Adding a new table/column/index → add forward `up/vX.Y.Z/NNN.sql`; add matching `down/vX.Y.Z/NNN.sql`. If automatic rollback is unsafe but the retained schema remains component-compatible, add a comment-only down file and document the retained-schema decision in `docs/07-data-model.md` / ADR.
|
|
34
|
+
- Adding an index → keep the PO GORM tag in sync where GORM can express it, and add the explicit SQL because server startup no longer owns main DB DDL.
|
|
35
|
+
- Dropping / renaming / narrowing → breaking schema change; update code in a rolling-compatible sequence, add `down` only when it is meaningful, and update ADR 0003 when external or rolling-deploy compatibility is affected.
|
|
36
|
+
- Rollback order for breaking changes must be explicit: roll application binaries back to a version compatible with the pre-change schema before running destructive `down` SQL, unless the ADR / rollout plan proves the reverse order is safe.
|
|
37
|
+
- SQL file rule: MySQL non-baseline migrations must contain one SQL statement per file because MySQL DDL commits implicitly. PostgreSQL should also prefer one DDL per file; if a PostgreSQL file contains multiple statements, each statement must be independently idempotent and safe to retry after partial failure.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
## Delete Semantics
|
|
41
|
+
|
|
42
|
+
Source of truth: `docs/07-data-model.md` §1.2.
|
|
43
|
+
|
|
44
|
+
| Table kind | Delete behavior | PO shape | Repository behavior |
|
|
45
|
+
|---|---|---|---|
|
|
46
|
+
| Domain entity / aggregate table | **Soft delete** | Carry `deleted_at`; new bigint-based models should prefer `soft_delete.DeletedAt` with `gorm:"softDelete:milli;column:deleted_at;type:bigint;default:0"` | Use GORM `Delete` with an existing filter or primary-key condition for pure soft delete; model-path reads rely on GORM's soft-delete scope; raw SQL / alias queries must exclude deleted rows manually |
|
|
47
|
+
| Relationship / binding table | **Physical delete** | No `deleted_at` by default | Unbind deletes the association row directly inside the service transaction |
|
|
48
|
+
|
|
49
|
+
Examples:
|
|
50
|
+
|
|
51
|
+
- Soft-delete domain entities: `agents`, `agent_channels`, `skills`, `skill_versions`, `directories`, `resources`, `envs`.
|
|
52
|
+
- Physical-delete relationship rows: `agent_skills`, `agent_resources`, and other pure binding tables whose lifecycle is only "this relation exists / no longer exists".
|
|
53
|
+
|
|
54
|
+
Mandatory rules:
|
|
55
|
+
|
|
56
|
+
- Do not add `deleted_at` to a pure relationship table unless the relationship itself has independent domain lifecycle / audit requirements. If you need that exception, document it in `docs/07-data-model.md`.
|
|
57
|
+
- Do not physically delete a domain entity row just because the product action says "delete"; implement the action as a soft delete and keep indexes compatible with the deleted marker.
|
|
58
|
+
- Pure soft-delete repository methods must call GORM `Delete` with an existing filter or primary-key condition (for example `db.Delete(&po.X{}, id)` or `db.Where("id = ?", id).Delete(&po.X{})`); do not hand-roll soft delete with `Update("deleted_at", ...)` or `Updates(map{"deleted_at": ...})`.
|
|
59
|
+
- Exception: if the delete operation must also change other columns in the same statement (for example unbind state, lifecycle status, or unique-key release fields), `Update(s)` is allowed. Keep the write scoped to the required fields and do not use it as a replacement for ordinary soft delete.
|
|
60
|
+
- Repository reads must not surface soft-deleted rows. With GORM soft-delete models, keep queries on the model path (`Model(&po.X{})`, `Find(&[]po.X{})`, `First(&po.X{})`, `Delete(&po.X{})`) so GORM injects the predicate; do not add redundant helpers such as `scopeNotDeleted` or repeated `deleted_at = 0` on those model-path statements.
|
|
61
|
+
- Raw SQL, `Table("... AS alias")`, cross-table joins, subqueries, and `Unscoped()` queries must add the matching live-row predicate manually, qualified by alias when needed.
|
|
62
|
+
- Match the table's `deleted_at` representation: bigint soft-delete models use live value `0`; nullable timestamp models use `IS NULL`. Prefer the bigint `soft_delete.DeletedAt` pattern for new domain models; do not migrate existing representation without an ADR / compatibility plan.
|
|
63
|
+
- Unique indexes on soft-deleted domain entities must include the deleted marker or an equivalent live-row partial index when supported, so deleting an entity frees the business key for recreate without colliding with the historical row.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Forward-Only Safety
|
|
67
|
+
|
|
68
|
+
Preserve rolling-deploy safety in both application behavior and explicit SQL:
|
|
69
|
+
|
|
70
|
+
- Adding a NOT NULL column on an existing table with rows: ship it as nullable or with a safe application default first. Single-shot mandatory fields can fail or block existing data.
|
|
71
|
+
- Renaming a column: ship as add-new + dual-write + backfill + remove-old across **two releases**.
|
|
72
|
+
- Dropping a column: only after every binary version that reads it has stopped running. Clean application code first, then remove the GORM PO field in a later release.
|
|
73
|
+
|
|
74
|
+
If you cannot preserve forward-only safety, this is a **breaking change** — see §ADR 0003 Trigger.
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## Schema Ownership
|
|
78
|
+
|
|
79
|
+
Only the **migrate CLI / Helm migrate Job** runs coding-engine main DB schema changes.
|
|
80
|
+
|
|
81
|
+
- `migration/mysql/**`, `migration/postgres/**`, and `migration/dm/**` are the source SQL directories.
|
|
82
|
+
- `deployments/coding-engine/sql/**` is generated from `migration/**` by `make migrate-sql`; verify with `make check-migrate-sql`.
|
|
83
|
+
- Source files under `migration/**` are append-only once present on the target branch. Do not modify, delete, rename, or adjust comments in existing SQL files. For the same release version, add the next contiguous `NNN.sql` under both `up/` and `down/` as applicable; for a new release version, create a new `vX.Y.Z/` directory and start at `001.sql`. `make check-migration-sql-immutability` enforces this against the target branch.
|
|
84
|
+
- When adding a new main-DB dialect directory, update the dialect whitelist used by `scripts/check-migration-sql-immutability.sh` (`MIGRATION_DIALECT_RE`) and its script fixtures in the same MR.
|
|
85
|
+
- `make check-migrate-sql-syntax` statically checks each migration dialect separately for SQL statement boundaries, missing semicolons / unterminated quotes or comments, obvious cross-dialect syntax tokens, and MySQL non-baseline one-statement files. It is intentionally lightweight and does not replace database integration tests for runtime behavior.
|
|
86
|
+
- `internal/adapters/outbound/persistence/rdb/po/**` remains the GORM mapping. Keep tags, table names, column names, indexes, nullability, and soft-delete representation aligned with SQL.
|
|
87
|
+
- Server startup validates that the database has already been migrated to the latest schema version carried by the current image; it must not run GORM `AutoMigrate` or hand-written DDL for the main DB.
|
|
88
|
+
- Worker, gateway, daemon: **never call `AutoMigrate` and never run schema SQL**. They depend on the migrate Job / CLI provisioned schema.
|
|
89
|
+
- Helm must use the existing migrate Job pattern for main DB schema changes. Do not add a second schema runner or a component-private schema Job.
|
|
90
|
+
|
|
91
|
+
Implication: if you add a worker-only aggregate, the PO still belongs in `internal/adapters/outbound/persistence/rdb/po/`, and the SQL still belongs under top-level `migration/{mysql,postgres,dm}/`. Don't shortcut by adding a second schema call site.
|
|
92
|
+
|
|
93
|
+
History: `fix(migarte): add enable service links false` was rooted in worker startup competing with server schema readiness — separating ownership prevents that class of bug.
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## RDB Repository Behavior Gate
|
|
97
|
+
|
|
98
|
+
`persistence/rdb` is the only production persistence implementation for coding-engine domain repositories. Local and all-in-one modes use the same RDB repositories; they differ only in local transport adapters such as bus/lane/lease.
|
|
99
|
+
|
|
100
|
+
Trigger this gate when you:
|
|
101
|
+
- Add a new rdb repository
|
|
102
|
+
- Add or change a method on a domain repository interface used by rdb
|
|
103
|
+
- Change rdb repository filtering, tenant/workspace scoping, sorting, pagination, duplicate checks, soft-delete visibility, binding deletion behavior, or returned not-found errors
|
|
104
|
+
|
|
105
|
+
Required steps:
|
|
106
|
+
1. Keep the RDB repository type asserted against the domain repository interface when practical.
|
|
107
|
+
2. Add or update focused RDB repository tests for the behavior, especially filters, deletion visibility, duplicate/name checks, and transaction-required paths.
|
|
108
|
+
3. Run at least:
|
|
109
|
+
```bash
|
|
110
|
+
go test ./internal/adapters/outbound/persistence/rdb/repository
|
|
111
|
+
```
|
|
112
|
+
4. For behavior that depends on SQL semantics, compile integration tests and run the affected `tests/integration/*_repository_test.go` coverage against supported DBs.
|
|
113
|
+
|
|
114
|
+
Do not add reusable in-memory repository adapters for tests. Application tests should prefer generated domain mocks or narrow same-package fakes. Use package-local RDB / sqlite fixtures only when the application workflow materially depends on transaction boundaries, SQL ordering/filtering, uniqueness, or cross-repository persistence semantics. Repository behavior itself belongs in RDB unit/integration coverage.
|
|
115
|
+
|
|
116
|
+
## RDB Repository Transaction / Context Rule
|
|
117
|
+
|
|
118
|
+
All SQL transactions are application-layer boundaries. RDB repositories must
|
|
119
|
+
not open, commit, roll back, or otherwise control transactions.
|
|
120
|
+
|
|
121
|
+
Mandatory rules for any code under
|
|
122
|
+
`internal/adapters/outbound/persistence/rdb/repository/**` or
|
|
123
|
+
`mem-svc/internal/adapters/outbound/persistence/rdb/repository/**`:
|
|
124
|
+
|
|
125
|
+
- Do not call GORM transaction APIs in repositories: `.Transaction(...)`,
|
|
126
|
+
`.Begin(...)`, `.Commit(...)`, `.Rollback(...)`, or `*Tx` equivalents.
|
|
127
|
+
- Main coding-engine rdb repositories use the single public DB entrypoint
|
|
128
|
+
`rdb.DB(ctx, r.db)` (or a package-local `conn(ctx)` wrapper that delegates to
|
|
129
|
+
it). Do not expose or call a second public transaction/context helper.
|
|
130
|
+
- Repository code must not branch on whether the caller is inside a
|
|
131
|
+
transaction. It receives `ctx`, calls the unified DB helper, and lets the
|
|
132
|
+
application-layer `port.TransactionManager` decide transaction scope.
|
|
133
|
+
- If a repository method requires a caller transaction because it uses row locks
|
|
134
|
+
or multi-statement read-modify-write semantics, call
|
|
135
|
+
`rdb.RequireTransaction(ctx)` once at the method boundary and use the returned
|
|
136
|
+
DB handle. Do not hand-roll `rdb.DB(ctx, nil)` probes.
|
|
137
|
+
- If a repository operation needs multiple SQL statements to be atomic, move
|
|
138
|
+
the transaction boundary to the owning application service/use case and pass
|
|
139
|
+
the transactional `ctx` into the existing repository methods.
|
|
140
|
+
- Any caller of an rdb repository method that performs read-modify-write with
|
|
141
|
+
row locks must run inside `port.TransactionManager.WithinTransaction`. Current
|
|
142
|
+
examples are `runtime.Repository.PatchMetadata`,
|
|
143
|
+
`runtime.Repository.PatchMetadataWithFence`, and
|
|
144
|
+
`message.Repository.NextRunSequence` followed by
|
|
145
|
+
`message.Repository.SaveRuntimeEvent`.
|
|
146
|
+
- Keep GORM statements straightforward. Prefer simple chained `Model` /
|
|
147
|
+
`Where` / `Create` / `Updates` / `Delete` calls over clever SQL builder
|
|
148
|
+
abstractions when fixing transaction placement.
|
|
149
|
+
|
|
150
|
+
Required check for any rdb repository / PO / mapper / constructor change:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
make check-repository-transactions
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## RDB Structured Query Rule
|
|
157
|
+
|
|
158
|
+
RDB repositories must be dialect-neutral by construction. Do not fix database
|
|
159
|
+
compatibility by branching on the driver in repository/business code.
|
|
160
|
+
|
|
161
|
+
Mandatory rules for production files under
|
|
162
|
+
`internal/adapters/outbound/persistence/rdb/repository/**` and
|
|
163
|
+
`mem-svc/internal/adapters/outbound/persistence/rdb/repository/**`:
|
|
164
|
+
|
|
165
|
+
- Do not branch on database type, driver name, or dialect name. Patterns such as
|
|
166
|
+
`if driver == "dm"` or `switch db.Dialector.Name()` belong outside repository
|
|
167
|
+
business logic.
|
|
168
|
+
- Prefer GORM structured predicates: `clause.Eq`, `clause.IN`, `clause.And`,
|
|
169
|
+
`clause.Or`, `clause.Expr`, and package helpers such as `columnEq`,
|
|
170
|
+
`tableColumnEq`, `columnIN`, `columnEqColumn`, and `orderBy`.
|
|
171
|
+
- Select field lists must quote identifiers through GORM placeholders, for
|
|
172
|
+
example `Select("? AS id", clause.Column{Table: "items", Name: "id"})`.
|
|
173
|
+
Do not write raw field lists such as `Select("items.id, items.name")`.
|
|
174
|
+
- Joins must quote identifiers through GORM placeholders:
|
|
175
|
+
`Joins("JOIN ? ON ? = ?", clause.Table{Name: "..."}, clause.Column{...}, clause.Column{...})`.
|
|
176
|
+
Do not write direct table or alias SQL such as `JOIN foo AS f ON f.id = ...`.
|
|
177
|
+
- Use table aliases only when they materially simplify a query shape that cannot
|
|
178
|
+
be expressed clearly with base table names. For normal joins, prefer real table
|
|
179
|
+
names plus `clause.Table` / `clause.Column`; this avoids dialect-specific
|
|
180
|
+
alias quoting issues.
|
|
181
|
+
- Do not use `Raw` or `Exec` in production repositories. Schema DDL belongs in
|
|
182
|
+
explicit migration SQL, not startup/repository code.
|
|
183
|
+
- Tests may query system tables or use test-only raw SQL to inspect fixtures,
|
|
184
|
+
but database-type branching must stay in test utilities or system-table
|
|
185
|
+
inspection helpers rather than leaking into repository behavior.
|
|
186
|
+
|
|
187
|
+
Rare escape hatch:
|
|
188
|
+
|
|
189
|
+
```go
|
|
190
|
+
// coding:allow-raw-sql <why structured GORM clauses cannot model this>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Use this only for a narrowly scoped production query that cannot be represented
|
|
194
|
+
with GORM clauses. The reason must be specific enough for code review.
|
|
195
|
+
|
|
196
|
+
Required check for any rdb repository change:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
make check-rdb-structured-queries
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
## ADR 0003 Trigger
|
|
204
|
+
|
|
205
|
+
A change is a **breaking change** (and must update or add an ADR-status entry referencing `docs/adr/0003-data-model-breaking-changes.md`) when it does any of:
|
|
206
|
+
|
|
207
|
+
- Renames a column that application code outside this PR may still read
|
|
208
|
+
- Removes a column that any DTO or external consumer references
|
|
209
|
+
- Changes a column type in a way that requires application-side parsing changes
|
|
210
|
+
- Removes a status / enum value
|
|
211
|
+
- Changes the `tenant_id` / `workspace_id` semantics
|
|
212
|
+
|
|
213
|
+
Steps:
|
|
214
|
+
1. Update the GORM PO and application code in a forward-compatible sequence
|
|
215
|
+
2. Update `docs/adr/0003-data-model-breaking-changes.md` Decision section with the new bullet when the change is breaking (immutable history — append only, never edit prior bullets)
|
|
216
|
+
3. Update `docs/07-data-model.md` to match
|
|
217
|
+
4. Run the Docs Verification Gate (see `AGENTS.md`)
|
|
218
|
+
|
|
219
|
+
Reference the ADR in nearby code or docs if the change is non-obvious.
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
## Done Checklist
|
|
223
|
+
|
|
224
|
+
- [ ] Forward-only safety holds OR an ADR 0003 entry was added
|
|
225
|
+
- [ ] GORM struct (`po/<aggregate>.go`) updated to match the new shape
|
|
226
|
+
- [ ] Main DB schema changes include matching `migration/mysql` and `migration/postgres` `up` SQL
|
|
227
|
+
- [ ] Rollback-safe changes include matching executable `down` SQL; intentionally retained schema changes include matching comment-only `down` SQL and are documented in docs / ADR
|
|
228
|
+
- [ ] `deployments/coding-engine/sql/**` regenerated with `make migrate-sql` and checked with `make check-migrate-sql`
|
|
229
|
+
- [ ] Migration SQL immutability guard passes: `make check-migration-sql-immutability`
|
|
230
|
+
- [ ] Migration SQL static guard passes: `make check-migrate-sql-syntax`
|
|
231
|
+
- [ ] SQL syntax and retry safety were reviewed: MySQL non-baseline files contain one statement; PostgreSQL multi-statement files are idempotent and safe after partial failure
|
|
232
|
+
- [ ] RDB repository transaction guard passes: `make check-repository-transactions`
|
|
233
|
+
- [ ] RDB repository behavior has focused unit or integration coverage for every new or changed repository behavior
|
|
234
|
+
- [ ] Application tests use mocks/fakes for pure service behavior, or package-local RDB / sqlite fixtures when the workflow depends on persistence semantics
|
|
235
|
+
- [ ] Delete semantics match `docs/07-data-model.md`: domain entity soft delete, relationship / binding physical delete
|
|
236
|
+
- [ ] Repository read paths exclude soft-deleted rows, including raw SQL / `Table(...)` queries
|
|
237
|
+
- [ ] If a column was dropped: every Go reference to it removed (handler, DTO, mapper, events)
|
|
238
|
+
- [ ] Indexes are declared both in migration SQL and PO tags when GORM can express them
|
|
239
|
+
- [ ] RDB repository / PO / mapper changes pass integration compile: `go test -tags=integration ./tests/integration/... -run '^$'`
|
|
240
|
+
- [ ] Corresponding repository integration tests pass against testcontainers, for example `go test -tags=integration ./tests/integration -run '<AffectedRepositoryTest>' -count=1 -parallel=2`
|
|
241
|
+
- [ ] `make test` passes — see `coding-testing` Strategy 5
|
|
242
|
+
- [ ] If breaking: `docs/adr/0003-data-model-breaking-changes.md` and `docs/07-data-model.md` updated
|
|
243
|
+
- [ ] PR commit uses scope `(config)` or `(server)` — NEVER the typo `(migarte)` (history shows it has been used 3+ times; rejected on review)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
## Common Mistakes
|
|
247
|
+
|
|
248
|
+
| Mistake | Fix |
|
|
249
|
+
|---|---|
|
|
250
|
+
| Add a column in docs or repository code only, forget the GORM struct field | Update the PO and the migration SQL in the same MR |
|
|
251
|
+
| Add a PO field but forget migration SQL | The database will not be changed by server startup. Add `migration/mysql` and `migration/postgres` SQL and regenerate deployment SQL |
|
|
252
|
+
| Omit a matching `down/vX.Y.Z/NNN.sql` file | Add real rollback SQL, or add a comment-only down file when automatic rollback is intentionally unsupported but retained schema is component-compatible |
|
|
253
|
+
| Edit an existing migration SQL file, even only a comment | Add a new sequential `NNN.sql` file in the same version, or start `001.sql` in a new `vX.Y.Z/` directory |
|
|
254
|
+
| Add a new dialect directory but forget the immutability guard whitelist | Update `MIGRATION_DIALECT_RE` in `scripts/check-migration-sql-immutability.sh` and add focused script fixtures |
|
|
255
|
+
| Put multiple MySQL DDL statements in one non-baseline SQL file | Split to one DDL per file; MySQL DDL commits implicitly and the runner rejects multi-statement non-baseline MySQL files |
|
|
256
|
+
| Leave a deleted column on the GORM struct | The application can keep reading/writing retired schema. Drop the struct field when the app no longer uses it |
|
|
257
|
+
| Add a reusable in-memory repository to make application tests convenient | Use generated domain mocks or narrow same-package fakes; use package-local RDB / sqlite fixtures only for workflows that need persistence semantics |
|
|
258
|
+
| Physically delete a domain entity row | Add / use `deleted_at` soft delete; physical deletion is for relationship / binding rows |
|
|
259
|
+
| Add `deleted_at` to a pure binding table | Binding rows should be physically deleted on unbind; only add soft delete if the relationship has its own audited lifecycle and docs explain why |
|
|
260
|
+
| Raw SQL reads a soft-delete table without a live-row predicate | Add `deleted_at = 0` for bigint soft-delete models or `deleted_at IS NULL` for nullable timestamp models |
|
|
261
|
+
| Use scope `migarte` (typo) in commit message | Use `config`, `server`, or `schema`. The typo has been bounced in review repeatedly |
|
|
262
|
+
| Add a NOT NULL column to a populated table | Ship as nullable or with an application-level default first. Test with non-empty fixture |
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
## Cross-references
|
|
266
|
+
|
|
267
|
+
- `migration/{mysql,postgres}/` — main DB migration SQL source of truth
|
|
268
|
+
- `deployments/coding-engine/sql/` — generated release SQL; verify with `make check-migrate-sql`
|
|
269
|
+
- `internal/adapters/outbound/persistence/rdb/po/` — GORM mapping, must match migration SQL
|
|
270
|
+
- `docs/adr/0003-data-model-breaking-changes.md` — append-only ADR for schema breaking changes
|
|
271
|
+
- `docs/07-data-model.md` — narrative description; keep in sync with status markers per `docs/CONVENTIONS.md`
|
|
272
|
+
- `coding-testing` Strategy 5 — integration tests with testcontainers exercise persistence behavior
|
|
273
|
+
- `coding-deploy-config` p2-dsn-in-go — database connection strings are still assembled in Go
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-deploy-config
|
|
3
|
+
description: Use when changing any deployment/runtime/config item in coding_engine — Helm values, vecompass-override, configs/engine.yaml.example, Go config struct, image repo/tag, DSN, K8s probe/service port, Secret/ConfigMap field.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# coding-deploy-config: Deployment & Config Sync Gate
|
|
7
|
+
|
|
8
|
+
> Single-surface config edits are the **#1 source of regressions** on `main`.
|
|
9
|
+
> If you are touching any of the trigger items below, you MUST reconcile every applicable surface before the task is done.
|
|
10
|
+
|
|
11
|
+
## Trigger — does this skill apply?
|
|
12
|
+
|
|
13
|
+
YES if your change touches any of:
|
|
14
|
+
|
|
15
|
+
- A YAML key under `configs/engine.yaml.example`, `deployments/coding-engine/values.yaml`, or `deployments/coding-engine/vecompass-override.yaml`
|
|
16
|
+
- A field on `internal/bootstrap/app/engine_config.go` (unified `EngineConfig`), `internal/bootstrap/worker/registry.go` (`RegistryConfig` / provider wiring), or `internal/adapters/outbound/<provider>/config.go`
|
|
17
|
+
- An image (`repository`, `tag`, `name`, init image)
|
|
18
|
+
- A DSN, connection string, or any `<scheme>://...` URL
|
|
19
|
+
- A K8s probe path/port, Service port, or service name
|
|
20
|
+
- A TOP Action IAM registration (`deployments/coding-engine/templates/server/iam-register-codingserver.yaml`)
|
|
21
|
+
- A credential (`password`, `secret_key`, `access_key`, `ak`, `sk`, `token`, `apikey`, `api_key`)
|
|
22
|
+
- A runtime adapter (`hermes`) config struct, or `runtime.WorkspaceSyncConfig` (wired via the worker registry; the code is `internal/application/agent/workspace_sync.go`, not an outbound adapter)
|
|
23
|
+
|
|
24
|
+
If unsure, run the Trigger Grep below — if you get hits across multiple surfaces, this skill applies.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Replace <KEY> with the field you're touching (e.g. initImageTag, storage_class, client_encoding)
|
|
28
|
+
grep -rn "<KEY>" internal/bootstrap/app/engine_config.go internal/adapters/outbound/ \
|
|
29
|
+
internal/bootstrap/worker/registry.go configs/ deployments/ docs/
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## The 5 Surfaces (per service)
|
|
34
|
+
|
|
35
|
+
For each backend component (`server`, `gateway`, `worker`, `daemon`), every config-shape change must touch:
|
|
36
|
+
|
|
37
|
+
| # | Surface | Path | Owns |
|
|
38
|
+
|---|---|---|---|
|
|
39
|
+
| 1 | Go config struct + defaults + validation | `internal/bootstrap/app/engine_config.go` (unified `EngineConfig`; component dirs only hold `config_test.go` against `app.EngineConfig` / `app.NewDefaultEngineConfig()`). Adapter-local config stays in `internal/adapters/outbound/<provider>/config.go` | Type, defaults, semantic validation |
|
|
40
|
+
| 2 | Local example file | `configs/engine.yaml.example` (component top-level section) | Dev-friendly defaults, comments |
|
|
41
|
+
| 3 | Helm chart defaults | `deployments/coding-engine/values.yaml` (component section) | Chart-render input |
|
|
42
|
+
| 4 | vecompass production override | `deployments/coding-engine/vecompass-override.yaml` (component section) | Prod values |
|
|
43
|
+
| 5 | Component doc table | `docs/0N-coding-<component>.md` | Behavior contract for operators |
|
|
44
|
+
|
|
45
|
+
**Runtime adapters** (`hermes`, future…) are anchored on the **worker** surfaces. Their closed loop is: adapter config struct in `internal/adapters/outbound/<provider>/config.go`, unified `EngineConfig`, worker `RegistryConfig` / provider wiring in `internal/bootstrap/worker/registry.go`, local YAML example, Helm values / vecompass override, and the worker component doc. Runtime adapter config lives under `customconfig.coding.worker.runtime.<provider>` in `deployments/coding-engine/vecompass-override.yaml`. Workspace sync is not an outbound adapter: it is `runtime.WorkspaceSyncConfig` (code in `internal/application/agent/workspace_sync.go`) wired via the worker `RegistryConfig`. See `coding-runtime-adapter` §Deployment Config Sync Projection for runtime mechanics.
|
|
46
|
+
|
|
47
|
+
A change is **not done** until each applicable surface either (a) has the new key, or (b) has a written rationale for omission.
|
|
48
|
+
|
|
49
|
+
## TOP Action IAM Registration
|
|
50
|
+
|
|
51
|
+
Externally exposed TOP Actions must be registered in the unified server IAM ConfigMap:
|
|
52
|
+
|
|
53
|
+
| IAM registration template | Owns |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `deployments/coding-engine/templates/server/iam-register-codingserver.yaml` | All externally exposed TOP Actions, including gateway-served Actions whose `Proxy` points at the rendered gateway Service |
|
|
56
|
+
|
|
57
|
+
When adding, removing, renaming, or moving an Action:
|
|
58
|
+
|
|
59
|
+
1. Locate the actual route owner in `internal/bootstrap/server` or `internal/bootstrap/gateway`, not just the IDL service name.
|
|
60
|
+
2. Update `deployments/coding-engine/templates/server/iam-register-codingserver.yaml`.
|
|
61
|
+
3. Keep `Action`, `Version`, `Path`, `Proxy`, `ResourceName`, `_Role`, `_ModuleAction`, `IsAuth`, and `IsAudit` aligned with the implemented endpoint and resource model.
|
|
62
|
+
4. If the Action is served by gateway, keep the IAM registration in the server template but point `Proxy` at the rendered gateway Service fullname and port.
|
|
63
|
+
5. Update the component doc when the externally visible API contract or serving component changes.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Pattern Files (read when applicable)
|
|
67
|
+
|
|
68
|
+
| Sub-rule | Pattern file |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Image (`repository` + `tag` split, no `:latest`, contract validators) | `.agents/skills/coding-deploy-config/patterns/p1-image-fields.md` |
|
|
71
|
+
| DSN / connection string assembly in Go | `.agents/skills/coding-deploy-config/patterns/p2-dsn-in-go.md` |
|
|
72
|
+
| Credential placement: Secret vs ConfigMap | `.agents/skills/coding-deploy-config/patterns/p3-secret-vs-configmap.md` |
|
|
73
|
+
| Probe / Service port alignment with `server.addr` | `.agents/skills/coding-deploy-config/patterns/p5-probe-port-align.md` |
|
|
74
|
+
|
|
75
|
+
## Templates (copy and adapt)
|
|
76
|
+
|
|
77
|
+
| Need | Template |
|
|
78
|
+
|------|----------|
|
|
79
|
+
| Verification grep across all 5 surfaces | `.agents/skills/coding-deploy-config/templates/verify-key.sh` |
|
|
80
|
+
| Helm `_helpers.tpl` image-tag guard | `.agents/skills/coding-deploy-config/templates/image-tag-guard.tpl` |
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## Six Hard Rules (memorize)
|
|
84
|
+
|
|
85
|
+
1. **No `:latest` tag, ever.** Image must be split into `repository` + `tag`. The Helm template MUST reject `tag: ""` and `tag: "latest"`. See `p1-image-fields.md`.
|
|
86
|
+
2. **DSN is built in Go, never hand-concatenated in YAML.** Add the new param to `DSN()` on the component config struct — never paste a literal `postgres://...` into a YAML file. See `p2-dsn-in-go.md`.
|
|
87
|
+
3. **Credentials live in Secret, never ConfigMap.** Anything matching `password|secret_key|access_key|ak|sk|token|apikey|api_key` MUST come from a Secret-backed config file, `envFrom`, or `valueFrom.secretKeyRef`. Rendered ConfigMaps must contain only references / placeholders. Narrow exception: existing platform-owned `platform-info` environment credentials may be read from the `platform-info` ConfigMap only for the established platform contracts recorded in ADR 0022 and ADR 0048. See `p3-secret-vs-configmap.md`.
|
|
88
|
+
4. **Application config is YAML-first with narrow env exceptions.** Do not add `CODING_*` or other environment-variable overlays for application settings unless an ADR records the exception. Current exceptions are `CODING_SECRET_KEY` and ADR 0048 platform credentials; use YAML fields and Secret-backed rendered values for all other settings.
|
|
89
|
+
5. **Probe / Service port = `server.addr` port.** Never edit one without the other. See `p5-probe-port-align.md`.
|
|
90
|
+
6. **IAM registration is unified in the server template.** A TOP Action belongs in `iam-register-codingserver.yaml`; its `Proxy` follows the HTTP owner. Gateway-served Actions stay in the server IAM template and point at the gateway Service.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Done Checklist
|
|
94
|
+
|
|
95
|
+
Before marking any deployment/config task done:
|
|
96
|
+
|
|
97
|
+
- [ ] Trigger grep run; every applicable surface is reconciled
|
|
98
|
+
- [ ] Image fields: `repository` + `tag` split, no `:latest`, contract validator updated if applicable
|
|
99
|
+
- [ ] DSN/connection strings assembled in Go, not YAML
|
|
100
|
+
- [ ] No credential plaintext in rendered ConfigMaps
|
|
101
|
+
- [ ] TOP Action IAM registration reconciled with the actual serving component, including stale registration removal after moves/renames
|
|
102
|
+
- [ ] `make test` and `make check` pass
|
|
103
|
+
- [ ] If a Helm template changed: `helm template deployments/coding-engine` renders without error
|
|
104
|
+
- [ ] If a behavior contract changed: corresponding component doc table updated, status marker (`[已实现]` etc.) accurate
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## Common Mistakes
|
|
108
|
+
|
|
109
|
+
| Mistake | Fix |
|
|
110
|
+
|---|---|
|
|
111
|
+
| Edit only `vecompass-override.yaml`, leaving Helm chart default + Go default stale | Reconcile all 5 surfaces or write an explicit rationale |
|
|
112
|
+
| Paste full `postgres://user:pass@host/db?...` literal into a YAML field | Build via the component config `DSN()` helper |
|
|
113
|
+
| Add a new credential field to `values.yaml` as plaintext | Move to Secret-backed config or `valueFrom.secretKeyRef`; ConfigMap only holds the reference |
|
|
114
|
+
| Bump a `tag:` in `vecompass-override.yaml` but forget the chart default | Update `deployments/coding-engine/values.yaml` too — chart consumers without override will break |
|
|
115
|
+
| Add image as `image: foo:bar` (single string) | Split into `image.repository` + `image.tag` |
|
|
116
|
+
| Change `server.addr` from `:8080` to `:8081` without updating `service.httpPort` and probe path/port | Triple-edit; see `p5-probe-port-align.md` |
|
|
117
|
+
| Add an environment-variable config path for application settings | Add a YAML field to the unified engine config instead |
|
|
118
|
+
| Add a runtime adapter config field but skip the worker bootstrap mirror | Add the field to `RegistryConfig` and reconcile provider wiring in `internal/bootstrap/worker/registry.go` |
|
|
119
|
+
| Rename a config key in Go but leave `*.yaml.example` showing the old name | Old name is what new contributors will copy — must reconcile |
|
|
120
|
+
| Add a TOP Action handler but skip `iam-register-codingserver.yaml` | Register the Action in the unified server IAM template |
|
|
121
|
+
| Move an Action from gateway to server, or server to gateway, but leave the old Proxy | Keep the Action in the server IAM template and update `Proxy` to the actual serving component |
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## Cross-references
|
|
125
|
+
|
|
126
|
+
- `AGENTS.md` §Deployment Config Sync Gate — top-level rule (this skill is the deep version)
|
|
127
|
+
- `coding-runtime-adapter` §Deployment Config Sync Projection — runtime-adapter projection (worker-anchored)
|
|
128
|
+
- `docs/adr/0010-helm-library-chart.md` — shared chart helpers
|
|
129
|
+
- `docs/adr/0007-openclaw-operator-contract.md` — example of a contract validator that gates an image field
|