監控頁三塊的接法收進腳本,組頁那一步不再由呼叫端臨場挑工具 #34

Merged
admin merged 2 commits from feat/patrol-rebuild-joins-the-three-blocks into develop 2026-09-04 09:45:00 +00:00
5 changed files with 13 additions and 7 deletions
Showing only changes of commit a050404a77 - Show all commits
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-assist",
"version": "0.2.6",
"version": "0.2.7",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills",
"author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-assist",
"version": "0.2.6",
"version": "0.2.7",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills",
"jsc": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-assist",
"version": "0.2.6",
"version": "0.2.7",
"description": "助理:事件收攏、健康巡檢與待辦簿(MONITOR_{HASH} wiki 頁)",
"skills": "./skills/",
"jsc": {
File diff suppressed because one or more lines are too long
+9 -3
View File
@@ -71,7 +71,7 @@ Every tool below is addressed through `{CURRENT}/{plugin}`, with `{CURRENT}` sta
| What it does | Path to run |
| --- | --- |
| one patrol round | `{CURRENT}/jsc-assist/tools/patrol.sh` |
| one patrol round, and joining the monitor page's three blocks | `{CURRENT}/jsc-assist/tools/patrol.sh` |
| the system scheduler | `{CURRENT}/jsc-assist/tools/schedule.sh` |
| the task book, the only writer there is | `{CURRENT}/jsc-assist/tools/tasks.sh` |
| the built-in check items, reconciled against the delegation list | `{CURRENT}/jsc-assist/tools/seed-tasks.sh` |
@@ -356,15 +356,21 @@ One round: read five sources, record the result, then beat. Everything before th
3. **Rebuild `MONITOR_{HASH}` from its three blocks.** Hand it to `jsc-gitea:wiki` with page type `MONITOR`, so the repo is the one `gitea.sh wiki-repo MONITOR` resolves — `JSC_WIKI_REPO_MONITOR`, then `JSC_WIKI_REPO`, then exit 3. This is the content page and it stays in that repo; only the directory page of step 4 moved to the `CONTENTS` repo, and neither chain ever falls back to the other. Read the page back first, then build the new body out of what came back plus this round's files, in this order and with nothing else on the page:
**The three blocks are joined by `{CURRENT}/jsc-assist/tools/patrol.sh rebuild --old {the file the old page was read into}`, never by hand.** It prints `rebuilt_file=` — put that file. It also prints `old_format=`, `blocks=`, `summary_rows=` and `old_rows_kept=`; carry those into the report. Exit 6 means an argument was rejected or the old-page file is not there, exit 5 a scratch file could not be written; both take step 3's abort row.
Joining them by hand is what this replaces, and the reason is worth keeping. The join is a fixed shape, so leaving it to the caller meant a fresh agent picked its own tools for it every round: one round reached for `awk`, was refused by the permission gate twice, worked around it because somebody was there to watch, and said in its own report that the same refusal would hang an unattended round — with the round lock already taken. The scratch directory had accumulated 124 files by then, named `newpage.md`, `new-page.md`, `new_page.md`, `page-new.md` and so on: the same join, redone every round, under a different set of names. **A step with one correct shape does not belong in a prompt.** What the script joins:
| Block | Where it comes from |
| --- | --- |
| 本頁基本資料 | the old page, byte for byte from its heading to the line before 最新一輪. Never rewritten, never re-derived |
| 本頁基本資料 | the old page, byte for byte from its heading to the line before 最新一輪. Never rewritten, never re-derived — the script does not even normalise its trailing blank lines |
| 最新一輪 | the whole content of `latest_file`, replacing the old block entirely |
| 近 24 輪摘要 | `summary_file`, which already holds the heading, the five-column table header (`巡檢時間`、`本輪判定`、`各項成敗`、`待人處理`、`警示來源`) and this round's row; then the old table's data rows in their old order underneath, cut so the table holds at most 24 rows |
An old-format page — per-round sections stacked up, no 最新一輪 heading — is detected by the script itself, which keeps the basic-data block, drops the stacked sections, starts the table with this round's row, and prints `old_format=yes converted=1`. Report that the page was converted.
**Verify the page's links before the write.** List every link the rebuilt body carries — the ones the latest-round block brought in, and any that survived in the block carried over from the old page — and run `{CURRENT}/jsc-gitea/tools/link-check.sh` over the whole list. Exit 0 is the only result that permits the write. On exit 1 report the `DEAD` lines verbatim, then run `{CURRENT}/jsc-assist/tools/patrol.sh abort --round {round}` and stop: a round that writes a dead link records a false trail nobody can follow back. Exits 2, 3 and 7 take the same abort, each reported by the rule B table above. A body carrying no link at all needs no call — say so in the report rather than claiming a check that never ran.
Put the whole page. An old-format page — per-round sections stacked up, no summary table — has no rows to carry over: keep its `本頁基本資料` block, drop the stacked sections, let the table start with this round's row, and say in the report that the page was converted. Only exit 4 from the read permits creating the page instead, and then the body is the whole content of `newpage_file`, which already carries all three blocks. Exit 7 and exit 8 mean the old content is unknown: create nothing, write nothing — rebuilding a page from an unknown original throws the summary table away. On any write failure — including exit 3 with no wiki repo configured for `MONITOR`, which the patrol cannot ask about — run `{CURRENT}/jsc-assist/tools/patrol.sh abort --round {round}`, report the code, and stop. **No record, no heartbeat**, and that verdict belongs to this step alone: the round's result lives on this page, so a repo this step cannot resolve leaves the round with nowhere to be recorded. Step 4 is judged on its own terms. Completion condition: `link-check.sh` exited 0 over the body's links or the body carried none, the put or the create returned success, and the page holds exactly three blocks with the summary table at 24 rows or fewer and this round's row on top, or the abort ran and the round was reported as unrecorded with its exit code.
Put the whole page. Only exit 4 from the read permits creating the page instead, and then the body is the whole content of `newpage_file`, which already carries all three blocks. Exit 7 and exit 8 mean the old content is unknown: create nothing, write nothing — rebuilding a page from an unknown original throws the summary table away. On any write failure — including exit 3 with no wiki repo configured for `MONITOR`, which the patrol cannot ask about — run `{CURRENT}/jsc-assist/tools/patrol.sh abort --round {round}`, report the code, and stop. **No record, no heartbeat**, and that verdict belongs to this step alone: the round's result lives on this page, so a repo this step cannot resolve leaves the round with nowhere to be recorded. Step 4 is judged on its own terms. Completion condition: `link-check.sh` exited 0 over the body's links or the body carried none, the put or the create returned success, and the page holds exactly three blocks with the summary table at 24 rows or fewer and this round's row on top, or the abort ran and the round was reported as unrecorded with its exit code.
4. **Update this machine's block in `MONITOR_CONTENTS`, through `jsc-gitea/tools/wiki-contents.sh`.** That page is a directory every machine writes to, and it lives in the repo `gitea.sh wiki-repo CONTENTS` resolves — `JSC_WIKI_REPO_CONTENTS`, then `JSC_WIKI_REPO`, then exit 3, and never a fallback to `JSC_WIKI_REPO_MONITOR`. The page carries no table: it is an H1, a `>` preamble, and then one H2 block per machine — the heading is that machine's monitor page name, and the fields are one `- {name}:{value}` bullet each underneath. The script owns the read-match-write of one block, so never read this page and rebuild it by hand, never write it through `jsc-gitea:wiki`, and never rebuild it the way step 3 rebuilds the content page — every other block here belongs to a machine that is not this one, and one careless whole-page write deletes their records.