ops-wiki-agent-kit 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/.github/agents/docs-target-catalog.agent.md +52 -0
- package/.github/agents/docs-target-queue-from-catalog.agent.md +34 -0
- package/.github/agents/source-code-to-spec-documenter.agent.md +39 -0
- package/.github/agents/source-code-to-spec-reviewer.agent.md +51 -0
- package/.github/agents/source-code-to-system-ops-overview.agent.md +39 -0
- package/.github/prompts/00-generate-target-all-spec.prompt.md +35 -0
- package/.github/prompts/01-generate-target-foundation-spec.prompt.md +35 -0
- package/.github/prompts/02-generate-target-architecture-spec.prompt.md +35 -0
- package/.github/prompts/03-generate-target-ops-spec.prompt.md +35 -0
- package/.github/prompts/04-review-target-spec.prompt.md +24 -0
- package/.github/prompts/docs-target-catalog.prompt.md +32 -0
- package/.github/prompts/docs-target-queue-from-catalog.prompt.md +28 -0
- package/.github/prompts/generate-system-ops-overview.prompt.md +62 -0
- package/.github/skills/database-query/SKILL.md +140 -0
- package/.github/skills/database-query/references/client-commands.md +189 -0
- package/.github/skills/database-query/references/query-safety.md +109 -0
- package/.github/skills/database-query/scripts/find_db_config.py +273 -0
- package/.github/skills/docs-target-catalog/SKILL.md +194 -0
- package/.github/skills/docs-target-catalog/references/docs-target-queue-conversion.md +164 -0
- package/.github/skills/docs-target-catalog/references/entrypoint-source-patterns.md +83 -0
- package/.github/skills/docs-target-catalog/references/output-templates.md +168 -0
- package/.github/skills/docs-target-queue-from-catalog/SKILL.md +255 -0
- package/.github/skills/docs-target-queue-from-catalog/references/docs-target-queue-contract.md +125 -0
- package/.github/skills/docs-target-queue-from-catalog/references/metadata-acquisition-patterns.md +149 -0
- package/.github/skills/docs-target-queue-from-catalog/scripts/write_documentation_target_queue.py +527 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/SKILL.md +128 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/01-system-overview-and-business-scenarios-guideline.md +172 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/02-core-architecture-flow-data-logic-guideline.md +637 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/03-error-ops-scenario-coverage-guideline.md +533 -0
- package/.github/skills/source-code-to-ops-spec-guidelines/references/supporting-output-format-diagram-and-example-reference.md +523 -0
- package/.github/skills/source-code-to-spec-documenter/SKILL.md +80 -0
- package/.github/skills/source-code-to-spec-documenter/references/generation-handoff-contract.md +155 -0
- package/.github/skills/source-code-to-spec-documenter/references/generation-workflow.md +184 -0
- package/.github/skills/source-code-to-spec-documenter/references/source-tracing-rules.md +271 -0
- package/.github/skills/source-code-to-spec-documenter/references/target-queue-contract.md +78 -0
- package/.github/skills/source-code-to-spec-documenter/scripts/spec_queue.py +222 -0
- package/.github/skills/source-code-to-spec-tools/SKILL.md +117 -0
- package/.github/skills/source-code-to-spec-tools/references/repository-artifact-contract.md +122 -0
- package/.github/skills/source-code-to-spec-tools/references/target-queue-schema-contract.md +116 -0
- package/.github/skills/source-code-to-spec-tools/references/terminology-contract.md +121 -0
- package/.github/skills/source-code-to-spec-tools/scripts/catalog_query.py +324 -0
- package/.github/skills/source-code-to-spec-tools/scripts/queue_contract.py +210 -0
- package/.github/skills/source-code-to-spec-tools/scripts/source_lookup.py +360 -0
- package/.github/skills/source-code-to-spec-tools/scripts/target_query.py +407 -0
- package/.github/skills/source-code-to-system-ops-overview/SKILL.md +82 -0
- package/.github/skills/source-code-to-system-ops-overview/references/system-operations-overview-guideline.md +332 -0
- package/README.md +116 -0
- package/ops-wiki-agent-kit.js +173 -0
- package/package.json +22 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Source Tracing Rules
|
|
2
|
+
|
|
3
|
+
從佇列列出的 `entrypoint` 開始追蹤;除非 entrypoint 缺失且任務目標就是要補出它,否則不要先從任意檔案搜尋開始。
|
|
4
|
+
|
|
5
|
+
詞彙語意以 `.github/skills/source-code-to-spec-tools/references/terminology-contract.md` 為準。`keyword` 可協助 lookup,但不得取代 `entrypoint` tracing 或 `source_evidence`;coverage / scenario applicability 也必須由 evidence 支撐,不可從 `source_type` 名稱直接推論。
|
|
6
|
+
|
|
7
|
+
在追蹤 source code 之前,必須先執行 `Knowledge Map Preflight`。此 preflight 不取代 source evidence;它只建立 trace hypotheses、search priority 與 known-gap ledger,避免每次 generation 都從完全空白狀態重新 discovery。
|
|
8
|
+
|
|
9
|
+
固定工具優先順序:
|
|
10
|
+
|
|
11
|
+
1. 載入 `source-code-to-spec-tools`,使用 `target_query.py preflight` 讀取 selected row、queue summary、queue coverage 與 related rows。
|
|
12
|
+
2. 使用 `source-code-to-spec-tools` 的 `catalog_query.py handoff` / `catalog_query.py search` 查詢 catalog handoff、direct rows 與 catalog coverage。
|
|
13
|
+
3. 使用 `source-code-to-spec-tools` 的 canonical source lookup command 取得 source evidence refs,再依 refs 進入檔案閱讀與 call chain tracing。
|
|
14
|
+
|
|
15
|
+
只有在上述 CLI 查不到、解析失敗或檔案格式超出支援時,才補手動 `rg` 或 parser-specific inspection,並在 handoff 中記錄 CLI limitation。不要呼叫其他 skill 私有 `scripts/` 目錄。
|
|
16
|
+
|
|
17
|
+
## Canonical Source Lookup Command
|
|
18
|
+
|
|
19
|
+
`source_root` 是本次 selected row 要做 source tracing 的 source artifact 根目錄;若 queue、handoff、使用者指示或 workflow context 沒有提供更窄範圍,預設為 target source repo root。即使 `source_root` 等於 repo root,也必須在 `source_lookup.py` 命令中顯式傳入 `--root`,不要依賴目前 shell `cwd`。
|
|
20
|
+
|
|
21
|
+
```powershell
|
|
22
|
+
python -B .github/skills/source-code-to-spec-tools/scripts/source_lookup.py --root "<source-root>" --handle "<entrypoint>" --ignore-case --output json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
若 source repo 與 workflow repo 分離、target 位於 monorepo 子模組、或 selected row 只對應特定 extracted source tree,`source_root` 必須指向該可追蹤範圍,而不是工具所在 repo root。需要縮小檔案類型時,使用 `--include` 補 bounded glob;不要改用未限定 root 的全文搜尋取代 canonical lookup。
|
|
26
|
+
|
|
27
|
+
## EvidenceRef Contract
|
|
28
|
+
|
|
29
|
+
所有寫入 handoff `source_evidence` 的 source evidence,都必須能對應到同一個 `EvidenceRef` 物件。Target-facing generated docs 聚焦於業務行為、處理流程、資料規則、錯誤處理與維運判斷方式;source path、line、symbol 與 `EvidenceRef[]` 保存在 handoff。文件中只在內容需要時保留必要識別資料,例如 API path、SQL ID、table、status column、job name、config key、file name、log keyword 或 trace id。
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"path": "src/main/java/com/example/OrderController.java",
|
|
34
|
+
"line": 42,
|
|
35
|
+
"symbol": "OrderController.importOrders()",
|
|
36
|
+
"kind": "method"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Field | Required | Rule |
|
|
41
|
+
| ------------ | -------: | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| `path` | Y | Repo-relative file path、可重讀 metadata path,或穩定 source identifier。對 repo file 必須使用實際相對路徑,不要只寫 filename。 |
|
|
43
|
+
| `line` | Y | Repo file evidence 必須填 1-based line number。只有 DB metadata、runtime export、external contract 或 generated doc 無可用行號時才可填 `null`。 |
|
|
44
|
+
| `symbol` | Y | 最小可搜尋 technical handle,例如 `ClassName.methodName()`、`GET /api/orders`、`TABLE_NAME`、`config.key`、`JobName`、`ProcedureName`。 |
|
|
45
|
+
| `kind` | Y | 使用穩定英文值:`entrypoint`、`route`、`handler`、`class`、`method`、`SQL`、`table`、`config`、`job`、`procedure`、`routine`、`file`、`test`、`runtime_metadata`、`generated_doc`、`external_contract`、`other`。 |
|
|
46
|
+
|
|
47
|
+
`source_lookup.py` 的 `matches[].evidence_ref` 是可複用的初始 EvidenceRef;後續人工 tracing 可調整 `kind` 與 `symbol`,但不可移除必要欄位。若同一結論需要多個 evidence,請用多個 `EvidenceRef`,不要把多個 path/line 塞進同一欄字串。
|
|
48
|
+
|
|
49
|
+
## Knowledge Map Preflight
|
|
50
|
+
|
|
51
|
+
1. 使用 `target_query.py preflight` 讀取 `docs/docs-target-queue.md` 的 selected row,確認 `id`、`source_type`、`group`、`name`、`entrypoint`、`document_path`、`keyword`、status、`last_handoff` 與 `notes`。
|
|
52
|
+
2. 讀取 queue 的 `Source Acquisition Summary`,確認 selected row 來自 DB export、catalog direct rows、repo-owned route/config、hardcoded source、external metadata 或 unresolved source。
|
|
53
|
+
3. 讀取 queue 的 `Coverage Review`,先排除 known helper、folder-only row、unmapped servlet、missing metadata 或 excluded target,避免把 gap 當成新 target。
|
|
54
|
+
4. 使用 `catalog_query.py` 讀取 `docs/docs-target-catalog.md` 的 `Authoritative Target Source Handoff`、direct target rows、hardcoded target rows 與 catalog-level `Coverage Review`,確認 final row authority 與 acquisition action。
|
|
55
|
+
5. 使用 `target_query.py related` 查找 candidate related rows:同 `group`、同 `entrypoint`、同 handler/class、同 route/path、同 scheduler/job、同 table/resource、同 `keyword` 或 catalog evidence 指向同一 implementation artifact 的 rows。這些只是候選關係,不是 target boundary 結論;必須依 `Functional Boundary And Handoff Edges` 分類後,才可寫入 handoff `related_rows`。
|
|
56
|
+
6. 若 selected row 有 `last_handoff`、既有 docs、partial output 或 review failure,先讀取並復用已確認的 evidence、unresolved items 與仍有效的說明;但舊 handoff 的 `id`、path segment 或 related row key 不得作為 reader-facing label 復用。
|
|
57
|
+
7. 建立 `reader_facing_name_map`,至少包含 selected row,以及本次可能寫入 final SPEC 或 handoff summary 的 candidate related rows、confirmed `handoff_edge` rows、既有 handoff related rows 與 catalog handoff rows。每筆必須保留 machine-readable `id`,但 final SPEC 顯示用 `display_label` 必須優先取 row `name` / 功能名稱,其次取 source-backed job / API / handler / batch name;若無法確認可讀 label,`display_label=Unresolved`。若既有 handoff 沒有 `reader_facing_name_map` 或某筆 map 只剩 raw `id`,必須用 current queue / catalog / source evidence 重建 map,並把無法解析的 label 寫成 `Unresolved`。
|
|
58
|
+
8. 將 preflight 結果整理為 `source map`、`known gaps`、`related rows`、`reader_facing_name_map`、`coverage hints`、`trace hypotheses`、`search_priority`,再開始 source tracing。
|
|
59
|
+
|
|
60
|
+
## Existing Output Reconciliation
|
|
61
|
+
|
|
62
|
+
既有 target 文件、handoff 與 reviewer note 是前次 generation context,不是目前 SPEC truth。當使用者指定 `id`,或 queue row 的 `document_path` / `last_handoff` 指向既有輸出時,必須在寫新內容前做 reconciliation:
|
|
63
|
+
|
|
64
|
+
這個 reconciliation requirement 是 documenter workflow 的 shared rule;不因 `generation_scope`、selected coverage views 或下游 entrypoint 而改變。
|
|
65
|
+
|
|
66
|
+
1. 讀取既有三份 target SPEC、handoff JSON 與 reviewer note。
|
|
67
|
+
2. 抽出可重用的 `EvidenceRef`、unresolved items、coverage gaps、profile decision 與仍符合 source evidence 的段落;若舊 handoff 缺少 `reader_facing_name_map`、`display_label` 或 related row `name`,只把它當成 evidence context,不把其中的 label wording 當成可重用文件文字。
|
|
68
|
+
3. 將既有內容與 selected row、current preflight、`reader_facing_name_map`、source lookup、catalog handoff、candidate related rows、selected coverage views 逐項比對。
|
|
69
|
+
4. 若既有內容與現行 source evidence 不符、缺少新發現 behavior / coverage / data resource、仍保留已失效描述,或在 reader-facing content 中使用 known queue row `id` 代稱功能 / job / target / participant / sibling row,更新文件與 handoff,並在 handoff 記錄 map drift、naming correction 或 reconciliation result。
|
|
70
|
+
5. 若 handoff 的 `related_rows`、`relation_candidates`、`coverage_hints` 或 `unresolved_items` 需要被轉寫到 final SPEC,必須先經 `reader_facing_name_map` 轉成 `display_label` 或 source-backed technical identifier;不得複製 raw JSON field value 到 reader-facing doc。
|
|
71
|
+
6. 若既有內容仍符合現行 evidence,保留既有段落與 link,不要重建無差異內容。
|
|
72
|
+
|
|
73
|
+
Generated docs 只有在能回查到 `EvidenceRef` 或可重讀 source extract 時,才可作為 `generated_doc` evidence;否則只能當作 context,必須回到 source code、runtime metadata 或 authoritative source 驗證。
|
|
74
|
+
|
|
75
|
+
## Idempotent Update Gate
|
|
76
|
+
|
|
77
|
+
若 target SPEC 已存在,更新前必須先判斷是否存在 material difference。更新必須是 evidence-driven patch,不得重新生成整份文件後用同義改寫覆蓋既有內容。
|
|
78
|
+
|
|
79
|
+
只有下列情況允許修改既有文件:
|
|
80
|
+
|
|
81
|
+
- source code、SQL、config、DB object、queue row、catalog handoff、runtime evidence 或既有文件證據顯示目前內容錯誤。
|
|
82
|
+
- 既有文件缺少 `source-code-to-ops-spec-guidelines` 要求的必要章節、欄位或維運資訊,且該缺漏影響目前 `doc_profile` / `generation_scope`。
|
|
83
|
+
- 既有文件引用的 class、method、table、column、API path、status、error message、log keyword、file path、job name 或 config key 已過時。
|
|
84
|
+
- Markdown table、Mermaid、code fence、Metadata 或 sibling 文件關係有結構性錯誤。
|
|
85
|
+
- 既有文件在標題、Metadata、摘要、表格描述、Mermaid participant alias、ERD 補充表、圖表文字說明、狀態 mapping、維護注意事項、監控指標、troubleshooting 或 cross-reference 中,把 known queue row `id` 當成 reader-facing display label。此情況是 naming contract violation,即使 source behavior 沒變,也必須依 `reader_facing_name_map` patch 成 row `name` / 功能名稱、source-backed technical identifier 或 `Unresolved`。
|
|
86
|
+
- 新增 source evidence 可補足原本標示為 `N/A`、`TBD`、`Unresolved`、`Inferred`、`推論` 或「無法由目前來源確認」的內容。
|
|
87
|
+
|
|
88
|
+
下列情況不得修改:
|
|
89
|
+
|
|
90
|
+
- 內容語意相同,只是換句話說。
|
|
91
|
+
- 只是調整語氣、詞序、段落順序或排版偏好。
|
|
92
|
+
- 只是把現有內容改成另一種同樣正確的表格、條列或段落格式。
|
|
93
|
+
- 沒有新增、刪除或修正任何可追溯到 source evidence 的資訊。
|
|
94
|
+
- 只是為了符合模型當次生成風格而重寫。
|
|
95
|
+
|
|
96
|
+
若差異只是在 final SPEC reader-facing content 中把 `F1`、`F2`、`J2` 這類 known queue row `id` 改為 `reader_facing_name_map.display_label`,仍屬 material correction,不得歸類為語氣或風格調整。
|
|
97
|
+
|
|
98
|
+
若只有 non-material difference,對應 file action 必須回報 `UNCHANGED`。若需要修改,必須只 patch 受影響章節,保留仍正確且有來源依據的既有文字、表格、圖表與章節順序。
|
|
99
|
+
|
|
100
|
+
更新既有文件時,handoff 或 final response 必須附上逐檔或逐章節的 `Change Justification`:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
Change Justification:
|
|
104
|
+
- <file or section>: <CREATED | UPDATED | UNCHANGED>
|
|
105
|
+
Reason: <missing | outdated | incorrect | broken-format | evidence-added | unchanged>
|
|
106
|
+
Evidence: <source path / SQL / config / DB object / queue row / catalog handoff / existing doc>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Code Verification Pass
|
|
110
|
+
|
|
111
|
+
Knowledge map 是索引與假設,不是 SPEC 行為描述的最終來源。每個寫入文件的行為、資料流、權限、錯誤處理、coverage applicability 或操作步驟,都必須由 source code、runtime metadata、可重讀的 source extract 或既有 generated docs 中的 source evidence 支撐。
|
|
112
|
+
|
|
113
|
+
Code verification 的目標是產生 full detail source-backed SPEC,而不是只確認高階流程是否存在。摘要不可取代正式詳細章節;若 source evidence 可確認 SQL、DAO / Repository / Mapper method、table、status transition、config、job、file I/O、external integration、error handling 或 operations behavior,必須在對應 scope 的章節保留可審查細節。
|
|
114
|
+
|
|
115
|
+
- 從 selected row 的 `entrypoint` 實際解析到 source file、class、route、handler、job、procedure 或 config。
|
|
116
|
+
- 驗證 preflight 中的 handler、target name、entrypoint、data resource、coverage hints 與 known gaps 是否仍符合 source。
|
|
117
|
+
- 如果 queue/catalog 與 code 不一致,以 code evidence 為準,但必須記錄差異。
|
|
118
|
+
- 不可因 preflight 沒提到某個行為,就跳過 entrypoint 可達的 code path。
|
|
119
|
+
- `generation_scope` 只限制本次 selected output file 與本次 run 擁有的正式章節,不限制 source tracing 範圍,也不降低本 scope 內 source-backed detail 的深度。若同一 business lifecycle 可能需要 downstream job、callback、staging table、status transition 或 external integration 才能解釋目前 scope 的交付點,必須檢查足夠 evidence 並依 `Functional Boundary And Handoff Edges` 分類;不可因本次只產生 foundation / architecture / ops 單檔就省略,也不可把獨立 downstream target 的內部流程展開到目前文件。
|
|
120
|
+
- `doc_profile=full` 時,必須保留可讀取的完整 SQL excerpt;動態 SQL 必須轉為 source-backed pseudo SQL,並列出條件來源、參數、join、排序、狀態過濾與限制。DAO / Repository / Mapper method 必須 mapping 到 SQL、table、status column、DB object、stored routine、file resource 或 external resource。
|
|
121
|
+
|
|
122
|
+
每次 generation / update 都必須整理 `Evidence Checked` / `Not Checked`:
|
|
123
|
+
|
|
124
|
+
- `Evidence Checked` 列出實際查過的 JSP / UI event、Tag / include、Controller / Servlet、Service、DAO / Repository、SQL、table、status column、Job、config、error message、log keyword、runtime metadata、existing doc 或 external contract。
|
|
125
|
+
- `Not Checked` 列出依 `source_type`、`entrypoint`、selected coverage view 與 ops SPEC guideline 應追蹤但尚未確認的項目,並說明原因。
|
|
126
|
+
- 若主要 source path 尚未追完,handoff `status` 必須是 `partial`、`blocked` 或 `failed`;不得以 `generated` 包裝成完成版。
|
|
127
|
+
|
|
128
|
+
## Functional Boundary And Handoff Edges
|
|
129
|
+
|
|
130
|
+
Target 文件的責任邊界到「本 target 完成自身處理並交付給下一個可獨立啟動單元」為止。若 A 寫入 DB、queue、file、message 或 staging data 供 B 使用,而 B 在 `docs/docs-target-queue.md` 有獨立 row、獨立 entrypoint、獨立 scheduler/API/command/menu 或其他 activation evidence,A 文件必須完整寫清 A 產生的 handoff data、status、flag、correlation key、SQL / DAO mapping 與 source evidence;B 的內部處理只寫 activation pointer、handoff summary 與 cross-reference。
|
|
131
|
+
|
|
132
|
+
A 文件可以描述:
|
|
133
|
+
|
|
134
|
+
- A 寫入或更新的 table / queue / file / message / status / flag / correlation key。
|
|
135
|
+
- A 的成功結果是「work item 已建立並等待後續處理」,或「已交付給下游 target」。
|
|
136
|
+
- 下游 target 名稱與最小 cross-reference,例如「後續由 `JobName` 依 `STATUS='READY'` 接手處理」;若下游 target 來自 queue / handoff,名稱必須取 `reader_facing_name_map.display_label` 或 source-backed job / API / handler / batch name,不得取 raw row `id`。
|
|
137
|
+
- A 如何產生 handoff data 的 source-backed detail,例如 handler / service / DAO method、SQL excerpt 或 pseudo SQL、欄位 mapping、狀態轉移與錯誤時保留狀態。
|
|
138
|
+
|
|
139
|
+
A 文件不應展開 B-owned 內部規格:
|
|
140
|
+
|
|
141
|
+
- B-owned schedule、batch size、完整查詢條件、DAO SQL 明細。
|
|
142
|
+
- B 的 transaction / rollback / retry / rerun / monitoring / troubleshooting。
|
|
143
|
+
- B 後面再接 C / D 的完整 lifecycle。
|
|
144
|
+
|
|
145
|
+
例外情況:
|
|
146
|
+
|
|
147
|
+
- B 沒有獨立 activation evidence,只是 A 的 private helper、include、internal method 或同一 handler 內的實作細節。
|
|
148
|
+
- selected target 本身是 `Workflow`、end-to-end business process,或使用者明確要求端到端流程文件。
|
|
149
|
+
- B 的少量行為是判斷 A 的結果狀態、錯誤意義或 handoff 是否成功所必需;此時可保留必要 source-backed downstream cue,例如 B 消化的 status predicate、topic、file pattern、correlation key 或 result writeback,但仍不寫 B 的完整規格。
|
|
150
|
+
|
|
151
|
+
若 selected row 的 `entrypoint` 是 UI、JSP、screen operation、API、file import/export 或其他 front-door handler,但 tracing 過程發現下列任一 lifecycle 線索,必須檢查 downstream relation 並分類,不得直接推定為目前 target 的完整 downstream lifecycle:
|
|
152
|
+
|
|
153
|
+
- 寫入 request header / line、work queue、staging table、outbox table、integration table 或 pending table。
|
|
154
|
+
- 出現 `status`、`process_status`、`state`、`phase`、`flag`、`retry`、`batch_id`、`process_id`、`job_id`、`request_id` 等狀態推進欄位。
|
|
155
|
+
- 更新防重複、鎖定、pending、sent、validated、registered、completed、failed 或 rollback/reprocess 相關欄位。
|
|
156
|
+
- 呼叫或引用 DAO / service / config / table / class name,指向 scheduler、job、worker、consumer、callback、external integration 或 reprocess path。
|
|
157
|
+
- related rows、catalog handoff、既有文件或 source lookup 指向同一資料資源、同一 status lifecycle 或同一 external process。
|
|
158
|
+
|
|
159
|
+
### Handoff Relation Classification
|
|
160
|
+
|
|
161
|
+
將 candidate relation 分為以下三類:
|
|
162
|
+
|
|
163
|
+
| relation | Definition | Current target doc behavior | Handoff behavior |
|
|
164
|
+
| --- | --- | --- | --- |
|
|
165
|
+
| `handoff_edge` | A 建立 work item,B 以明確 source evidence 接手並推進同一 work item。 | 完整寫 A 的交付資料、狀態、correlation key、SQL / DAO mapping 與 source evidence;B 只寫 activation pointer、交接摘要與 cross-reference。 | 可寫入 `related_rows`。 |
|
|
166
|
+
| `shared_data_dependency` | A / B 使用同一 table/resource,但沒有明確接手或狀態推進關係。 | 通常不寫;必要時只列資料影響。 | 不寫入 `related_rows`;必要時寫入 `coverage_gaps` / `unresolved_items`。 |
|
|
167
|
+
| `incidental_reference` | lookup、report、audit/log、history、join、permission check 或其他偶然引用。 | 不寫。 | 不寫入 `related_rows`。 |
|
|
168
|
+
|
|
169
|
+
只有同時符合下列條件,才可判定為 `handoff_edge`:
|
|
170
|
+
|
|
171
|
+
1. A 寫入或更新明確 handoff 狀態,例如 `STATUS='READY'`、`QUEUE_STATUS='READY'`、`PROCESS_PHASE='PENDING'`、message topic、file pattern 或 pending record。
|
|
172
|
+
2. B 有 source evidence 明確消化該 handoff 狀態,例如 SQL 查同一 status、consumer 讀同一 topic、job 掃同一 pending table 或 parser 讀同一 file pattern。
|
|
173
|
+
3. A 與 B 之間有可追蹤 correlation key,例如 `REQUEST_ID`、`WORK_ITEM_ID`、`PROCESS_ID`、message key、file name 或 business key。
|
|
174
|
+
4. B 的處理會推進 A 建立的 work item,例如 status transition、flag 更新、result writeback、ack / error result 或 completion marker。
|
|
175
|
+
|
|
176
|
+
若只看到「共用同一張表」或「同一 group / keyword / resource」,不得建立 `handoff_edge`。若只能看到疑似欄位或命名慣例,缺少可重讀 source evidence,不得補成完整 relation;在文件與 handoff 標示「無法由目前來源確認」。
|
|
177
|
+
|
|
178
|
+
`related_rows` 必須保持 compact,只放 `handoff_edge`,且每筆只保留:
|
|
179
|
+
|
|
180
|
+
- related row `id` / `name` / `entrypoint`。
|
|
181
|
+
- `relation=handoff_edge`。
|
|
182
|
+
- 一句 `reason`。
|
|
183
|
+
- `correlation_key`。
|
|
184
|
+
- 可對應 `source_evidence` 的 refs 或 source location。
|
|
185
|
+
|
|
186
|
+
Current target doc 描述 related row 或 downstream target 時,必須使用 `reader_facing_name_map.display_label`、source-backed job / API / handler / batch name,或標示 `Unresolved`;不得使用 related row `id` 作為功能、job、target、participant 或 cross-reference label。Related row `id` 只保留在 handoff、review note、final response 或 machine-readable reconciliation。
|
|
187
|
+
|
|
188
|
+
不要在 handoff `related_rows` 複製 downstream target 的完整分析。
|
|
189
|
+
|
|
190
|
+
`N/A: 已確認此功能不涉及 Batch、Scheduler 或背景處理` 只能在完成下列檢查後使用:
|
|
191
|
+
|
|
192
|
+
1. 已從 selected entrypoint 追蹤 form action / handler / service / DAO / SQL / table / status column。
|
|
193
|
+
2. 已檢查 candidate related rows、catalog handoff、keyword、handler/class/table/resource lookup,未發現符合 `handoff_edge` 條件的 job、scheduler、worker、consumer、callback、staging table 或 reprocess path。
|
|
194
|
+
3. `Evidence Checked` 明確列出上述檢查項目。
|
|
195
|
+
|
|
196
|
+
若尚未完成這些檢查,只能寫「無法由目前來源確認」,並把缺少的 job / scheduler / downstream evidence 寫入 `Not Checked`、`coverage_gaps` 或 `unresolved_items`。
|
|
197
|
+
|
|
198
|
+
## Coverage Gap Handling
|
|
199
|
+
|
|
200
|
+
`source-code-backed SPEC` 不是「source code alone guarantees complete SPEC」。當完整行為依賴 repo 外部資料時,請產生可審查缺口,不要補成推測結論。
|
|
201
|
+
|
|
202
|
+
常見缺口包含:
|
|
203
|
+
|
|
204
|
+
- DB metadata、seed data、menu/navigation table、permission table 或 production records。
|
|
205
|
+
- Runtime config、environment file、feature flag、scheduler registry 或 deployment manifest。
|
|
206
|
+
- Generated registry、code generation output、compiled artifact 或 runtime discovery result。
|
|
207
|
+
- Credentials、external contract、vendor schema、message topic definition 或 managed service setting。
|
|
208
|
+
|
|
209
|
+
處理規則:
|
|
210
|
+
|
|
211
|
+
- 若缺口不阻擋目前 scope 的 source-backed 描述,保留 partial SPEC,並在 handoff `coverage_gaps` / `unresolved_items` 說明影響與最小下一步。
|
|
212
|
+
- 若缺口阻擋 target boundary、entrypoint 或主要流程確認,將 handoff `status` 設為 `blocked`。
|
|
213
|
+
- 若缺口只影響部分 coverage view、欄位或操作細節,將 handoff `status` 設為 `partial`,文件內對應欄位填 `TBD` 或 `Unresolved`。
|
|
214
|
+
- 不可把沒有 evidence 的 DB rows、permissions、runtime values、external responses 或 generated mappings 寫成已確認事實。
|
|
215
|
+
|
|
216
|
+
## Expansion Search
|
|
217
|
+
|
|
218
|
+
在完成主要 handler trace 後,必須沿 entrypoint 附近搜尋地圖可能漏掉的 secondary flows:
|
|
219
|
+
|
|
220
|
+
- UI:form action、link、button handler、AJAX/fetch/XHR、popup、tab、wizard step、print、export/import、upload/download。
|
|
221
|
+
- API/service:secondary endpoint、callback、webhook、message publish/consume、internal service operation。
|
|
222
|
+
- Batch/job:manual trigger、rerun/retry path、scheduler config、job dependency、worker/queue consumer。
|
|
223
|
+
- Data/resource:SQL、stored routine / database program、view/table、file I/O、report template、external system call。
|
|
224
|
+
- Cross-cutting:permission branch、audit/logging/error handling、config flag、feature toggle。
|
|
225
|
+
|
|
226
|
+
若 Expansion Search 發現 downstream lifecycle 線索,必須依 `Functional Boundary And Handoff Edges` 判定它是 `handoff_edge`、`shared_data_dependency`、`incidental_reference`,或目前來源不足的 unresolved item。
|
|
227
|
+
|
|
228
|
+
若附加行為沒有獨立 activation evidence,通常寫入目前 target 的 sub-action;若有獨立 menu、route、job、API、command、permission 或 scheduler evidence,只在符合 `handoff_edge` 條件時寫入 compact `related_rows`,否則依關係類型忽略或記錄為 gap / unresolved item。
|
|
229
|
+
|
|
230
|
+
## Map Drift Handling
|
|
231
|
+
|
|
232
|
+
若 code verification 或 expansion search 發現知識地圖不完整或過期:
|
|
233
|
+
|
|
234
|
+
- `map_drift`: 描述 queue/catalog 與 source code 的差異。
|
|
235
|
+
- `map_corrections`: 建議如何修正 selected row、related rows、source acquisition summary 或 catalog coverage。
|
|
236
|
+
- `unmapped_behaviors_found`: 列出 entrypoint 可達但地圖未標記的附加操作、secondary flows 或 coverage views。
|
|
237
|
+
- `unresolved_items`: 若 drift 影響 target boundary、completion 或 review outcome,列出後續需要 catalog/queue 修正的最小事項。
|
|
238
|
+
|
|
239
|
+
## Evidence Order
|
|
240
|
+
|
|
241
|
+
1. 啟動來源:選單列、路由對應、排程註冊、命令、API 合約、外部檔案或平台中繼資料。
|
|
242
|
+
2. 執行期處理器:JSP/action、servlet/controller、job 類別、procedure、script、consumer 或 command handler。
|
|
243
|
+
3. 處理邏輯:service/domain 類別,以及由 handler 直接呼叫的輔助流程。
|
|
244
|
+
4. 資料存取:DAO/repository/mapper、SQL 文字、stored routine / database program、table/view/resource。
|
|
245
|
+
5. 覆蓋面:UI、API、DB/SQL、batch、file I/O、external integration、Oracle PL/SQL、security、observability、config、operation。
|
|
246
|
+
|
|
247
|
+
## Rules
|
|
248
|
+
|
|
249
|
+
- 將原始碼視為證據;不要自行臆測業務行為。
|
|
250
|
+
- 原始路徑、類別、方法、SQL 識別字、設定鍵、路由路徑與資料表名稱都必須精確引用。
|
|
251
|
+
- Handoff 的 `source_evidence` 必須是 `EvidenceRef[]`,不可只填自由文字。
|
|
252
|
+
- Generated docs 以可讀內容呈現 source-backed 事實;`EvidenceRef[]` 保存在 handoff,文件本身只在操作、資料、狀態、錯誤或排查內容需要時保留必要識別資料。
|
|
253
|
+
- 不確定的項目請標記為 `TBD` 或 `Unresolved`。
|
|
254
|
+
- 除非具有獨立的啟動證據,否則不要把 helper 檔、CRUD 子畫面、popup、include 或產生物提升為獨立 target。
|
|
255
|
+
- 當 entrypoint 指向 UI 頁面時,要追蹤 form action、連結、AJAX 呼叫、伺服器處理器、被引用 script 與權限檢查。
|
|
256
|
+
- 當 entrypoint 指向 job 時,要追蹤排程註冊、參數、job 類別、交易行為、資料資源、retry/rerun 與 logging。
|
|
257
|
+
- 當 entrypoint 指向 API/servlet 時,要追蹤 request path、handler 類別、request/response 合約、service 呼叫、資料資源、auth、錯誤處理與 observability。
|
|
258
|
+
|
|
259
|
+
## Minimum Source-Backed Content For Generated Docs
|
|
260
|
+
|
|
261
|
+
每份產生的文件都應包含:
|
|
262
|
+
|
|
263
|
+
- Reader-facing target label,依 `supporting-output-format-diagram-and-example-reference.md` 的 Metadata / naming contract。
|
|
264
|
+
- Entrypoint,以及已解析出的 source file/class/config。
|
|
265
|
+
- 入口、資料資源、狀態、錯誤或操作判斷所需的必要 identifiers;完整 path / line / symbol 證據摘要保留在 handoff。
|
|
266
|
+
- 主要流程的 source-backed detailed section;摘要只能作為導覽,若無法完整追蹤,必須說明缺少的 evidence。
|
|
267
|
+
- 資料資源,或明確標註 `N/A`。
|
|
268
|
+
- Coverage applicability:`Y`、`N/A` 或 `TBD`。
|
|
269
|
+
- `doc_profile=full` 時,保留完整 SQL excerpt 或 source-backed pseudo SQL、DAO / Repository / Mapper method mapping、欄位 / 狀態 / request / response mapping,以及與維運判斷相關的 branch、transaction、retry、rerun、log 與 error detail。
|
|
270
|
+
- 若 source evidence 顯示 File I/O / Report 行為,architecture 文件必須在 `6.5 檔案 I/O 規格` 保留欄位規格、驗證規則與錯誤輸出;有匯出 / 報表 evidence 時也要保留資料來源與欄位對應。來源不足時在對應表格標示「無法由目前來源確認」,不得以流程摘要或 ops troubleshooting 取代。
|
|
271
|
+
- 對於缺少 DB metadata、環境檔、generated registry、外部匯出、credentials 或程式路徑不清楚之處,列出 `coverage_gaps` 與 unresolved 項目。
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Target Queue Contract
|
|
2
|
+
|
|
3
|
+
`docs/docs-target-queue.md` 是 SPEC generation / review 的 target queue。每一列代表一個可被獨立鎖定、產生文件並回寫狀態的 documentation target。
|
|
4
|
+
|
|
5
|
+
共用詞彙以 `.github/skills/source-code-to-spec-tools/references/terminology-contract.md` 為準。Queue schema、status enum、`doc_profile` 規則、`source_type` registry 與 prefix / `document_path` default pattern 以 `.github/skills/source-code-to-spec-tools/references/target-queue-schema-contract.md` 為準;scripts 必須 import `.github/skills/source-code-to-spec-tools/scripts/queue_contract.py`。
|
|
6
|
+
|
|
7
|
+
## Selection Rules
|
|
8
|
+
|
|
9
|
+
1. 明確指定 `id` 時,一律以該 `id` 為準。
|
|
10
|
+
2. 明確指定 `id` 時,不檢查 `document_completed_flag(Y/N)` 或任何 doc status;即使該列不是 `pending` 或不是 `N`,也必須處理該 selected row。
|
|
11
|
+
3. 未提供 `id` 時,依 `docs/docs-target-queue.md` main target table 順序由上到下挑選第一筆符合本次 scope 的 row。
|
|
12
|
+
4. 若 `scope=all`,挑選第一筆 `document_completed_flag(Y/N)=N` 的 row。
|
|
13
|
+
5. 若 `scope=foundation`,挑選第一筆 `foundation_doc_status=pending` 的 row。
|
|
14
|
+
6. 若 `scope=architecture`,挑選第一筆 `architecture_doc_status=pending` 的 row。
|
|
15
|
+
7. 若 `scope=ops`,挑選第一筆 `ops_doc_status=pending` 的 row。
|
|
16
|
+
8. No-id auto selection 不自動挑選 `failed`、`partial`、`blocked`、`in_progress`、`generated`、`n/a` 或其他非 `pending` status;若要重跑這些 row,必須明確指定 `id`。
|
|
17
|
+
9. `review_status` 不參與 generation no-id auto selection;review workflow 有自己的 selection / status 規則。
|
|
18
|
+
|
|
19
|
+
明確指定 `id` 只鎖定 selected row,不代表直接覆蓋文件,也不得只因 target docs 或 `last_handoff` 已存在就跳過。Selected output file 的 create-or-update action 由 `generation-workflow.md` 的 Output Action Contract 擁有;既有內容比對與 material difference 判斷由 `source-tracing-rules.md` 擁有。
|
|
20
|
+
|
|
21
|
+
## Profile-Aware Completion
|
|
22
|
+
|
|
23
|
+
`generation_scope` 控制本次處理哪一份文件;`doc_profile` 控制 target 文件深度與 completion standard。Documenter 必須先用 selected row 的 `doc_profile` 與本次 `generation_scope` 建立 `doc_file_plan`,再依 evidence 決定三份文件中哪些需要產生、更新或標記 `N/A` / `Unresolved`。
|
|
24
|
+
|
|
25
|
+
支援 scope:
|
|
26
|
+
|
|
27
|
+
| scope | target document | status field |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| `all` | 三份文件全部處理 | `foundation_doc_status`、`architecture_doc_status`、`ops_doc_status` |
|
|
30
|
+
| `foundation` | `{name}-01-document-foundation-and-business.md` | `foundation_doc_status` |
|
|
31
|
+
| `architecture` | `{name}-02-core-architecture-flow-data-logic.md` | `architecture_doc_status` |
|
|
32
|
+
| `ops` | `{name}-03-error-ops-scenario-coverage.md` | `ops_doc_status` |
|
|
33
|
+
|
|
34
|
+
`full` 是 `doc_profile` value,不是 execution scope。`full` 不等於無條件產生所有 possible content;本次 scope 內的正式章節應保留章節標題,但不存在、未觸發或沒有 evidence 的章節只輸出簡短 `N/A` / `無法由目前來源確認` / `Unresolved` 原因,不產生空表格、空圖表或推測內容。Reviewer 不得把已清楚標示且不影響 completion 的 non-applicable chapter 當作 generation gap。
|
|
35
|
+
|
|
36
|
+
## Status Transitions
|
|
37
|
+
|
|
38
|
+
Generation:
|
|
39
|
+
|
|
40
|
+
| generation entrypoint / scope | status fields owned by this run |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `00-generate-target-all-spec.prompt.md` / `all` | `foundation_doc_status`、`architecture_doc_status`、`ops_doc_status` |
|
|
43
|
+
| `01-generate-target-foundation-spec.prompt.md` / `foundation` | `foundation_doc_status` |
|
|
44
|
+
| `02-generate-target-architecture-spec.prompt.md` / `architecture` | `architecture_doc_status` |
|
|
45
|
+
| `03-generate-target-ops-spec.prompt.md` / `ops` | `ops_doc_status` |
|
|
46
|
+
|
|
47
|
+
Status update rules:
|
|
48
|
+
|
|
49
|
+
| event | status update |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| 選入本次 scope 產生流程 | 本次 scope owned status field 設為 `in_progress`;`all` scope 同時設定三個 doc status |
|
|
52
|
+
| 本次 selected output file 已產生、更新或經 reconciliation 判定 existing file 可作為目前 scope 的有效輸出 | 對應 doc status 設為 `generated` |
|
|
53
|
+
| 本次 scope 不適用 | 對應 doc status 設為 `n/a` |
|
|
54
|
+
| 本次 scope 產生未完成,但仍保留可審查 partial output | 對應 doc status 設為 `partial` |
|
|
55
|
+
| 本次 scope 找不到必要來源或 target boundary 受阻 | 對應 doc status 設為 `blocked`,且 `review_status=blocked` |
|
|
56
|
+
| 本次 scope 產生發生錯誤 | 對應 doc status 設為 `failed` |
|
|
57
|
+
| 本次產生或更新任一文件,且未 blocked | `review_status=pending` |
|
|
58
|
+
|
|
59
|
+
Completion flag update:
|
|
60
|
+
|
|
61
|
+
- 每次 generation run 結束後,都必須檢查 selected row 的 `document_path` 下三份 target SPEC 文件是否存在。
|
|
62
|
+
- 若 `{name}-01-document-foundation-and-business.md`、`{name}-02-core-architecture-flow-data-logic.md`、`{name}-03-error-ops-scenario-coverage.md` 三份文件都存在,設定 `document_completed_flag(Y/N)=Y`。
|
|
63
|
+
- 若三份文件尚未齊全,設定或保持 `document_completed_flag(Y/N)=N`。
|
|
64
|
+
- `document_completed_flag(Y/N)` 不等待 `review_status=passed`,也不代表 review 已通過。
|
|
65
|
+
- Generation workflow 不應將 `review_status` 設為 `passed`、`failed` 或 `waived`;這些狀態只由 review workflow 更新。Generation 只可在有文件產生/更新時設為 `pending`,或在 source/blocker 情境設為 `blocked`。
|
|
66
|
+
|
|
67
|
+
Review:
|
|
68
|
+
|
|
69
|
+
| event | status update |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| 開始審查 | `review_status=pending` |
|
|
72
|
+
| 審查通過 | `review_status=passed` |
|
|
73
|
+
| 審查通過但仍有 coverage gap | `review_status=passed`, `notes` 保留 gap summary |
|
|
74
|
+
| 審查失敗 | `review_status=failed` |
|
|
75
|
+
| 審查受阻 | `review_status=blocked` |
|
|
76
|
+
| 明確豁免審查 | `review_status=waived` |
|
|
77
|
+
|
|
78
|
+
`document_completed_flag(Y/N)` 表示三份 target SPEC 文件是否已存在,不再由 `review_status` gate。Review workflow 只更新 `review_status` 與 review findings;除非 review 發現三份文件實際缺漏或路徑錯誤,否則不應只因 review 未通過而把 completion flag 改回 `N`。
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
sys.dont_write_bytecode = True
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
for parent in Path(__file__).resolve().parents:
|
|
11
|
+
shared_scripts = parent / "source-code-to-spec-tools" / "scripts"
|
|
12
|
+
if (shared_scripts / "queue_contract.py").exists():
|
|
13
|
+
sys.path.insert(0, str(shared_scripts))
|
|
14
|
+
break
|
|
15
|
+
else:
|
|
16
|
+
raise SystemExit("Cannot locate source-code-to-spec-tools/scripts/queue_contract.py")
|
|
17
|
+
|
|
18
|
+
from queue_contract import (
|
|
19
|
+
DOC_STATUSES,
|
|
20
|
+
MAIN_COLUMNS,
|
|
21
|
+
REVIEW_STATUSES,
|
|
22
|
+
normalize_completed_flag as normalize_flag,
|
|
23
|
+
normalize_doc_profile,
|
|
24
|
+
normalize_status,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
SUPPORTED_SCOPE_TEXT = "all, foundation, architecture, ops"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def split_markdown_row(line):
|
|
32
|
+
line = line.strip()
|
|
33
|
+
if not line.startswith("|") or not line.endswith("|"):
|
|
34
|
+
return []
|
|
35
|
+
cells = []
|
|
36
|
+
current = []
|
|
37
|
+
escaped = False
|
|
38
|
+
for char in line[1:-1]:
|
|
39
|
+
if escaped:
|
|
40
|
+
current.append(char)
|
|
41
|
+
escaped = False
|
|
42
|
+
elif char == "\\":
|
|
43
|
+
escaped = True
|
|
44
|
+
elif char == "|":
|
|
45
|
+
cells.append("".join(current).strip())
|
|
46
|
+
current = []
|
|
47
|
+
else:
|
|
48
|
+
current.append(char)
|
|
49
|
+
cells.append("".join(current).strip())
|
|
50
|
+
return cells
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def markdown_escape(value):
|
|
54
|
+
return str(value or "").replace("|", "\\|").strip()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def normalize_row(row):
|
|
58
|
+
normalized = {column: row.get(column, "") for column in MAIN_COLUMNS}
|
|
59
|
+
normalized["doc_profile"] = normalize_doc_profile(
|
|
60
|
+
normalized.get("doc_profile", ""), normalized.get("source_type", "")
|
|
61
|
+
)
|
|
62
|
+
for field in ("foundation_doc_status", "architecture_doc_status", "ops_doc_status"):
|
|
63
|
+
normalized[field] = normalize_status(normalized[field], DOC_STATUSES, "pending")
|
|
64
|
+
normalized["review_status"] = normalize_status(
|
|
65
|
+
normalized["review_status"], REVIEW_STATUSES, "not_started"
|
|
66
|
+
)
|
|
67
|
+
normalized["document_completed_flag(Y/N)"] = normalize_flag(
|
|
68
|
+
normalized["document_completed_flag(Y/N)"]
|
|
69
|
+
)
|
|
70
|
+
return normalized
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def read_queue(path):
|
|
74
|
+
path = Path(path)
|
|
75
|
+
lines = path.read_text(encoding="utf-8-sig").splitlines()
|
|
76
|
+
for index, line in enumerate(lines):
|
|
77
|
+
header = split_markdown_row(line)
|
|
78
|
+
if header != MAIN_COLUMNS:
|
|
79
|
+
continue
|
|
80
|
+
rows = []
|
|
81
|
+
end = index + 2
|
|
82
|
+
for data_index in range(index + 2, len(lines)):
|
|
83
|
+
if not lines[data_index].strip().startswith("|"):
|
|
84
|
+
break
|
|
85
|
+
values = split_markdown_row(lines[data_index])
|
|
86
|
+
if len(values) != len(header):
|
|
87
|
+
break
|
|
88
|
+
rows.append(normalize_row(dict(zip(header, values))))
|
|
89
|
+
end = data_index + 1
|
|
90
|
+
return path, lines, index, end, rows
|
|
91
|
+
raise SystemExit(f"No current docs-target-queue target table found in {path}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def write_queue(path, lines, table_start, table_end, rows):
|
|
95
|
+
new_table = render_table(rows)
|
|
96
|
+
updated = lines[:table_start] + new_table + lines[table_end:]
|
|
97
|
+
Path(path).write_text("\n".join(updated) + "\n", encoding="utf-8", newline="\n")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def render_table(rows):
|
|
101
|
+
table = []
|
|
102
|
+
table.append("| " + " | ".join(MAIN_COLUMNS) + " |")
|
|
103
|
+
table.append("| " + " | ".join("---" for _ in MAIN_COLUMNS) + " |")
|
|
104
|
+
for row in rows:
|
|
105
|
+
table.append("| " + " | ".join(markdown_escape(row.get(column, "")) for column in MAIN_COLUMNS) + " |")
|
|
106
|
+
return table
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def row_for_id(rows, target_id):
|
|
110
|
+
for row in rows:
|
|
111
|
+
if row.get("id", "").casefold() == target_id.casefold():
|
|
112
|
+
return row
|
|
113
|
+
raise SystemExit(f"Target id not found: {target_id}")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def scope_fields(scope):
|
|
117
|
+
scope = str(scope or "").strip().lower()
|
|
118
|
+
if scope == "foundation":
|
|
119
|
+
return ["foundation_doc_status"]
|
|
120
|
+
if scope == "architecture":
|
|
121
|
+
return ["architecture_doc_status"]
|
|
122
|
+
if scope == "ops":
|
|
123
|
+
return ["ops_doc_status"]
|
|
124
|
+
if scope == "all":
|
|
125
|
+
return ["foundation_doc_status", "architecture_doc_status", "ops_doc_status"]
|
|
126
|
+
raise SystemExit(f"Unsupported scope: {scope}. Supported scopes: {SUPPORTED_SCOPE_TEXT}")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def is_selectable(row, scope):
|
|
130
|
+
normalized_scope = str(scope or "").strip().lower()
|
|
131
|
+
scope_fields(normalized_scope)
|
|
132
|
+
if normalized_scope == "all":
|
|
133
|
+
return normalize_flag(row.get("document_completed_flag(Y/N)")) == "N"
|
|
134
|
+
for field in scope_fields(normalized_scope):
|
|
135
|
+
if row.get(field) == "pending":
|
|
136
|
+
return True
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def select_row(rows, args):
|
|
141
|
+
scope_fields(args.scope)
|
|
142
|
+
target_id = getattr(args, "id", None)
|
|
143
|
+
if target_id:
|
|
144
|
+
return row_for_id(rows, target_id)
|
|
145
|
+
for row in rows:
|
|
146
|
+
if is_selectable(row, args.scope):
|
|
147
|
+
return row
|
|
148
|
+
raise SystemExit(f"No selectable target row found for scope={args.scope}")
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def command_select(args):
|
|
152
|
+
_, _, _, _, rows = read_queue(args.queue)
|
|
153
|
+
row = select_row(rows, args)
|
|
154
|
+
print(json.dumps(row, ensure_ascii=False, indent=2))
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def command_update(args):
|
|
158
|
+
path, lines, start, end, rows = read_queue(args.queue)
|
|
159
|
+
row = row_for_id(rows, args.id)
|
|
160
|
+
for argument_name, field_name in (
|
|
161
|
+
("foundation", "foundation_doc_status"),
|
|
162
|
+
("architecture", "architecture_doc_status"),
|
|
163
|
+
("ops", "ops_doc_status"),
|
|
164
|
+
):
|
|
165
|
+
value = getattr(args, argument_name)
|
|
166
|
+
if value is not None:
|
|
167
|
+
row[field_name] = normalize_status(value, DOC_STATUSES, row[field_name])
|
|
168
|
+
if args.review is not None:
|
|
169
|
+
row["review_status"] = normalize_status(args.review, REVIEW_STATUSES, row["review_status"])
|
|
170
|
+
if args.profile is not None:
|
|
171
|
+
row["doc_profile"] = normalize_doc_profile(args.profile, row.get("source_type", ""))
|
|
172
|
+
if args.completed is not None:
|
|
173
|
+
row["document_completed_flag(Y/N)"] = normalize_flag(args.completed)
|
|
174
|
+
if args.last_handoff is not None:
|
|
175
|
+
row["last_handoff"] = args.last_handoff
|
|
176
|
+
if args.notes is not None:
|
|
177
|
+
row["notes"] = args.notes
|
|
178
|
+
write_queue(path, lines, start, end, rows)
|
|
179
|
+
print(json.dumps(row, ensure_ascii=False, indent=2))
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def build_parser():
|
|
183
|
+
parser = argparse.ArgumentParser(description="Select and update docs-target-queue target queue rows.")
|
|
184
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
185
|
+
|
|
186
|
+
select = subparsers.add_parser("select", help="Select an explicit id or next eligible row.")
|
|
187
|
+
select.add_argument("--queue", required=True)
|
|
188
|
+
select.add_argument("--id")
|
|
189
|
+
select.add_argument("--scope", default="all", help=f"Supported scopes: {SUPPORTED_SCOPE_TEXT}")
|
|
190
|
+
select.set_defaults(func=command_select)
|
|
191
|
+
|
|
192
|
+
select_next = subparsers.add_parser("select-next", help="Select the next eligible row.")
|
|
193
|
+
select_next.add_argument("--queue", required=True)
|
|
194
|
+
select_next.add_argument("--scope", default="all", help=f"Supported scopes: {SUPPORTED_SCOPE_TEXT}")
|
|
195
|
+
select_next.set_defaults(func=command_select)
|
|
196
|
+
|
|
197
|
+
update = subparsers.add_parser("update", help="Update queue status fields for one row.")
|
|
198
|
+
update.add_argument("--queue", required=True)
|
|
199
|
+
update.add_argument("--id", required=True)
|
|
200
|
+
update.add_argument("--foundation")
|
|
201
|
+
update.add_argument("--architecture")
|
|
202
|
+
update.add_argument("--ops")
|
|
203
|
+
update.add_argument("--review")
|
|
204
|
+
update.add_argument("--profile")
|
|
205
|
+
update.add_argument("--completed")
|
|
206
|
+
update.add_argument("--last-handoff")
|
|
207
|
+
update.add_argument("--notes")
|
|
208
|
+
update.set_defaults(func=command_update)
|
|
209
|
+
|
|
210
|
+
return parser
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def main():
|
|
214
|
+
args = build_parser().parse_args()
|
|
215
|
+
args.func(args)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
try:
|
|
220
|
+
main()
|
|
221
|
+
except BrokenPipeError:
|
|
222
|
+
sys.exit(1)
|