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,285 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-docs-audit
|
|
3
|
+
description: Use when performing a bounded, read-only audit of stable docs under docs/ plus root README.md, README.zh-CN.md, onboarding.html, and vibe-coding.html against current code implementation, excluding ADRs and OpenAPI/interface docs, and writing docs-audit-report.md with a Chinese discrepancy-only report, Critical/Major/Minor/Suggestion severity, mandatory git blame attribution to specific people, and a final per-person task summary. Enforces fixed phases, budgets, and stop conditions to avoid open-ended scans.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# coding-docs-audit: Stable Docs vs Implementation Audit
|
|
7
|
+
|
|
8
|
+
Read-only audit for stable project documentation. The final output is a Chinese report containing only mismatches between stable documentation and the current implementation. Every formal finding must be attributed to specific people from `git blame` / `git log` evidence.
|
|
9
|
+
|
|
10
|
+
## Output Contract
|
|
11
|
+
|
|
12
|
+
- Final report language: Chinese. Keep severity labels in English: `[Critical]`, `[Major]`, `[Minor]`, `[Suggestion]`.
|
|
13
|
+
- Final report destination: write the complete final report to repo-root `docs-audit-report.md`. Overwrite stale audit output only when the user asks to run this audit; do not write elsewhere.
|
|
14
|
+
- Report only discrepancies. Do not list correct checks, matched claims, "PASS" items, or documents with no findings.
|
|
15
|
+
- Every formal finding must name specific responsible person(s): author name, email when available, commit short SHA, date, and commit subject. For CI issue routing, always prefer `xxx@bytedance.com` email in owner/task headings when git history provides it; do not output only a Chinese display name.
|
|
16
|
+
- End the report with a per-person task summary derived from formal findings. Each task must reference the finding title/severity and state what that person should do.
|
|
17
|
+
- If a suspected mismatch cannot be attributed to at least one specific person from git history, do not include it in `## 差异点`; put it in `## 待确认问题`.
|
|
18
|
+
- Do not modify documentation or code.
|
|
19
|
+
|
|
20
|
+
## Scope
|
|
21
|
+
|
|
22
|
+
Audit:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
{
|
|
26
|
+
find docs -type f -name '*.md' \
|
|
27
|
+
! -path 'docs/adr/*' \
|
|
28
|
+
! -path 'docs/openapi/*' \
|
|
29
|
+
! -path 'docs/assets/*'
|
|
30
|
+
printf '%s\n' README.md README.zh-CN.md onboarding.html vibe-coding.html
|
|
31
|
+
} | sort
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Exclude:
|
|
35
|
+
|
|
36
|
+
- `docs/adr/` - ADRs are historical decision records; do not treat old decisions as required current behavior unless a stable doc repeats the claim.
|
|
37
|
+
- `docs/openapi/` - interface docs are owned by `coding-http-api` / `make check-openapi`.
|
|
38
|
+
- `docs/assets/` and generated images.
|
|
39
|
+
- `AGENTS.md` - not part of this audit scope for now; it is the agent routing layer, not stable product/operator documentation.
|
|
40
|
+
|
|
41
|
+
This skill never edits docs or code. It only reads files, runs search/blame commands, and writes the final report to `docs-audit-report.md`.
|
|
42
|
+
|
|
43
|
+
## Severity
|
|
44
|
+
|
|
45
|
+
Use exactly these labels:
|
|
46
|
+
|
|
47
|
+
| Severity | Meaning |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `[Critical]` | Documentation promises behavior, security, API, deployment, data durability, migration, or operational safety that code contradicts or lacks; users/operators could make unsafe decisions. |
|
|
50
|
+
| `[Major]` | Material feature/lifecycle/config/data-model mismatch that can mislead implementers or operators, but does not create an immediate unsafe path. |
|
|
51
|
+
| `[Minor]` | Local outdated detail, renamed package/file, small behavior nuance, stale example, or incomplete status marker with low blast radius. |
|
|
52
|
+
| `[Suggestion]` | Documentation is technically true but could point to newer code, clearer terminology, or useful missing context. |
|
|
53
|
+
|
|
54
|
+
If unsure between two severities, choose the lower one unless the mismatch can cause broken operations, data loss, security exposure, or incorrect API usage.
|
|
55
|
+
|
|
56
|
+
## Workflow
|
|
57
|
+
|
|
58
|
+
### 0. Timebox and stop rules
|
|
59
|
+
|
|
60
|
+
This audit must be bounded. Do not run an open-ended "check everything until nothing remains" loop.
|
|
61
|
+
|
|
62
|
+
Default budget for one run:
|
|
63
|
+
|
|
64
|
+
| Budget | Limit |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Stable doc files scanned | all stable docs, outline only |
|
|
67
|
+
| Candidate claims selected | max 90 |
|
|
68
|
+
| Formal findings | max 40 |
|
|
69
|
+
| Open questions | max 20 |
|
|
70
|
+
| `rg` searches | max 250 |
|
|
71
|
+
| `git blame` / `git log` calls | max 150 |
|
|
72
|
+
| Wall-clock target | about 60 minutes; stop at 90 minutes |
|
|
73
|
+
|
|
74
|
+
Stop immediately when any limit is reached. In `docs-audit-report.md`, add a short `## 审计边界` section saying which limit stopped the run and that remaining claims were not checked. Do not keep expanding scope.
|
|
75
|
+
|
|
76
|
+
### 1. Build the audit inventory
|
|
77
|
+
|
|
78
|
+
List stable docs:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
{
|
|
82
|
+
find docs -type f -name '*.md' \
|
|
83
|
+
! -path 'docs/adr/*' \
|
|
84
|
+
! -path 'docs/openapi/*' \
|
|
85
|
+
! -path 'docs/assets/*'
|
|
86
|
+
printf '%s\n' README.md README.zh-CN.md onboarding.html vibe-coding.html
|
|
87
|
+
} | sort
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Inventory pass is outline-only:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
rg -n '^#{1,4} |<h[1-4][ >]|\\[(已实现|部分实现|规划中)\\]|`[A-Za-z0-9_./:-]+`' \
|
|
94
|
+
docs README.md README.zh-CN.md onboarding.html vibe-coding.html \
|
|
95
|
+
--glob '*.md' \
|
|
96
|
+
--glob '*.html' \
|
|
97
|
+
--glob '!docs/adr/**' \
|
|
98
|
+
--glob '!docs/openapi/**' \
|
|
99
|
+
--glob '!docs/assets/**'
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Do not read every document end to end in the first pass. For each file, inspect headings/status markers and pick only concrete, high-risk claims.
|
|
103
|
+
|
|
104
|
+
Prioritize claims that name concrete implementation surfaces:
|
|
105
|
+
|
|
106
|
+
- components, packages, binaries, ports, adapters, runtimes
|
|
107
|
+
- config keys, env vars, Helm values, K8s resources, secrets
|
|
108
|
+
- DB tables/columns/indexes and persistence behavior
|
|
109
|
+
- lifecycle/error/retry/idempotency semantics
|
|
110
|
+
- Redis keys/commands, event names, queues, topics
|
|
111
|
+
- public CLI commands and user-visible workflows
|
|
112
|
+
|
|
113
|
+
Ignore purely explanatory prose unless it asserts current behavior.
|
|
114
|
+
|
|
115
|
+
Candidate selection rules:
|
|
116
|
+
|
|
117
|
+
- Take at most 3 candidate claims per doc file in one run.
|
|
118
|
+
- Prefer `[已实现]` and `[部分实现]` claims over `[规划中]`.
|
|
119
|
+
- Prefer higher-risk surfaces first: lifecycle/events, config/deploy, data model, runtime cleanup, security/credentials, API behavior.
|
|
120
|
+
- Skip claims whose identifiers are not concrete enough for targeted `rg`.
|
|
121
|
+
- Record skipped lower-priority areas only in `## 审计边界`, not as findings.
|
|
122
|
+
|
|
123
|
+
### 2. Turn doc claims into code checks
|
|
124
|
+
|
|
125
|
+
For each concrete claim, search the implementation using identifiers from the doc. Prefer `rg`:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
rg -n "<identifier|config_key|type|action|resource>" internal api cmd configs deployments pkg tests
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Use structured sources over prose when possible:
|
|
132
|
+
|
|
133
|
+
| Claim type | Primary evidence |
|
|
134
|
+
|---|---|
|
|
135
|
+
| HTTP / TOP Action behavior | `api/idl/*.thrift`, handlers, service methods |
|
|
136
|
+
| Config / deployment behavior | `configs/engine.yaml.example`, `internal/bootstrap/app/engine_config.go`, `deployments/` |
|
|
137
|
+
| DB schema | GORM PO models and `ensureSchema` wiring |
|
|
138
|
+
| Runtime adapter behavior | adapter `config.go`, `executor.go`, `controller.go`, bootstrap registration |
|
|
139
|
+
| Redis behavior | Redis adapter code and tests for key-slot/hash-tag constraints |
|
|
140
|
+
| Component lifecycle | `cmd/`, `internal/bootstrap/`, component packages |
|
|
141
|
+
|
|
142
|
+
If the doc names behavior but there is no searchable code evidence, report it only after checking nearby terminology and likely renamed concepts.
|
|
143
|
+
|
|
144
|
+
Per-claim search cap:
|
|
145
|
+
|
|
146
|
+
- Max 3 targeted `rg` searches per claim.
|
|
147
|
+
- Max 2 code files inspected per claim.
|
|
148
|
+
- Max 1 negative-search finding per claim. Do not chase every synonym.
|
|
149
|
+
- If the first 3 searches are inconclusive, move the claim to `## 待确认问题` or skip it if low risk.
|
|
150
|
+
|
|
151
|
+
### 3. Validate before reporting
|
|
152
|
+
|
|
153
|
+
Every finding needs both:
|
|
154
|
+
|
|
155
|
+
- **Doc evidence**: exact doc file/line and the claim being contradicted.
|
|
156
|
+
- **Code evidence**: exact code/config file/line showing the current implementation, or a documented negative search when code is absent.
|
|
157
|
+
|
|
158
|
+
Do not report a mismatch from memory. If evidence is ambiguous, put it under `## 待确认问题` instead of forcing a finding. Do not output "checked and correct" evidence.
|
|
159
|
+
|
|
160
|
+
Validation cap:
|
|
161
|
+
|
|
162
|
+
- Spend proof effort only on candidate mismatches, not on correct claims.
|
|
163
|
+
- Once a candidate is proven correct, stop investigating that claim and do not mention it in the report.
|
|
164
|
+
- Once a mismatch has enough doc/code evidence for one finding, stop expanding related sub-issues unless they change severity.
|
|
165
|
+
|
|
166
|
+
### 4. Attribute with git blame
|
|
167
|
+
|
|
168
|
+
For every finding, run blame on the doc line(s) and the code line(s):
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
git blame -L <start>,<end> -- <path>
|
|
172
|
+
git log -1 --format='%H%n%an <%ae>%n%ad%n%s' -- <commit>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Mandatory attribution rule:
|
|
176
|
+
|
|
177
|
+
- **Doc owner**: author of the blamed doc line containing the outdated/current claim.
|
|
178
|
+
- **Code owner**: author of the blamed implementation line proving current behavior.
|
|
179
|
+
- **Responsible person(s)**: every finding must include at least one concrete person from doc blame, code blame, or removal/rename history.
|
|
180
|
+
- **Primary responsible person**: the side most likely responsible for the drift:
|
|
181
|
+
- stale doc vs newer code: primary = doc owner if doc line is newer than the code behavior it misstates; otherwise primary = code owner if implementation changed after the doc claim.
|
|
182
|
+
- removed/renamed code with unchanged doc: primary = code owner of the removal/rename when identifiable from `git log -S` / `git log -- <path>`; otherwise primary = doc owner with "implementation removal not isolated".
|
|
183
|
+
- both sides changed recently or causality unclear: mark both as "joint/unclear" and explain.
|
|
184
|
+
|
|
185
|
+
For deleted or renamed code paths, use pickaxe/history:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
git log --follow -- <old-or-current-path>
|
|
189
|
+
git log -S '<identifier>' --all -- <likely-path-or-directory>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
If blame returns an all-zero commit for uncommitted changes, attribute that side to `working tree (uncommitted)` and say final ownership requires commit history.
|
|
193
|
+
|
|
194
|
+
If the investigation cannot produce a specific person for either side, the item is not a formal finding. Move it to `## 待确认问题` with the missing attribution step.
|
|
195
|
+
|
|
196
|
+
Attribution cap:
|
|
197
|
+
|
|
198
|
+
- Run blame only after a mismatch is validated.
|
|
199
|
+
- Use one blame range for the doc claim and one blame range for the code evidence.
|
|
200
|
+
- Use `git log -S` / `--follow` only for deleted/renamed code evidence, max 2 commands per finding.
|
|
201
|
+
- Do not blame every supporting line; attribute the line that best represents the drift.
|
|
202
|
+
|
|
203
|
+
### 5. Write `docs-audit-report.md`
|
|
204
|
+
|
|
205
|
+
Write the final report to repo-root `docs-audit-report.md` using this Chinese structure. Do not add a section for correct results or executed commands.
|
|
206
|
+
|
|
207
|
+
```markdown
|
|
208
|
+
## 文档实现一致性审计
|
|
209
|
+
|
|
210
|
+
范围:稳定 `docs/` Markdown 加根目录 `README.md`、`README.zh-CN.md`、`onboarding.html`、`vibe-coding.html`;排除 `docs/adr/`、`docs/openapi/`、`docs/assets/` 和 `AGENTS.md`。
|
|
211
|
+
版本:`<git rev-parse --short HEAD>`
|
|
212
|
+
|
|
213
|
+
## 摘要
|
|
214
|
+
- Critical: N
|
|
215
|
+
- Major: N
|
|
216
|
+
- Minor: N
|
|
217
|
+
- Suggestion: N
|
|
218
|
+
- 仅统计差异点;未列出的文档/检查项表示未发现需要报告的问题。
|
|
219
|
+
|
|
220
|
+
## 审计边界
|
|
221
|
+
- 候选 claim:N / 90
|
|
222
|
+
- 正式差异点:N / 40
|
|
223
|
+
- 待确认问题:N / 20
|
|
224
|
+
- 搜索/归因预算:说明是否触达上限。
|
|
225
|
+
- 未覆盖范围:仅在触达预算上限或主动跳过高成本区域时填写。
|
|
226
|
+
|
|
227
|
+
## 差异点
|
|
228
|
+
|
|
229
|
+
### [Severity] 简短标题
|
|
230
|
+
- 文档证据:`<doc path>:<line>` - 用中文概括文档声称了什么。
|
|
231
|
+
- 实现证据:`<path>:<line>` - 用中文概括当前代码/配置实际是什么;如果是缺失,写明负向搜索命令和范围。
|
|
232
|
+
- 差异说明:一句话说明文档与实现如何不一致。
|
|
233
|
+
- 责任归因:
|
|
234
|
+
- 主要责任人:`<姓名> <email>`,`<commit short>`,`<date>`,`<commit subject>` - 用中文说明为什么归到此人/此提交。
|
|
235
|
+
- 文档 blame:`<姓名> <email>`,`<commit short>`,`<date>`,`<commit subject>`。
|
|
236
|
+
- 实现 blame:`<姓名> <email>`,`<commit short>`,`<date>`,`<commit subject>`;若实现缺失,改为 `删除/重命名历史` 并给出 `git log -S` 或 `git log --follow` 定位到的提交。
|
|
237
|
+
- 建议处理:用中文说明应该让人更新文档、核实实现,或补充代码;不要直接修改。
|
|
238
|
+
|
|
239
|
+
## 按人员整理的任务
|
|
240
|
+
|
|
241
|
+
### `<姓名> <email>` 或 `<email>`
|
|
242
|
+
- `[Severity] <差异点标题>`:该人员需要完成的动作。明确是更新文档、核实实现、补代码、补配置,还是协调另一侧 owner。
|
|
243
|
+
- 证据:引用对应差异点里的文档/实现证据路径,不重新展开完整 blame。
|
|
244
|
+
|
|
245
|
+
## 待确认问题
|
|
246
|
+
- 只放证据不足、实现语义不明确、或无法归因到具体人员的疑似问题。不要混入正式差异点。
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
If there are no discrepancies, output only:
|
|
250
|
+
|
|
251
|
+
```markdown
|
|
252
|
+
## 文档实现一致性审计
|
|
253
|
+
|
|
254
|
+
范围:稳定 `docs/` Markdown 加根目录 `README.md`、`README.zh-CN.md`、`onboarding.html`、`vibe-coding.html`;排除 `docs/adr/`、`docs/openapi/`、`docs/assets/` 和 `AGENTS.md`。
|
|
255
|
+
版本:`<git rev-parse --short HEAD>`
|
|
256
|
+
|
|
257
|
+
未发现需要报告的文档/实现差异。
|
|
258
|
+
|
|
259
|
+
## 审计边界
|
|
260
|
+
- 候选 claim:N / 90
|
|
261
|
+
- 搜索/归因预算:未触达上限 / 触达上限。
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Sort findings by severity, then by document path.
|
|
265
|
+
|
|
266
|
+
Build `## 按人员整理的任务` after finalizing `## 差异点`:
|
|
267
|
+
|
|
268
|
+
- Group by `主要责任人`; if a finding is marked joint/unclear but has concrete people, list the task under every named person and say "共同确认".
|
|
269
|
+
- Task group headings must include a bytedance email whenever available from blame/log output, because `docs-audit-to-issues.py` uses that email to resolve the Codebase assignee. A display name alone is not enough for automation.
|
|
270
|
+
- Do not create tasks for `## 待确认问题` unless a concrete next owner is known from blame/history; otherwise leave them only in `## 待确认问题`.
|
|
271
|
+
- Do not include people from correct checks, because correct checks must not be reported.
|
|
272
|
+
- Keep task wording action-oriented and specific enough for assignment.
|
|
273
|
+
|
|
274
|
+
## Quality Bar
|
|
275
|
+
|
|
276
|
+
- Audit must follow the fixed budget in §0; do not exceed it to chase completeness.
|
|
277
|
+
- No finding without line-level doc evidence.
|
|
278
|
+
- No finding without line-level implementation evidence or an explicit negative-search note.
|
|
279
|
+
- No finding without a named responsible person backed by `git blame` / `git log` evidence.
|
|
280
|
+
- No final report with formal findings unless it also contains `## 按人员整理的任务`.
|
|
281
|
+
- Final report must be written to repo-root `docs-audit-report.md`.
|
|
282
|
+
- No output of correct/matched checks.
|
|
283
|
+
- Final report must be Chinese, except fixed severity labels and file/command names.
|
|
284
|
+
- Do not blame authors for historical ADR drift; ADRs are out of scope.
|
|
285
|
+
- Do not modify documentation as part of this skill.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-docs-audit-autofix
|
|
3
|
+
description: Use after coding-docs-audit has produced docs-audit-report.md to conservatively fix obvious stable-doc drift and write a focused notification report for the findings that still need code/config/implementation follow-up.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# coding-docs-audit-autofix
|
|
7
|
+
|
|
8
|
+
This skill is the docs-audit split stage. It does two things:
|
|
9
|
+
|
|
10
|
+
1. Fix only findings that are clearly documentation drift after reading the cited docs and implementation.
|
|
11
|
+
2. Write `docs-audit-notification-report.md` by removing the fixed documentation-only findings from the original report, so notification can send that file without doing its own semantic filtering.
|
|
12
|
+
|
|
13
|
+
## Required References
|
|
14
|
+
|
|
15
|
+
Read these references before acting:
|
|
16
|
+
|
|
17
|
+
- `.agents/skills/coding-docs-audit-autofix/references/autofix-docs.md` - how to judge and fix documentation-only findings.
|
|
18
|
+
- `.agents/skills/coding-docs-audit-autofix/references/notification-report.md` - how to derive the notification report from the original report.
|
|
19
|
+
|
|
20
|
+
Only read `.agents/skills/coding-docs-audit-autofix/references/open-mr.md` when changing the CI MR-opening script or pipeline flow.
|
|
21
|
+
|
|
22
|
+
## Hard Boundaries
|
|
23
|
+
|
|
24
|
+
- Do not edit code, config, deployment YAML, migrations, API contracts, ADRs, OpenAPI docs, or generated assets.
|
|
25
|
+
- Do not classify by keyword rules alone. Use the finding's actual meaning, the cited documentation, and the cited implementation/config evidence.
|
|
26
|
+
- Be conservative: if a finding could require implementation work, leave it in `docs-audit-notification-report.md`.
|
|
27
|
+
- Keep `docs-audit-report.md` as the immutable original audit output. Write the derived notification copy to `docs-audit-notification-report.md`.
|
|
28
|
+
|
|
29
|
+
## Expected Outputs
|
|
30
|
+
|
|
31
|
+
- Stable doc edits only within the docs-audit stable-document scope owned by `scripts/lib/docs-audit-scope.sh`, only when safe.
|
|
32
|
+
- `docs-audit-notification-report.md` always exists after the skill runs.
|
|
33
|
+
- If no findings were fixed, `docs-audit-notification-report.md` is an exact semantic copy of `docs-audit-report.md`.
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-http-api
|
|
3
|
+
description: Use when changing any HTTP API surface in coding_engine — adding/modifying/removing a Thrift IDL field or service method under `api/idl/*.thrift`, editing a Hertz handler under `internal/adapters/inbound/http/handlers/`, or aligning generated clients/frontends with backend changes. Encodes the IDL field-tag conventions, required↔optional compatibility rules, the codegen/regen step, the handler→service→domain dispatch shape, the cross-layer cleanup checklist for renames/removals, and the frontend-alignment trigger.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# coding-http-api: API / IDL / Handler Contract
|
|
7
|
+
|
|
8
|
+
## Trigger — does this skill apply?
|
|
9
|
+
|
|
10
|
+
YES if your change touches any of:
|
|
11
|
+
|
|
12
|
+
- `api/idl/*.thrift` (any field, struct, service method, or annotation)
|
|
13
|
+
- `internal/adapters/inbound/http/thrift_gen/` (this is generated — touch the IDL instead)
|
|
14
|
+
- `internal/adapters/inbound/http/handlers/<aggregate>_handler.go`
|
|
15
|
+
- `internal/application/<aggregate>/dto.go` or `mapper.go` if the application boundary type is changing
|
|
16
|
+
- `web/` and the change you're making affects API requests/responses
|
|
17
|
+
- A field's `optional` ↔ `required` flip in any IDL struct
|
|
18
|
+
- `docs/openapi/coding-engine-api.html` (Redocly-rendered page; regenerated from the IDL together with `docs/openapi/openapi.yaml` by `make check-openapi`; Makefile pins Redocly to the same `@redocly/cli@2.31.6` version used by CI because HTML output changes across Redocly versions)
|
|
19
|
+
|
|
20
|
+
NO if you're only touching internal domain logic that doesn't reach the wire.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## The Pipeline
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
api/idl/<aggregate>.thrift ← single source of truth (Thrift IDL)
|
|
27
|
+
│
|
|
28
|
+
│ make gen-thrift (hz model — uses api/idl/server.thrift as umbrella)
|
|
29
|
+
▼
|
|
30
|
+
internal/adapters/inbound/http/thrift_gen/<aggregate>/ ← generated, never hand-edit
|
|
31
|
+
│
|
|
32
|
+
│ imported by handlers
|
|
33
|
+
▼
|
|
34
|
+
internal/adapters/inbound/http/handlers/<aggregate>_handler.go ← Hertz handler, implements httpserver.<Service>
|
|
35
|
+
│
|
|
36
|
+
│ calls application use cases
|
|
37
|
+
▼
|
|
38
|
+
internal/application/<aggregate>/ ← service, DTO, mapper
|
|
39
|
+
│
|
|
40
|
+
│ uses domain types
|
|
41
|
+
▼
|
|
42
|
+
internal/domain/<aggregate>/ ← entity, repository
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
A change at the IDL surface must be rolled forward through every layer in the same PR. Single-layer edits are caught at compile time only when handlers `var _ httpserver.AgentService = (*AgentHandler)(nil)` — but field semantics (rename without compile-break) won't be.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## IDL Conventions
|
|
49
|
+
|
|
50
|
+
Scope: current `api/idl/*.thrift` files are all TOP / Hertz HTTP API contracts. `make gen-thrift` consumes `api/idl/server.thrift` as the umbrella and generates HTTP models under `internal/adapters/inbound/http/thrift_gen/`. There are no internal RPC / non-HTTP-exposed IDL exceptions today. If a future non-HTTP IDL surface is introduced, it must use a separate directory or an explicitly documented file boundary before this convention can diverge.
|
|
51
|
+
|
|
52
|
+
```thrift
|
|
53
|
+
struct CreateAgentRequest {
|
|
54
|
+
1: required string WorkspaceID (go.tag = 'json:"WorkspaceID"')
|
|
55
|
+
2: required string Name (go.tag = 'json:"Name"')
|
|
56
|
+
3: optional string Description (go.tag = 'json:"Description,omitempty"')
|
|
57
|
+
4: optional string ModelID (go.tag = 'json:"ModelID,omitempty"')
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Mandatory rules:
|
|
62
|
+
|
|
63
|
+
| Rule | Why |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Field IDs are stable. **Never reuse** a field ID for a different field even after removal | Thrift wire compatibility — old clients sending the old id at the new struct corrupts decoding |
|
|
66
|
+
| `optional` fields ALWAYS carry `,omitempty` in their `go.tag` JSON spec | Prevents `null` / zero values from being sent over the wire when the caller didn't set them |
|
|
67
|
+
| `required` fields NEVER use `,omitempty` | The whole point of required is that it must serialize |
|
|
68
|
+
| Request structs do not expose transport identity fields; user and tenant data come from `requestctx` | Keeps identity handling in the HTTP dispatcher/middleware layer |
|
|
69
|
+
| Field ID `255` is reserved for legacy compatibility | Don't reuse field id 255 for anything else |
|
|
70
|
+
| Field name in PascalCase (Thrift), JSON key also in PascalCase via `go.tag` for all `api/idl/*.thrift` files | Project HTTP API convention; keep request/response wire shape aligned with generated frontend types. Run `make lint-thrift` to validate IDL syntax; it does not enforce JSON casing, so keep casing manually consistent or add a regen-time check |
|
|
71
|
+
| Service / response struct names match across the file | `AgentService.CreateAgent → CreateAgentRequest → AgentResponse` |
|
|
72
|
+
|
|
73
|
+
After editing IDL, regenerate:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
make gen-thrift # Hertz HTTP models (writes thrift_gen/)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The IDL → Go pipeline is HTTP-only: Hertz `hz model` consumes `api/idl/server.thrift` and writes `internal/adapters/inbound/http/thrift_gen/<aggregate>/`. There is no RPC stub codegen and no top-level generated RPC package — handlers depend only on the HTTP models above.
|
|
80
|
+
|
|
81
|
+
Never hand-edit `internal/adapters/inbound/http/thrift_gen/` — the next regen wipes it.
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
## Compatibility — Required ↔ Optional Flips
|
|
85
|
+
|
|
86
|
+
| Direction | Wire impact | Cleanup required |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `optional → required` | **Breaking**: callers that omit it now fail validation | Audit every caller (frontend, SDK, internal); the field must be guaranteed-present at the application layer first |
|
|
89
|
+
| `required → optional` | **Non-breaking** for callers, but breaks consumers if the response side: clients reading the field expecting non-null break | Audit response readers; ensure handler still produces it when available |
|
|
90
|
+
| Add new `optional` field | Non-breaking | Frontend can choose to populate over time |
|
|
91
|
+
| Add new `required` field | **Breaking** | Must coordinate with all clients; ship as `optional` first, flip later |
|
|
92
|
+
| Remove field | **Breaking** | Same audit as required→optional, plus remove all DTO/mapper/handler/event references |
|
|
93
|
+
|
|
94
|
+
History — the `Agent.Name optional → required` flip in commit `66b0ea5`:
|
|
95
|
+
> 将 Agent Name 字段从 optional 改为 required,使 IDL 定义与业务层校验保持一致;同时清理 DisplayName 字段在 domain/dto/mapper/handler/events 中的遗留引用
|
|
96
|
+
|
|
97
|
+
That commit touched 6 layers: IDL, DTO, mapper, handler, domain entity, event payload. The Cross-Layer Cleanup Checklist below codifies that audit.
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
## Cross-Layer Cleanup Checklist (rename / remove / type-change)
|
|
101
|
+
|
|
102
|
+
When a field is **renamed**, **removed**, or **type-changed**, every following file class needs an audit:
|
|
103
|
+
|
|
104
|
+
- [ ] `api/idl/<aggregate>.thrift` — request, response, list-response, and any nested input struct
|
|
105
|
+
- [ ] `internal/adapters/inbound/http/thrift_gen/<aggregate>/` — regenerated via `make gen-thrift`
|
|
106
|
+
- [ ] `internal/adapters/inbound/http/handlers/<aggregate>_handler.go` — every method that reads/writes the field
|
|
107
|
+
- [ ] `internal/adapters/inbound/http/handlers/<aggregate>_handler_test.go` — table cases
|
|
108
|
+
- [ ] `internal/application/<aggregate>/dto.go` — request/response DTO struct
|
|
109
|
+
- [ ] `internal/application/<aggregate>/mapper.go` — domain ↔ DTO conversion
|
|
110
|
+
- [ ] `internal/application/<aggregate>/service.go` (or use-case files) — direct field reads/writes
|
|
111
|
+
- [ ] `internal/domain/<aggregate>/entity.go` — aggregate root field
|
|
112
|
+
- [ ] `internal/domain/events/*.go` — event payloads if the field appears
|
|
113
|
+
- [ ] `internal/adapters/outbound/persistence/rdb/po/<aggregate>.go` — GORM model
|
|
114
|
+
- [ ] `web/` — frontend request/response types (TypeScript or generated client)
|
|
115
|
+
- [ ] `docs/openapi/openapi.yaml` + `docs/openapi/coding-engine-api.html` — regenerated by `make check-openapi` so the new/renamed/removed `paths` and `components.schemas` are reflected; commit both
|
|
116
|
+
- [ ] `docs/0N-*.md` — component doc API tables
|
|
117
|
+
- [ ] `docs/07-data-model.md` — if the field shows in the data-model description
|
|
118
|
+
- [ ] If breaking and persistent: ADR 0003 entry under `docs/adr/`
|
|
119
|
+
|
|
120
|
+
Verification — single grep before merging:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
grep -rn "<old_field_name>" api/ internal/ web/ docs/
|
|
124
|
+
# Expected: zero hits OR explicit rationale per remaining hit
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
## Cross-Layer Plumbing Checklist (field-add)
|
|
129
|
+
|
|
130
|
+
Adding a new field to a Request or Response struct **does not wire itself up** — `make gen-thrift` produces getters and setters, not the application boundary. Without an end-to-end pass the field is silently dropped: compile passes, request body parses, persisted entity holds the zero value.
|
|
131
|
+
|
|
132
|
+
History — `fix(agent): plumb SystemPrompt through CreateAgent/UpdateAgent HTTP API` (commit c6c45d7): `SystemPrompt` was added to `CreateAgentRequest` / `UpdateAgentActionRequest` / `AgentResponse` in IDL, but the handler never called `req.GetSystemPrompt()`, the command struct did not carry it, and the response mapper did not set it back. Persisted agents had empty system prompts and `GetAgent` returned an empty field.
|
|
133
|
+
|
|
134
|
+
Audit every layer a new field must traverse:
|
|
135
|
+
|
|
136
|
+
- [ ] `api/idl/<aggregate>.thrift` — fresh field ID; `,omitempty` matches optional/required (see §IDL Conventions)
|
|
137
|
+
- [ ] `make gen-thrift` regenerated
|
|
138
|
+
- [ ] `internal/adapters/inbound/http/handlers/<aggregate>_handler.go` — **read `req.GetXxx()` and pass into the application command**; **populate `resp.Xxx` in the response mapper** (`agentResponseFromDTO` and equivalents)
|
|
139
|
+
- [ ] `internal/adapters/inbound/http/handlers/<aggregate>_handler_test.go` — round-trip case: send the field in the request, assert it on the persisted entity AND in the response payload
|
|
140
|
+
- [ ] `internal/application/<aggregate>/dto.go` — Command / Query DTO carries the field; for Update commands, use `*string` (or matching pointer type) so callers can express "unchanged"
|
|
141
|
+
- [ ] `internal/application/<aggregate>/service.go` — read from the command; write onto the entity (Create) or thread through the existing dirty-flag helper (Update — `optionalStringValue` / `hasAgentChanges` pattern)
|
|
142
|
+
- [ ] `internal/domain/<aggregate>/entity.go` — aggregate root field
|
|
143
|
+
- [ ] Persistent storage, if any — load `coding-db-schema` for PO, migration, repository, and data-model rules
|
|
144
|
+
- [ ] `web/` — frontend request/response TypeScript types
|
|
145
|
+
- [ ] `docs/openapi/openapi.yaml` + `docs/openapi/coding-engine-api.html` — regenerated by `make check-openapi` so the new field's parent schema is included; commit both
|
|
146
|
+
|
|
147
|
+
### Audit-field seeding (Create use cases)
|
|
148
|
+
|
|
149
|
+
GORM PO audit columns in this repo are **all hand-seeded**, not GORM-managed:
|
|
150
|
+
|
|
151
|
+
| Column | PO type | Auto-managed? |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| `created_by` | `string`, no DB default | No — Go entity value persists verbatim, including `""` |
|
|
154
|
+
| `updated_by` | `string`, no DB default | No — same |
|
|
155
|
+
| `created_at` | `int64` (epoch ms), `not null` | No — POs use `int64` not `time.Time`, no `autoCreateTime` tag |
|
|
156
|
+
| `updated_at` | `int64` (epoch ms), `not null` | No — same |
|
|
157
|
+
|
|
158
|
+
The Go entity-construction site in `internal/application/<aggregate>/service.go` is the **only** place these get populated.
|
|
159
|
+
|
|
160
|
+
On every `Create`:
|
|
161
|
+
|
|
162
|
+
- [ ] Set `entity.CreatedBy = cmd.CreatedBy`
|
|
163
|
+
- [ ] **Set `entity.UpdatedBy = cmd.CreatedBy`** — otherwise rows persist with `UpdatedBy=""` until the first `Update` call (`fix(agent,gateway): seed UpdatedBy on CreateAgent`, commit 56d7a12). `ListAgents` / `GetAgent` will return an empty `UpdatedBy` for freshly created records
|
|
164
|
+
- [ ] Seed `entity.CreatedAt` and `entity.UpdatedAt` from `s.deps.Now().UTC()` — both fields, same timestamp
|
|
165
|
+
- [ ] If the Create transaction also constructs nested child entities (e.g. channels, MCPs, skills), apply the same four-field seeding rule to each
|
|
166
|
+
- [ ] Handler test asserts the persisted entity has all four audit fields populated, not just `CreatedBy`
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
## Handler Pattern (Hertz)
|
|
170
|
+
|
|
171
|
+
Canonical handler shape — `internal/adapters/inbound/http/handlers/agent_handler.go`:
|
|
172
|
+
|
|
173
|
+
```go
|
|
174
|
+
type AgentHandler struct {
|
|
175
|
+
service agent.Service
|
|
176
|
+
userResolver port.UserResolver
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
var _ httpserver.AgentService = (*AgentHandler)(nil) // compile-time contract pin
|
|
180
|
+
|
|
181
|
+
func NewAgentHandler(service agent.Service, userResolver port.UserResolver) *AgentHandler {
|
|
182
|
+
return &AgentHandler{
|
|
183
|
+
service: service,
|
|
184
|
+
userResolver: userResolver,
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
func (h *AgentHandler) CreateAgent(ctx context.Context, req *httpagent.CreateAgentRequest) (*httpagent.CreateAgentResponse, error) {
|
|
189
|
+
if req == nil {
|
|
190
|
+
return nil, toHTTPError(invalid("req is required"))
|
|
191
|
+
}
|
|
192
|
+
tenantID, workspaceID, err := tenantAndWorkspaceID(ctx, req.GetWorkspaceID())
|
|
193
|
+
if err != nil {
|
|
194
|
+
return nil, toHTTPError(err)
|
|
195
|
+
}
|
|
196
|
+
// ... map Thrift req → application DTO, call h.service.CreateAgent(ctx, agent.CreateAgentCommand{...}), map result → Thrift resp
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Mandatory rules:
|
|
201
|
+
|
|
202
|
+
- `var _ httpserver.<Service> = (*<Aggregate>Handler)(nil)` — compile-time interface check; never remove
|
|
203
|
+
- All errors flow through `toHTTPError(err)` (defined in `helpers.go`); never return raw `error`
|
|
204
|
+
- All validation errors use `invalid(msg)`; never `errors.New`
|
|
205
|
+
- Pull `tenantID` / `workspaceID` from request context via `tenantAndWorkspaceID(ctx, ...)` — never trust request body fields alone
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
## Frontend Alignment Trigger
|
|
209
|
+
|
|
210
|
+
Whenever a request or response struct changes shape (field added, removed, renamed, required-flipped, or type-changed), the frontend must be aligned. History: `feat: align coding frontend with updated APIs` was a single PR retrofitting many drift items at once — exactly the situation this skill prevents.
|
|
211
|
+
|
|
212
|
+
Practical workflow:
|
|
213
|
+
|
|
214
|
+
1. Make the IDL + handler + tests change in one branch
|
|
215
|
+
2. In the same PR (or a paired PR): update `web/` API client types and any UI code that reads removed/renamed fields
|
|
216
|
+
3. CI should fail loudly if frontend types drift — if no such CI exists, treat the audit as manual and run a grep across `web/`
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
## Templates (copy and adapt)
|
|
220
|
+
|
|
221
|
+
| Need | Template |
|
|
222
|
+
|------|----------|
|
|
223
|
+
| New IDL service + struct skeleton | `.agents/skills/coding-http-api/templates/new-service.thrift` |
|
|
224
|
+
| New Hertz handler skeleton | `.agents/skills/coding-http-api/templates/new-handler.go` |
|
|
225
|
+
| Pre-merge cross-layer grep | `.agents/skills/coding-http-api/templates/grep-field.sh` |
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
## Done Checklist
|
|
229
|
+
|
|
230
|
+
- [ ] IDL change applied; field IDs unchanged for existing fields; new fields use fresh IDs
|
|
231
|
+
- [ ] `make gen-thrift` run; `thrift_gen/` regenerated
|
|
232
|
+
- [ ] Handler updated; `var _ httpserver.<Service> = ...` still compiles
|
|
233
|
+
- [ ] DTO and mapper updated; domain entity updated if the field is persistent
|
|
234
|
+
- [ ] If persistent: GORM PO / AutoMigrate schema update via `coding-db-schema`
|
|
235
|
+
- [ ] If breaking: ADR 0003 entry; doc updated
|
|
236
|
+
- [ ] Frontend aligned in the same PR (or explicit paired PR linked)
|
|
237
|
+
- [ ] Cross-layer grep returns clean (rename / remove / type-change)
|
|
238
|
+
- [ ] If field-add: §Cross-Layer Plumbing Checklist passes (`req.GetXxx()` → command → entity → response, round-trip handler test)
|
|
239
|
+
- [ ] If Create use case: all four audit fields seeded (`CreatedBy`, `UpdatedBy`, `CreatedAt`, `UpdatedAt`); nested child entities seeded the same way
|
|
240
|
+
- [ ] `docs/openapi/openapi.yaml` + `docs/openapi/coding-engine-api.html` regenerated by `make check-openapi` (green, working tree clean) and committed (mandatory whenever `api/idl/*.thrift` changed; use the Makefile default pinned Redocly version unless intentionally matching a CI version bump)
|
|
241
|
+
- [ ] Handler tests updated — see `coding-testing` Strategy 4
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
## Common Mistakes
|
|
245
|
+
|
|
246
|
+
| Mistake | Fix |
|
|
247
|
+
|---|---|
|
|
248
|
+
| Hand-edit a file under `internal/adapters/inbound/http/thrift_gen/` | Lost on next `make gen-thrift`. Edit the `.thrift` and regen |
|
|
249
|
+
| Reuse a removed field's ID for a new field | Old clients sending old data populate the new field with garbage. Use a fresh ID |
|
|
250
|
+
| Add `optional` field but forget `,omitempty` in `go.tag` | Zero values serialize as `null`, frontend dispatches false truthy paths |
|
|
251
|
+
| Flip `required → optional` without auditing response readers | Frontend code reading `.field` without nil-check breaks — required field-flip needs explicit handling |
|
|
252
|
+
| Rename a field, update IDL + handler, forget `web/` | "Works locally" until first frontend request fails 400/422 |
|
|
253
|
+
| Update Thrift but skip `make gen-thrift` | `thrift_gen/` is stale; `var _ httpserver.<Service>` still compiles against old shape |
|
|
254
|
+
| Add new endpoint to IDL but forget to add it to `httpserver.<Service>` interface assertion | Compile passes (interface assertion only checks declared methods); endpoint exists but routing missed. Always re-pin the interface |
|
|
255
|
+
| Drop a field from `events/*.go` payload but leave domain entity carrying it | Event consumers receive zero-value; tests pass but downstream breaks |
|
|
256
|
+
| Use `errors.New("invalid")` in handler | Use `invalid("descriptive message")`; the helper sets correct HTTP status |
|
|
257
|
+
| Skip handler test update — only update the use-case test | Handler tests catch mapper / Thrift binding regressions; both are required |
|
|
258
|
+
| Add new IDL field, run `make gen-thrift`, but handler skips `req.GetXxx()` or response mapper does not set `resp.Xxx` | Silent drop — compile passes, request parses, persisted entity holds the zero value. Wire end-to-end (cmd → entity → response) and add a round-trip handler test |
|
|
259
|
+
| On `Create`, set only `CreatedBy` (leave `UpdatedBy` / `CreatedAt` / `UpdatedAt` zero) | PO columns have no DB default and `int64` timestamps are not GORM-managed — rows persist with `UpdatedBy=""` and `UpdatedAt=0` until first `Update`. Seed all four from the requesting user + `s.deps.Now()` |
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
## Cross-references
|
|
263
|
+
|
|
264
|
+
- `Makefile` — `gen-thrift` target is authoritative (HTTP-only; no RPC codegen)
|
|
265
|
+
- `coding-architecture` — the layer map (handler → service → domain → adapter) and DTO/mapper conventions
|
|
266
|
+
- `coding-testing` Strategy 4 — handler tests with Hertz test client
|
|
267
|
+
- `coding-db-schema` — when the field is persistent, GORM schema ownership must be updated alongside
|
|
268
|
+
- `coding-deploy-config` — when an endpoint changes port, probe path, or Service contract
|
|
269
|
+
- `docs/CONVENTIONS.md` — `[已实现]` / `[规划中]` status markers for component-doc updates
|